Skip to main content

17. 事务 (Transactions)

SIP是一个事务性协议:组件之间的交互发生在一系列独立的消息交换中。具体来说,SIP事务由单个请求和对该请求的任何响应组成,包括零个或多个临时响应和一个或多个最终响应。

事务定义

INVITE事务的特殊性:

  • 在请求是INVITE的事务中(称为INVITE事务),事务还包括ACK,但仅当最终响应不是2xx响应时
  • 如果响应是2xx,ACK不被视为事务的一部分

分离的原因: 这种分离的根源在于向UAC传递所有对INVITE的200 (OK)响应的重要性。为了将它们全部传递给UAC:

  • UAS单独负责重传它们(参见第13.3.1.4节)
  • UAC单独负责用ACK确认它们(参见第13.2.2.4节)
  • 由于此ACK仅由UAC重传,它实际上被视为其自己的事务

事务的客户端和服务器端

事务有客户端和服务器端:

  • 客户端事务 (Client Transaction): 发送请求
  • 服务器事务 (Server Transaction): 发送响应

客户端和服务器事务是嵌入在任意数量元素中的逻辑功能。具体来说,它们存在于用户代理和有状态代理服务器中。

事务关系示例

+---------+        +---------+        +---------+        +---------+
| +-+|Request |+-+ +-+|Request |+-+ +-+|Request |+-+ |
| |C||------->||S| |C||------->||S| |C||------->||S| |
| |l|| ||e| |l|| ||e| |l|| ||e| |
| |i|| ||r| |i|| ||r| |i|| ||r| |
| |e|| ||v| |e|| ||v| |e|| ||v| |
| |n|| ||e| |n|| ||e| |n|| ||e| |
| |t|| ||r| |t|| ||r| |t|| ||r| |
| | || || | | || || | | || || | |
| |T|| ||T| |T|| ||T| |T|| ||T| |
| |r|| ||r| |r|| ||r| |r|| ||r| |
| |a|| ||a| |a|| ||a| |a|| ||a| |
| |n|| ||n| |n|| ||n| |n|| ||n| |
| |s||Response||s| |s||Response||s| |s||Response||s| |
| +-+|<-------|+-+ +-+|<-------|+-+ +-+|<-------|+-+ |
+---------+ +---------+ +---------+ +---------+
UAC Outbound Inbound UAS
Proxy Proxy

图4: 事务关系

无状态代理

无状态代理不包含客户端或服务器事务。 事务存在于一侧的UA或有状态代理与另一侧的UA或有状态代理之间。就SIP事务而言,无状态代理实际上是透明的。


客户端事务的目的

客户端事务的目的是:

  1. 从嵌入客户端的元素(称为"事务用户"或TU;它可以是UA或有状态代理)接收请求
  2. 可靠地将请求传递给服务器事务
  3. 接收响应并将它们传递给TU
  4. 过滤掉任何响应重传或不允许的响应(如对ACK的响应)
  5. 对于INVITE请求,负责为除2xx响应以外的任何最终响应生成ACK请求

服务器事务的目的

服务器事务的目的是:

  1. 从传输层接收请求并将它们传递给TU
  2. 过滤网络中的任何请求重传
  3. 从TU接受响应并将它们传递给传输层以在网络上传输
  4. 对于INVITE事务,吸收除2xx响应以外的任何最终响应的ACK请求

2xx响应和ACK的特殊处理

2xx响应及其ACK接受特殊处理:

  • 此响应仅由UAS重传,其ACK仅由UAC生成
  • 需要这种端到端处理,以便呼叫方知道接受呼叫的整套用户
  • 由于这种特殊处理,2xx响应的重传由UA核心处理,而不是事务层
  • 同样,2xx的ACK生成由UA核心处理
  • 路径上的每个代理仅转发每个对INVITE的2xx响应及其相应的ACK

17.1 客户端事务 (Client Transaction)

客户端事务通过维护状态机提供其功能。

TU接口

TU通过简单接口与客户端事务通信:

  1. 当TU希望发起新事务时,它创建客户端事务
  2. 将要发送的SIP请求传递给它
  3. 传递要发送到的IP地址、端口和传输
  4. 客户端事务开始执行其状态机
  5. 有效响应从客户端事务向上传递给TU

两种类型的客户端事务

