Passa al contenuto principale

6. The Usage of SCTP for Data Channels (SCTP用于数据通道的使用)

6.1 SCTP Protocol Considerations (SCTP协议考虑)

必须 (MUST) 使用 [RFC8261] 中描述的SCTP数据包的DTLS封装。

此SCTP协议栈及其上层必须 (MUST) 支持使用多个SCTP流。用户消息可以有序或无序发送,并具有部分或完全可靠性。

需要以下SCTP协议扩展:

  • 必须 (MUST) 支持 [RFC6525] 中定义的流重新配置扩展 (Stream Reconfiguration Extension)。它用于关闭通道。

  • 必须 (MUST) 使用 [RFC5061] 中定义的动态地址重新配置扩展 (Dynamic Address Reconfiguration Extension) 来信号支持 [RFC6525] 中定义的流重置扩展。[RFC5061] 的其他特性是可选的 (OPTIONAL)。

  • 必须 (MUST) 支持 [RFC3758] 中定义的部分可靠性扩展 (Partial Reliability Extension)。除了 [RFC3758] 中定义的定时可靠性PR-SCTP策略外,还必须 (MUST) 支持 [RFC7496] 中定义的有限重传策略 (Limited Retransmission Policy)。将重传次数限制为零,结合无序传递,提供类似UDP的服务,其中每个用户消息恰好发送一次并按接收顺序传递。

应该 (SHOULD) 使用 [RFC8260] 中定义的消息交错 (Message Interleaving) 支持。

6.2 SCTP Association Management (SCTP关联管理)

在WebRTC上下文中,当WebRTC PeerConnection的两个端点同意打开SCTP关联时,将建立该关联,如由JavaScript会话建立协议 (JavaScript Session Establishment Protocol, JSEP) 协商的那样,通常是会话描述协议 (Session Description Protocol, SDP) [RFC8829] 的交换。它将使用通过ICE选择的DTLS连接,通常这将通过BUNDLE或等效方式与用于密钥SRTP媒体流的DTLS连接共享。

在SCTP关联建立期间协商的流数量应该 (SHOULD) 是65535,这是在关联建立期间可以协商的最大流数量。

SCTP支持两种终止SCTP关联的方式。第一种方法是优雅的 (Graceful),其中使用确保在关联关闭期间不会丢失消息的过程。第二种方法是非优雅的 (Non-graceful),其中一方可以直接中止关联。

每个SCTP端点通过监视用户消息和测试消息的重传次数来持续监督其对等端的可达性。在过度重传的情况下,关联以非优雅的方式终止。

如果SCTP关联以优雅的方式关闭,则其所有数据通道都将关闭。在非优雅拆除的情况下,所有数据通道也将关闭,但如果可能,应该 (SHOULD) 提供错误指示。

6.3 SCTP Streams (SCTP流)

SCTP将流 (Stream) 定义为在SCTP关联内到另一个SCTP端点的单向逻辑通道。流用于提供顺序传递的概念和复用。每个用户消息在特定流上发送,有序或无序。仅对在同一流上发送的有序消息保留顺序。

6.4 Data Channel Definition (数据通道定义)

数据通道的定义使得其伴随的应用级API可以紧密镜像WebSockets的API,这意味着双向数据流和一个称为'label'的文本字段,用于标识数据通道的含义。

数据通道的实现是一对传入流和传出SCTP流,具有相同的SCTP流标识符 (Stream Identifier)。如何选择这些SCTP流标识符取决于协议和实现。这允许双向通信。

此外,每个数据通道在每个方向上具有以下属性:

  • 可靠或不可靠的消息传输: 在不可靠传输的情况下,使用相同级别的不可靠性。请注意,在SCTP中,这是SCTP用户消息的属性,而不是SCTP流的属性。

  • 有序或无序的消息传递: 请注意,在SCTP中,这是SCTP用户消息的属性,而不是SCTP流的属性。

  • 优先级 (Priority), 这是一个2字节无符号整数: 这些优先级必须 (MUST) 根据 [RFC8260] 中支持交错的相应流调度器的定义解释为加权公平队列调度优先级。对于WebRTC中的使用,使用的值应该 (SHOULD) 是128 ("低于正常"), 256 ("正常"), 512 ("高") 或1024 ("超高") 之一。

  • 可选的标签 (Label)

  • 可选的协议 (Protocol)

