大致網絡示意和終端號碼:
客戶端側: 終端號碼(1019)終端IP(192.168.1.15)+ 網關(192.168.1.1) + 路由器公網IP(動態地址)
服務器側: 防火牆(181.92.2.7)+ 負載(10.40.50.20X)+ FreeSWITCH(10.10.10.190)+ 終端號碼(27909,本局域網內用戶)
1. 公網的數據包怎么到達freeswitch?
需要在防火牆上配置轉發規則:
信令轉發:181.92.2.7:5060 -> 10.10.10.190:5060 媒體端口轉發:181.92.2.7:20000-30000 -> 10.10.10.190:20000-30000
2. FreeSWITCH配置公網地址
配置文件:sip_profiles/internal.xml
配置項:ext-sip-ip和ext-rtp-ip
外部的地址有以下幾種配置方式:
auto-nat //默認配置,由於我的外網路由器沒有開啟UPNP或者NAT-PMP協議,所以默認的配置不生效。 auto //使用內網地址,肯定不行。 stun:stun.freeswitch.org //能得到外網地址,但是不是實際使用的地址(可能是我的環境同時配置多個公網IP有關系),也PASS了。 181.92.2.7 //直接寫上外部的服務IP,不靈活,但是可以用。 host:host.server.com //由於我本身就使用了域名,所以這個最合適。
最后配置成這個樣子
<param name="ext-rtp-ip" value="host:cc-voip.xxx.com"/> <param name="ext-sip-ip" value="host:cc-voip.xxx.com"/>
這個配置有什么用?
當FreeSWITCH識別出來呼叫的終端位於nat后面時,在構造SDP消息時,會“聰明”的加上ext-rtp-ip的配置值。
所以想和公網的終端通話,必須配置外部IP為公網的地址。
3. 客戶端的公網地址
測試終端,軟電話(linphone)。
本機地址:192.168.1.15,公網地址:動態未知
未知?
假設我這台裝有軟電話的筆記本在家里打電話,是一個公網地址。我拿到公司打電話,顯然是另外一個公網地址。
4. 客戶端的注冊
找一個能ping通181.92.2.7的網絡。填寫注冊地址cc-voip.xxx.com(注意:這是通過域名的方式,這涉及一個域用戶的配置,可以單開一篇)
注冊成功!!!
注冊消息是怎么走的?
REGISTER (1019)192.168.1.15 -> 192.168.1.1(網關) -> 動態公網IP ->(公網路由節點)-> 181.92.2.7:5060 -> 10.40.50.203:15535 -> 10.10.10.190:5060
200 OK (1019)192.168.1.15 <- 192.168.1.1(網關) <- 動態公網IP <-(公網路由節點)<- 181.92.2.7:5060 <- 10.40.50.203:15535 <- 10.10.10.190:5060
5. 打電話試試?
入向撥號: 1019 -> 27909,振鈴了,接通。看上去很美妙。但是沒聲音。
出向撥號: 27909 -> 1019,偶爾通,大部分時間不通。再進一步測試觀察,哦,如果這個客戶端剛注冊上來,不超過1分鍾,撥通的概率還是很大的。超過2分鍾,就打不通了。當然了,即使撥通也沒聲音。
為什么出向撥號不通?
這就涉及到了一個常聽的術語:UDP打洞。
客戶端剛注冊的時候,中途經過的各個轉發設備都會臨時啟用一個新的端口(”打洞“)轉發這條注冊消息,並且保持這個新的端口一段時間(一般是120秒,各設備可以自己設定)。
保持的這段時間,所有轉發地址的映射關系也存在。
例如上圖注冊消息路由示意圖,出向撥號,FS記錄1019的下一跳地址是10.40.50.203:15535;203記錄15535端口映射的下一跳地址是181.92.2.7:5060,以此類推,直到INVITE消息送到192.168.1.15的地址上。
可是一旦過了端口保持的時期,這個15535端口就被釋放掉了。但是FS記錄的下一跳不變,悲劇了,再也無法出向撥號了。
這里又引出了另一個常用的術語:保活。
原理很簡單,既然打洞只能存續一小段時間,那我就在這個洞消失之前,再發一條新的消息,刷新一下端口記錄。比如120秒后釋放,那我每隔100秒發一個注冊消息,理論上這些個洞就會一直存在了。
這樣就可以隨時出向撥號了。
6. 沒有聲音怎么辦?
先看看原因,抓包看SDP,啊哦,1019帶的SDP地址竟然是192.168.1.15,FS往這個地址發語音包,1019肯定是收不到了。
這就需要使用各種NAT服務器了。
比如STUN、TURN、ICE(大致原理就是1019先去這些服務器查詢一下自己的動態的公網IP,然后使用這些公網IP。具體細節自行百度)
比如我的1019客戶端使用ICE服務器。再撥打一次電話,振鈴了,接通,哎呀,能聽到聲音了!!!
再抓個包看SDP,1019帶的SDP除了192.168.1.15,還帶了一個公網轉發地址,FS往公網地址發RTP包,這個公網再轉發一下,沒問題了啊。
附:
這是網絡結構比較復雜的穿透情況。而且還有一些附帶的問題。最好不要這么部署。
最簡單的就是直接把FS部署到公網IP上。
再不濟,也要把FS直接設置到公網IP后面,向我這種夾了一層私網的,真是難為FreeSWITCH了。