可靠的 UDP 协议

可靠 UDP 协议

译自 https://tools.ietf.org/html/draft-ietf-sigtran-reliable-udp-00

摘要

此 Internet 草案讨论了可靠UDP(RUDP)。RUDP 基于 RFC 1151 和 908。RUDP 在 UDP/IP 协议层之上,为虚拟连接提供可靠的有序传送(最多可重传次数)。

RUDP 具有非常灵活的设计,适用于各种传输用途。其中一个用途是传输电信信号协议。

目录

  • 可靠 UDP 协议
    • 摘要
    • 目录
    • 1. 简介
      • 1.1. 背景
      • 1.2. 数据结构格式
        • 1. RUDP 头部
        • 2. SYN 段
        • 3. ACK 段
        • 4. EACK 段
        • 5. RST 段
        • 6. NUL 段
        • 3. TCS 段
    • 2. 详细设计
      • 2.1. 重传定时器
      • 2.2. 重传计数器
      • 2.3. 独立 ACK 分片
      • 2.4. ACK 信息捎带
      • 2.5. 累积 ACK 计数器
      • 2.6. 无序 ACK 计数器
      • 2.7. 累积 ACK 分片定时器
      • 2.8. NULL 段定时器
      • 2.9. 自动重置
      • 2.10. 接收端接收队列大小
      • 2.11. 拥塞控制和慢启动
      • 2.12. UDP 端口号
      • 2.13. 支持冗余连接
      • 2.14. 连接断开的处理
      • 2.15. 重传算法
      • 2.16. 上层协议通信信号
      • 2.17. 校验和算法
      • 2.18. FEC 前向纠错
      • 2.19. 安全性
    • 3. 参数协商

1. 简介

1.1. 背景

可靠的传输协议用于传输 IP 网络电信信令。这种传输必须能够为通过 IP 传输的各种应用程序(例如信号协议)提供一个架构。

该协议应符合以下标准:

  • 传输需要可靠,直到最大重传次数(即避免旧的消息)。
  • 传输需要有序。
  • 传输应该是基于消息的。
  • 传输应提供流量控制机制。
  • 传输应具有低开销,高性能。
  • 每个虚拟连接应该是可配置的(例如定时器)。
  • 传输应提供 keep-alive 机制。
  • 传输应提供错误检测机制。
  • 传输应提供安全机制。

RUDP 的设计目的是允许每个连接单独可配,以便可以在同一平台上同时实现具有不同传输要求的多种协议。

1.2. 数据结构格式

1. RUDP 头部

 0 1 2 3 4 5 6 7 8             15
+-+-+-+-+-+-+-+-+---------------+
|S|A|E|R|N|C|T| |    Header     |
|Y|C|A|S|U|H|C|0|    Length     |
|N|K|K|T|L|K|S| |               |
+-+-+-+-+-+-+-+-+---------------+
|  Sequence #   +   Ack Number  |
+---------------+---------------+
|            Checksum           |
+---------------+---------------+
  • Control bits
    • SYN 表示一个同步段
    • ACK 表示确认号
    • EACK 表示一个扩展的确认段
    • RST 表示该数据包是一个重置段
    • NUL 表示该数据包是空段
    • TCS 表示报文是一个传输连接状态段

SYN、EACK、RST 和 TCS 是互斥的。当 NUL 被设置时,ACK 位始终置 1。CHK 表示校验和字段是仅包含头部或包含头部和数据的校验和。如果 CHK 位为零,校验和字段只包含头的校验和。如果 CHK 位是1,校验和字段包含头和数据的校验和。

  • Header length:表示用户数据在数据包中的开始位置。
  • Sequence number:每个数据包都包含一个序列号。首次打开连接时,每个对端随机选择一个初始序列号。发送数据,NULL 或者 reset 段前,序号自增。
  • Acknowledgment Number:已接收到的最后有序分组。
  • Checksum:计算报头校验和,确保完整性。如果 CHK 位置1,则计算报头和数据的校验和。RUDP 中使用的校验和算法与 UDP 和 TCP 头中使用的算法相同,算法为每16位数据位的二进制反码相加然后再进行取反。

2. SYN 段

