1
votes

There are three devices in question.

  1. A VoIP phone behind NAT
  2. My own Kamailio Server on an EC2 instance.
  3. 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

  1. The port that the invite was sent from (private and public side)
  2. 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.

1
hey, did you try rtpengine? it helps you to fix natted problems. kamailio.org/docs/modules/5.2.x/modules/… you can change c and o line with rtpengine ip-address. rtp flows over rtpengine.Ycaner

1 Answers

1
votes

You will need to setup rtpproxy or rtpengine.

Here is the simplest procedure for installing and configuring rtpproxy with Kamailio:

1- install rtpproxy

apt install rtpproxy

2- Enter these 2 lines in rtpproxy configuration file (/etc/default/rtpproxy):

CONTROL_SOCK=udp:127.0.0.1:7722
EXTRA_OPTS="-l IP-address"

IP-address is the external IP address of your host.

3- Enter this define near the top of Kamailio configuration file (/etc/kamailio/kamailio.cfg):

#!define WITH_NAT

4- Restart rtpproxy

systemctl restart rtpproxy

5- Restart Kamailio

systemctl restart kamailio

INVITE and 200 OK relayed by Kamailio should then have their SDP Contact IPs and Ports replaced with the ones for rtpproxy

Note: I noticed at least one of the UAC should use TCP Transport for the above to work.