检测重复SIP消息的最佳实现是什么?

时间:2010-07-01 07:49:32

标签: filter uac sip jain-sip

我写了一个SIP UAC,我尝试了几种方法来检测和忽略来自UAS的重复传入消息,但是我尝试的每一种方法都出错了,我的问题是所有的消息都有与同一个调用具有相同的签名,并且比较所有的消息文本太多了,所以我想知道,在尝试检测这些重复消息时,我应该查看构成消息的参数。

更新

我遇到了传入的选项问题,我通过向服务器发送一个空的Ok响应来处理。 (更新:经过一段时间的测试后,我注意到,我仍然得到了所有,然后我得到另一个选项请求,每隔几秒就有几个,所以我尝试使用Bad请求进行响应,现在我只获得一次/两次选项请求每次注册/重新注册)

目前我有重复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;
}

谢谢, 亚当。

2 个答案:

答案 0 :(得分:2)

这比ChrisW的回答要复杂一点。

首先,事务层过滤掉大多数重传。在大多数情况下,它通过将收到的消息与当前事务列表进行比较来实现此目的。如果找到了一个事务,那么该事务将主要根据RFC 3261, section 17中的图表吞下重传。例如,Proceeding状态中的UAC INVITE事务将丢弃延迟重传的INVITE。

匹配以两种方式之一进行,具体取决于远程堆栈。如果它是RFC 3261堆栈(最顶层Via的分支参数以“z9hG4bK”开头),那么事情就相当简单了。 Section 17.2.3涵盖了全部细节。

这样的匹配将过滤掉重复/重新传输的OPTIONS(您提到的特定问题)。 OPTIONS消息不会形成对话框,因此查看CSeq将无法正常工作。特别是,如果UAS发出五个不仅仅是重传的OPTIONS请求,您将获得五个OPTIONS请求(以及五个非INVITE服务器事务)。

对非INVITE事务的重新传输的临时响应被传递到Transaction-User层,或者有时被称为核心,但除了第一个之外,最终响应不是。 (同样,您只需通过为该事务实现FSM即可实现此目的 - 最终响应将UAC非INVITE事务置于已完成状态,这将丢弃任何进一步的响应。

之后,Transaction-User层通常会收到INVITE事务的多个响应。

UAS发送多个183s是完全正常的,至少对于INVITE来说是这样。例如,它可能会立即发送100来熄灭您的重传(至少通过不可靠的传输),然后是几个183,一个180,可能多一些183,最后一个200(或更多,对于不可靠的传输)。

交易层提交所有这些响应非常重要,因为代理和用户代理以不同方式处理响应。

在此级别,响应不会在某种程度上重新传输。我应该说:UAS不使用重传逻辑来发送大量临时响应(除非它实现RFC 3262)。重新发送200 OKs到INVITE,因为它们会破坏UAC事务。您可以通过及时发送您的ACK来避免重新传输。

答案 1 :(得分:0)

我认为消息是重复/相同的,如果它...

  • Cseq的
  • 呼叫ID
  • 和方法名称(例如“邀请”)

...值与另一条消息的值匹配。

请注意,响应消息与其响应的请求具有相同的CSeq;并且,单个请求可以获得多个临时但非重复的响应(例如RINGING后跟OK)。