根据TU传递的请求方法,有两种类型的客户端事务状态机:

1. INVITE客户端事务:

  • 处理INVITE请求的客户端事务

2. 非INVITE客户端事务:

  • 处理除INVITE和ACK以外的所有请求的客户端事务

重要: 没有ACK的客户端事务。如果TU希望发送ACK,它将其直接传递给传输层进行传输。

INVITE事务的独特性

INVITE事务与其他方法的事务不同,因为其持续时间更长:

  • 通常需要人工输入才能响应INVITE
  • 发送响应预期的长延迟要求三次握手
  • 另一方面,其他方法的请求预期快速完成
  • 由于非INVITE事务依赖于两次握手,TU应该立即响应非INVITE请求

17.1.1 INVITE客户端事务

17.1.1.1 INVITE事务概述

INVITE事务由三次握手组成:

  1. 客户端事务发送INVITE
  2. 服务器事务发送响应
  3. 客户端事务发送ACK

重传机制

对于不可靠传输(如UDP):

  • 客户端事务以从T1秒开始的间隔重传请求
  • 每次重传后间隔加倍
  • T1是往返时间(RTT)的估计,默认为500毫秒
  • 几乎所有事务计时器都随T1缩放
  • 更改T1会调整它们的值

对于可靠传输:

  • 请求不会通过可靠传输重传

收到1xx响应后:

  • 任何重传完全停止
  • 客户端等待进一步的响应
  • 服务器事务可以发送额外的1xx响应(服务器事务不可靠地传输这些响应)

最终响应:

  • 最终,服务器事务决定发送最终响应
  • 对于不可靠传输,该响应定期重传
  • 对于可靠传输,它发送一次
  • 对于在客户端事务收到的每个最终响应,客户端事务发送ACK,其目的是抑制响应的重传

17.1.1.2 正式描述(状态机)

INVITE客户端事务的状态机如图5所示。

初始状态:"Calling"

当TU用INVITE请求发起新客户端事务时,必须进入初始状态"Calling"。

进入Calling状态时:

  1. 客户端事务必须将请求传递给传输层进行传输
  2. 如果使用不可靠传输,客户端事务必须启动计时器A,值为T1
  3. 如果使用可靠传输,客户端事务不应该启动计时器A(计时器A控制请求重传)
  4. 对于任何传输,客户端事务必须启动计时器B,值为64*T1秒(计时器B控制事务超时)

计时器A触发(不可靠传输):

  • 客户端事务必须通过将请求传递给传输层来重传请求
  • 必须将计时器重置为2*T1的值
  • 当计时器A在2*T1秒后再次触发时,请求必须再次重传(假设客户端事务仍处于此状态)
  • 此过程必须继续,以便请求以每次传输后加倍的间隔重传
  • 这些重传应该仅在客户端事务处于"Calling"状态时完成

T1值:

  • 默认值为500毫秒
  • T1是客户端和服务器事务之间RTT的估计
  • 元素可以(虽然不推荐)在不允许一般互联网连接的封闭专用网络中使用更小的T1值
  • T1可以选择更大,如果预先知道(例如在高延迟接入链路上)RTT更大,则推荐这样做
  • 无论T1的值如何,必须使用本节中描述的重传的指数退避

计时器B触发:

  • 如果当计时器B触发时客户端事务仍处于"Calling"状态,客户端事务应该通知TU已发生超时
  • 客户端事务不得生成ACK
  • 64*T1的值等于在不可靠传输的情况下发送七个请求所需的时间量

状态转换

1. Calling → Proceeding(收到临时响应):

  • 如果客户端事务在"Calling"状态时收到临时响应,它转换到"Proceeding"状态
  • 在"Proceeding"状态,客户端事务不应该再重传请求
  • 此外,临时响应必须传递给TU
  • 任何进一步的临时响应必须在"Proceeding"状态时向上传递给TU

2. Calling/Proceeding → Completed(收到300-699响应):

  • 当处于"Calling"或"Proceeding"状态时,接收状态代码300-699的响应必须导致客户端事务转换到"Completed"
  • 客户端事务必须将收到的响应向上传递给TU
  • 客户端事务必须生成ACK请求,即使传输是可靠的
  • 然后将ACK传递给传输层进行传输
  • ACK必须发送到与原始请求发送到的相同地址、端口和传输
  • 客户端事务应该在进入"Completed"状态时启动计时器D,对于不可靠传输值至少为32秒,对于可靠传输值为零秒

