Search code examples
sipnatkamailio

How to get Kamailio to set `Record-Route` header to internal IP for internal leg of call?


I have Kamailio 5.4.1 (and RTPEngine) running on an internal server with a private IP address 172.31.7.96 and One-to-one NAT to an external IP address. The external IP is 192.0.2.100. (Note: The internal IP addresses are all unedited, but the public IPs have been replaced with TEST-NET-1 and TEST-NET-2 example addresses.) I will eventually be doing transcoding with RTPEngine, but for now this is a simple SIP Proxy.

I have a Java application that sets up SIP calls running on an internal server with a private IP address 172.31.7.171. The Java application has set properties.setProperty("javax.sip.OUTBOUND_PROXY", "172.31.7.96"); to use Kamailio as an outbound SIP proxy.

The Kamailio server is a stock Kamailio sample configuration with the following changes:

#!define WITH_NAT
#!define WITH_RTPENGINE
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_IPAUTH

#!define WITH_DEBUG

listen=udp:0.0.0.0:5060 advertise 192.0.2.100:5060

#!define DBURL "mysql://kamailio:[email protected]/kamailio"

I have added my Java server's IP to the Kamailio database as an allowed server using kamctl address add 172.31.7.171 32 5060.

I am trying to make a call to extension 2003 at a SIP server located at 198.51.100.200.

My Java server follows the OUTBOUND_PROXY setting and sends the following request to Kamailio:

INVITE sip:[email protected]:5060 SIP/2.0
Call-ID: [email protected]
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:[email protected]:5060>
Max-Forwards: 70
Contact: <sip:[email protected]:5060;lr>
Content-Type: application/sdp
Via: SIP/2.0/UDP 172.31.6.171:5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Content-Length: 788

v=0
o=- 3808349342 3808349342 IN IP4 172.31.6.171
s=Kurento Media Server
c=IN IP4 172.31.6.171
t=0 0
m=audio 29134 RTP/AVPF 96 0 97
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:96 opus/48000/2
a=rtpmap:97 AMR/8000
a=rtcp:29135
a=sendrecv
a=mid:audio0
a=ssrc:3129303479 cname:user3476653135@host-5072a15e
m=video 15672 RTP/AVPF 102 103
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:102 VP8/90000
a=rtpmap:103 H264/90000
a=rtcp:15673
a=sendrecv
a=mid:video0
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 ccm fir
a=rtcp-fb:103 nack
a=rtcp-fb:103 nack pli
a=rtcp-fb:103 ccm fir
a=ssrc:1221454331 cname:user3476653135@host-5072a15e

Kamailio correctly modifies and forwards this request to the SIP server:

INVITE sip:[email protected]:5060 SIP/2.0
Record-Route: <sip:192.0.2.100;lr;nat=yes>
Call-ID: [email protected]
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:[email protected]:5060>
Max-Forwards: 69
Contact: <sip:[email protected]:5060;lr;alias=172.31.6.171~5060~1>
Content-Type: application/sdp
Via: SIP/2.0/UDP 192.0.2.100:5060;branch=z9hG4bK9466.896020178e132b7f5da3e990cd54fe55.0
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Content-Length: 1048
P-Hint: outbound

v=0
o=- 3808349342 3808349342 IN IP4 172.31.7.96
s=Kurento Media Server
c=IN IP4 172.31.7.96
t=0 0
m=audio 50062 RTP/AVPF 96 0 97
a=ssrc:3129303479 cname:user3476653135@host-5072a15e
a=mid:audio0
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:97 AMR/8000
a=sendrecv
a=rtcp:50063
a=ice-ufrag:jd1CMyb6
a=ice-pwd:nOhBs6gMNStuK301ELxdXtu0qB
a=candidate:nA5nzY4ckB4NyJQB 1 UDP 2130706431 172.31.7.96 50062 typ host
a=candidate:nA5nzY4ckB4NyJQB 2 UDP 2130706430 172.31.7.96 50063 typ host
m=video 50094 RTP/AVPF 102 103
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 ccm fir
a=rtcp-fb:103 nack
a=rtcp-fb:103 nack pli
a=rtcp-fb:103 ccm fir
a=ssrc:1221454331 cname:user3476653135@host-5072a15ea=mid:video0
a=rtpmap:102 VP8/90000
a=rtpmap:103 H264/90000
a=sendrecv
a=rtcp:50095
a=ice-ufrag:k5OhtdDn
a=ice-pwd:R8U3hA1ocUe1ln1F5rpgyHRK98
a=candidate:nA5nzY4ckB4NyJQB 1 UDP 2130706431 172.31.7.96 50094 typ host
a=candidate:nA5nzY4ckB4NyJQB 2 UDP 2130706430 172.31.7.96 50095 typ host

