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:REAL_PASSWORD_HERE@127.0.0.1/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:2003@198.51.100.200:5060 SIP/2.0
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>
Max-Forwards: 70
Contact: <sip:+18005551234@172.31.6.171: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:2003@198.51.100.200:5060 SIP/2.0
Record-Route: <sip:192.0.2.100;lr;nat=yes>
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 INVITE
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200:5060>
Max-Forwards: 69
Contact: <sip:+18005551234@172.31.6.171: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:2003@198.51.100.200:5060>;tag=as7825a958
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
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:2003@198.51.100.200: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:2003@198.51.100.200:5060>;tag=as7825a958
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
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:2003@198.51.100.200: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:2003@198.51.100.200:5060 SIP/2.0
Call-ID: 7979ef9aadc442801835750ef2564a19@172.31.6.171
CSeq: 1 ACK
Via: SIP/2.0/UDP 172.31.6.171:5060;branch=z9hG4bK-343236-57a2ec825886f425ef0b9f8cf2034887
From: <tel:+18005551234>;tag=1eu0cJThbWsUcycT
To: <sip:2003@198.51.100.200: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?
To resolve such an issue I switched to use IPv6 on internal SIP servers for signaling and IPv4 for RTP media.