计时器D的目的:

  • 计时器D反映当使用不可靠传输时服务器事务可以保持在"Completed"状态的时间量
  • 这等于INVITE服务器事务中的计时器H,其默认值为64*T1
  • 但是,客户端事务不知道服务器事务使用的T1值,因此使用32秒的绝对最小值,而不是基于T1的计时器D

在Completed状态接收响应重传:

  • 在"Completed"状态接收的最终响应的任何重传必须导致ACK重新传递给传输层进行重传
  • 但新收到的响应不得向上传递给TU

3. Calling/Proceeding → Terminated(收到2xx响应):

  • 当处于"Calling"或"Proceeding"状态时,接收2xx响应必须导致客户端事务进入"Terminated"状态
  • 响应必须向上传递给TU
  • 此响应的处理取决于TU是代理核心还是UAC核心
  • UAC核心将处理此响应的ACK生成
  • 代理核心将始终向上游转发200 (OK)
  • 代理和UAC之间200 (OK)的不同处理是它不在事务层处理的原因

4. Completed → Terminated(计时器D触发):

  • 如果当客户端事务处于"Completed"状态时计时器D触发,客户端事务必须移动到Terminated状态

销毁客户端事务: 客户端事务必须在进入"Terminated"状态的瞬间被销毁。这实际上是保证正确操作所必需的。原因是对INVITE的2xx响应得到不同处理;每一个都由代理转发,UAC中的ACK处理不同。因此,每个2xx需要传递给代理核心(以便可以转发)和UAC核心(以便可以确认)。不进行事务层处理。


INVITE客户端事务状态图

                           |INVITE from TU
Timer A fires |INVITE sent
Reset A, V Timer B fires
INVITE sent +-----------+ or Transport Err.
+---------| |---------------+inform TU
| | Calling | |
+-------->| |-------------->|
+-----------+ 2xx |
| | 2xx to TU |
| |1xx |
300-699 +---------------+ |1xx to TU |
ACK sent | | |
resp. to TU | 1xx V |
| 1xx to TU -----------+ |
| +---------| | |
| | |Proceeding |-------------->|
| +-------->| | 2xx |
| +-----------+ 2xx to TU |
| 300-699 | |
| ACK sent, | |
| resp. to TU| |
| | |
| 300-699 V |
| ACK sent +-----------+Transport Err. |
| +---------| |Inform TU |
| | | Completed |-------------->|
| +-------->| | |
| +-----------+ |
| ^ | |
| | | Timer D fires |
+--------------+ | - |
| |
V |
+-----------+ |
| | |
| Terminated|<--------------+
| |
+-----------+

图5: INVITE客户端事务

17.1.1.3 ACK请求的构造

本节指定在客户端事务内发送的ACK请求的构造。为2xx生成ACK的UAC核心必须遵循第13节中描述的规则。

ACK请求必须包含的头字段值:

  • Call-ID, From, Request-URI: 等于客户端事务传递给传输的请求中这些头字段的值(称为"原始请求")
  • To: ACK中的To头字段必须等于被确认的响应中的To头字段,因此通常会通过添加标签参数而与原始请求中的To头字段不同
  • Via: ACK必须包含单个Via头字段,这必须等于原始请求的顶部Via头字段
  • CSeq: ACK中的CSeq头字段必须包含与原始请求中相同的序列号值,但方法参数必须等于"ACK"

Route头字段: 如果被确认响应的INVITE请求有Route头字段,这些头字段必须出现在ACK中。这是为了确保ACK可以通过任何下游无状态代理正确路由。

消息体: 虽然任何请求都可能包含消息体,但ACK中的消息体是特殊的,因为如果不理解消息体,请求不能被拒绝。因此,不推荐在非2xx的ACK中放置消息体,但如果这样做,消息体类型仅限于INVITE中出现的任何类型,假设对INVITE的响应不是415。如果是415,ACK中的消息体可以是415中Accept头字段中列出的任何类型。

ACK示例:

原始INVITE:

INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 INVITE

对非2xx最终响应的ACK:

ACK sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>;tag=99sa0xk
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 ACK