0             7 8              15
+-+-+-+-+-+-+-+-+---------------+
| |A| | | | | | |               |
|1|C|0|0|0|0|0|0|       28      |
| |K| | | | | | |               |
+-+-+-+-+-+-+-+-+---------------+
|  Sequence #   +   Ack Number  |
+---------------+---------------+
| Vers  | Spare | Max # of Out  |
|       |       | standing Segs |
+---------------+---------------+
| Option Flags  |     Spare     |
+---------------+---------------+
|      Maximum Segment Size     |
+---------------+---------------+
| Retransmission Timeout Value  |
+---------------+---------------+
| Cumulative Ack Timeout Value  |
+---------------+---------------+
|   Null Segment Timeout Value  |
+---------------+---------------+
| Transfer State Timeout Value  |
+---------------+---------------+
|  Max Retrans  | Max Cum Ack   |
+---------------+---------------+
| Max Out of Seq| Max Auto Reset|
+---------------+---------------+
|    Connection Identifier      |
+                               +
|      (32 bits in length)      |
+---------------+---------------+
|           Checksum            |
+---------------+---------------+

SYN 段用于在两个主机之间建立连接并同步序列号。

  • Sequence Number:连接序列号。
  • Acknowledgment Number:仅当设置了 ACK 标志时该字段才有效。这个
    字段包含收到的 SYN 段的序列号。
  • Version:RUDP 版本,初始值为 1.
  • Maximum Number of Outstanding Segments:未收到 ACK 时能发送的最大分片。 被接收端用作流控手段。连接建立时确定,在通信过程中不会改变。发送数据时,每端必须使用对端提供的值。
  • Options Flag Field
Bit Bit Name Description
0 not used 未使用,置为1
1 CHK 整个 RUDP 数据包的校验和,可协商
2 REUSE reset 时设置此位。接收端忽略该字段,发送方将 SYN 的以下字段清零:Maximum Segment Size,Retransmission Timeout Value,Cumulative Ack Timeout Value, Max Retransmissions, Max Cumulative Ack, Max Out of Sequence,Max Auto Reset
3-7 Spare 备用

- Maximum Segment Size:发送 SYN 段的对端可以接收的最大字节数。
- Retransmission Timeout Value:重传未确认数据包的超时时间,单位毫秒。有效范围是 100 到 65536。
- Cumulative Ack Timeout Value:累积确认超时时间
- Null Segment Timeout Value:连接空闲时,发送 NUL 的时间间隔。目的在于心跳机制,单位毫秒。
- Transfer State Timeout Value:在自动重置发生之前为连接保存状态信息的时间。
- Max Retrans:认为连接被断开之前尝试连续重传的最大次数。
- Max Cum Ack:最大累积 ACK 数量,到达此值发送确认。
- Max Out of Seq:最大允许乱序包的数量。
- Max Auto Reset:在连接被重置前,可执行连续自动复位的最大次数。
- Connection Identifier:建立一个新的连接时,双方会传输一个唯一的连接 ID 给对方。

3. ACK 段

0 1 2 3 4 5 6 7 8              15
+-+-+-+-+-+-+-+-+---------------+
|0|1|0|0|0|0|0|0|       6       |
+-+-+-+-+-+-+-+-+---------------+
| Sequence #    |   Ack Number  |
+---------------+---------------+
|           Checksum            |
+---------------+---------------+

ACK 用于确认有序分片。包含下一个发送序列号和确认序列号。 ACK 段可单独发送,但应尽可能地与数据组合。 Data 和 Null 段必须始终包含 ACK 位和 Acknowledgment Number 字段。 独立 ACK 段的大小是 6 Bytes。

4. EACK 段

0 1 2 3 4 5 6 7 8              15
+-+-+-+-+-+-+-+-+---------------+
|0|1|1|0|0|0|0|0|     N + 6     |
+-+-+-+-+-+-+-+-+---------------+
| Sequence #    |   Ack Number  |
+---------------+---------------+
|1st out of seq |2nd out of seq |
|  ack number   |   ack number  |
+---------------+---------------+
|  . . .        |Nth out of seq |
|               |   ack number  |
+---------------+---------------+
|            Checksum           |
+---------------+---------------+

EACK 段用于确认收到的乱序包。
它包含不乱序的一个或多个包的序列号。 EACK 始终与段中的 ACK 组合,给出收到最后一个有序包的序列号。 EACK 段头部长度可变, 其最小值为7,其最大值取决于最大接收队列长度。

5. RST 段

