There are three devices in question.
- A VoIP phone behind NAT
- My own Kamailio Server on an EC2 instance.
- The Linphone application for android on my phone.
My phone is on mobile data, and since I have an MVNO, it appears to be NATed as well (private IP like 192.0.0.X).
My problem, is that Although SIP signalling is working just fine, I can't get either device to receive the other's RTP media streams.
I've defined WITH_NAT in the kamailio.cfg, but it doesn't seem to be helping with gathering candidates. Here's the invite before and after passing through Kamailio.
Before:
Via: SIP/2.0/UDP 192.0.0.4:46244;branch=z9hG4bK.bLB4chm4B;rport.
From: "the app" <sip:105@<SERVERDOMAIN>>;tag=EHCGj~8d5.
To: sip:104@<SERVERDOMAIN>.
CSeq: 20 INVITE.
Call-ID: SyOH-iCt1A.
Max-Forwards: 70.
Supported: replaces, outbound, gruu.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE.
Content-Type: application/sdp.
Content-Length: 721.
Contact: <sip:[email protected]:43565;transport=udp>;expires=3600;received="sip:172.56.20.144:43565";+sip.instance="<urn:uuid:f102067f-da3a-00f6-9530-ee66544ec6b4>".
User-Agent: <USERAGENT>/0.2.1-debug (Mobile Dev Environment 1) LinphoneSDK/4.1-366-g1b22291 (master) (belle-sip/1.6.3).
.
v=0.
o=105 911 2837 IN IP4 192.0.0.4.
s=Talk.
c=IN IP4 192.0.0.4.
t=0 0.
a=ice-pwd:42da1553a4faaaf4b57c93f2.
a=ice-ufrag:894dda61.
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics.
m=audio 7078 RTP/AVP 0 8 101.
a=rtpmap:101 telephone-event/8000.
a=candidate:1 1 UDP 2130706303 192.0.0.4 7078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 7079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
m=video 9078 RTP/AVP 96.
a=rtpmap:96 H264/90000.
a=fmtp:96 profile-level-id=42801F.
a=candidate:1 1 UDP 2130706303 192.0.0.4 9078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 9079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
a=rtcp-fb:96 nack pli.
a=rtcp-fb:96 ccm fir.
After:
Record-Route: <sip:<SERVERDOMAIN>:<PORT>;lr;nat=yes>.
Via: SIP/2.0/UDP <SERVERDOMAIN>:<PORT>;branch=z9hG4bKdd88.20b5965a3ea168d68a6b0603ebaa6c80.0.
Via: SIP/2.0/UDP 192.0.0.4:46244;received=172.56.20.144;branch=z9hG4bK.bLB4chm4B;rport=43565.
From: "the app" <sip:105@<SERVERDOMAIN>>;tag=EHCGj~8d5.
To: sip:104@<SERVERDOMAIN>.
CSeq: 20 INVITE.
Call-ID: SyOH-iCt1A.
Max-Forwards: 69.
Supported: replaces, outbound, gruu.
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE.
Content-Type: application/sdp.
Content-Length: 721.
Contact: <sip:[email protected]:43565;transport=udp;alias=172.56.20.144~43565~1>;expires=3600;received="sip:172.56.20.144:43565";+sip.instance="<urn:uuid:f102067f-da3a-00f6-9530-ee66544ec6b4>".
User-Agent: <USERAGENT>/0.2.1-debug (Mobile Dev Environment 1) LinphoneSDK/4.1-366-g1b22291 (master) (belle-sip/1.6.3).
.
v=0.
o=105 911 2837 IN IP4 192.0.0.4.
s=Talk.
c=IN IP4 192.0.0.4.
t=0 0.
a=ice-pwd:42da1553a4faaaf4b57c93f2.
a=ice-ufrag:894dda61.
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics.
m=audio 7078 RTP/AVP 0 8 101.
a=rtpmap:101 telephone-event/8000.
a=candidate:1 1 UDP 2130706303 192.0.0.4 7078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 7079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
m=video 9078 RTP/AVP 96.
a=rtpmap:96 H264/90000.
a=fmtp:96 profile-level-id=42801F.
a=candidate:1 1 UDP 2130706303 192.0.0.4 9078 typ host.
a=candidate:1 2 UDP 2130706302 192.0.0.4 9079 typ host.
a=rtcp-fb:* trr-int 1000.
a=rtcp-fb:* ccm tmmbr.
a=rtcp-fb:96 nack pli.
a=rtcp-fb:96 ccm fir.
It's the same story for inbound calls.
I was expecting the nathelper module to add something like
a=candidate:2 1 UDP 1694498815 <SOME_PUBLIC_IP> <SOME_PUBLIC_PORT> typ srflx raddr
192.0.0.4 rport 7078
but clearly it is not. I can modify o=
and c=
in the headers to use the IP that the server received the invite from, but how is the server suppose to know which ports the RTP media should be sent to? The only ports the server could know are
- The port that the invite was sent from (private and public side)
- The ports provided in the sdp. But these are on the private-side. Surely they would be different on the public-side?
Any help on this would be appreciated.