您如何使用Kamailio发出信号来进行RTP媒体的NAT遍历?

时间:2019-05-01 15:41:34

标签: sip linphone kamailio nat-traversal ice-protocol

有3个设备有问题。

  1. 位于NAT之后的VoIP电话
  2. 在EC2实例上我自己的Kamailio服务器。
  3. 手机上的Android版Linphone应用程序。

我的手机上有移动数据,并且由于我有MVNO,所以它似乎也已被NAT(像192.0.0.X这样的私有IP)

我的问题是,尽管SIP信令工作正常,但是我无法让任何一个设备接收对方的RTP媒体流。

我已经在kamailio.cfg中定义了WITH_NAT,但似乎对收集候选人没有帮助。这是通过Kamailio之前和之后的邀请。

之前:

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:105@172.56.20.144: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.

之后:

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:105@172.56.20.144: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.

呼入电话也是如此。

我期望nathelper模块添加类似的内容

a=candidate:2 1 UDP 1694498815 <SOME_PUBLIC_IP> <SOME_PUBLIC_PORT> typ srflx raddr
192.0.0.4 rport 7078

但显然不是。我可以修改标头中的o=c=以使用服务器从其接收邀请的IP,但是服务器如何知道应该将RTP媒体发送到哪个端口? 服务器 可以知道的唯一端口是

  1. 邀请发出的端口(私人和公共端)
  2. sdp中提供的端口。但是这些都是在私人方面。他们肯定会在公共方面有所不同吗?

任何帮助,将不胜感激。

1 个答案:

答案 0 :(得分:0)

您将需要设置rtpproxy或rtpengine。

这是使用Kamailio安装和配置rtpproxy的最简单过程:

1-安装rtpproxy

apt install rtpproxy

2-在rtpproxy配置文件(/ etc / default / rtpproxy)中输入以下两行:

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

IP地址是主机的外部IP地址。

3-在Kamailio配置文件(/etc/kamailio/kamailio.cfg)顶部附近输入以下定义:

#!define WITH_NAT

4-重新启动rtpproxy

systemctl restart rtpproxy

5-重新启动Kamailio

systemctl restart kamailio

Kamailio中继的INVITE和200 OK应该将其SDP联系人IP和端口替换为rtpproxy的

注意:我注意到至少有一个UAC应该使用TCP传输才能使上述功能正常工作。