0 1 2 3 4 5 6 7 8              15
+-+-+-+-+-+-+-+-+---------------+
| |A| | | | | | |               |
|0|C|0|1|0|0|0|0|        6      |
| |K| | | | | | |               |
+-+-+-+-+-+-+-+-+---------------+
| Sequence #    |   Ack Number  |
+---------------+---------------+
|         Header Checksum       |
+---------------+---------------+

RST 段用于关闭或重置连接。 收到 RST 段后,发送方必须停止发送新数据包,但会发送已从 API 接收的数据包。 RST 作为单独的段发送,不包含任何数据。

6. NUL 段

0 1 2 3 4 5 6 7 8              15
+-+-+-+-+-+-+-+-+---------------+
|0|1|0|0|1|0|0|0|       6       |
+-+-+-+-+-+-+-+-+---------------+
| Sequence #    |  Ack Number   |
+---------------+---------------+
|            Checksum           |
+---------------+---------------+

NUL 段用于确定连接的另一侧是否仍处于活动状态。 因此,NUL 承担 keep-avive 功能。
收到一个 NUL 段时,如果连接连接且序号有序,RUDP 立刻回复 ACK。NUL 段从不携带数据。

3. TCS 段

0 1 2 3 4 5 6 7 8              15
+-+-+-+-+-+-+-+-+---------------+
| |A| | | | | | |               |
|0|C|0|0|0|0|1|0|       12      |
| |K| | | | | | |               |
+-+-+-+-+-+-+-+-+---------------+
| Sequence #    |   Ack Number  |
+---------------+---------------+
| Seq Adj Factor|      Spare    |
+---------------+---------------+
|      Connection Identifier    |
+                               +
|       (32 bits in length)     |
+---------------+---------------+
|            Checksum           |
+---------------+---------------+
  • Sequence Number:包含连接的初始序号。
  • Acknowledgment Number:接收端收到的最后一个有序包的序号。
  • Seq Adj Factor:用于调整上一连接和当前连接转移状态的序号。
  • Connection Identifier:每打开一个新连接时,每个端都会发送一个RUDP中唯一的ID,每一端会保存收到的连接ID。

2. 详细设计

2.1. 重传定时器

发送端有重传定时器,超时时间可配。每次发送 data,null 或 reset 段并且当前没有一个片段被计时,都会初始化此计时器。

如果在定时器到期时未收到对此数据段的确认,则重发已发送但未确认的所有分片。如果仍有一个或多个已发送但未确认的数据包,则在收到定时段时重启重传定时器。 重传定时器的推荐值为600毫秒。

2.2. 重传计数器

发送端维护一个重发次数的计数器,计数器最大值可配,建议为 2。如果计数器超过其最大值,则认为连接已断开。

2.3. 独立 ACK 分片

独立 ACK 段是仅包含确认信息的段。 其 sequence number 字段包含要发送的下一个 data,null 或 reset 段的序列号。

2.4. ACK 信息捎带

当接收端向发送端发送 data,null 或 reset 段时,接收端需要在报头的 ACK 中填上最后的一次从发送端收到的 data,null 或 reset 段的序列号。

2.5. 累积 ACK 计数器

接收端维持接收到的未确认分片的计数器,计数器的最大值可配。 如果超过计数器的最大值,则接收端发送独立 ACK 或 EACK(如果存在无序分片)。 累积 ACK 计数器的建议值为3。

2.6. 无序 ACK 计数器

接收端维护一个已经无序到达的分片的计数器。当计数器超过配置的最大值时,发送一个包含已经接收的所有当前无序段的序列号的 EACK 段到发送端,然后计数器重置为零。无序 ACK 计数器的建议值为3。

当发送端接收到 EACK 时,会将丢失的数据段重新发送给接收端。

2.7. 累积 ACK 分片定时器

当接收端有未确认的分片或无序队列中有分片时,它会分别在发送独立确认或扩展确认之前等待最长时间。 当此定时器到期时,如果在无序队列中存在分片,则发送扩展确认。 否则,如果当前有未确认分片,则发送独立确认。 累积 ACK 定时器的建议值为 300 毫秒。

每当在数据,空或重置段中发送确认时,重新启动累积 ACK 定时器,前提是当前没有分片在无序列队列中。 如果序列外队列中存在分片,则不会重新启动定时器,以便在再次到期时再发送另一个扩展确认。

2.8. NULL 段定时器

Client 维护一个定时器,连接打开时启动,每次发送数据段时重置。如果 Client 的 NULL 段定时器到期,则 Client 将 NULL 段发送到 Server。

