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

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

 



hello,

does anybody knows when this patch will go into
cvs (v2.0) ?

I think it is a very useful functionality.
Does it work only for gateways or can be also
used for terminals ?

Razvan Radu
CORE Technologies
Tel: 021 2420383
 


> -----Original Message-----
> From: openh323gk-users-admin@lists.sourceforge.net 
> [mailto:openh323gk-users-admin@lists.sourceforge.net] On 
> Behalf Of Steinar Kolnes
> Sent: 09 January 2004 00:54
> To: openh323gk-users@lists.sourceforge.net
> Subject: RE:  Re: Re: Rewriting E164 
> numbers after GW selection
> 
> 
> Ian,
> 
> Is the code included in ver 2.0.7 ?
> 
> Thanks in advance
> 
> Steinar
> 
> -----Original Message-----
> From: openh323gk-users-admin@lists.sourceforge.net
> [mailto:openh323gk-users-admin@lists.sourceforge.net] On Behalf Of
> Ian.Campbell@band-x.com
> Sent: 16. desember 2003 13:23
> To: openh323gk-users@lists.sourceforge.net;
> openh323gk-developer@lists.sourceforge.net
> Cc: Justin.Wells@band-x.com
> 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,calle
> dNumber)) {
> +			
> 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,cal
> ledNumber)) {
> +			
> 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_facilityCall
> Deflection);
>  	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,Se
> tup.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,S
> etup.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,ob
> j_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,o
> bj_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_notCurrent
> lyRegistered);
>  		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,ob
> j_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_authenticatio
> nCapability)
>  			&&
> 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/
> 
> 
> 
> 
> -------------------------------------------------------
> This SF.net email is sponsored by: Perforce Software.
> Perforce is the Fast Software Configuration Management System offering
> advanced branching capabilities and atomic changes on 50+ platforms.
> Free Eval! http://www.perforce.com/perforce/loadprog.html
> _______________________________________________
> List: Openh323gk-users@lists.sourceforge.net
> Archive: http://sourceforge.net/mailarchive/forum.php?forum_id=8549
> Homepage: http://www.gnugk.org/
> 



-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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