如何让Kamailio将`Record-Route`标头设置为内部呼叫的内部IP?

问题描述

我的Kamailio 5.4.1(和RTPEngine)在内部服务器上运行,该服务器具有专用IP地址172.31.7.96和与外部IP地址的一对一NAT。外部IP为192.0.2.100。 (注意:内部IP地址均未编辑,但是公共IP已被示例地址TEST-NET-1TEST-NET-2代替。)我最终将使用RTPEngine进行转码,但是现在这很简单SIP代理。

我有一个Java应用程序,该应用程序设置在具有专用IP地址172.31.7.171的内部服务器上运行的SIP调用。 Java应用程序已将properties.setProperty("javax.sip.OUTBOUND_PROXY","172.31.7.96");设置为将Kamailio用作出站SIP代理。

Kamailio服务器是Kamailio的库存示例配置,具有以下更改:

#!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"

我已使用kamctl address add 172.31.7.171 32 5060将Java服务器的IP作为允许的服务器添加到Kamailio数据库中。

我正尝试在位于2003的SIP服务器上呼叫分机198.51.100.200

我的Java服务器遵循OUTBOUND_PROXY设置,并将以下请求发送到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正确地修改了此请求并将其转发到SIP服务器:

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

在期望的100 Trying180 Ringing数据包之后,SIP服务器发送回200 OK数据包:

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对此进行翻译并将其发送回我的Java应用程序:

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,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

这是问题开始的地方。我的Java应用程序看到了Record-Route标头,上面写着192.0.2.100,并尝试将ACK响应发送到该地址,并将其包含在Route标头中:

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

这里的问题是我的内部服务器实际上无法将流量路由到Kamailio服务器的公用IP,因此ACK永远不会到达那里。

我尝试像这样向Kamailio添加第二个listen指令,然后将OUTBOUND_PROXY设置为使用端口5061,但随后Kamailio尝试将172.31.7.96:5061放入出站也有SIP消息:

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

如何将Kamailio配置为在与内部服务器对话时使用其私有IP,并在与外部服务器对话时使用其公共IP?

解决方法

为解决此问题,我切换为在内部SIP服务器上使用IPv6进行信令传输,并在RTP媒体上使用IPv4。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...