如何确保 BYE 消息绕过 SIP 代理?

How do I ensure that BYE messages bypass a SIP proxy?

我正在尝试构建类似于此图中的无状态 SIP 代理:

当 "Alice" 首先挂断时它的行为是正常的,BYE 消息直接发送到 "Bob" 并且不接触代理。但是,当 "Bob" 先挂断时,BYE 消息在以太网中丢失,或者到达代理,而不是 "Alice"。

这是 Proxy 发送给 Alice 的 200 消息,就在 ACK 之前(从 Bob 转发)

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.168.103:58922;received=98.0.xxx.xxx;rport=39612;branch=z9hG4bKPjkdKDifFk6647hFrB-.WRwaWW0HixPPnG
Record-Route:  <sip:208.xx.xx.11;ftag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r;lr=on>,  <sip:199.x.xxx.101;lr;ftag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r;nc=1;did=615.7e25f325;pr=3>
From: "Alice" <sip:alice@foo.com>;tag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r
To:  <sip:proxy@proxy-uri.com>;tag=as13aaa2d9
Call-ID: gL7sgrTlu7wCcQCeOqhgOSe6tr.LDu9v
CSeq: 19813 INVITE
User-Agent: Asterisk PBX
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO
Supported: replaces
Contact:  <sip:12340@208.xx.xx.12:5090>
Content-Type: application/sdp
Content-Length: 300

v=0
o=root 3520 3520 IN IP4 199.x.xxx.73
s=session
c=IN IP4 199.x.xxx.73
t=0 0
m=audio 59316 RTP/AVP 0 8 9 101
a=silenceSupp:off - - - -
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=sendrecv
a=rtcp:59317
a=ptime:20

这是 Alice 发送给 Bob 的 ACK:

ACK sip:12340@208.xx.xx.12:5090 SIP/2.0
Via: SIP/2.0/UDP 192.168.168.103:58922;rport;branch=z9hG4bKPjKxiikjcMSTNLKavscYpxTToZfOn7AlCI
Max-Forwards: 70
From: "Alice" <sip:alice@foo.com>;tag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r
To: <sip:proxy@proxy-uri.com>;tag=as13aaa2d9
Call-ID: gL7sgrTlu7wCcQCeOqhgOSe6tr.LDu9v
CSeq: 19813 ACK
Route: <sip:199.x.xxx.101;lr;ftag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r;nc=1;did=615.7e25f325;pr=3>
Route: <sip:208.xx.xx.11;lr;ftag=I9jUO6GotuK.DLbMUK9.HRKStDfVA18r>
User-Agent: Blink Lite 4.6.0 (MacOSX)
Content-Length:  0

我只能控制代理生成的消息。我猜我需要添加/删除/更改代理在 ACK 之前发送的 200,但我不确定?提前致谢。

tl;dr 您的代理必须是 so-called 非 Record-Routing 代理,以确保您的代理不属于任何后续请求。

嘿亚当,

在 SIP 中,有几个 "magic" header 控制消息在网络上的路由方式。 Route headers 用于请求,Via headers 用于响应。如果要确保任何请求都遵循网络中的特定路径,则需要确保添加正确的 Route headers 以强制以特定方式请求(或者,在您的情况下,不添加路由headers)。对于新请求,由 UAC(用户代理客户端 - 在本例中为 Alice)发起的请求,客户端可以将路由 headers 推送到该请求上。由于该请求在到达 UAS(用户代理服务器 - Bob)的途中通过其他元素并且这些元素希望留在后续请求的路径中,因此这些元素需要添加 Record-Route header到消息,它构建了路由集,然后 UA 稍后将使用该路由集将路由 headers 推送到后续请求。

因此,简而言之,您需要通过在这种情况下不在代理中添加 Record-Route 来控制后续请求的路径。

另外,如果 BYE 没有到达 Alice,那很可能是因为 Alice 没有在联系人 header 中标记正确的信息。确保无论你标记什么,Bob 都能访问到某些东西(假设这是 public 互联网,那么它必须是 public IP 地址)。

如果您想了解有关这些内容的所有详细信息,实际上我很久以前就录制了关于这个主题的演示文稿,因为这是 SIP 最容易被误解的领域之一。参见:https://vimeo.com/140267478

我认为问题出在 Alice 发送给 Bob 的 ACK 上。它没有用于路由新事务的联系人 header。它可能工作不正常。在您的 200 OK 中,联系人不是代理,因此 ACK 未通过它。

为了避免 Alice 不在 ACK 中发送联系人,您的代理应该这样做。我会尝试在 200 OK:

中设置联系人内部的代理

SIP/2.0 200 行
[...]
联系人:< sip:12340@proxyIP>
[...]

这样做,Alice 发送给 Bob 的 ACK 将在代理中收到,您必须将其发送给 Bob,将 Contact 更改为 Alice。

希望对您有所帮助。让我知道它是否有效。

为了帮助您,您还应该 post INVITE 消息。正如其他人提到的,问题可能是 record-route header 的存在。也可能是来自 Alice 的 INVITE 中的错误联系人 header。

header via 中 "received=" 的存在对 BYE 消息没有影响,仅对 Bob 对代理的响应(在您的情况下为 180 和 200)有影响。