1. 概述
本文解決如下問題:xlite之間已經正常的進行sip協定的互動,并且1008和1018已經呼通,但是1008和1018互相之間無法聽到聲音。
主要涉及如下内容:
1. 語音不通的原因分析
2. SDP協定
2. NAT的問題
3. freeswitch如何實作NAT的穿越的問題
2. 案例環境說明
軟電話使用x-lite,使用freeswitch的預設的兩個号碼1008和1018。
freeswitch部署在伺服器的私網位址是172.23.4.92,公網位址115.aa.aa.aa。
1008的測試機器在私網上(IP為10.240.80.69),通過115.aa.aa.aa:5060注冊freeswitch,但是出去後的公網位址是59.bb.bb.bb。
1018的測試機器在私網上,通過115.aa.aa.aa:5060注冊freeswitch,但是出去後的公網位址是123.cc.cc.cc
在172.23.4.92上,使用tcpdump捕獲通信過程中的所有包
為了安全,本文把真實環境的公網位址,全部使用假的位址進行替換
3. 原因分析
xlite之間已經正常的進行sip協定的互動,并且1008和1018已經呼通,但是1008和1018互相之間無法聽到聲音。
3.1 初步判斷原因
- a. 正常的流程時,1008和1018之間使用sip協定建立通話後,1008和1018的語音包不直接發送給對方,而是都先發送到freeswitch,由freeswitch轉發給對方。但是他們之間通話資訊傳輸使用的卻是rtp包或其他UPD包,并且rtp包或其他UPD包不是在已經建立的sip協定線路上傳輸資料,而是使用别外一條線路傳輸,所有猜測有可能1008和1018的包都沒有成功傳輸到freeswitch,導緻無法聽到對方聲音
- b. rtp包的傳輸使用的是UDP,且1008和1018都在内網,fs部署到公網,是以這裡又涉及NAT的問題
3.2. SDP
第一個問題:1008和1018之間是如何知道對方的RTP包或其他UPD包互動的IP位址?答案是通過SDP互相知道的。SIP在建立會話時,SIP協定會包含相關的媒體(如視訊和音頻)的資訊,媒體的相關的資料會包含在SDP中。SDP也會放在SIP協定的正文(body)中
3.3. 1008主叫的問題分析
1008 向freeswitch發起INVITE 消息包分析
No. Time Source Destination Protocol Length Info
aa.aa.aa SIP/SDP Request: INVITE sip:@aa.aa.aa: |
Frame : bytes on wire ( bits), bytes captured ( bits)
Ethernet II, Src: ZteCorpo_60:: (:::::), Dst: Vmware_83::d (:::::d)
Internet Protocol Version , Src: aa.aa.aa, Dst:
User Datagram Protocol, Src Port: (), Dst Port: ()
Session Initiation Protocol (INVITE)
Request-Line: INVITE sip:@aa.aa.aa: SIP/
Message Header
略..
Message Body
Session Description Protocol
Session Description Protocol Version (v):
Owner/Creator, Session Id (o): - IN IP4
Session Name (s): X-Lite release stamp
Connection Information (c): IN IP4
Time Description, active time (t):
Media Description, name and address (m): audio RTP/AVP
Media Attribute (a): rtpmap: opus//
Media Attribute (a): fmtp: useinbandfec=; usedtx=; maxaveragebitrate=
Media Attribute (a): rtpmap: speex/
Media Attribute (a): rtpmap: telephone-event/
Media Attribute (a): fmtp: -
Media Attribute (a): sendrecv
SDP協定的字段說明如下:
和通信位址相關的是:
- 1.Connection Information (c): IN IP4 10.240.80.69:告訴freeswitch本機的通信ip為10.240.80.69
- 2.Media Description, name and address (m): audio 64836 RTP/AVP 9 8 120 0 84 101:告訴freeswitch本機的通信端口為64836
FS 向1008産生一個回鈴音時,會通過SDP告訴1008自己的接受語音的IP位址
No. Time Source Destination Protocol Length Info
aa.aa.aa SIP/SDP Status: Session Progress |
Frame : bytes on wire ( bits), bytes captured ( bits)
Ethernet II, Src: Vmware_83::d (:::::d), Dst: IETF-VRRP-VRID_04 (::e:::)
Internet Protocol Version , Src: , Dst: aa.aa.aa
User Datagram Protocol, Src Port: (), Dst Port: ()
Session Initiation Protocol ()
Status-Line: SIP/ Session Progress
Message Header
略
Message Body
Session Description Protocol
Session Description Protocol Version (v):
Owner/Creator, Session Id (o): FreeSWITCH IN IP4 aa.aa.aa
Session Name (s): FreeSWITCH
Connection Information (c):
Time Description, active time (t):
Media Description, name and address (m): audio RTP/AVP
Media Attribute (a): rtpmap: G722/
Media Attribute (a): rtpmap: telephone-event/
Media Attribute (a): fmtp: -
Media Attribute (a): ptime:
在這個消息中freeswitch通知1008的音頻的本機的ip為172.23.4.92,是個私網位址
因為1008和freeswitch不在一個區域網路中,所有1008發送給freeswitch全部失敗。
3.4. 1018被叫的問題分析
freeswitch 進行路由找到1018的資訊,向1018發送INVITE資訊時,也會通過SDP資訊帶上自己的接收語音包的IP位址
No. Time Source Destination Protocol Length Info
SIP/SDP Request: INVITE sip:@:;rinstance=d9373ba78a06600 |
Frame : bytes on wire ( bits), bytes captured ( bits)
Ethernet II, Src: Vmware_83::d (:::::d), Dst: IETF-VRRP-VRID_04 (::e:::)
Internet Protocol Version , Src: , Dst:
User Datagram Protocol, Src Port: (), Dst Port: ()
Session Initiation Protocol (INVITE)
Request-Line: INVITE sip:@:;rinstance=d9373ba78a06600 SIP/
Message Header
略…
Message Body
Session Description Protocol
Session Description Protocol Version (v):
Owner/Creator, Session Id (o): FreeSWITCH IN IP4 aa.aa.aa
Session Name (s): FreeSWITCH
Connection Information (c): IN IP4
Time Description, active time (t):
Media Description, name and address (m): audio RTP/AVP
Media Attribute (a): rtpmap: G722/
Media Attribute (a): rtpmap: PCMA/
Media Attribute (a): rtpmap: PCMU/
Media Attribute (a): rtpmap: telephone-event/
Media Attribute (a): fmtp: -
Media Attribute (a): ptime:
這裡也時使用的私網位址: Connection Information (c): IN IP4 172.23.4.92
1018 接聽電話,向FS回送200 OK消息,通過SDP告訴freeswitch自己的位址
No. Time Source Destination Protocol Length Info
SIP/SDP Status: OK |
Frame : bytes on wire ( bits), bytes captured ( bits)
Ethernet II, Src: ZteCorpo_60:: (:::::), Dst: Vmware_83::d (:::::d)
Internet Protocol Version , Src: , Dst:
User Datagram Protocol, Src Port: (), Dst Port: ()
Session Initiation Protocol ()
Status-Line: SIP/ OK
Message Header
….
Message Body
Session Description Protocol
Session Description Protocol Version (v):
Owner/Creator, Session Id (o): - IN IP4
Session Name (s): X-Lite release stamp
Connection Information (c): IN IP4
Time Description, active time (t):
Media Description, name and address (m): audio RTP/AVP
Media Attribute (a): rtpmap: telephone-event/
Media Attribute (a): fmtp: -
Media Attribute (a): sendrecv
Connection Information (c): IN IP4 10.240.80.146:此時1018告訴freeswitch的也是私網位址
3.5. 結論
是以的問題的原因如下:
- a. freeswitch傳回給1008和1018的SDP資訊裡的自己的IP位址是私網位址,那麼1008和1018向這個私網位址發送語音udp包,當然無法送到freeswitch。是以需要freeswitch在回送的SDP的中的IP位址是自己的公網ip
- b. 解決a的問題,還需要解決freeswitch正确回送語音包的問題。1008和1018向freeswitch提供的SDP裡的IP資訊也都是私網位址,freeswitch也必須需要識别出1008和1018的對外的公網位址
以上兩個問題都是NAT的問題,要解決問題,必須實作NAT穿越
4. NAT
4.1. 什麼是NAT的問題
以下已經講的很清楚,這時不在說明
4.2. NAT的種類
5. freeswich端解決NAT的問題
解決NAT的方法有很多,如用戶端的解決方案ICE,STUM,TURN。這裡我們略。我目前碰到的NAT問題,使用freeswitch端的NAT的方案即可。
5.1. 修改配置sip_profiles/internal.xml
修改ext-rtp-ip和ext-sip-ip為freeswitch公網位址
<param name="ext-rtp-ip" value="115.aa.aa.aa"/>
<param name="ext-sip-ip" value="115.aa.aa.aa"/>
5.2. 修改freeswitch支援NAT方式啟動
預設安裝後,freesiwtch是以不支援NAT的方式啟動,這時一個大坑。使用ps檢視
修改freeswitch支援NAT
// ## 修改freeswitch啟動配置
vim /lib/systemd/system/freeswitch.service
// 注釋掉這一行
#Environment="DAEMON_OPTS=-nonat"
// 重新加載配置
systemctl daemon-reload
// 重新開機freeswitch
systemctl restart freeswitch
5.3. 開放公網端口
開啟freeswitch對應公網的位址的rtp的UDP端口,可以被外網通路
5.4. 測試
如果配置成功,則1008和1018收到freeswitch的回送的SDP的c屬性的IP位址為freeswitch的公網IP,并且fs_cli的控制台會輸出以下類似的資訊,保證freeswitch會将1008和1018傳送過來的私網位址轉化為對應的公網位址,freeswitch會向1008和1018的公網位址回送語音包,進而保證1008和1018進行正确的通話
Auto Changing audio port from : to aa.aa.aa:
…
Auto Changing audio port from : to aa.aa.aa:
…
至此,問題解決
6. 參考文獻
本文中的所有的圖,都是作者用手機拍攝自圖書”freeswitch權威指南”