本文原創自 http://blog.csdn.net/voipmaker 轉載注明出處。
本文是VOIP通信NAT系列專題的第三篇,
本文論述NAT對SIP協議穿越的影響。SIP協議是基於文本的,而他的一些地址是保存在消息頭傳輸。NAT設備在沒開啟ALG情況下不會改動消息頭地址,
多數client填寫的地址都是內網地址,這就導致消息路由問題,SIP 信令穿越涉及兩部分,一個是注冊。還有一個是INVITE(呼叫),涉及的消息頭為contact頭和via頭,
contact頭是告知對方自己直接可達的地址,via頭告知對方,此消息是從哪個地址,哪個port送過來,接收端響應時依據via地址做響應,先說register, client注冊時
會把自己的地址port填寫到contact頭,但這個地址在nat環境下並無論用。注冊的作用是告知server自己的可達地址,后面有呼叫送給他時server直接送到這個地址就可以,
而client填寫的私有地址在nat環境下並不可達。server興許呼叫直接送這個地址是失敗的。解決問題須要client支持 sip outbound, 其原理是server發現假設client是在nat環境下,則記錄接收到register請求的地址和port。而不是contact地址和port。 這個地址和port一般是NAT設備給client映射的外部port,而NAT設備維護這個映射是 有時間限制的,為確保這個映射一直開啟就須要client周期性發keep-alive包。包的類型有多種,有的直接周期發register,有的發options, rfc5626規范要求TCP用回車換行發送。UDP則用stun 的bind request 保持NAT 映射處於活躍狀態。 這就攻克了呼叫client問題。 SIP穿越的還有一個問題是響應發送給誰。前面提到,響應者會依據via頭做 response,但via頭一般是內網地址。NAT環境下是不可達的,RFC 3581攻克了這個問題,通過在via頭中添加 rport和received字段支持此擴展,rport在發起請求者的包中是空的,接收到收到后發現有這兩個頭,接收端會檢測實際收到的包的地址和port,把這兩個值填寫到recived和rport中,告知請求發起者,同一時候在響應請求時把響應向這個地址和port發送,通常這個地址和port是NAT設備映射的地址和port。
至此SIP信令穿越問題完美解決。
下一篇文章講述VOIP NAT穿越 之媒體穿越。
