天天看點

kamailio在公網部署注冊和呼叫相關的問題

       kamailio在公網部署,收到SIP終端注冊的消息中的contact位址可能帶的是内網的IP位址和端口,例如終端注冊封包如下:

REGISTER sip:47.99.60.58:5060 SIP/2.0

Via: SIP/2.0/UDP 192.168.1.110:5060;rport;branch=z9hG4bK504370402

Route: <sip:47.99.60.58;lr>

From: "1982595644" <sip:[email protected]>;tag=1899555974

To: "1982595644" <sip:[email protected]>

Call-ID: [email protected]

CSeq: 1 REGISTER

Contact: <sip:[email protected]:5060>

Max-Forwards: 70

User-Agent: Cisco

Expires: 300

Allow: INVITE,ACK,CANCEL,BYE,UPDATE,INFO,OPTIONS,REFER,NOTIFY

Content-Length: 0

SIP/2.0 401 Unauthorized

Via: SIP/2.0/UDP 192.168.1.110:5060;rport=5060;branch=z9hG4bK504370402;received=122.226.117.78

From: "1982595644" <sip:[email protected]>;tag=1899555974

To: "1982595644" <sip:[email protected]>;tag=bf8638324618dc61059d4c604476fea1.f3fe

Call-ID: [email protected]

CSeq: 1 REGISTER

WWW-Authenticate: Digest realm="47.99.60.58", nonce="XtYVo17WFHdzgA1OOXJnCD4S1iVq+mNh", qop="auth", algorithm=MD5

Server: kamailio (5.2.4 (x86_64/linux))

Content-Length: 0

REGISTER sip:47.99.60.58:5060 SIP/2.0

Via: SIP/2.0/UDP 192.168.1.110:5060;rport;branch=z9hG4bK1729793929

Route: <sip:47.99.60.58;lr>

From: "1982595644" <sip:[email protected]>;tag=1899555974

To: "1982595644" <sip:[email protected]>

Call-ID: [email protected]

CSeq: 2 REGISTER

Contact: <sip:[email protected]:5060>

Authorization: Digest username="1982595644", realm="47.99.60.58", nonce="XtYVo17WFHdzgA1OOXJnCD4S1iVq+mNh", uri="sip:47.99.60.58:5060", response="615570b427d299ad05baaa94bc8533d7", algorithm=MD5, cnonce="0a4f113b", qop=auth, nc=00000001

Max-Forwards: 70

User-Agent: Cisco

Expires: 300

Allow: INVITE,ACK,CANCEL,BYE,UPDATE,INFO,OPTIONS,REFER,NOTIFY

Content-Length: 0

SIP/2.0 200 OK

Via: SIP/2.0/UDP 192.168.1.110:5060;rport=5060;branch=z9hG4bK1729793929;received=122.226.117.78

From: "1982595644" <sip:[email protected]>;tag=1899555974

To: "1982595644" <sip:[email protected]>;tag=bf8638324618dc61059d4c604476fea1.262a

Call-ID: [email protected]

CSeq: 2 REGISTER

Contact: <sip:[email protected]:5060>;expires=300

Server: kamailio (5.2.4 (x86_64/linux))

Content-Length: 0

      kamailio儲存在記憶體中的終端位址為終端注冊過來的内網位址,而不是來源的IP位址和端口,通過kamailio進行外呼這個注冊的終端,發現kamailio會将消息發往終端注冊過來的内網位址,可能會導緻呼叫失敗。通過閱讀kamailio的官方文檔,可以通過設定NAT相關标緻來解決,但是發現一般NAT是和rtpproxy一塊使用,我們項目中隻使用kamailio來做信令的代理,不處理媒體,而且本人設定了下NAT相關的,發現儲存注冊過來的SIP終端的位址還是内網的位址,可能是我沒有用好kamailio的NAT,本人通過修改kamailio的registrar的save.c函數中的save函數,如果發現contact位址中的IP和來源IP位址不一緻,将REGISTER封包中的contact位址改為來源的IP位址和端口,這時kamailio記憶體中儲存的注冊資訊的contact位址從内網位址變成了公網位址。但是發現通過kamailio進行外呼注冊的SIP終端還是不能呼叫成功,發現終端回複的INVITE的200 OK中的contact位址為終端的内網位址,導緻主叫回複到ACK 中的request-uri(ACK sip:[email protected]:5060 SIP/2.0)為終端的内網位址,導緻kamailio路由ACK信令時,将信令轉到了request-uri中的導緻,最後導緻ack信令沒有到達終端,導緻呼叫失敗。

       通過修改kamailio.cfg配合檔案,判斷如果收到終端回複的INVITE 200 OK信令時,在該信令中添加一個私有頭域,帶上該200 OK的來源IP位址和端口,主叫收到200 OK後,解析該私有頭域,後續發送ACK、UPDATE、BYE等信令時,request-uri中的IP位址和端口都使用該位址,最後呼叫成功。

       外呼模型為:标準SIP網關-------kamailio-------SIP終端,信令都通過kamailio進行代理;

       kamailio.cfg的更改如下:

# Manage incoming replies

onreply_route[MANAGE_REPLY] {

        xdbg("incoming reply\n");

        if ( is_method("INVITE") && t_check_status("200") ) {

                xinfo("----- IP:$si:$sp");

                append_hf("SourceAddress: $si:$sp\r\n");

        }

        if(status=~"[12][0-9][0-9]") {

                route(NATMANAGE);

        }

}