摘要

  • RFC 792 把 ICMP 类型 4 交给无法继续吸收流量的网关和目的主机。报文引用触发它的数据包,请求源端降低发往特定目的地的速率。
  • 这条命令既不认证发言者,也不说明队列深度、公平速率或持续时间。拥塞时生成额外控制包会消耗容量,伪造报文还能压低别人的吞吐量。
  • 长期控制后来转入端到端传输状态,ECN 又把显式拥塞信号放进实际遇到队列的数据包。RFC 6633 最终要求传输协议忽略 Source Quench,安全设备丢弃并记录它。

从满队列里诞生的命令

1981 年的 RFC 792 设想:网关没有足够缓冲把数据报排入下一条链路,于是丢包,并向源端发送 ICMP 类型 4、代码 0。若目的主机来不及处理到达的数据,也可以这样做。Source Quench 要求源端降低发往该目的地的速率;警告停止后,再逐步增加。

这个直觉有合理之处。中间网关能看见远端源主机看不见的队列,源主机却控制未来发送。反馈必须跨过这条边界。但 ICMP 本来就是不可靠反馈:原包和控制报告都可能丢失,报告到达时局面也可能已经改变。它不构成容量预留。

报文带回原始 IP 头和前 64 位数据,让主机能把警告关联到一次传输会话。这张“收据”仍很薄:没有队列深度、竞争流数目、应减少多少、应维持多久,也没有密码学证据证明发件者真的处理过被引用的数据包。

1989 年的 RFC 1122 仍保留了旧安排。主机接近资源耗尽时可以发送 Source Quench;收到后,IP 层必须上报给传输层。TCP 应减慢对应连接,通常回到 slow start。信息有限的收据因此能够触发影响很大的动作。

反馈为何会加深过载

RFC 896 在 1984 年描述了拥塞崩溃:队列填满、时延上升,主机把只是迟到的数据误判为丢失并重传;网络忙于运输副本,有效吞吐反而坍塌。增加内存只会延迟问题,并不能修复反馈回路。

Source Quench 可以为每个丢弃的数据包再生成一个控制包。即使限速,它仍要求饱和路径运输“路径已经饱和”的消息。多个网关也可能针对同一流发命令,却没有共同计账;服从的流可能反而把容量让给无视命令的流。

所以 1995 年的 RFC 1812 改变了路由器规范:路由器不应产生 Source Quench,因为研究认为它既无效又不公平;若仍产生,则必须限速。看见满队列不再自动等于拥有远程限速权。

发送方从结果中学习

TCP 拥塞控制把响应放到掌握流状态的一端。RFC 5681 用拥塞窗口、slow start、拥塞避免和恢复处理速率,而不依赖 Source Quench。ACK 证明某些数据已经离开网络并到达接收端;丢失与超时并非完美证据,却属于端点共同追踪的序列。

路由器并没有因此失去职责。RFC 2309 建议主动队列管理,在缓冲溢出前暴露拥塞,同时把队列管理、调度与公平性分开。路由器处置自己能观察的队列,传输层调整自己能识别的流。

写进数据包的标记

RFC 3168 用 ECN 保留了显式反馈,却换了一种语法。端点先声明数据包具备 ECN 能力;路由器遇到拥塞时,可以把该包的字段改为 Congestion Experienced,而不是丢弃。接收端通过传输状态回报,发送端作出近似于丢包的响应。

标记随真正遇到队列的数据包前进,不再是一条引用旧包的孤立命令。ECN 并非完美认证,也没有全球普及;标记仍可能被擦除或伪造,严重拥塞仍可能丢包。但证据至少被绑定到一次能力协商和一条可识别的会话。

还要撤销服从

只劝路由器别发送还不够。只要主机继续服从,旧设备、错误实现或攻击者就保留控制杆。2012 年的 RFC 6633 关闭了这条路径:主机不得发送;TCP、UDP 和其他传输必须静默忽略;路由器必须忽略;防火墙必须丢弃,并应作为安全故障记录类型 4。

风险很具体。攻击者可以伪造 Source Quench,实施盲目降吞吐攻击,而无需让所谓瓶颈真正拥塞。普遍的 ICMP 过滤也让消息交付无法成为可靠控制基础。ICMPv6 从未定义 Source Quench。

这八份 RFC 证明的是规范逐步撤权,不是全球在某一天同步停用。它们不证明所有路由器都发过、所有主机都服从、所有丢包都是拥塞,也不证明 ECN 不可操纵。更准确的历史结论是:一个仍可识别的编号,可以被运行代码彻底剥夺执行权限。