请注意,对于使用 [RFC8832] 中指定的协议协商的数据通道,上述所有属性在两个方向上都是相同的。

6.5 Opening a Data Channel (打开数据通道)

数据通道可以通过在SCTP关联内使用协商 (称为带内协商, In-band Negotiation) 或带外协商 (Out-of-band Negotiation) 来打开。带外协商定义为导致就通道参数达成一致并创建通道的任何方法。详细信息超出本文档的范围。使用数据通道的应用程序需要在两个端点上一致地使用协商方法。

[RFC8832] 中指定了用于带内协商的简单协议。

当一方想要使用带外协商打开通道时,它选择一个流。除非另有定义或协商,否则根据DTLS角色选择流 (客户端选择偶数流标识符,服务器选择奇数流标识符)。但是,应用程序负责避免与现有流的冲突。如果它尝试重用作为现有数据通道一部分的流,则添加必须 (MUST) 失败。除了选择流之外,应用程序还应该 (SHOULD) 确定用于发送消息的选项。应用程序必须 (MUST) 以特定于应用程序的方式确保对等端的应用程序也知道要使用的选定流,以及从该侧发送数据的选项。

6.6 Transferring User Data on a Data Channel (在数据通道上传输用户数据)

在数据通道上双向发送的所有数据必须 (MUST) 使用打开数据通道时定义的可靠性通过底层流发送,除非选项已更改或更高级别指定了每消息选项。

SCTP的消息方向性用于保留用户消息的消息边界。因此,发送方禁止 (MUST NOT) 将多个应用程序消息放入一个SCTP用户消息中。除非使用已弃用的基于PPID的分片和重组,否则发送方必须 (MUST) 在每个SCTP用户消息中恰好包含一个应用程序消息。

SCTP有效载荷协议标识符 (Payload Protocol Identifiers, PPIDs) 用于信号"有效载荷数据"的解释。必须 (MUST) 使用以下PPID (参见第8节):

WebRTC String: 用于标识以UTF-8编码的非空JavaScript字符串。

WebRTC String Empty: 用于标识以UTF-8编码的空JavaScript字符串。

WebRTC Binary: 用于标识非空JavaScript二进制数据 (ArrayBuffer, ArrayBufferView或Blob)。

WebRTC Binary Empty: 用于标识空JavaScript二进制数据 (ArrayBuffer, ArrayBufferView或Blob)。

SCTP不支持发送空用户消息。因此,如果必须发送空消息,则使用适当的PPID (WebRTC String Empty或WebRTC Binary Empty),并发送一个零字节的SCTP用户消息。当接收到具有这些PPID之一的SCTP用户消息时,接收方必须 (MUST) 忽略SCTP用户消息并将其作为空消息处理。

PPID "WebRTC String Partial"和"WebRTC Binary Partial"的使用已弃用。它们用于属于可靠和有序数据通道的用户消息的基于PPID的分片和重组。

如果接收到具有不受支持的PPID的消息,或者接收方检测到与接收到的消息相关的某些错误条件 (例如,非法排序),则接收方应该 (SHOULD) 关闭相应的数据通道。这特别意味着使用附加PPID的扩展在没有事先协商的情况下无法使用。

[RFC4960] 中指定的SCTP基本协议不支持用户消息的交错。因此,发送大型用户消息可能会垄断SCTP关联。为了克服这一限制,[RFC8260] 定义了支持消息交错的扩展,应该 (SHOULD) 使用该扩展。只要不支持消息交错,发送方应该 (SHOULD) 将最大消息大小限制为16 KB以避免垄断。

建议将消息大小保持在一定的大小范围内,因为应用程序将无法支持任意大的单个消息。必须协商此限制,例如,通过使用 [RFC8841]。

发送方应该 (SHOULD) 禁用Nagle算法 (参见 [RFC1122]) 以最小化延迟。

6.7 Closing a Data Channel (关闭数据通道)

数据通道的关闭必须 (MUST) 通过重置相应的传出流 [RFC6525] 来发出信号。这意味着如果一方决定关闭数据通道,它将重置相应的传出流。当对等端看到传入流已重置时,它也会重置其相应的传出流。一旦完成,数据通道就关闭了。重置流将流的流序列号 (Stream Sequence Numbers, SSNs) 设置回'零',并向应用层发出已执行重置的相应通知。流在执行重置后可供重用。

[RFC6525] 还保证在流重置之前传递 (或放弃) 所有消息。