17.1.2 非INVITE客户端事务

17.1.2.1 非INVITE事务概述

非INVITE事务不使用ACK。它们使用简单的请求-响应模型。这种差异的原因是INVITE请求建立会话,可能需要很长时间才能完成。对于非INVITE请求,预期会快速完成。

17.1.2.2 正式描述(状态机)

非INVITE客户端事务的状态机比INVITE事务简单。

初始状态:"Trying"

当TU发起新客户端事务时,必须进入初始状态"Trying"。

进入Trying状态时:

  1. 客户端事务必须将请求传递给传输层进行传输
  2. 如果使用不可靠传输,客户端事务必须启动计时器E,初始值为T1
  3. 如果使用可靠传输,客户端事务不应该启动计时器E
  4. 对于任何传输,客户端事务必须启动计时器F,值为64*T1秒

计时器E触发(不可靠传输):

  • 请求必须重传
  • 计时器E必须重置为2*T1
  • 每次后续触发时,计时器值加倍(4T1, 8T1, ...)
  • 计时器E的最大值为T2(默认4秒)
  • 一旦达到T2,以T2间隔继续重传

计时器F触发:

  • 如果客户端事务仍处于"Trying"状态,客户端事务应该通知TU已发生超时
  • 客户端事务必须转换到Terminated状态

状态转换

1. Trying → Proceeding(收到临时响应):

  • 如果客户端事务在"Trying"状态时收到临时响应(100-199),它转换到"Proceeding"状态
  • 临时响应必须传递给TU
  • 任何进一步的临时响应必须传递给TU
  • 在"Proceeding"状态,如果使用不可靠传输,仍然必须继续重传(由计时器E控制)

2. Trying/Proceeding → Completed(收到最终响应):

  • 当收到最终响应(200-699)时,客户端事务转换到"Completed"状态
  • 响应必须传递给TU
  • 客户端事务必须启动计时器K,值为T4(对于不可靠传输为5秒,对于可靠传输为0秒)
  • 计时器K的目的是吸收最终响应的任何重传

3. Completed → Terminated(计时器K触发):

  • 当计时器K触发时,客户端事务转换到Terminated状态
  • 客户端事务必须被销毁

非INVITE客户端事务状态图

                           |Request from TU
|send request
Timer E V
send request +-----------+
+--------| |-------------------+
| | Trying | Timer F |
+------->| | or Transport Err.|
+-----------+ inform TU |
| | |
| |Timer E |
| |send req |
200-699 | | |
resp. to TU | |1xx |
+-------------------+ |resp. to TU |
| | |
| Timer E V |
| send req +-----------+ |
| +-----------+ | |
| | |Proceeding |------------------>|
| +---------->| |Timer F |
| +-----------+or Transport Err. |
| | ^ inform TU |
| | | |
| | +--------+ |
| 200-699 | |1xx |
| resp. to TU | |resp. to TU |
| V | |
| +-----------+ | |
| | | | |
| | Completed | | |
| | | | |
| +-----------+ | |
| | | |
| |Timer K | |
| |- | |
| | | |
| V | |
| +-----------+ | |
| | | | |
+------------>| Terminated|<--------+------------+
| |
+-----------+

图6: 非INVITE客户端事务

17.1.3 将响应匹配到客户端事务

当传输层收到响应时,它必须检查响应的顶部Via头字段值。如果此Via头字段值指示发送消息的主机(等于此主机的主机、域或IP地址),响应的下一步将是事务层。

事务匹配规则: 响应匹配客户端事务的条件:

  1. 响应的CSeq方法必须与发送请求中的方法匹配
  2. 响应的顶部Via头字段的分支参数必须等于请求的顶部Via头字段的分支参数
  3. 响应的顶部Via头字段的sent-by值必须等于请求的顶部Via头字段的sent-by值(作为后备)

ACK的特殊情况:

  • CANCEL形成自己的事务
  • 但对它的响应将匹配原始INVITE的客户端事务
  • 这不会产生问题,因为CANCEL事务的TU(无论是代理还是UAC)在收到对CANCEL的1xx/2xx时会忽略它们

17.1.4 处理传输错误

