SCTP association 与握手 · 四次握手和 Cookie

一个 SCTP association 是两端间的一条连接,建立它要四次握手——比 TCP 多一步,为的是用 Cookie 抵御 DoS 攻击。这一章讲清 association 是什么、四次握手 INIT/INIT-ACK/COOKIE-ECHO/COOKIE-ACK 的流程,以及 Cookie 机制的巧妙。

作者 David更新于 第 79 篇(共 112 篇)

一个 SCTP association(关联) 就是两端之间的一条 SCTP 连接(类似 TCP 的 connection),所有数据通道复用它。用它之前得先建立——SCTP 的握手比 TCP 多一步,是四次,多出来的一步藏着精巧的安全设计。这一章看它。

四次握手

DcSctpSocket::Connect() 发起握手。SCTP 用四次交换建立 association:

图表加载中…
  • ① INIT —— 发起方说“我要建连”,附上初始参数(TSN 起点、流数量、接收窗口等)。
  • ② INIT-ACK —— 接受方回应,附上自己的参数和一个 Cookie(下面详说)。
  • ③ COOKIE-ECHO —— 发起方把收到的 Cookie 原样送回。
  • ④ COOKIE-ACK —— 接受方验证 Cookie 无误,association 建立,可以传数据了。

为什么多一步:Cookie 抗 DoS

TCP 三次握手就够了,SCTP 为什么要四次、多一个 Cookie 环节?

那个多出来的 Cookie,是为了让接受方在握手完成前不必分配任何状态**,从而抵御 DoS 攻击。** 想想 TCP 的 SYN Flood 攻击:攻击者狂发 SYN(第一步),服务器每收一个就分配连接状态(半开连接)等第三步——攻击者不回第三步,服务器的半开连接表被塞爆,资源耗尽。

SCTP 的 Cookie 化解了它:收到 INIT 后,接受方不分配任何状态,而是把“建立这个连接所需的全部信息”打包、签名成一个 Cookie,塞进 INIT-ACK 发回去(状态存在 Cookie 里,不在接受方内存里)。只有当发起方把 Cookie 原样送回(COOKIE-ECHO)、且接受方验证签名无误时,才真正分配状态建立连接。于是攻击者狂发 INIT 也没用——接受方根本不为它们存状态,一身轻松。“把状态外包给客户端(装进签名的 Cookie),验证通过才落地”,是抗 DoS 的经典手法(和 DTLS 的 HelloRetryRequest cookie、STUN 的无状态异曲同工)。多握一次手,换来了健壮——值。

握手协商了什么

四次握手不只是“建立连接”,还协商了这条 association 的关键参数:

协商完,双方就 association 的运作规则达成一致——和 SDP 协商媒体是一个道理,只是这里协商的是传输层参数。在 WebRTC 里,SCTP 跑在已经建好的 DTLS 上,所以这四次握手是在加密通道内进行的——又快又安全。

小结与下一章

一个 SCTP association 是两端间的连接,数据通道复用它。Connect() 发起四次握手:INIT → INIT-ACK(带 Cookie)→ COOKIE-ECHO → COOKIE-ACK。比 TCP 多的那步用 Cookie 抗 DoS——接受方握手完成前不分配状态(状态签名进 Cookie 外包给客户端),验证回传的 Cookie 才落地,免疫 SYN-Flood 式攻击。握手还协商 TSN / 流数 / 窗口 / 扩展。它跑在已建的 DTLS 内。

握手建好了连接,数据怎么组织?SCTP 的数据单位是“chunk”,装进“packet”。下一章看包和块的结构。👉 SCTP 包与 chunk。

参考资料

  • [1] libwebrtc 源码.net/dcsctp/socket/(握手状态机)、net/dcsctp/packet/chunk/(INIT/COOKIE 等 chunk)。
  • [2] IETF RFC 9260「SCTP」§ 4-5(association 建立、Cookie 机制)。
  • [3] 关联DTLS 握手、STUN 无状态——抗 DoS 的类似思路。

本页目录