如果 Server 的序列号有效,则由 Server 确认空段。 Server 维护一个空段定时器,其超时值是 Client 超时值的两倍。

只要从 Client 收到数据或空段,Server 的计时器就会重置。 如果 Server 的空段定时器到期,则认为连接已断开。空段定时器的值是 2 秒。

2.9. 自动重置

连接的任何一方都可以自动重置。自动重置的原因可能是
- 重传计数超过其最大值
- 服务器的 NULL 段计时器到期
- 传输状态计时器到期

自动重置将使两端重置其当前状态,包括刷新重传和无序队列,然后重置其初始序列号并重新协商连接。每端将通知其上层协议(ULP)自动重置。

有一个连续的重置计数器,用于设置在没有连接打开的情况下可以发生的最大自动重置次数。 如果此计数器超过其最大值,则重置连接。连续重置计数器的建议值为 3。

2.10. 接收端接收队列大小

接收端接收队列的大小是可配置参数。建议值为 32 个数据包。

接收队列大小充当流控制机制。

2.11. 拥塞控制和慢启动

RUDP 未提供。

2.12. UDP 端口号

RUDP 对使用哪个 UDP 端口号没有任何限制。
有效端口号是 RFC 1700 中未定义的端口。

2.13. 支持冗余连接

如果 RUDP 连接失败,将发信号通知上层协议,并启动传输状态计时器。 ULP 可以通过 API 调用启动将此状态传输到另一个 RUDP 连接
RUDP 会将状态信息传输到新连接,以确保数据包不会重复或丢失。

如果 ULP 在传输状态计时器到期之前没有将状态转移到另一个连接,则连接状态将丢失,并且连接队列的缓冲区被释放。 传输状态定时器的超时值是可配置的。

传输状态计时器的建议值为 1 秒。

2.14. 连接断开的处理

以下情况发生时,则认为 RUDP 连接断开:

  • 重传定时器到期且重传计数已超过其最大值。
  • NULL 段定时器过期。

如果出现上述两种情况中的任何一种并且传输状态超时不为零,则通过 API 的连接失败信号通知 ULP 连接失败,并且将启动传输状态定时器。 如果传输状态计时器到期,则执行自动复位,并通过 API 的连接自动复位信号通知 ULP。

如果传输状态超时值为零,则当上述两种情况中的任何一种发生时,将立即执行自动复位。 ULP 将通过 API 的连接自动重置信号通知连接失败。

2.15. 重传算法

接收到 EACK 段或重传定时器超时而发生重传。

收到 EACK 段时,消息中指定的段将从未确认的已发送队列中删除。 要重传的段是通过检查 EACK 段中的 ack 号和最后一个 seq 号来确定的。 重新发送未确认的发送队列不包括这两个序列号之间的所有报文段。

当发生重传超时时,重传未确认的已发送队列上的所有消息。

2.16. 上层协议通信信号

以下信号将通过 API 传输给上层协议,通知异步事件:

  • Connection open:连接状态变为 Open 时发送信号。
  • Connection refused:连接状态从 Close Wait 以外状态转为 Closed 时发送信号。
  • Connection closed:连接状态从 Close Wait 转为 Closed 时发送信号。
  • Connection failure:连接状态断开时发送信号。
  • Connection auto reset:连接自动复位时发送信号。向上层协议通知数据可能丢失且 RUDP 正试图将连接返回到打开状态。

2.17. 校验和算法

RUDP 中使用的校验和算法与 UDP 和 TCP 头中使用的算法相同,它是被检验数据的每16位求和的补码。CHK 置1时,对整个报文计算校验和。否则,只对头部计算校验和。

2.18. FEC 前向纠错

RUDP没有定义前向纠错(FEC)的处理。它会丢弃收到的重复包。

2.19. 安全性

RUDP 将兼容 IPsec 标准。

3. 参数协商

  • 当客户端发起连接时,发送一个 SYN 段,包含上层通过 API 定义的协商参数。
  • 服务器可以通过带有 ACK 响应的 SYN 接受这些参数,或者在其 SYN 中使用 ACK 响应提出不同的参数。
  • 然后,客户端可以选择接受服务器发送的参数并发送 ACK 来建立连接,或者发送 RST 来拒绝连接。
  • 在自动重置期间无法重新协商。

你可能感兴趣的:(Protocol)