After the expected 100 Trying and 180 Ringing packets, the SIP server sends back a 200 OK packet:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.0.2.100:5060;branch=z9hG4bK9466.896020178e132b7f5da3e990cd54fe55.0;received=192.0.2.100;rport=5060
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Record-Route: <sip:192.0.2.100;lr;nat=yes>
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:[email protected]:5060>;tag=as7825a958
Call-ID: [email protected]
CSeq: 1 INVITE
Server: FPBX-13.0.197.22(13.28.1)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Contact: <sip:[email protected]:5060>
Content-Type: application/sdp
Content-Length: 311

v=0
o=root 2047371680 2047371680 IN IP4 198.51.100.200
s=Asterisk PBX 13.28.1
c=IN IP4 198.51.100.200
b=CT:384
t=0 0
m=audio 14980 RTP/AVPF 0
a=rtpmap:0 PCMU/8000
a=maxptime:150
a=sendrecv
m=video 12536 RTP/AVPF 103 102
a=rtpmap:103 H264/90000
a=rtpmap:102 VP8/90000
a=rtcp-fb:* ccm fir
a=sendrecv

Kamailio translates this and sends it back to my Java application:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 172.31.6.171:5060;rport=5060;branch=z9hG4bK-343236-823591d229bb5a87df35606cbc45e6e6
Record-Route: <sip:192.0.2.100;lr;nat=yes>
From: <tel:+16676664567>;tag=1eu0cJThbWsUcycT
To: <sip:[email protected]:5060>;tag=as7825a958
Call-ID: [email protected]
CSeq: 1 INVITE
Server: FPBX-13.0.197.22(13.28.1)
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Contact: <sip:[email protected]:5060>
Content-Type: application/sdp
Content-Length: 363

v=0
o=root 2047371680 2047371680 IN IP4 172.31.7.96
s=Asterisk PBX 13.28.1
c=IN IP4 172.31.7.96
b=CT:384
t=0 0
m=audio 50076 RTP/AVPF 0
a=maxptime:150
a=mid:audio0
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:50077
m=video 50116 RTP/AVPF 103 102
a=rtcp-fb:* ccm fir
a=mid:video0
a=rtpmap:103 H264/90000
a=rtpmap:102 VP8/90000
a=sendrecv
a=rtcp:50117

This is where the problem starts. My Java application sees the Record-Route header which says 192.0.2.100 and tries to send the ACK response to that address, as well as including it in a Route header:

ACK sip:[email protected]:5060 SIP/2.0
Call-ID: [email protected]
CSeq: 1 ACK
Via: SIP/2.0/UDP 172.31.6.171:5060;branch=z9hG4bK-343236-57a2ec825886f425ef0b9f8cf2034887
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:[email protected]:5060>;tag=as7825a958
Max-Forwards: 70
Route: <sip:192.0.2.100;lr;nat=yes>
Record-Route: <sip:192.0.2.100;lr;nat=yes>
Content-Length: 0

The problem here is that my internal server cannot actually route traffic to the public IP of the Kamailio server so the ACK never gets there.

I tried adding a second listen directive to Kamailio like this and then set the OUTBOUND_PROXY to use port 5061, but then Kamailio tries to put 172.31.7.96:5061 in the outbound SIP messages too:

listen=udp:0.0.0.0:5060 advertise 192.0.2.100:5060
listen=udp:172.31.7.96:5061

How can I configure Kamailio to use its private IP when talking to the internal server and its public IP when talking to the external server?


Solution

  • To resolve such an issue I switched to use IPv6 on internal SIP servers for signaling and IPv4 for RTP media.