检测重复 SIP 消息的最佳实施是什么?
我写了一个 SIP UAC,并且尝试了几种方法来检测和忽略来自 UAS 的重复传入消息,但是我尝试的每种方法都会出现问题,我的问题是所有与相同的调用具有相同的签名,并且比较所有消息文本太多了,所以我想知道,在尝试检测这些重复消息时应该查看组成消息的哪些参数。
更新:
我遇到了传入选项的问题,我通过向服务器发送空的“Ok”响应来处理该问题。 (更新:经过一段时间的测试后,我注意到,我仍然时不时地收到另一个选项请求,每隔几秒就会收到几次,所以我尝试用错误的请求进行响应,现在我只收到一次/两次选项请求每次注册/重新注册)
目前我有重复的 SessionInPogress 消息,以及不同的错误消息,例如此处繁忙和不可用,我收到了很多这样的消息,它弄乱了我的日志,我想过滤它们。
知道如何实现这一目标吗?
更新:
在发回之前我会尝试一下你的技术,也许这可以解决我的问题
这是我使用的,效果很好:
private boolean compare(SIPMessage message1, SIPMessage message2) {
if (message1.getClass() != message2.getClass())
return false;
if (message1.getCSeq().getSeqNumber() != message2.getCSeq().getSeqNumber())
return false;
if (!message1.getCSeq().getMethod().equals(message2.getCSeq().getMethod()))
return false;
if (!message1.getCallId().equals(message2.getCallId()))
return false;
if (message1.getClass()==SIPResponse.class)
if(((SIPResponse)message1).getStatusCode()!=((SIPResponse)message2).getStatusCode())
return false;
return true;
}
谢谢, 亚当.
I've wrote a SIP UAC, and I've tried a few ways to detect and ignore repeating incoming messages from the UAS, but with every approach I tried, something went wrong, my problem is that all the messages that has to do with the same call has the same signature, and to compare all of the message text is too much, so I was wondering, what parameter that compose a message should I be looking at when trying to detect these repeating messages.
UPDATE:
I had a problem with an incoming Options, which I handled with sending the server an empty Ok response. (Update: after a while of testing I noticed, that I still get every now and then I get another Options request, few every few second, so I try responding with a Bad request, and now I only get the Options request once/twice every registration/reregistration)
currently I have repeating messages of SessionInPogress, and different error messages such as busy here, and unavailable, I get so many of these, and it messes my log up, I would like to filter them.
any idea how to achieve that?
UPDATE:
I'll try your Technics before posting back, perhaps this would solve my problems
Here is what I used, it works nicely:
private boolean compare(SIPMessage message1, SIPMessage message2) {
if (message1.getClass() != message2.getClass())
return false;
if (message1.getCSeq().getSeqNumber() != message2.getCSeq().getSeqNumber())
return false;
if (!message1.getCSeq().getMethod().equals(message2.getCSeq().getMethod()))
return false;
if (!message1.getCallId().equals(message2.getCallId()))
return false;
if (message1.getClass()==SIPResponse.class)
if(((SIPResponse)message1).getStatusCode()!=((SIPResponse)message2).getStatusCode())
return false;
return true;
}
Thanks,
Adam.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这比 ChrisW 的答案复杂一点。
首先,事务层过滤掉大部分重传。对于大多数事情,它是通过将接收到的消息与当前事务列表进行比较来实现的。如果发现交易,则该交易将按照 RFC 3261 中的图表大部分吞掉重传,第 17 节。例如,处于 Proceeding 状态的 UAC INVITE 事务将丢弃延迟重传的 INVITE。
匹配以两种方式之一进行,具体取决于远程堆栈。如果它是 RFC 3261 堆栈(最顶层 Via 上的分支参数以“z9hG4bK”开头),那么事情就相当简单了。 第 17.2.3 节涵盖了完整的详细信息。
像这样的匹配将过滤掉重复/重新传输的选项(您提到这是一个特定问题)。 OPTIONS 消息不形成对话框,因此查看 CSeq 不起作用。特别是,如果 UAS 发出 5 个 OPTIONS 请求(不仅仅是重传),您将收到 5 个 OPTIONS 请求(以及 5 个非 INVITE 服务器事务)。
对非 INVITE 事务的重新传输临时响应将向上传递到事务用户层,或有时称为核心层,但除了第一个响应之外,最终响应不会传递到事务用户层。 (同样,您只需通过为该事务实现 FSM 即可获得这一点 - 最终响应将 UAC 非 INVITE 事务置于“已完成”状态,这会丢弃任何进一步的响应。
之后,事务用户层通常会收到多个响应INVITE 事务
发送多个 183 是完全正常的,至少对于 INVITE 而言,它可能会立即发送 100 来终止您的重传(至少通过不可靠的传输),然后发送几个 183、一个 180,也许一些。更多 183,最后是 200(或更多,对于不可靠的传输)
事务层提交所有这些响应很重要,因为代理和用户代理以不同的
方式 处理响应。我应该说:UAS 不使用重传逻辑来发送大量临时响应(除非它实现 RFC 3262)。重新发送 200 OK to INVITE,因为它们破坏了 UAC 事务。您可以通过及时发送 ACK 来避免重传。
It's a bit more complicated than ChrisW's answer.
First, the transaction layer filters out most retransmissions. It does this by, for most things, comparing the received message against a list of current transactions. If a transaction's found, that transaction will mostly swallow retransmissions as per the diagrams in RFC 3261, section 17. For instance, a UAC INVITE transaction in the Proceeding state will drop a delayed retransmitted INVITE.
Matching takes place in one of two ways, depending on the remote stack. If it's an RFC 3261 stack (the branch parameter on the topmost Via starts with "z9hG4bK") then things are fairly straightforward. Section 17.2.3 covers the full details.
Matching like this will filter out duplicate/retransmitted OPTIONS (which you mention as a particular problem). OPTIONS messages don't form dialogs, so looking at CSeq won't work. In particular, if the UAS sends out five OPTIONS requests which aren't just retransmissions, you'll get five OPTIONS requests (and five non-INVITE server transactions).
Retransmitted provisional responses to a non-INVITE transaction are passed up to the Transaction-User layer, or core as it's sometimes called, but other than the first one, final responses are not. (Again, you get this simply by implementing the FSM for that transaction - a final response puts a UAC non-INVITE transaction in the Completed state, which drops any further responses.
After that, the Transaction-User layer will typically receive multiple responses for INVITE transactions.
It's perfectly normal for a UAS to send multiple 183s, at least for an INVITE. For instance it might immediately send a 100 to quench your retransmissions (over unreliable transports at least), then a few 183s, a 180, maybe some more 183s, and finally a 200 (or more, for unreliable transports).
It's important that the transaction layer hands up all these responses because proxies and user agents handle the responses differently.
At this level the responses aren't, in a way, retransmitted. I should say: a UAS doesn't use retransmission logic to send loads of provisional responses (unless it implements RFC 3262). 200 OKs to INVITEs are resent because they destroy the UAC transaction. You can avoid their retransmission by sending your ACKs timeously.
我认为一条消息是重复/相同的,如果它的...
... 值与另一条消息的值匹配。
请注意,响应消息与其响应的请求具有相同的 CSeq;并且,单个请求您会收到多个临时但不重复的响应(例如,“RINGING”后接“OK”)。
I think that a message is duplicate/identical, if its ...
... values match that of another message.
Note that a response message has the same CSeq as the request to which it's responding; and, that a single request you get several, provisional, but non-duplicate responses (e.g. RINGING followed by OK).