3. SCTP数据包格式 (SCTP Packet Format)
SCTP数据包由公共头部和块 (chunks) 组成. 块包含控制信息或用户数据.
SCTP数据包格式如下所示:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Common Header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk #1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk #n |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
多个块可以打包到一个SCTP数据包中,直到MTU大小,但INIT、INIT ACK和SHUTDOWN COMPLETE块除外. 这些块禁止 (MUST NOT) 与数据包中的任何其他块打包在一起. 有关块打包的更多详细信息,请参见第6.10节.
如果用户数据消息不适合一个SCTP数据包,则可以使用第6.9节中定义的过程将其分片为多个块.
SCTP数据包中的所有整数字段必须 (MUST) 以网络字节序传输,除非另有说明.
3.1. SCTP公共头部字段描述 (SCTP Common Header Field Descriptions)
SCTP公共头部格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port Number | Destination Port Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Verification Tag |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
源端口号 (Source Port Number): 16位(无符号整数)
这是SCTP发送方的端口号. 接收方可以将其与源IP地址、SCTP目标端口以及可能的目标IP地址结合使用,以识别此数据包所属的关联. 端口号0禁止 (MUST NOT) 使用.
目标端口号 (Destination Port Number): 16位(无符号整数)
这是此数据包要发送到的SCTP端口号. 接收主机将使用此端口号将SCTP数据包解复用到正确的接收端点/应用程序. 端口号0禁止 (MUST NOT) 使用.
验证标签 (Verification Tag): 32位(无符号整数)
此数据包的接收方使用验证标签来验证此SCTP数据包的发送方. 在传输时,此验证标签的值必须 (MUST) 设置为在关联初始化期间从对等端点接收的发起标签 (Initiate Tag) 的值,但以下情况除外:
-
包含INIT块的数据包必须 (MUST) 具有零验证标签.
-
包含设置了T位的SHUTDOWN COMPLETE块的数据包必须 (MUST) 从带有SHUTDOWN ACK块的数据包中复制验证标签.
-
包含ABORT块的数据包可以 (may) 从导致发送ABORT的数据包中复制验证标签. 有关详细信息,请参见第8.4节和第8.5节.
INIT块必须 (MUST) 是携带它的SCTP数据包中的唯一块.
校验和 (Checksum): 32位(无符号整数)
此字段包含此SCTP数据包的校验和. 其计算在第6.8节中讨论. SCTP使用附录B中描述的CRC32c算法来计算校验和.
3.2. 块字段描述 (Chunk Field Descriptions)
下图说明了要在SCTP数据包中传输的块的字段格式. 每个块都使用块类型 (Chunk Type) 字段、块特定标志 (Flag) 字段、块长度 (Chunk Length) 字段和值 (Value) 字段进行格式化.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Type | Chunk Flags | Chunk Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\ \
/ Chunk Value /
\ \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
块类型 (Chunk Type): 8位(无符号整数)
此字段标识块值 (Chunk Value) 字段中包含的信息类型. 它的取值范围为0到254. 值255保留供将来用作扩展字段.
块类型的值定义如下:
ID值 块类型
----- ----------
0 - 有效载荷数据 (Payload Data, DATA)
1 - 初始化 (Initiation, INIT)
2 - 初始化确认 (Initiation Acknowledgement, INIT ACK)
3 - 选择性确认 (Selective Acknowledgement, SACK)
4 - 心跳请求 (Heartbeat Request, HEARTBEAT)
5 - 心跳确认 (Heartbeat Acknowledgement, HEARTBEAT ACK)
6 - 中止 (Abort, ABORT)
7 - 关闭 (Shutdown, SHUTDOWN)
8 - 关闭确认 (Shutdown Acknowledgement, SHUTDOWN ACK)
9 - 操作错误 (Operation Error, ERROR)
10 - 状态Cookie (State Cookie, COOKIE ECHO)
11 - Cookie确认 (Cookie Acknowledgement, COOKIE ACK)
12 - 为显式拥塞通知回显保留 (Reserved for ECNE)
13 - 为拥塞窗口减少保留 (Reserved for CWR)
14 - 关闭完成 (Shutdown Complete, SHUTDOWN COMPLETE)
15到62 - 可用
63 - 为IETF定义的块扩展保留
64到126 - 可用
127 - 为IETF定义的块扩展保留
128到190 - 可用
191 - 为IETF定义的块扩展保留
192到254 - 可用
255 - 为IETF定义的块扩展保留
块类型的编码方式是,最高阶的2位指定如果处理端点不识别块类型时必须采取的操作.
00 - 停止处理此SCTP数据包并丢弃它,不处理其中的任何进一步块.
01 - 停止处理此SCTP数据包并丢弃它,不处理其中的任何进一步块,
并在"未识别的块类型"中报告未识别的块.
10 - 跳过此块并继续处理.
11 - 跳过此块并继续处理,但使用"未识别的块类型"错误原因在ERROR块中报告.
注意: ECNE和CWR块类型保留供将来使用显式拥塞通知 (ECN); 请参见附录A.
块标志 (Chunk Flags): 8位
这些位的使用取决于块类型 (Chunk Type) 字段给出的块类型. 除非另有规定,否则在传输时它们设置为0,在接收时被忽略.
块长度 (Chunk Length): 16位(无符号整数)
此值表示块的大小(以字节为单位),包括块类型、块标志、块长度和块值字段. 因此,如果块值字段的长度为零,则长度字段将设置为4. 块长度字段不计算任何块填充.
块(包括类型、长度和值字段)由发送方用全零字节填充,以使其长度为4字节的倍数. 此填充总共不得 (MUST NOT) 超过3个字节. 块长度值不包括块的终止填充. 但是,它确实包括除块中最后一个参数之外的任何可变长度参数的填充. 接收方必须 (MUST) 忽略填充.
注意: 健壮的实现应该接受块,无论最终填充是否已包含在块长度中.
块值 (Chunk Value): 可变长度
块值字段包含要在块中传输的实际信息. 此字段的使用和格式取决于块类型.
块的总长度(包括类型、长度和值字段)必须 (MUST) 是4字节的倍数. 如果块的长度不是4字节的倍数,则发送方必须 (MUST) 用全零字节填充块,并且此填充不包括在块长度字段中. 发送方不得 (MUST NOT) 用超过3个字节填充. 接收方必须 (MUST) 忽略填充字节.
SCTP定义的块在第3.3节中详细描述. IETF定义的块扩展指南可以在本文档的第14.1节中找到.
3.2.1. 可选/可变长度参数格式 (Optional/Variable-Length Parameter Format)
SCTP控制块的块值由块类型特定的必需字段头部组成,后跟零个或多个参数. 块中包含的可选和可变长度参数以类型-长度-值格式定义,如下所示.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Parameter Type | Parameter Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\ \
/ Parameter Value /
\ \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
块参数类型 (Chunk Parameter Type): 16位(无符号整数)
类型字段是参数类型的16位标识符. 它的取值范围为0到65534.
值65535保留供IETF定义的扩展使用. 除特定SCTP块描述中定义的值外,其他值保留供IETF使用.
块参数长度 (Chunk Parameter Length): 16位(无符号整数)
参数长度字段包含参数的大小(以字节为单位),包括参数类型、参数长度和参数值字段. 因此,具有零长度参数值字段的参数的长度字段为4. 参数长度不包括任何填充字节.
块参数值 (Chunk Parameter Value): 可变长度
参数值字段包含要在参数中传输的实际信息.
参数的总长度(包括类型、参数长度和值字段)必须 (MUST) 是4字节的倍数. 如果参数的长度不是4字节的倍数,则发送方在参数末尾(即参数值字段之后)用全零字节填充参数. 填充的长度不包括在参数长度字段中. 发送方不得 (MUST NOT) 用超过3个字节填充. 接收方必须 (MUST) 忽略填充字节.
参数类型的编码方式是,最高阶的2位指定如果处理端点不识别参数类型时必须采取的操作.
00 - 停止处理此参数; 不处理此块内的任何进一步参数.
01 - 停止处理此参数,不处理此块内的任何进一步参数,
并在"未识别的参数"中报告未识别的参数,如第3.2.2节所述.
10 - 跳过此参数并继续处理.
11 - 跳过此参数并继续处理,但在"未识别的参数"中报告未识别的参数,
如第3.2.2节所述.
请注意,在所有四种情况下,都会发送INIT ACK或COOKIE ECHO块. 在00或01情况下,未知参数之后的参数处理被取消,但已经完成的处理不会回滚.
实际的SCTP参数在特定的SCTP块部分中定义. IETF定义的参数扩展规则在第14.2节中定义. 请注意,参数类型必须 (MUST) 在所有块中唯一. 例如,参数类型"5"用于表示IPv4地址(参见第3.3.2.1节). 然后,值"5"在所有块中保留以表示IPv4地址,并且不得 (MUST NOT) 在任何其他块中以不同的含义重用.
3.2.2. 未识别参数的报告 (Reporting of Unrecognized Parameters)
如果INIT块的接收方检测到未识别的参数并且必须根据第3.2.1节报告它们,则它必须 (MUST) 将"未识别的参数"参数放在响应INIT块发送的INIT ACK块中. 请注意,如果INIT块的接收方不打算建立关联(例如,由于缺少资源),则"未识别的参数"不会包含在发送给INIT发送方的任何ABORT中.
如果INIT ACK块的接收方检测到未识别的参数并且必须根据第3.2.1节报告它们,则它应该 (SHOULD) 将包含"未识别的参数"错误原因的ERROR块与响应INIT ACK块发送的COOKIE ECHO块打包在一起. 如果INIT ACK的接收方不能将COOKIE ECHO块与ERROR块打包在一起,则ERROR块可以 (MAY) 单独发送,但不能在收到COOKIE ACK之前发送.
注意: 每当COOKIE ECHO在数据包中发送时,它必须 (MUST) 是第一个块.
3.3. SCTP块定义 (SCTP Chunk Definitions)
本节定义了不同SCTP块类型的格式.
注: 由于第3.3节包含大量子章节(3.3.1到3.3.13),详细定义了各种块类型(DATA、INIT、INIT ACK、SACK等),这些内容将在后续文档中继续完成.