当客户端事务向传输层发送请求时,如果传输层指示失败,客户端事务必须:

  1. 通知TU传输失败已发生
  2. 如果客户端事务不在"Completed"状态,转换到"Terminated"状态
  3. 客户端事务必须被销毁

17.2 服务器事务 (Server Transaction)

服务器事务的状态机比客户端事务简单。

TU接口

服务器事务通过简单接口与TU通信:

  1. 当请求从传输层到达时,服务器事务被创建
  2. 请求传递给TU
  3. TU将响应传递给服务器事务
  4. 服务器事务负责可靠地传递响应

17.2.1 INVITE服务器事务

INVITE服务器事务的目的是:

  1. 可靠地接收INVITE请求
  2. 传递给TU
  3. 可靠地发送响应
  4. 吸收ACK

状态机

初始状态:"Proceeding"

当从传输层收到INVITE请求时,服务器事务创建并进入"Proceeding"状态。

进入Proceeding状态时:

  1. 服务器事务必须将请求传递给TU
  2. TU处理请求并生成响应
  3. 如果使用不可靠传输,服务器事务必须启动计时器G(初始值T1)
  4. 如果使用可靠传输,不启动计时器G

在Proceeding状态:

  • 如果收到请求的重传,服务器事务必须将最后发送的响应传递给传输层进行重传
  • 服务器事务必须通过计时器G重传临时响应(如果使用不可靠传输)

状态转换

1. Proceeding → Completed(发送300-699响应):

  • 当TU传递300-699响应时,服务器事务转换到"Completed"状态
  • 响应必须传递给传输层进行传输
  • 如果使用不可靠传输,服务器事务必须启动计时器H,值为64*T1
  • 计时器G必须停止

在Completed状态:

  • 服务器事务等待INVITE的ACK
  • 如果收到请求重传,服务器事务必须重传最终响应
  • 如果收到ACK,服务器事务吸收它(不传递给TU)
  • 如果使用不可靠传输,服务器事务必须启动计时器I,值为T4(5秒)
  • 如果使用可靠传输,计时器I值为0秒

2. Completed → Confirmed(收到ACK):

  • 收到ACK时,服务器事务转换到"Confirmed"状态
  • 启动计时器I

3. Completed/Confirmed → Terminated:

  • 如果计时器H触发(未收到ACK),服务器事务转换到Terminated状态
  • 如果计时器I触发,服务器事务转换到Terminated状态
  • 服务器事务必须被销毁

4. Proceeding → Terminated(发送2xx响应):

  • 当TU传递2xx响应时,服务器事务必须将其传递给传输层进行传输
  • 然后转换到"Terminated"状态
  • 2xx响应的重传由TU处理,不是服务器事务

INVITE服务器事务状态图

                           |INVITE
|pass INV to TU
INVITE V send 100 if TU won't in 200ms
send response+-----------+
+--------| |--------+101-199 from TU
| | Proceeding| |send response
+------->| |<-------+
+-----------+
| |
| |Timer G fires
| |send response
300-699 from TU | |
send response | |
| V
| +-----------+
| | |
+->| Completed |<----------+
| | |
+--| |---+Timer H fires
| +-----------+ |or Transport Err.
ACK | | |Inform TU
- | |Timer G fires|
| |send response|
V | |
+-----------+ |
| | |
| Confirmed | |
| | |
+-----------+ |
| |
|Timer I fires |
|- |
| |
V |
+-----------+ |
| | |
| Terminated|<-----------+
| |
+-----------+

图7: INVITE服务器事务

17.2.2 非INVITE服务器事务

非INVITE服务器事务比INVITE服务器事务简单得多。

状态机

初始状态:"Trying"

当从传输层收到非INVITE请求时,服务器事务创建并进入"Trying"状态。

进入Trying状态时:

  1. 服务器事务必须将请求传递给TU
  2. 一旦TU传递响应,服务器事务必须转换到"Completed"状态

在Trying状态:

  • 如果收到请求的重传,服务器事务必须将最后发送的响应(如果有)传递给传输层进行重传

状态转换

1. Trying → Proceeding(TU发送临时响应):

  • 当TU传递临时响应时,服务器事务转换到"Proceeding"状态
  • 响应必须传递给传输层进行传输

