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 §ion) > -{ > +{ > 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 ®exStr) > @@ -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 §ion); > > @@ -179,7 +210,7 @@ > */ > static BOOL MatchRegex(const PString &str, const PString ®exStr); > > - /** 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/