Re: Re: Re: Rewriting E164 numbers after GW selection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



please provide this patch in 2.2 beta i am so worried.
________________
Engr. Rafat Subhan
Software Developer
Advanced Communications
House no 423 F-11/3
Islamabad
mail: rafat@advcomm.net
MSN: qudrat2210@hotmail.com
Cell : +92-300-5195822
http://www.advcomm.net

----- Original Message -----
From: <Ian.Campbell@band-x.com>
To: <openh323gk-users@lists.sourceforge.net>;
<openh323gk-developer@lists.sourceforge.net>
Cc: <Justin.Wells@band-x.com>
Sent: Tuesday, December 16, 2003 5:23 PM
Subject:  Re: Re: Rewriting E164 numbers after GW
selection


> Hello All,
> I have finally got round to implementing per gateway E164 number
> rewriting as discussed in this thread in early November. Attached is a
patch
> providing it for version 2.0.6. The code provides triple stage rewriting:
>
> per gw input E164 rewriting -> standard E164 rewriting -> (endpoint
> selection) -> per gw output E164 rewriting
>
> This is configured in a new configuration section as follows:
>
> [RasSrv::GWRewriteE164]
> foo=out=1223=2323
> foo=out=13=4444
> foo=in=777=8888
> bar=in=777=9999
>
> And so on. The first element in the line is the GW that the rule is being
> applied to the second the direction (whether it is applied before the
> standard rewriting and the endpoint selection or after) and finally the
rule
> itself in the same as the standard rewriting ([RasSrv::RewriteE164]). All
> this allows much more sophisticated control of what is sent to the
endpoint
> for example an authentication prefix and per endpoint routing policies to
be
> constructed. The code has been tested by me, but should probably be
> considered alpha quality for now.
>
> Jan et al. is there anything I need to do (beyond applying this to the 2.2
> CVS archive) to get this included in a future release?
>
> Regards,
>
> Ian Campbell
> Band-X Ltd.
>
> diff -r -U 3 openh323gk/ProxyChannel.cxx
> openh323gk.gwrewrite/ProxyChannel.cxx
> --- openh323gk/ProxyChannel.cxx 2003-09-24 10:19:44.000000000 +0000
> +++ openh323gk.gwrewrite/ProxyChannel.cxx 2003-12-15
> 16:55:05.000000000 +0000
> @@ -393,6 +393,8 @@
>
>  ProxySocket::Result CallSignalSocket::ReceiveData()
>  {
> + PString in_rewrite_id,out_rewrite_id;
> +
>   if (!ReadTPKT())
>   return NoData;
>
> @@ -424,7 +426,7 @@
>   }
>   m_crv = (m_lastQ931->GetCallReference() | 0x8000u);
>   m_setupUUIE = new H225_H323_UserInformation(signal);
> - changed = OnSetup(body);
> + changed =
> OnSetup(body,in_rewrite_id,out_rewrite_id);
>   break;
>   case H225_H323_UU_PDU_h323_message_body::e_callProceeding:
>   changed = OnCallProceeding(body);
> @@ -492,11 +494,28 @@
>   if (m_lastQ931->HasIE(Q931::CalledPartyNumberIE)) {
>   unsigned plan, type;
>   PString calledNumber;
> +
> + // Do per GW inbound rewrite before global rewrite
> + if (m_lastQ931->GetCalledPartyNumber(calledNumber, &plan,
> &type) &&
> +
> Toolkit::Instance()->GWRewritePString(in_rewrite_id,true,calledNumber)) {
> + m_lastQ931->SetCalledPartyNumber(calledNumber, plan,
> type);
> + changed = true;
> + }
> +
> + // Normal rewrite
>   if (m_lastQ931->GetCalledPartyNumber(calledNumber, &plan,
> &type) &&
>       Toolkit::Instance()->RewritePString(calledNumber)) {
>   m_lastQ931->SetCalledPartyNumber(calledNumber, plan,
> type);
>   changed = true;
>   }
> +
> + // Do per GW outbound rewrite after global rewrite
> + if (m_lastQ931->GetCalledPartyNumber(calledNumber, &plan,
> &type) &&
> +
> Toolkit::Instance()->GWRewritePString(out_rewrite_id,false,calledNumber))
{
> + m_lastQ931->SetCalledPartyNumber(calledNumber, plan,
> type);
> + changed = true;
> + }
> +
>   }
>
>   if (m_lastQ931->HasIE(Q931::DisplayIE)) {
> @@ -687,6 +706,9 @@
>
>  TCPProxySocket *CallSignalSocket::ForwardCall()
>  {
> +
> + PString in_rewrite_id,out_rewrite_id;
> +
>   // disconnect from forwarder
>
> SendReleaseComplete(H225_ReleaseCompleteReason::e_facilityCallDeflection);
>   Close();
> @@ -744,7 +766,7 @@
>   ret->m_h245handler = 0;
>
>   CallSignalSocket *result = 0;
> - if (ret->OnSetup(SetupUUIE)) {
> + if (ret->OnSetup(SetupUUIE,in_rewrite_id,out_rewrite_id)) {
>   SetUUIE(*Setup, suuie);
>   Setup->Encode(ret->buffer);
>   PrintQ931(5, "Forward Setup to " + ret->remote->Name(),
> Setup, &suuie);
> @@ -774,7 +796,7 @@
>   return result;
>  }
>
> -bool CallSignalSocket::OnSetup(H225_Setup_UUIE & Setup)
> +bool CallSignalSocket::OnSetup(H225_Setup_UUIE & Setup, PString
> &in_rewrite_id, PString &out_rewrite_id)
>  {
>   const time_t setupTime = time(NULL);
>
> @@ -791,8 +813,26 @@
>   H323SetAliasAddress(destination,
> Setup.m_destinationAddress[0]);
>   }
>   }
> - if (Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress))
> + if (Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)) {
> +
> + // Do inbound per GWRewrite if we can before global rewrite
> + if (Setup.HasOptionalField(H225_Setup_UUIE::e_sourceAddress)
> == true) {
> + PString source;
> + PStringArray tokenised_source;
> + source = AsString(Setup.m_sourceAddress);
> +
> + // Chop up source to get the h323_ID or dialedDigits
> + tokenised_source = source.Tokenise(PString(":"));
> +
> + if (tokenised_source.GetSize() == 2) {
> +
>
Toolkit::Instance()->GWRewriteE164(tokenised_source[0],true,Setup.m_destinat
> ionAddress);
> + in_rewrite_id = tokenised_source[0];
> + }
> + }
> +
> + // Normal rewrite
>
> Toolkit::Instance()->RewriteE164(Setup.m_destinationAddress);
> + }
>
>  #if PTRACING
>   PString callid;
> @@ -815,10 +855,11 @@
>   GkClient *gkClient = RasThread->GetGkClient();
>   Address fromIP;
>   GetPeerAddress(fromIP);
> +
>   if (m_call) {
>  #ifdef HAS_ACCT
>   if( m_call->GetCalledStationId().IsEmpty() )
> - if(
> Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)
> + if(
> Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)
>   && (Setup.m_destinationAddress.GetSize() >
> 0) )
>   {
>   const PString calledPartyNumber =
> GetBestAliasAddressString(
> @@ -830,10 +871,10 @@
>   if( !calledPartyNumber.IsEmpty() )
>
> m_call->SetCalledStationId(calledPartyNumber);
>   }
> -
> +
>  #endif
>   m_call->SetSetupTime(setupTime);
> -
> +
>   if (m_call->IsSocketAttached()) {
>   PTRACE(2, "Q931\tWarning: socket already attached
> for callid " << callid);
>   return false;
> @@ -866,7 +907,7 @@
>   */
>   {
>   ReadLock cfgLock(ConfigReloadMutex);
> -
> +
>   GkAuthenticatorList* authList =
> RasThread->GetAuthList();
>   if( authList )
>   {
> @@ -877,7 +918,7 @@
>   PTRACE(3,"GKAUTH\tH.225 Setup
> authentication failed: "<<reason);
>   return false;
>   }
> -
> +
>   if( limit > 0 )
>   m_call->SetDurationLimit( limit );
>   }
> @@ -901,14 +942,16 @@
>   }
>  #endif
>   }
> +
>   } else {
>   bool fromParent;
>   if (!RasThread->AcceptUnregisteredCalls(fromIP, fromParent))
> {
>   PTRACE(3, "Q931\tNo CallRec found in CallTable for
> callid " << callid);
>   return false;
>   }
> - if (fromParent)
> + if (fromParent) {
>   gkClient->RewriteE164(*m_lastQ931, Setup, false);
> + }
>
>   endptr called;
>   PString destinationString;
> @@ -934,14 +977,14 @@
>   // workaround for bandwidth, as OpenH323 library :p
>   CallRec *call = new CallRec(Setup.m_callIdentifier,
> Setup.m_conferenceID, destinationString, sourceString, 100000,
h245Routed);
>   call->SetCalled(called, m_crv);
> -
> - call->SetSetupTime(setupTime);
> -
> +
> + call->SetSetupTime(setupTime);
> +
>   long durationLimit = -1;
> -
> +
>   {
>   ReadLock cfgLock(ConfigReloadMutex);
> -
> +
>   GkAuthenticatorList* authList =
> RasThread->GetAuthList();
>   if( authList )
>   {
> @@ -955,7 +998,7 @@
>   }
>
>  #ifdef HAS_ACCT
> - if(
> Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)
> + if(
> Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)
>   && (Setup.m_destinationAddress.GetSize() >
> 0) ) {
>   const PString calledPartyNumber =
> GetBestAliasAddressString(
>   Setup.m_destinationAddress,
> @@ -966,7 +1009,7 @@
>   if( !calledPartyNumber.IsEmpty() )
>
> call->SetCalledStationId(calledPartyNumber);
>   }
> -
> +
>   GkAcctLoggers* acct =
> Toolkit::Instance()->GetAcctList();
>   if( acct != NULL )
>   if( call->GetAcctEventsLogged() &
> GkAcctLogger::AcctStart )
> @@ -988,7 +1031,7 @@
>   }
>  #endif
>   }
> -
> +
>   if( durationLimit > 0 )
>   call->SetDurationLimit( durationLimit );
>
> @@ -1000,6 +1043,26 @@
>   }
>   }
>
> + // Do outbound per GW rewrite
> + if (Setup.HasOptionalField(H225_Setup_UUIE::e_destinationAddress)) {
> + endptr rewriteEndPointOut = m_call->GetCalledParty();
> + if (rewriteEndPointOut != NULL) {
> + PString source;
> + PStringArray tokenised_source;
> +
> + source =
> AsString(rewriteEndPointOut->GetAliases()[0]);
> +
> + // Chop up source to get the h323_ID or dialedDigits
> + tokenised_source = source.Tokenise(PString(":"));
> +
> + if (tokenised_source.GetSize() == 2) {
> +
>
Toolkit::Instance()->GWRewriteE164(tokenised_source[0],false,Setup.m_destina
> tionAddress);
> + out_rewrite_id = tokenised_source[0];
> + }
> +
> + }
> + }
> +
>   const H225_TransportAddress *addr = m_call->GetCalledAddress();
>   if (!addr || !GetIPAndPortFromTransportAddr(*addr, peerAddr,
> peerPort)) {
>   CallTable::Instance()->RemoveCall(m_call);
> @@ -1067,7 +1130,7 @@
>  {
>   if (m_call) // hmm... it should not be null
>   m_call->SetConnected();
> -
> +
>  #ifndef NDEBUG
>   if (!Connect.HasOptionalField(H225_Connect_UUIE::e_callIdentifier))
> {
>   PTRACE(1, "Q931\tConnect_UUIE doesn't contain
> CallIdentifier!");
> diff -r -U 3 openh323gk/ProxyChannel.h openh323gk.gwrewrite/ProxyChannel.h
> --- openh323gk/ProxyChannel.h 2003-04-10 02:39:55.000000000 +0000
> +++ openh323gk.gwrewrite/ProxyChannel.h 2003-12-15 16:46:50.000000000
+0000
> @@ -94,7 +94,7 @@
>
>   LogicalChannel *FindLogicalChannel(WORD);
>   RTPLogicalChannel *FindRTPLogicalChannelBySessionID(WORD);
> -
> +
>  private:
>   // override from class H245Handler
>   virtual bool HandleRequest(H245_RequestMessage &);
> @@ -152,7 +152,7 @@
>   TCPProxySocket *InternalConnectTo();
>   TCPProxySocket *ForwardCall();
>
> - bool OnSetup(H225_Setup_UUIE &);
> + bool OnSetup(H225_Setup_UUIE &, PString &in_rewrite_id, PString
> &out_rewrite_id);
>   bool OnCallProceeding(H225_CallProceeding_UUIE &);
>   bool OnConnect(H225_Connect_UUIE &);
>   bool OnAlerting(H225_Alerting_UUIE &);
> diff -r -U 3 openh323gk/RasSrv.cxx openh323gk.gwrewrite/RasSrv.cxx
> --- openh323gk/RasSrv.cxx 2003-09-24 10:19:44.000000000 +0000
> +++ openh323gk.gwrewrite/RasSrv.cxx 2003-12-16 12:27:21.000000000 +0000
> @@ -20,7 +20,7 @@
>  //
>  //////////////////////////////////////////////////////////////////
>
> -#if (_MSC_VER >= 1200)
> +#if (_MSC_VER >= 1200)
>  #pragma warning( disable : 4800 ) // one performance warning off
>  #pragma warning( disable : 4786 ) // warning about too long debug symbol
> off
>  #define snprintf _snprintf
> @@ -361,7 +361,7 @@
>   }
>   }
>  }
> -
> +
>  #if HAS_WAITARQ
>  BOOL H323RasSrv::RouteToAlias(PString TargetAlias, PString SourceEpId,
> PString CallRef)
>  {
> @@ -374,7 +374,7 @@
>   return wArqList->RouteReject(SourceEpId, CallRef);
>  }
>  #endif
> -
> +
>  int NeighborList::SendLRQ(int seqNum, const H225_AdmissionRequest &
> obj_arq, const endptr & e)
>  {
>   int nbCount = 0;
> @@ -396,7 +396,7 @@
>   }
>   }
>   }
> -
> +
>   eIter = List.end();
>   for(Iter = List.begin(); Iter != eIter; ++Iter) {
>   if (Iter->SendLRQ(seqNum, obj_arq, RasSrv, e))
> @@ -428,7 +428,7 @@
>   }
>   }
>   }
> -
> +
>   eIter = List.end();
>   for(Iter = List.begin(); Iter != eIter; ++Iter) {
>   if (Iter->ForwardLRQ(ip, obj_lrq, RasSrv))
> @@ -470,7 +470,7 @@
>        : PThread(10000, NoAutoDeleteThread), requestSeqNum(0)
>  {
>   GKHome = _GKHome;
> -
> +
>          GKRasPort = GkConfig()->GetInteger("UnicastRasPort",
> GK_DEF_UNICAST_RAS_PORT);
>
>   EndpointTable = RegistrationTable::Instance(); //initialisation is
> done in LoadConfig
> @@ -492,7 +492,7 @@
>  #if HAS_WAITARQ
>   wArqList = new WaitingARQlist();
>  #endif
> -
> +
>   LoadConfig();
>
>   arqPendingList = new NBPendingList(this,
> GkConfig()->GetInteger(LRQFeaturesSection, "NeighborTimeout", 2));
> @@ -536,7 +536,7 @@
>  #if HAS_WAITARQ
>   delete wArqList ;
>  #endif
> -
> +
>  }
>
>  void H323RasSrv::SetRoutedMode(bool routedSignaling, bool routedH245)
> @@ -638,7 +638,7 @@
>   const PStringArray tokens = altgks[idx].Tokenise(":",
> FALSE);
>   if (tokens.GetSize() < 4) {
>   PTRACE(1,"GK\tFormat error in AlternateGKs");
> - continue;
> + continue;
>   }
>
>   H225_AlternateGK & A = altGKs[idx];
> @@ -679,19 +679,19 @@
>          delete destAnalysisList;
>   destAnalysisList = new GkDestAnalysisList(GkConfig());
>   EndpointTable->Initialize(*destAnalysisList);
> -
> +
>  #if defined(HAS_LDAP) // shall use LDAP
> -
> +
>   // initialize LDAP
>   GkLDAP::Instance()->Initialize(*GkConfig());
> -
> +
>  #endif // HAS_LDAP
>
>  #if defined(HAS_WAITARQ) // supports VirtualQueues
>   // (re) load config
>   wArqList->LoadConfig();
>  #endif
> -
> +
>   // add neighbors
>   delete NeighborsGK;
>   NeighborsGK = new NeighborList(this, GkConfig());
> @@ -729,7 +729,7 @@
>   delete GkStatusThread;
>   GkStatusThread = 0;
>   }
> -
> +
>   PTRACE(1, "GK\tRasSrv closed");
>  }
>
> @@ -854,7 +854,7 @@
>
>   unsigned rsn = H225_GatekeeperRejectReason::e_securityDenial;
>   if ((redirectGK != e_noRedirect) || !authList->Check(obj_gr, rsn)) {
> - obj_rpl.SetTag(H225_RasMessage::e_gatekeeperReject);
> + obj_rpl.SetTag(H225_RasMessage::e_gatekeeperReject);
>   H225_GatekeeperReject & obj_grj = obj_rpl;
>   obj_grj.m_protocolIdentifier = obj_gr.m_protocolIdentifier;
>   if (redirectGK != e_noRedirect) {
> @@ -872,7 +872,7 @@
>   (const unsigned char *)
> obj_grj.m_rejectReason.GetTagName()
>   );
>   } else {
> - obj_rpl.SetTag(H225_RasMessage::e_gatekeeperConfirm);
> + obj_rpl.SetTag(H225_RasMessage::e_gatekeeperConfirm);
>   H225_GatekeeperConfirm & obj_gcf = obj_rpl;
>
>   obj_gcf.m_requestSeqNum = obj_gr.m_requestSeqNum;
> @@ -900,11 +900,11 @@
>   }
>  */
>   SelectH235Capability( obj_gr, obj_gcf  );
> -
> +
>   //if (bShellSendReply)cw   need to forward GRQ?
>   // ForwardRasMsg(obj_grq);
>
> - msg = PString(PString::Printf, "GCF|%s|%s|%s;\r\n",
> + msg = PString(PString::Printf, "GCF|%s|%s|%s;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char *) aliasListString,
>   (const unsigned char *)
> AsString(obj_gr.m_endpointType) );
> @@ -912,13 +912,13 @@
>
>   PTRACE(2, msg);
>   GkStatusThread->SignalStatus(msg);
> -
> +
>   return bShellSendReply;
>  }
>
>  void H323RasSrv::BuildRCF(H225_RasMessage & obj_ras, const
> H225_RegistrationRequest & rrq, const endptr & ep, const
PIPSocket::Address
> & rx_addr)
>  {
> - obj_ras.SetTag(H225_RasMessage::e_registrationConfirm);
> + obj_ras.SetTag(H225_RasMessage::e_registrationConfirm);
>   H225_RegistrationConfirm & rcf = obj_ras;
>   rcf.m_requestSeqNum = rrq.m_requestSeqNum;
>   rcf.m_protocolIdentifier = rrq.m_protocolIdentifier;
> @@ -990,7 +990,7 @@
>   if (bShellSendReply)
>   BuildRCF(obj_rpl, obj_rr, ep, rx_addr);
>   // forward lightweights, too
> - if (bShellForwardRequest)
> + if (bShellForwardRequest)
>   ForwardRasMsg(obj_rrq);
>
>   ep->Update(obj_rrq);
> @@ -1040,7 +1040,7 @@
>   rejectReason =
> H225_RegistrationRejectReason::e_securityDenial;
>   }
>   }
> -
> +
>   if (!bReject) {
>   unsigned rsn =
> H225_RegistrationRejectReason::e_securityDenial;
>   if (!authList->Check(obj_rr, rsn)) {
> @@ -1065,7 +1065,7 @@
>   } else {
>   bReject = TRUE;
>   rejectReason =
> H225_RegistrationRejectReason::e_duplicateAlias;
> - }
> + }
>   }
>
>   // reject the empty string
> @@ -1089,7 +1089,7 @@
>   rejectReason =
> H225_RegistrationRejectReason::e_invalidAlias;
>   break;
>   /* only while debugging
> - default:
> + default:
>   bReject = TRUE;
>
> rejectReason.SetTag(H225_RegistrationRejectReason::e_invalidAlias);
>   break;
> @@ -1112,9 +1112,9 @@
>   else
>   ep->SetNAT(false);
>   if (bShellSendReply) {
> - //
> + //
>   // OK, now send RCF
> - //
> + //
>   BuildRCF(obj_rpl, obj_rr, ep, rx_addr);
>   H225_RegistrationConfirm & rcf = obj_rpl;
>
> rcf.IncludeOptionalField(H225_RegistrationConfirm::e_terminalAlias);
> @@ -1148,7 +1148,7 @@
>
>   // Note that the terminalAlias is not optional here
> as we pass the auto generated alias if not were provided from
>   // the endpoint itself
> - PString msg(PString::Printf, "RCF|%s|%s|%s|%s;\r\n",
>
> + PString msg(PString::Printf, "RCF|%s|%s|%s|%s;\r\n",
>       (const unsigned char *)
> AsDotString(ep->GetCallSignalAddress()),
>       (const unsigned char *)
> AsString(ep->GetAliases()),
>       (const unsigned char *)
> AsString(obj_rr.m_terminalType),
> @@ -1167,7 +1167,7 @@
>   //
>   // final rejection handling
>   //
> - obj_rpl.SetTag(H225_RasMessage::e_registrationReject);
> + obj_rpl.SetTag(H225_RasMessage::e_registrationReject);
>   H225_RegistrationReject & rrj = obj_rpl;
>
>   rrj.m_requestSeqNum = obj_rr.m_requestSeqNum;
> @@ -1185,8 +1185,8 @@
>   aliasListString = AsString(obj_rr.m_terminalAlias);
>   else
>   aliasListString = " ";
> -
> - PString msg(PString::Printf, "RRJ|%s|%s|%s|%s;\r\n",
> +
> + PString msg(PString::Printf, "RRJ|%s|%s|%s|%s;\r\n",
>       inet_ntoa(rx_addr),
>       (const unsigned char *) aliasListString,
>       (const unsigned char *) AsString(obj_rr.m_terminalType),
> @@ -1284,18 +1284,18 @@
>  BOOL H323RasSrv::DoARQ(const PIPSocket::Address & rx_addr, const
> H225_RasMessage & obj_arq)
>  {
>   H225_RasMessage obj_rpl;
> - const H225_AdmissionRequest & obj_rr = obj_arq;
> -
> + const H225_AdmissionRequest & obj_rr = obj_arq;
> +
>   // find the caller
>   const endptr RequestingEP =
> EndpointTable->FindByEndpointId(obj_rr.m_endpointIdentifier);
>   if (!RequestingEP) {
>   // TODO: signal error on status thread
>   return false;
>   };
> -
> +
>   BOOL ShallSendReply = OnARQ(rx_addr, obj_arq, obj_rpl);
>
> - if (ShallSendReply) {
> + if (ShallSendReply) {
>   const H225_TransportAddress_ipAddress & ip =
> RequestingEP->GetRasAddress();
>   PIPSocket::Address ipaddress(ip.m_ip[0], ip.m_ip[1],
> ip.m_ip[2], ip.m_ip[3]);
>   PTRACE(1, "GK\tDoARQ  sendReply " << ipaddress << " " <<
> ip.m_port );
> @@ -1304,14 +1304,14 @@
>   return true;
>  }
>
> -
> +
>  /* Admission Request */
>  BOOL H323RasSrv::OnARQ(const PIPSocket::Address & rx_addr, const
> H225_RasMessage & obj_arq, H225_RasMessage & obj_rpl)
> -{
> +{
>   PTRACE(1, "GK\tARQ Received");
>
>   const H225_AdmissionRequest & obj_rr = obj_arq;
> -
> +
>   BOOL bReject = FALSE;
>   long callDurationLimit = -1;
>   unsigned rejectReason = 0;
> @@ -1321,15 +1321,32 @@
>   const endptr RequestingEP =
> EndpointTable->FindByEndpointId(obj_rr.m_endpointIdentifier);
>
>   endptr CalledEP(0);
> -
> +
>   if (CallTbl->Size() >= callLimit && !obj_rr.m_answerCall) {
>   bReject = TRUE;
>   rejectReason =
> H225_AdmissionRejectReason::e_resourceUnavailable;
>   PTRACE(1, "GK\tWarning: Exceed call limit!!");
>   } else if (RequestingEP) { // Is the ARQ from a registered endpoint?
>   bool bHasDestInfo =
> (obj_rr.HasOptionalField(H225_AdmissionRequest::e_destinationInfo) &&
> obj_rr.m_destinationInfo.GetSize() >= 1);
> - if (bHasDestInfo) // apply rewriting rules
> + // apply rewriting rules
> + if (bHasDestInfo) {
> +
> + PString source;
> + PStringArray tokenised_source;
> +
> + // Do inbound per GW rewriting first
> + source = AsString(RequestingEP->GetAliases()[0]);
> +
> + // Chop up source to get the h323_ID or dialedDigits
> + tokenised_source = source.Tokenise(PString(":"));
> +
> + if (tokenised_source.GetSize() == 2) {
> +
>
Toolkit::Instance()->GWRewriteE164(tokenised_source[0],true,obj_rr.m_destina
> tionInfo[0]);
> + }
> +
> + // Normal rewriting
>
> Toolkit::Instance()->RewriteE164(obj_rr.m_destinationInfo[0]);
> + }
>
>   if (!authList->Check(obj_rr,rsn,callDurationLimit)) {
>   bReject = TRUE;
> @@ -1344,7 +1361,7 @@
>   PString alias = H323GetAliasAddressString
> (obj_rr.m_destinationInfo[0]);
>   if
> (wArqList->IsDestinationVirtualQueue(alias)) {
>   PString src = (RequestingEP) ?
> AsDotString(RequestingEP->GetCallSignalAddress()) : PString(" ");
> - PString msg(PString::Printf,
> "RouteRequest|%s|%s|%u|%s|%s;\r\n",
> + PString msg(PString::Printf,
> "RouteRequest|%s|%s|%u|%s|%s;\r\n",
>   (const unsigned char
> *) src,
>   (const unsigned char
> *) RequestingEP->GetEndpointIdentifier().GetValue(),
>   (unsigned)
> obj_rr.m_callReferenceValue,
> @@ -1372,7 +1389,7 @@
>   if (!CalledEP && bHasDestInfo) {
>  #if WITH_DEST_ANALYSIS_LIST
>   CalledEP =
> EndpointTable->getMsgDestination(obj_rr, rsn);
> - if (!CalledEP &&
> + if (!CalledEP &&
>   rsn ==
> H225_AdmissionRejectReason::e_incompleteAddress) {
>   bReject = TRUE;
>   rejectReason = rsn;
> @@ -1402,12 +1419,29 @@
>   }
>   }
>   if (bReject) {
> - obj_rpl.SetTag(H225_RasMessage::e_admissionReject);
> - H225_AdmissionReject & arj = obj_rpl;
> + obj_rpl.SetTag(H225_RasMessage::e_admissionReject);
> + H225_AdmissionReject & arj = obj_rpl;
>   arj.m_rejectReason.SetTag(rejectReason);
>   if (rejectReason ==
> H225_AdmissionRejectReason::e_resourceUnavailable)
>   SetAltGKInfo(arj);
>   }
> +
> + // Per GW outbound
> + if (CalledEP && (RequestingEP != CalledEP)) {
> + PString source;
> + PStringArray tokenised_source;
> +
> + source = AsString(CalledEP->GetAliases()[0]);
> +
> + // Chop up source to get the h323_ID or dialedDigits
> + tokenised_source = source.Tokenise(PString(":"));
> +
> + if (tokenised_source.GetSize() == 2) {
> +
>
Toolkit::Instance()->GWRewriteE164(tokenised_source[0],false,obj_rr.m_destin
> ationInfo[0]);
> + }
> +
> + }
> +
>   ProcessARQ(rx_addr, RequestingEP, CalledEP, obj_rr, obj_rpl,
> bReject);
>   if( callDurationLimit > 0 ) {
>   callptr pExistingCallRec =
> (obj_rr.HasOptionalField(H225_AdmissionRequest::e_callIdentifier)) ?
> @@ -1451,16 +1485,16 @@
>
>  #ifdef ARJREASON_ROUTECALLTOSCN
>   //
> - // call from one GW to itself?
> + // call from one GW to itself?
>   // generate ARJ-reason: 'routeCallToSCN'
>   //
> - if(!bReject &&
> + if(!bReject &&
>      Toolkit::AsBool(GkConfig()->GetString("RasSrv::ARQFeatures",
> "ArjReasonRouteCallToSCN", "1")))
>   {
>   // are the endpoints the same (GWs of course)?
> - if( (CalledEP) && (RequestingEP) && (CalledEP ==
> RequestingEP) &&
> + if( (CalledEP) && (RequestingEP) && (CalledEP ==
> RequestingEP) &&
>   (!obj_arq.m_answerCall) // only first ARQ may be
> rejected with with 'routeCallToSCN'
> - )
> + )
>   {
>   // we have to extract the SCN from the destination.
> only EP-1 will be rejected this way
>   if ( obj_arq.m_destinationInfo.GetSize() >= 1 ) {
> @@ -1471,14 +1505,14 @@
>   // set defaults
>
> PPN.m_publicTypeOfNumber.SetTag(H225_PublicTypeOfNumber::e_unknown);
>   PPN.m_publicNumberDigits = "";
> -
> +
>   // there can be diffent information in the
> destination info
>
> switch(obj_arq.m_destinationInfo[0].GetTag()) {
> - case H225_AliasAddress::e_dialedDigits:
> + case H225_AliasAddress::e_dialedDigits:
>   // normal number, extract only the
> digits
>   PPN.m_publicNumberDigits =
> AsString(obj_arq.m_destinationInfo[0], FALSE);
>   break;
> - case H225_AliasAddress::e_partyNumber:
> + case H225_AliasAddress::e_partyNumber:
>   // ready-to-use party number
>   PN = obj_arq.m_destinationInfo[0];
>   break;
> @@ -1486,7 +1520,7 @@
>   PTRACE(1,"Unsupported AliasAdress
> for ARQ reason 'routeCallToSCN': "
>      <<
> obj_arq.m_destinationInfo[0]);
>   }
> -
> +
>   // set the ARJ reason
>   bReject = TRUE;
>   rejectReason =
> H225_AdmissionRejectReason::e_routeCallToSCN;
> @@ -1494,7 +1528,7 @@
>   APN.SetSize(1);
>   APN[0] = PN;
>   }
> - else {
> + else {
>   // missing destination info. is this
> possible at this point?
>   }
>   }
> @@ -1533,7 +1567,7 @@
>   }
>
>   //
> - // Bandwidth
> + // Bandwidth
>   // and GkManager admission
>   //
>   int BWRequest = 1280;
> @@ -1565,7 +1599,7 @@
>   arj.m_rejectReason.SetTag(rejectReason);
>   arj.m_requestSeqNum = obj_arq.m_requestSeqNum;
>   SetCryptoTokens(obj_arq, arj);
> - PString msg(PString::Printf, "ARJ|%s|%s|%s|%s|%s;\r\n",
> + PString msg(PString::Printf, "ARJ|%s|%s|%s|%s|%s;\r\n",
>       (const unsigned char *) srcInfoString,
>       (const unsigned char *) destinationInfoString,
>       (const unsigned char *)
> AsString(obj_arq.m_srcInfo),
> @@ -1573,7 +1607,7 @@
>       (const unsigned char *)
> arj.m_rejectReason.GetTagName() );
>   PTRACE(2, msg);
>   GkStatusThread->SignalStatus(msg);
> -
> +
>   if (CalledEP && CalledEP->IsFromParent()) {
>   H225_RasMessage drq_ras;
>   drq_ras.SetTag(H225_RasMessage::e_disengageRequest);
> @@ -1599,8 +1633,8 @@
>   // else this may be a duplicate ARQ, ignore!
>   PTRACE(3, "GK\tACF: found existing call no " <<
> pExistingCallRec->GetCallNumber());
>   } else {
> - // the call is not in the table
> - CallRec *pCallRec = new
> CallRec(obj_arq.m_callIdentifier, obj_arq.m_conferenceID,
> + // the call is not in the table
> + CallRec *pCallRec = new
> CallRec(obj_arq.m_callIdentifier, obj_arq.m_conferenceID,
>   destinationInfoString,
> AsString(obj_arq.m_srcInfo), BWRequest, GKRoutedH245);
>
>   pCallRec->SetCalled(CalledEP,
> obj_arq.m_callReferenceValue);
> @@ -1611,7 +1645,7 @@
>   pCallRec->SetConnected();
>   CallTbl->Insert(pCallRec);
>   }
> -
> +
>   if ( GKRoutedSignaling ) {
>   acf.m_callModel.SetTag(
> H225_CallModel::e_gatekeeperRouted );
>   acf.m_destCallSignalAddress =
> GetCallSignalAddress(rx_addr);
> @@ -1657,7 +1691,7 @@
>   if (destinationInfoString.IsEmpty())
>   destinationInfoString = "unknown destination alias";
>   // always signal ACF
> - PString msg(PString::Printf, "ACF|%s|%s|%u|%s|%s|%s;\r\n",
> + PString msg(PString::Printf, "ACF|%s|%s|%u|%s|%s|%s;\r\n",
>   (const unsigned char *) srcInfoString,
>   (const unsigned char *)
> RequestingEP->GetEndpointIdentifier().GetValue(),
>   (unsigned) obj_arq.m_callReferenceValue,
> @@ -1729,25 +1763,25 @@
>
>   PString msg;
>   if (bReject) {
> - obj_rpl.SetTag(H225_RasMessage::e_disengageReject);
> + obj_rpl.SetTag(H225_RasMessage::e_disengageReject);
>   H225_DisengageReject & drj = obj_rpl;
>   drj.m_requestSeqNum = obj_rr.m_requestSeqNum;
>   drj.m_rejectReason.SetTag(rsn);
>   SetCryptoTokens(obj_rr, drj);
>
> - msg = PString(PString::Printf, "DRJ|%s|%s|%u|%s;\r\n",
> + msg = PString(PString::Printf, "DRJ|%s|%s|%u|%s;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char *)
> obj_rr.m_endpointIdentifier.GetValue(),
>   (unsigned) obj_rr.m_callReferenceValue,
>   (const unsigned char *)
> drj.m_rejectReason.GetTagName());
>   } else {
> - obj_rpl.SetTag(H225_RasMessage::e_disengageConfirm);
> + obj_rpl.SetTag(H225_RasMessage::e_disengageConfirm);
>   H225_DisengageConfirm & dcf = obj_rpl;
> - dcf.m_requestSeqNum = obj_rr.m_requestSeqNum;
> + dcf.m_requestSeqNum = obj_rr.m_requestSeqNum;
>   SetCryptoTokens(obj_rr, dcf);
>
>   // always signal DCF
> - msg = PString(PString::Printf, "DCF|%s|%s|%u|%s;\r\n",
> + msg = PString(PString::Printf, "DCF|%s|%s|%u|%s;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char *)
> obj_rr.m_endpointIdentifier.GetValue(),
>   (unsigned) obj_rr.m_callReferenceValue,
> @@ -1765,7 +1799,7 @@
>
>  /* Unregistration Request */
>  BOOL H323RasSrv::OnURQ(const PIPSocket::Address & rx_addr, const
> H225_RasMessage &obj_urq, H225_RasMessage &obj_rpl)
> -{
> +{
>   PTRACE(1, "GK\tURQ Received");
>
>   const H225_UnregistrationRequest & obj_rr = obj_urq;
> @@ -1804,18 +1838,18 @@
>   CopyNonStandardData(obj_rr, ucf);
>   SetCryptoTokens(obj_rr, ucf);
>
> - msg = PString(PString::Printf, "UCF|%s|%s;",
> + msg = PString(PString::Printf, "UCF|%s|%s;",
>   inet_ntoa(rx_addr),
>   (const unsigned char *) endpointIdentifierString) ;
>   } else {
> - // Return URJ
> + // Return URJ
>   obj_rpl.SetTag(H225_RasMessage::e_unregistrationReject);
>   H225_UnregistrationReject & urj = obj_rpl;
>   urj.m_requestSeqNum = obj_rr.m_requestSeqNum;
>
>
urj.m_rejectReason.SetTag(H225_UnregRejectReason::e_notCurrentlyRegistered);
>   CopyNonStandardData(obj_rr, urj);
>
> - msg = PString(PString::Printf, "URJ|%s|%s|%s;",
> + msg = PString(PString::Printf, "URJ|%s|%s|%s;",
>   inet_ntoa(rx_addr),
>   (const unsigned char *) endpointIdentifierString,
>   (const unsigned char *)
> urj.m_rejectReason.GetTagName() );
> @@ -1824,7 +1858,7 @@
>   PTRACE(2, msg);
>   GkStatusThread->SignalStatus(msg + "\r\n");
>
> - if (bShellForwardRequest)
> + if (bShellForwardRequest)
>   ForwardRasMsg(obj_urq);
>
>   return bShellSendReply;
> @@ -1833,7 +1867,7 @@
>
>  /* Bandwidth Request */
>  BOOL H323RasSrv::OnBRQ(const PIPSocket::Address & rx_addr, const
> H225_RasMessage & obj_rr, H225_RasMessage & obj_rpl)
> -{
> +{
>   PTRACE(1, "GK\tBRQ Received");
>
>   const H225_BandwidthRequest & obj_brq = obj_rr;
> @@ -1868,7 +1902,7 @@
>   if (bReject) {
>   brj.m_rejectReason.SetTag(rsn);
>   CopyNonStandardData(obj_brq, brj);
> - msg = PString(PString::Printf, "BRJ|%s|%s|%u|%s;\r\n",
> + msg = PString(PString::Printf, "BRJ|%s|%s|%u|%s;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char
> *)obj_brq.m_endpointIdentifier.GetValue(),
>   bandwidth,
> @@ -1880,7 +1914,7 @@
>   bcf.m_requestSeqNum = obj_brq.m_requestSeqNum;
>   bcf.m_bandWidth = bandwidth;
>   CopyNonStandardData(obj_brq, bcf);
> - msg = PString(PString::Printf, "BCF|%s|%s|%u;\r\n",
> + msg = PString(PString::Printf, "BCF|%s|%s|%u;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char
> *)obj_brq.m_endpointIdentifier.GetValue(),
>   bandwidth);
> @@ -1898,11 +1932,33 @@
>   PTRACE(1, "GK\tLRQ Received");
>
>   PString msg;
> - endptr WantedEndPoint;
> + endptr WantedEndPoint,rewriteEndPoint;
>
>   const H225_LocationRequest & obj_lrq = obj_rr;
> - if (obj_lrq.m_destinationInfo.GetSize() > 0)
> + if (obj_lrq.m_destinationInfo.GetSize() > 0) {
> +
> + // per GW rewrite first
> + rewriteEndPoint =
> EndpointTable->FindByEndpointId(obj_lrq.m_endpointIdentifier);
> + if (rewriteEndPoint) {
> +
> + PString source;
> + PStringArray tokenised_source;
> +
> + source = AsString(rewriteEndPoint->GetAliases()[0]);
> +
> + // Chop up source to get the h323_ID or dialedDigits
> + tokenised_source = source.Tokenise(PString(":"));
> +
> + if (tokenised_source.GetSize() == 2) {
> +
>
Toolkit::Instance()->GWRewriteE164(tokenised_source[0],true,obj_lrq.m_destin
> ationInfo[0]);
> + }
> +
> + }
> +
> + // Normal rewrite
>
> Toolkit::Instance()->RewriteE164(obj_lrq.m_destinationInfo[0]);
> + }
> +
>
>   unsigned rsn = H225_LocationRejectReason::e_securityDenial;
>   PIPSocket::Address ipaddr;
> @@ -1938,7 +1994,7 @@
>   lcf.m_rasAddress = GetRasAddress(rx_addr);
>   }
>
> - msg = PString(PString::Printf,
> "LCF|%s|%s|%s|%s;\r\n",
> + msg = PString(PString::Printf,
> "LCF|%s|%s|%s|%s;\r\n",
>   inet_ntoa(rx_addr),
>   (const unsigned char *)
> WantedEndPoint->GetEndpointIdentifier().GetValue(),
>   (const unsigned char *)
> AsString(obj_lrq.m_destinationInfo),
> @@ -1958,7 +2014,7 @@
>   lrj.m_rejectReason.SetTag(rsn);
>   CopyNonStandardData(obj_lrq, lrj);
>
> - msg = PString(PString::Printf, "LRJ|%s|%s|%s|%s;\r\n",
> + msg = PString(PString::Printf, "LRJ|%s|%s|%s|%s;\r\n",
>        inet_ntoa(rx_addr),
>        (const unsigned char *)
> AsString(obj_lrq.m_destinationInfo),
>        (const unsigned char *) sourceInfoString,
> @@ -2003,7 +2059,7 @@
>
>  /* Information Request Response */
>  BOOL H323RasSrv::OnIRR(const PIPSocket::Address & rx_addr, const
> H225_RasMessage &obj_rr, H225_RasMessage &obj_rpl)
> -{
> +{
>   PTRACE(1, "GK\tIRR Received");
>
>   const H225_InfoRequestResponse & obj_irr = obj_rr;
> @@ -2029,7 +2085,7 @@
>
>  /* Resource Availability Indicate */
>  BOOL H323RasSrv::OnRAI(const PIPSocket::Address & rx_addr, const
> H225_RasMessage &obj_rr, H225_RasMessage &obj_rpl)
> -{
> +{
>   PTRACE(1, "GK\tRAI Received");
>
>   const H225_ResourcesAvailableIndicate & obj_rai = obj_rr;
> @@ -2040,7 +2096,7 @@
>   rac.m_requestSeqNum = obj_rai.m_requestSeqNum;
>   rac.m_protocolIdentifier =  obj_rai.m_protocolIdentifier;
>   CopyNonStandardData(obj_rai, rac);
> -
> +
>   return TRUE;
>  }
>
> @@ -2050,13 +2106,13 @@
>   PTRACE(1, "GK\tSCI Received");
>   return FALSE;
>  }
> -
> +
>  BOOL H323RasSrv::OnSCR(const PIPSocket::Address & rx_addr, const
> H225_RasMessage & obj_rr, H225_RasMessage & obj_rpl)
>  {
>   PTRACE(1, "GK\tSCR Received");
>   return FALSE;
>  }
> -
> +
>  BOOL H323RasSrv::OnIgnored(const PIPSocket::Address &, const
> H225_RasMessage & obj_rr, H225_RasMessage &)
>  {
>   PTRACE(2, "GK\t" << obj_rr.GetTagName() << " received and safely
> ignored");
> @@ -2079,7 +2135,7 @@
>  #if HAS_WAITARQ
>   wArqList->CheckWaitingARQ();
>  #endif
> -
> +
>   return !IsTerminated();
>  }
>
> @@ -2137,7 +2193,7 @@
>
>   PTRACE(1, "GK\tRasThread " << getpid() << " started");
>
> - PString err_msg("ERROR: Request received by gatekeeper: ");
> + PString err_msg("ERROR: Request received by gatekeeper: ");
>   PTRACE(2, "GK\tEntering connection handling loop");
>
>   // queueSize is useless for UDPSocket
> @@ -2150,9 +2206,9 @@
>   gkClient = new GkClient(this);
>   loadLock.Signal(); // OK, the thread is ready
>
> - while (listener.IsOpen()) {
> + while (listener.IsOpen()) {
>   PIPSocket::Address rx_addr;
> - H225_RasMessage obj_req;
> + H225_RasMessage obj_req;
>   H225_RasMessage obj_rpl;
>
>   // large mutex! only allow the reloadhandler be executed
> @@ -2184,7 +2240,7 @@
>   PTRACE(3, "GK\n" << setprecision(2) << obj_req);
>   else
>   PTRACE(2, "GK\tReceived " << obj_req.GetTagName());
> -#endif
> +#endif
>
>   if (obj_req.GetTag() <=
> H225_RasMessage::e_serviceControlResponse) {
>   if ((this->*rasHandler[obj_req.GetTag()])(rx_addr,
> obj_req, obj_rpl))
> @@ -2201,14 +2257,14 @@
>   PTRACE(1, "GK\tRasThread terminated!");
>  }
>
> -void H323RasSrv::SelectH235Capability(
> +void H323RasSrv::SelectH235Capability(
>   const H225_GatekeeperRequest& grq,
>   H225_GatekeeperConfirm& gcf
>   )
>  {
>   if( authList == NULL )
>   return;
> -
> +
>   // if GRQ does not contain a list of authentication mechanisms
> simply return
>   if(
> !(grq.HasOptionalField(H225_GatekeeperRequest::e_authenticationCapability)
>   &&
> grq.HasOptionalField(H225_GatekeeperRequest::e_algorithmOIDs)
> @@ -2220,12 +2276,12 @@
>   H225_ArrayOf_PASN_ObjectId algorithmOIDs;
>
>   authList->GetH235Capabilities(mechanisms,algorithmOIDs);
> -
> +
>   // And now match H.235 capabilities found with those from GRQ
> - // to find the one to be returned in GCF
> + // to find the one to be returned in GCF
>   for( int i = 0; i < grq.m_authenticationCapability.GetSize(); i++ )
> - for( int j = 0; j < mechanisms.GetSize(); j++ )
> - if( grq.m_authenticationCapability[i].GetTag()
> + for( int j = 0; j < mechanisms.GetSize(); j++ )
> + if( grq.m_authenticationCapability[i].GetTag()
>   == mechanisms[j].GetTag() )
>   for( int l = 0; l < algorithmOIDs.GetSize();
> l++ )
>   for( int k = 0; k <
> grq.m_algorithmOIDs.GetSize(); k++ )
> @@ -2234,7 +2290,7 @@
>   GkAuthenticator*
> authenticator = authList ? authList->GetHead() : NULL;
>   while( authenticator
> )
>   {
> - if(
> authenticator->IsH235Capable()
> + if(
> authenticator->IsH235Capable()
>   &&
> authenticator->IsH235Capability(
>
> mechanisms[j], algorithmOIDs[l]
>
> ) )
> @@ -2243,7 +2299,7 @@
>
> gcf.m_authenticationMode = mechanisms[j];
>
> gcf.IncludeOptionalField(H225_GatekeeperConfirm::e_algorithmOID);
>
> gcf.m_algorithmOID = algorithmOIDs[l];
> -
> +
>
> PTRACE(4,"GK\tGCF will select authentication mechanism: "
>
> <<mechanisms[j]<<" and algorithm OID: "<<algorithmOIDs[l]
>
> );
> @@ -2251,7 +2307,7 @@
>   }
>
> authenticator = authenticator->GetNext();
>   }
> -
> +
>
> PTRACE(5,"GK\tAuthentication mechanism: "
>
> <<mechanisms[j]<<" and algorithm OID: "
>
> <<algorithmOIDs[l]<<" dropped"
> diff -r -U 3 openh323gk/Toolkit.cxx openh323gk.gwrewrite/Toolkit.cxx
> --- openh323gk/Toolkit.cxx 2003-06-19 15:37:59.000000000 +0000
> +++ openh323gk.gwrewrite/Toolkit.cxx 2003-12-16 12:22:48.000000000 +0000
> @@ -276,9 +276,9 @@
>   break;
>   }
>   }
> -
> - //
> - // Do the rewrite.
> +
> + //
> + // Do the rewrite.
>   // @param #t# will be written to #s#
>   //
>   if (do_rewrite) {
> @@ -286,10 +286,220 @@
>   s = t;
>   changed = true;
>   }
> -
> +
>   return changed;
>  }
>
> +// class Toolkit::GWRewriteTool
> +
> +static const char *GWRewriteSection = "RasSrv::GWRewriteE164";
> +
> +Toolkit::GWRewriteTool::~GWRewriteTool() {
> + for (PINDEX i = 0; i < m_GWRewrite.GetSize(); ++i) {
> + delete &(m_GWRewrite.GetDataAt(i));
> + }
> + m_GWRewrite.RemoveAll();
> +}
> +
> +bool Toolkit::GWRewriteTool::RewritePString(PString gw, bool direction,
> PString &data) {
> +
> + GWRewriteEntry *gw_entry;
> + std::vector<std::pair<PString,PString> >::iterator rule_iterator;
> + PString key,value;
> + bool inverted;
> + int striplen;
> +
> + // First lookup the GW in the dictionary
> + gw_entry = m_GWRewrite.GetAt(gw);
> +
> + if (gw_entry == NULL) {
> + return false;
> + }
> +
> + // True is "in" direction
> + if (direction == true) {
> + for (rule_iterator = gw_entry->m_entry_data.first.begin();
> rule_iterator != gw_entry->m_entry_data.first.end(); ++rule_iterator) {
> + key = (*rule_iterator).first;
> + inverted = false;
> +
> + // Inverted match sense
> + if (key.GetLength() !=0 && key[0] == '!') {
> + inverted = true;
> + key = key.Mid(1);
> + }
> +
> + // Attempt match
> + if ((strncmp(data, key, key.GetLength()) == 0) ^
> inverted) {
> +
> + // Start rewrite
> + value = (*rule_iterator).second;
> + striplen = (inverted) ? 0 : key.GetLength();
> + value += data.Mid(striplen);
> +
> + // Log
> + PTRACE(2, "\tGWRewriteTool::RewritePString:
> " << data << " to " << value);
> +
> + // Finish rewrite
> + data = value;
> +
> + break;
> + }
> +
> + }
> +
> + }
> + else {
> + for (rule_iterator = gw_entry->m_entry_data.second.begin();
> rule_iterator != gw_entry->m_entry_data.second.end(); ++rule_iterator) {
> + key = (*rule_iterator).first;
> + inverted = false;
> +
> + // Inverted match sense
> + if (key.GetLength() !=0 && key[0] == '!') {
> + inverted = true;
> + key = key.Mid(1);
> + }
> +
> + // Attempt match
> + if ((strncmp(data, key, key.GetLength()) == 0) ^
> inverted) {
> +
> + // Start rewrite
> + value = (*rule_iterator).second;
> + striplen = (inverted) ? 0 : key.GetLength();
> + value += data.Mid(striplen);
> +
> + // Log
> + PTRACE(2, "\tGWRewriteTool::RewritePString:
> " << data << " to " << value);
> +
> + // Finish rewrite
> + data = value;
> +
> + break;
> + }
> +
> + }
> +
> + }
> +
> +
> + return true;
> +
> +}
> +
> +void Toolkit::GWRewriteTool::PrintData() {
> +
> + std::vector<std::pair<PString,PString> >::iterator rule_iterator;
> +
> + PTRACE(2, "GK\tLoaded per GW rewrite data:");
> +
> + if (m_GWRewrite.GetSize() == 0) {
> + PTRACE(2, "GK\tNo per GW data loaded");
> + return;
> + }
> +
> + for (PINDEX i = 0; i < m_GWRewrite.GetSize(); ++i) {
> +
> + // In
> + for (rule_iterator =
> m_GWRewrite.GetDataAt(i).m_entry_data.first.begin(); rule_iterator !=
> m_GWRewrite.GetDataAt(i).m_entry_data.first.end(); ++rule_iterator) {
> + PTRACE(3, "GK\t" << m_GWRewrite.GetKeyAt(i) << "
> (in): " << (*rule_iterator).first << " = " << (*rule_iterator).second);
> + }
> +
> + // Out
> + for (rule_iterator =
> m_GWRewrite.GetDataAt(i).m_entry_data.second.begin(); rule_iterator !=
> m_GWRewrite.GetDataAt(i).m_entry_data.second.end(); ++rule_iterator) {
> + PTRACE(3, "GK\t" << m_GWRewrite.GetKeyAt(i) << "
> (out): " << (*rule_iterator).first << " = " << (*rule_iterator).second);
> + }
> +
> + }
> +
> + PTRACE(2, "GK\tLoaded " << m_GWRewrite.GetSize() << " GW entries
> with rewrite info");
> +
> +}
> +
> +
> +void Toolkit::GWRewriteTool::LoadConfig(PConfig *config) {
> +
> + PINDEX gw_size, i, j, lines_size;
> + PString key, cfg_value;
> + PStringArray lines, tokenised_line;
> + GWRewriteEntry *gw_entry;
> + std::map<PString,PString> in_strings, out_strings;
> + std::vector<std::pair<PString,PString> > sorted_in_strings,
> sorted_out_strings;
> + std::map<PString,PString>::reverse_iterator strings_iterator;
> + std::pair<PString,PString> rule;
> +
> + PStringToString cfgs(config->GetAllKeyValues(GWRewriteSection));
> +
> + // Clear old config
> + for (PINDEX i = 0; i < m_GWRewrite.GetSize(); ++i) {
> + delete &(m_GWRewrite.GetDataAt(i));
> + }
> + m_GWRewrite.RemoveAll();
> +
> + gw_size = cfgs.GetSize();
> + if (gw_size > 0) {
> + for (i = 0; i < gw_size; ++i) {
> +
> + // Get the config keys
> + key = cfgs.GetKeyAt(i);
> + cfg_value = cfgs[key];
> +
> + in_strings.clear();
> + out_strings.clear();
> + sorted_in_strings.clear();
> + sorted_out_strings.clear();
> +
> + // Split the config data into seperate lines
> + lines = cfg_value.Tokenise(PString("\n"));
> +
> + lines_size = lines.GetSize();
> +
> + for (j = 0; j < lines_size; ++j) {
> +
> + // Split the config line into three strings,
> direction, from string, to string
> + tokenised_line =
> lines[j].Tokenise(PString("="));
> +
> + if (tokenised_line.GetSize() < 3) {
> + continue;
> + }
> +
> + // Put into appropriate std::map
> +
> + if (tokenised_line[0] == "in") {
> + in_strings[tokenised_line[1]] =
> tokenised_line[2];
> +
> + }
> + if (tokenised_line[0] == "out") {
> + out_strings[tokenised_line[1]] =
> tokenised_line[2];
> + }
> +
> + }
> +
> + // Put the map contents into reverse sorted vectors
> + for (strings_iterator = in_strings.rbegin();
> strings_iterator != in_strings.rend(); ++strings_iterator) {
> + rule = *strings_iterator;
> + sorted_in_strings.push_back(rule);
> + }
> + for (strings_iterator = out_strings.rbegin();
> strings_iterator != out_strings.rend(); ++strings_iterator) {
> + rule = *strings_iterator;
> + sorted_out_strings.push_back(rule);
> + }
> +
> +
> + // Create the entry
> + gw_entry = new GWRewriteEntry();
> + gw_entry->m_entry_data.first = sorted_in_strings;
> + gw_entry->m_entry_data.second = sorted_out_strings;
> +
> +
> + // Add to PDictionary hash table
> + m_GWRewrite.Insert(key,gw_entry);
> +
> + }
> + }
> +
> + PrintData();
> +}
> +
> +
>  Toolkit::Toolkit() : m_Config(0), m_ConfigDirty(false)
>  #ifdef HAS_ACCT
>   , m_acctList(NULL)
> @@ -307,7 +517,7 @@
>   callptr dummycall;
>   m_acctList->LogAcctEvent( GkAcctLogger::AcctOff,
> dummycall );
>   }
> - delete m_acctList;
> + delete m_acctList;
>   } catch( ... ) {
>   PTRACE(0,"GKACCT\tException caught during Accounting-Off
> event logging");
>   }
> @@ -333,7 +543,7 @@
>  }
>
>  PConfig* Toolkit::SetConfig(const PFilePath &fp, const PString &section)
> -{
> +{
>   m_ConfigFilePath = fp;
>   m_ConfigDefaultSection = section;
>
> @@ -401,11 +611,12 @@
>   m_RouteTable.InitTable();
>   m_ProxyCriterion.LoadConfig(m_Config);
>   m_Rewrite.LoadConfig(m_Config);
> + m_GWRewrite.LoadConfig(m_Config);
>
>  #ifdef HAS_ACCT
>   const BOOL nasStart = (m_acctList == NULL);
> - try {
> - delete m_acctList;
> + try {
> + delete m_acctList;
>   } catch( ... ) {
>   PTRACE(0,"GKACCT\tException caught during accounting modules
> cleanup");
>   }
> @@ -420,7 +631,7 @@
>   PTRACE(0,"GKACCT\tException caught during Accounting-On
> event logging");
>   }
>  #endif
> - return m_Config;
> + return m_Config;
>  }
>
>  BOOL Toolkit::MatchRegex(const PString &str, const PString &regexStr)
> @@ -441,16 +652,16 @@
>
>
>  bool Toolkit::RewriteE164(H225_AliasAddress &alias)
> -{
> - if (alias.GetTag() != H225_AliasAddress::e_dialedDigits)
> +{
> + if (alias.GetTag() != H225_AliasAddress::e_dialedDigits)
>   return FALSE;
> -
> +
>   PString E164 = H323GetAliasAddressString(alias);
>
>   bool changed = RewritePString(E164);
>   if (changed)
>   H323SetAliasAddress(E164, alias);
> -
> +
>   return changed;
>  }
>
> @@ -462,8 +673,42 @@
>   return changed;
>  }
>
> -const PString
> -Toolkit::GKName()
> +
> +bool Toolkit::GWRewriteE164(PString gw, bool direction, H225_AliasAddress
> &alias) {
> +
> + PString E164;
> + bool changed;
> +
> + if (alias.GetTag() != H225_AliasAddress::e_dialedDigits) {
> + return false;
> + }
> +
> + E164 = H323GetAliasAddressString(alias);
> + changed = GWRewritePString(gw,direction,E164);
> +
> + if (changed) {
> + H323SetAliasAddress(E164, alias);
> + }
> +
> + return changed;
> +}
> +
> +bool Toolkit::GWRewriteE164(PString gw, bool direction,
> H225_ArrayOf_AliasAddress &aliases) {
> +
> + bool changed;
> + PINDEX n;
> +
> + changed = false;
> + for (n = 0; n < aliases.GetSize(); ++n) {
> + changed |= GWRewriteE164(gw,direction,aliases[n]);
> + }
> +
> + return changed;
> +}
> +
> +
> +const PString
> +Toolkit::GKName()
>  {
>    return GkConfig()->GetString("Name", "OpenH323GK"); //use default
section
> (MM 06.11.01)
>  }
> @@ -477,8 +722,8 @@
>  static const int INT_PTHREADS = 0;
>  #endif
>
> -const PString
> -Toolkit::GKVersion()
> +const PString
> +Toolkit::GKVersion()
>  {
>   return PString(PString::Printf,
>      "Gatekeeper(%s) Version(%s)
> Ext(pthreads=%d) Build(%s, %s) Sys(%s %s %s)\r\n",
> @@ -495,12 +740,12 @@
>
>
>  int
> -Toolkit::GetInternalExtensionCode( const unsigned &country,
> -    const
> unsigned &extension,
> -    const
> unsigned &manufacturer) const
> +Toolkit::GetInternalExtensionCode( const unsigned &country,
> +    const
> unsigned &extension,
> +    const
> unsigned &manufacturer) const
>  {
>   switch(country) {
> - case t35cOpenOrg:
> + case t35cOpenOrg:
>   switch(manufacturer) {
>   case t35mOpenOrg:
>   switch(extension) {
> @@ -514,7 +759,7 @@
>  }
>
>
> -bool Toolkit::AsBool(const PString & str)
> +bool Toolkit::AsBool(const PString & str)
>  {
>   if (str.IsEmpty())
>   return false;
> diff -r -U 3 openh323gk/Toolkit.h openh323gk.gwrewrite/Toolkit.h
> --- openh323gk/Toolkit.h 2003-06-19 15:37:59.000000000 +0000
> +++ openh323gk.gwrewrite/Toolkit.h 2003-12-15 11:40:50.000000000 +0000
> @@ -15,6 +15,7 @@
>  #ifndef _toolkit_h__
>  #define _toolkit_h__
>
> +#include <vector>
>  #include <ptlib.h>
>  #include <ptlib/sockets.h>
>  #include "h225.h"
> @@ -124,16 +125,46 @@
>
>   bool RewritePString(PString & s) { return
> m_Rewrite.RewritePString(s); }
>
> + // Class to allow correct use of STL inside PDictionary type
> + class GWRewriteEntry : public PObject {
> + PCLASSINFO(GWRewriteEntry, PObject);
> + public:
> + std::pair<std::vector<std::pair<PString,PString>
> >,std::vector<std::pair<PString,PString> > > m_entry_data;
> + };
> +
> +
> + // per GW RewriteTool
> + class GWRewriteTool {
> + public:
> +
> + GWRewriteTool() {
> + m_GWRewrite.AllowDeleteObjects(false);
> + }
> + ~GWRewriteTool();
> + void LoadConfig(PConfig *);
> + void PrintData();
> + bool RewritePString(PString gw, bool direction,
> PString &data);
> +
> + private:
> + PDictionary<PString, GWRewriteEntry> m_GWRewrite;
> +
> + };
> +
> + // Equivalent functions to RewriteE164 group
> + bool GWRewriteE164(PString gw, bool direction, H225_AliasAddress
> &alias);
> + bool GWRewriteE164(PString gw, bool direction,
> H225_ArrayOf_AliasAddress &aliases);
> + bool GWRewritePString(PString gw, bool direction, PString &data) {
> return m_GWRewrite.RewritePString(gw,direction,data); }
> +
>
>   // accessors
> - /** Accessor and 'Factory' to the static Toolkit.
> + /** Accessor and 'Factory' to the static Toolkit.
>   * If you want to use your own Toolkit class you have to
> - * overwrite this method and ensure that your version is
> + * overwrite this method and ensure that your version is
>   * called first -- before any other call to #Toolkit::Instance#.
> - * Example:
> + * Example:
>   * <pre>
>   * class MyToolkit: public Toolkit {
> - *  public:
> + *  public:
>   *   static Toolkit& Instance() {
>   *    if (m_Instance == NULL) m_Instance = new MyToolkit();
>   *     return m_Instance;
> @@ -145,16 +176,16 @@
>   * </pre>
>   */
>
> - /** Accessor and 'Factory' for the global (static) configuration.
> - * With this we are able to implement out own Config-Loader
> - * in the same way as #Instance()#. And we can use #Config()#
> + /** Accessor and 'Factory' for the global (static) configuration.
> + * With this we are able to implement out own Config-Loader
> + * in the same way as #Instance()#. And we can use #Config()#
>   * in the constructor of #Toolkit# (and its descentants).
>   */
> - PConfig* Config();
> - PConfig* Config(const char *);
> + PConfig* Config();
> + PConfig* Config(const char *);
>
>   /** Sets the config that the toolkit uses to a given config.
> - *  A prior loaded Config is discarded.
> + *  A prior loaded Config is discarded.
>   */
>   PConfig* SetConfig(const PFilePath &fp, const PString &section);
>
> @@ -179,7 +210,7 @@
>   */
>   static BOOL MatchRegex(const PString &str, const PString &regexStr);
>
> - /** returns the #BOOL# that #str# represents.
> + /** returns the #BOOL# that #str# represents.
>   * Case insensitive, "t...", "y...", "a...", "1" are #TRUE#, all
> other values are #FALSE#.
>   */
>   static bool AsBool(const PString & str);
> @@ -199,10 +230,10 @@
>   enum {
>   t35cOpenOrg = 255,       /// country code for the "Open
> Source Organisation" Country
>   t35mOpenOrg = 4242,     /// manufacurers code for the "Open
> Source Organisation"
> - t35eFailoverRAS = 255  /// Defined HERE!
> + t35eFailoverRAS = 255  /// Defined HERE!
>   };
> - /** If the triple #(country,extension,manufacturer)# represents an
> - * extension known to the GnuGK this method returns its 'internal
> extension code'
> + /** If the triple #(country,extension,manufacturer)# represents an
> + * extension known to the GnuGK this method returns its 'internal
> extension code'
>   # #iecXXX' or #iecUnknow# otherwise.
>   *
>   * Overwriting methods should use a simlilar scheme and call
> @@ -215,10 +246,10 @@
>   * </code>
>   * This results in 'cascading' calls until a iec!=iecUnkown is
> returned.
>   */
> - virtual int GetInternalExtensionCode(const unsigned &country,
> -
> const unsigned &extension,
> + virtual int GetInternalExtensionCode(const unsigned &country,
> +
> const unsigned &extension,
>
> const unsigned &manufacturer) const;
> -
> +
>
>   int GetInternalExtensionCode(const H225_H221NonStandard& data) const
> {
>   return GetInternalExtensionCode(data.m_t35CountryCode,
> @@ -249,6 +280,11 @@
>   RouteTable m_RouteTable;
>   ProxyCriterion m_ProxyCriterion;
>
> + /* GW Based RewriteTool */
> + GWRewriteTool m_GWRewrite;
> +
> +
> +
>  #ifdef HAS_ACCT
>   GkAcctLoggers* m_acctList;
>  #endif
> @@ -258,7 +294,7 @@
>
>
>  inline unsigned long
> -Toolkit::HashCStr(const unsigned char *name)
> +Toolkit::HashCStr(const unsigned char *name)
>  {
>   register unsigned long h = 0, g;
>   while (*name) {
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: SF.net Giveback Program.
> Does SourceForge.net help you be more productive?  Does it
> help you create better code?  SHARE THE LOVE, and help us help
> YOU!  Click Here: http://sourceforge.net/donate/
> _______________________________________________
> List: Openh323gk-users@lists.sourceforge.net
> Archive: http://sourceforge.net/mailarchive/forum.php?forum_id=8549
> Homepage: http://www.gnugk.org/



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
List: Openh323gk-users@lists.sourceforge.net
Archive: http://sourceforge.net/mailarchive/forum.php?forum_id=8549
Homepage: http://www.gnugk.org/

[Index of Archives]     [SIP]     [Open H.323]     [Gnu Gatekeeper]     [Asterisk PBX]     [ISDN Cause Codes]     [Yosemite News]

  Powered by Linux