7. 拥塞控制 (Congestion Control)
SCTP使用类似于TCP的拥塞控制机制来避免网络拥塞和确保公平的网络资源共享。
7.1. SCTP与TCP拥塞控制的差异 (SCTP Differences from TCP Congestion Control)
虽然SCTP的拥塞控制基于TCP的机制,但存在以下关键差异:
7.1.1. 多宿主和多路径
SCTP支持多宿主端点,每个目的传输地址维护独立的拥塞控制参数:
- 每个目的地的cwnd: 每个路径有自己的拥塞窗口
- 每个目的地的ssthresh: 每个路径有自己的慢启动阈值
- 每个目的地的RTO: 每个路径有自己的重传超时
这允许SCTP在不同路径上独立地进行拥塞控制。
7.1.2. 基于TSN的确认
SCTP使用TSN而非字节序列号进行确认。这意味着:
- 拥塞窗口以字节为单位维护
- SACK确认的是TSN范围
- cwnd更新基于确认的字节数而非TSN数量
7.1.3. 多流传输
SCTP的多个流共享同一个关联的拥塞控制参数。流之间没有单独的拥塞控制,这确保了:
- 所有流公平共享带宽
- 避免单个流垄断资源
7.2. SCTP慢启动和拥塞避免 (SCTP Slow-Start and Congestion Avoidance)
SCTP的拥塞控制算法遵循TCP的慢启动和拥塞避免原则。
7.2.1. 初始化和重启
当关联首次建立或路径在空闲后重新启动时:
cwnd = min(4*MTU, max(2*MTU, 4380字节))
ssthresh = 对等方的a_rwnd
注意: 初始cwnd的计算确保至少可以发送2个完整的数据包,但不超过4个MTU大小的数据包。
7.2.2. 慢启动阶段
在慢启动期间(cwnd <= ssthresh):
当收到新数据的SACK时:
cwnd = cwnd + min(确认的字节数, MTU)
规则:
- cwnd每次最多增加一个MTU
- 只有当所有确认的数据都是在当前cwnd下发送时才增加
- 当cwnd达到或超过ssthresh时,进入拥塞避免阶段
7.2.3. 拥塞避免阶段
当cwnd > ssthresh时:
使用适当字节计数 (Appropriate Byte Counting, ABC):
每个RTT内:
partial_bytes_acked = partial_bytes_acked + 确认的字节数
当 partial_bytes_acked >= cwnd 时:
cwnd = cwnd + MTU
partial_bytes_acked = partial_bytes_acked - cwnd
目标: 每个RTT增加cwnd约1个MTU。
7.2.4. 拥塞检测和响应
检测拥塞的信号:
- 重传超时 (RTO到期)
- 快速重传 (收到4个重复SACK)
响应RTO超时:
ssthresh = max(cwnd/2, 4*MTU)
cwnd = 1*MTU
partial_bytes_acked = 0
响应快速重传:
ssthresh = max(cwnd/2, 4*MTU)
cwnd = ssthresh
partial_bytes_acked = 0
7.2.5. 空闲期后的处理
如果目的地在RTO时间内没有数据传输(空闲):
选项1 (推荐):
cwnd = max(cwnd/2, 4*MTU)
选项2 (保守):
cwnd = min(4*MTU, max(2*MTU, 4380字节))
这防止了在长时间空闲后突然发送大量数据。
7.3. 路径MTU发现 (Path MTU Discovery)
SCTP端点应该 (SHOULD) 使用路径MTU发现(如[RFC4821]中定义的分组层PMTUD)来:
- 确定到目的地的最大可用MTU
- 避免IP分片
- 优化数据传输效率
7.3.1. PMTU发现过程
-
初始MTU: 使用保守的初始值(通常是576字节对于IPv4,1280字节对于IPv6)
-
探测更大的MTU:
- 发送带有"Don't Fragment"标志的数据包
- 如果成功,尝试更大的MTU
- 如果失败(收到ICMP "Packet Too Big"),使用较小的MTU
-
周期性重探测: 定期尝试更大的MTU,以适应路径变化
7.3.2. MTU更新对拥塞控制的影响
当PMTU增加时:
cwnd = (cwnd / 旧MTU) * 新MTU
ssthresh = (ssthresh / 旧MTU) * 新MTU
当PMTU减少时:
cwnd = (cwnd / 旧MTU) * 新MTU
ssthresh = (ssthresh / 旧MTU) * 新MTU
partial_bytes_acked = min(partial_bytes_acked, cwnd)
这确保了拥塞控制参数与MTU大小保持一致的关系。
7.3.3. 失败处理
如果PMTU发现失败或不可用:
- 使用保守的MTU值
- 不使用"Don't Fragment"标志
- 允许IP层进行分片
总结
SCTP的拥塞控制设计考虑了以下关键因素:
- 多路径支持: 每个路径独立的拥塞控制
- TCP友好性: 与TCP公平共享网络带宽
- 多流效率: 避免队头阻塞同时保持拥塞控制
- 路径自适应: 通过PMTU发现优化传输
这些机制确保SCTP既能高效利用网络资源,又能与其他流量公平共存。