【问题标题】:SIP ACK request re-transmission on transport errorSIP ACK 请求重传传输错误
【发布时间】:2016-08-29 12:02:32
【问题描述】:

这个问题是关于 SIP(​​会话发起协议)中的 ACK 请求。引用 RFC-3261 - 18.1.1 发送请求

If an element sends a request over TCP because of these message size
constraints, and that request would have otherwise been sent over
UDP, if the attempt to establish the connection generates either an
ICMP Protocol Not Supported, or results in a TCP reset, the element
SHOULD retry the request, using UDP.

这对于 INVITE 和除 ACK 之外的其他非邀请请求看起来没问题。以下是我认为上述陈述可能不适用于 ACK 的几点。

  1. ACK 只是一个请求而不是事务。所以 SIP 事务状态机一定不适用于 ACK 请求。由于状态机是唯一谈论重传的地方,所以 18.1.1 不适用于 ACK 请求。引用 3261 - “17.1 Client Transaction” - 支持上述论点。

    There are two types of client transaction state machines, depending
    on the method of the request passed by the TU. One handles client
    transactions for INVITE requests. This type of machine is referred
    to as an INVITE client transaction. Another type handles client
    transactions for all requests except INVITE and ACK. This is
    referred to as a non-INVITE client transaction. There is no client
    transaction for ACK. If the TU wishes to send an ACK, it passes one
    directly to the transport layer for transmission.
    
  2. 只有在下一个 B 方重传最终响应时才能重传 ACK。

Q:- 我的假设是否正确,SIP ACK 请求在收到传输错误(如连接错误、ICMP 错误)时无法重传?

引用 3261 - “17.1 客户交易” -

If the TU wishes to send an ACK, it passes one
directly to the transport layer for transmission.

问:- TU希望是什么意思?这是否意味着 TU 可以随时发送,还是意味着只要有最终响应,就只有 TU 发送?

问候, 苏丹苏

【问题讨论】:

    标签: sip


    【解决方案1】:

    1) 让我们回到基本的东西

    "如果一个元素由于这些消息大小而通过 TCP 发送请求 约束,否则该请求将被发送过来 UDP,如果尝试建立连接会生成 不支持 ICMP 协议,或导致 TCP 重置,该元素 应该使用 UDP 重试请求。”

    我的 cmets :- “应该重试请求”--> 它说应该重试而不是必须重试请求。 因此,发送 ACK 请求根本不是强制性的。

    2)

    Q:- 我的假设是否正确,SIP ACK 请求在收到传输错误(如连接错误、ICMP 错误)时无法重传?

    引用 3261 - “17.1 客户交易” -

    如果 TU 希望发送一个 ACK​​,它会直接将一个 ACK​​ 传递给传输层进行传输。

    cmets :- 这清楚地说明了 TU(事务用户)是否希望{不必须}将 ACK 请求传递给传输层进行传输。

    因此,根据声明,一旦您将 ACK 传递给传输层,应用程序希望不做任何事情。或者,如果在另一端,如果应用程序需要任何 TCP 错误 (ICMP),那么它可以通过 UDP 重新传输相同的 ACK 请求。

    请参阅 RFC 永远不会排除 ACK,这是应用程序的责任以及它是如何实现的。 也可以在 Sip-implementors mailing list 上提问。你会得到更多志同道合的人。

    【讨论】:

    • 答案 1) 似乎不可能。一旦 A-Party 发送了 ACK,它将终止由它维护的 INVITE 事务(在调用成功和失败的情况下)。因此,在传输错误的情况下,应用程序将如何生成 ACK。我相信它必须是端到端的。
    • Answer 2) 我相信这不是应用程序随机发送的愿望。必须有一些触发点才能做到这一点(例如 B 方重新传输最终响应)。
    • 请参阅 RFC section 8.1.3.1 " 8.1.3.1 事务层错误 在某些情况下,事务层返回的响应不会是 SIP 消息,而是事务层错误。当超时从事务层接收到错误,必须将其视为收到 408(请求超时)状态码。如果传输层报告了致命的传输错误(通常是由于 UDP 中的致命 ICMP 错误或连接失败)在 TCP 中),该条件必须被视为 503(服务不可用)状态代码。”
    • 对于 ACK 既不能返回 408 也不能返回 503。所以上述论点不适用于 ACK。
    • 它没有说在 ACK 上回复 408 或 503。请仔细阅读,它说当您收到非 SIP 标头错误回复时,请分别将其视为 503 或 408,并按照您在 SIP 堆栈中处理 503 或 408 的方式进行处理。
    【解决方案2】:

    首先进行一些澄清。来自 [RFC3261 第 6 节][1]:

    SIP 事务:一个 SIP 事务发生在一个客户端和一个 服务器并包含来自发送的第一个请求的所有消息 从客户端到服务器直到最终(非 1xx)响应 从服务器发送到客户端。如果请求是 INVITE 并且最终响应是非 2xx,事务也 包括对响应的 ACK。 2xx 响应的 ACK INVITE 请求是一个单独的事务

    因此,对非 2xx 的 ACK 是与 INVITE、任何 1xx 响应和最终响应相同的事务的一部分。特别是它具有相同的 CSeq 和相同的分支标签。对非 2xx 响应的 ACK 是逐跳的。

    对 2xx 的 ACK 是一个新事务(尽管这是一个特殊的 ACK 事务,并且没有响应)。它具有相同的 CSeq,但分支标记不同。对 2xx 响应的 ACK 一直从客户端到服务器。

    关于您的具体观点,第 17 节是关于事务层的。在这里,ACK 仅在响应重新传输的最终响应时才被重新传输。当事务层决定它需要发送一个 ACK​​ 时,它会将其发送到传输层,而传输层的工作就是传递它。

    第 18 节是关于传输层的。 ICMP 错误或 TCP 重置是传输层错误,它们不在 SIP 事务模型中。如果传输层需要将消息从 UDP 提升到 TCP,或者从 TCP 回退到 UDP,这与事务层模型是分开的。实际上,如果 TCP 套接字无法建立,则说明 ACK 尚未发送。在这种情况下,传输层不会重新传输它,而是第一次尝试通过不同的协议传输它。

    实际上,这种情况很少见。要使 ACK 的大小成为 UDP 的问题,它必须大于 INVITE 和最终响应——这些都已经通过 UDP 成功。通常情况下,INVITE 和最终响应包含一个 SDP 正文;在每个成功案例中,2xx 都包含一个主体。 ACK 变大的唯一情况是 INVITE 中没有 SDP 并且 ACK 添加到标头或正文中。

    如果您遇到这种情况 - 不支持 TCP 并且 ACK 对 UDP 来说太大,那么您可能无论如何都会走向失败。 [1]:https://www.rfc-editor.org/rfc/rfc3261#section-6

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-24
      • 2018-03-20
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多