1. 程式人生 > >freeswithc 對接運營商落地閘道器

freeswithc 對接運營商落地閘道器

freeswithc “Auto Changing audio port from” 原理解析

整體環境

在對接外部運營商的落地閘道器的時候,流程圖如下,core區的機器無法連線到外網,需要在外網區域增加一臺轉發伺服器fs,來達到內網和外部手機的通訊
dmz區IP:100.69.208.59
core區IP:100.69.216.126

對接所做配置檔案修改

撥出的配置
在這裡插入圖片描述

  1. core區修改dialplan/default.xml ,新增如下,轉接到dmz區的伺服器上
<extension name="out-dmz">
  <condition field="destination_number" expression="^0(.*)$">
        <action application="bridge" data="sofia/external/sip:
[email protected]
:5060"/> </condition> </extension>
  1. dmz區的external統一由dialplan/public/00_inbound_did.xml 來處理,新增 如下程式碼,轉接到IMS閘道器上
<extension name="test-to-ims">
<condition field="destination_number" expression="^10(.*)$">
          <action application="set" data="domain_name=$${domain}"/>  
     <action application="bridge" data="sofia/gateway/ims/99$1"/>
   </condition>
 </extension>

  1. 增加了 IMS閘道器 增加sip_profiles/external/gateway.xml 檔案,如下配置 ;
<include>
  <gateway name="ims"> 
	  <param name="username" value="075533614xxx"/>
	  <param name="password" value="none"/>
	  <param name="proxy" value="122.13.xx.xx:5060"/>
	  <param name="register" value="false"/>
  </gateway>
</include>

  1. 由於在撥出的時候invite 中的sdp會替換成dmz區的內網IP,所以需要在internal.xml中修改ext-rtp-ip為對映的外網IP如:112.xxx.xxx.xxx ;否者會出現呼叫能通但是沒有語音

呼入的配置

在這裡插入圖片描述

  1. public下的xml 增加外部呼入的規則,如下我寫定轉接到core區的1000,也可以做一個IVR分機撥號的功能;
<extension name="test-to-core">
    <condition field="destination_number" expression="^(07553361xxxx)$">
      <action application="set" data="domain_name=$${domain}"/>  
      <action application="bridge" data="sofia/external/sip:[email protected]:5060"/>
    </condition>
  </extension>

  1. core區的public下的xml增加1000的撥號規則,轉到internal的1000上
<extension name="public_test">
    <condition field="destination_number" expression="^(10[01][0-9])$">     
      <action application="transfer" data="$1 XML default"/>
    </condition>
  </extension>
3. 由於在呼入的時候,回覆invite 的包中的sdp會替換成dmz區的內網IP,所以需要在external.xml中修改ext-rtp-ip為對映的外網IP如:112.xxx.xxx.xxx ;否者會出現入能通但是沒有語音

疑問點1:

撥出的時候dmz的internal.xml修改了回覆invite中的sdp的IP資訊為外網IP,按理說應該core區訪問不了外網IP的。
解答:
在日誌中看到如下日誌,core區的freesiwtch會把dmz區的rtp-ip從外網112.95.xx.xx自動changing 到dmz內網IP:100.69.208.59,因為core區給126-》dmz,dmz會給126傳送RTP包做一個auto changing port用

 [INFO] switch_rtp.c:7497 Auto Changing audio port from 112.95.xxx.xxx:20604 to 100.69.208.59:20604

原理:
freeswitch如下圖
麻煩:當B處於NAT後,A的RTP流從freeswitch是不能到B的(因為B為內網的IP),而且交換信令的時候,不可能給出NAT後的B的RPT IP和埠
解決:前期freeswitch的RTP-IP給到B,B會給FS發rtp流,以便FS能知道B的真實NAT後的IP和埠(這也是auto changing port的原理),freeswitch會監聽UDP的 IP和埠以便接受B傳送過來的RTP流
在這裡插入圖片描述

rtp_common_read 程式碼中有設定switch_rtp_set_remote_address 設定RTP遠端地址的操作

		if (bytes && rtp_session->flags[SWITCH_RTP_FLAG_AUTOADJ] && switch_sockaddr_get_port(rtp_session->rtp_from_addr)) {
			if (!switch_cmp_addr(rtp_session->rtp_from_addr, rtp_session->remote_addr)) {
				if (++rtp_session->autoadj_tally >= rtp_session->autoadj_threshold) {
					const char *err;
					uint32_t old = rtp_session->remote_port;
					const char *tx_host;
					const char *old_host;
					char bufa[50], bufb[50];
					char adj_port[6];

					tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtp_from_addr);
					old_host = switch_get_addr(bufb, sizeof(bufb), rtp_session->remote_addr);

					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO,
									  "Auto Changing %s port from %s:%u to %s:%u\n", rtp_type(rtp_session), old_host, old, tx_host,
									  switch_sockaddr_get_port(rtp_session->rtp_from_addr));
			  rtp_session->auto_adj_used = 1;
					switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->rtp_from_addr), 0, SWITCH_FALSE, &err);

疑問點2:

ext-sip-ip 設定成外網IP後,sip信令將使用外網IP來通訊,導致core和dmz區不能正常sip互動