2. Trying/Proceeding → Completed(TU发送最终响应):

  • 当TU传递最终响应时,服务器事务转换到"Completed"状态
  • 响应必须传递给传输层进行传输
  • 服务器事务必须启动计时器J,值为64*T1(对于不可靠传输)或0秒(对于可靠传输)

在Completed状态:

  • 服务器事务必须将最终响应传递给传输层以重传,如果收到请求的任何重传
  • 服务器事务不能从TU接收任何其他响应

3. Completed → Terminated(计时器J触发):

  • 当计时器J触发时,服务器事务转换到Terminated状态
  • 服务器事务必须被销毁

非INVITE服务器事务状态图

                           |Request received
|pass to TU
V
+-----------+
| |
| Trying |----------+200-699 from TU
| | |send response
+-----------+ |
| |
|1xx from TU |
|send response |
V |
+-----------+ |
| | |
| Proceeding|----------+200-699 from TU
| | |send response
+-----------+ |
|
|
V
+-----------+
| |
| Completed |
| |
+-----------+
|
|Timer J fires
|-
|
V
+-----------+
| |
| Terminated|
| |
+-----------+

图8: 非INVITE服务器事务

17.2.3 将请求匹配到服务器事务

当传输层收到请求时,它必须检查该请求是否匹配现有服务器事务。

事务匹配规则: 请求匹配服务器事务的条件:

  1. 请求的Request-URI、To标签、From标签、Call-ID、CSeq号和顶部Via分支参数必须匹配事务请求中相应的值
  2. 请求方法必须匹配事务的方法(CANCEL和ACK除外)

ACK匹配:

  • 对非2xx最终响应的ACK匹配生成该响应的INVITE事务
  • ACK的Request-URI、To标签、From标签、Call-ID、CSeq号(不是方法)和顶部Via分支参数必须匹配INVITE事务

CANCEL匹配:

  • CANCEL不匹配任何事务
  • CANCEL创建自己的服务器事务
  • TU使用CANCEL的Request-URI、To标签、From标签、Call-ID、CSeq号和顶部Via分支参数来查找要取消的INVITE事务

17.2.4 处理传输错误

如果传输层通知服务器事务传输错误,服务器事务必须:

  1. 通知TU传输失败
  2. 转换到"Terminated"状态
  3. 服务器事务必须被销毁

📊 事务计时器总结

计时器用途默认值适用
Timer AINVITE请求重传初始T1, 每次加倍INVITE客户端事务(不可靠传输)
Timer BINVITE事务超时64*T1INVITE客户端事务
Timer D等待响应重传≥32秒(不可靠),0秒(可靠)INVITE客户端事务Completed状态
Timer E非INVITE请求重传初始T1, 加倍至T2非INVITE客户端事务(不可靠传输)
Timer F非INVITE事务超时64*T1非INVITE客户端事务
Timer K等待响应重传T4(不可靠),0秒(可靠)非INVITE客户端事务Completed状态
Timer GINVITE响应重传初始T1, 每次加倍INVITE服务器事务(不可靠传输)
Timer HACK接收等待64*T1INVITE服务器事务Completed状态
Timer IACK重传吸收T4(不可靠),0秒(可靠)INVITE服务器事务Confirmed状态
Timer J请求重传吸收64*T1(不可靠),0秒(可靠)非INVITE服务器事务Completed状态

基本计时器值:

  • T1: 500ms(RTT估计,可调整)
  • T2: 4秒(最大重传间隔)
  • T4: 5秒(网络保持时间)

关键要点

  1. INVITE事务使用三次握手:请求、响应、ACK
  2. 非INVITE事务使用两次握手:请求、响应
  3. 2xx响应及其ACK的特殊处理:不由事务层处理,而是由UA核心处理
  4. 可靠传输vs不可靠传输:计时器行为不同
  5. 事务匹配:基于分支参数、CSeq、Call-ID等
  6. 状态机驱动:所有事务行为由状态机定义
  7. 指数退避:重传间隔指数增长,最大到T2

本章小结:

第17章详细描述了SIP事务层的完整规范,包括客户端事务和服务器事务的状态机、计时器机制、请求/响应匹配规则。事务层是SIP协议栈的核心,负责提供可靠的消息传递。INVITE事务和非INVITE事务有显著差异,前者使用三次握手并有更复杂的状态机,后者使用两次握手。理解事务层对于实现健壮的SIP应用至关重要。