出于某种原因,我很难在 Google 上找到这个问题的答案,这个问题一开始似乎很简单:网络堆栈中的路由器是否会验证 UDP 和 TCP 校验和,如果不正确,是否会丢弃数据包?我的理解是路由器只考虑 IP 标头中的校验和,而 UDP / TCP 校验和是在端点完成的,但我不能 100% 确定这是否正确。
答案1
简短回答:否
较长的答案:仅实现路由器功能的路由器不会也无法验证 UDP 和 TCP 校验和。但是确实存在具有附加功能的路由器。如果路由器具有 NAT 和/或防火墙功能,答案可能会有所不同。
路由器不验证校验和的原因有很多:
- 这会减慢数据包处理速度。
- 路由器甚至可能不知道更高级别的协议,因此不知道它是否具有校验和以及如何检查它。
- 它可能被碎片化,使得校验和(仅存在于第一个碎片中)涵盖所有数据包。
- 它增加了不必要的复杂性,使其更难实现 - 特别是当您想要硬件实现而不是软件实现时。
但是,如果路由器同时实施 NAT 和/或防火墙,则必须考虑更高级别的协议。这样就消除了不验证校验和的一个理由。如果它破坏了数据包(NAT 按照定义会破坏数据包),则传输层校验和不再有效,因此必须进行更新。
无需验证旧校验和或从头计算新校验和即可更新校验和。相反,可以修改旧校验和以仅补偿对实际数据包所做的更改。这是由于校验和的工作方式而成为可能的。由于 NAT 需要修改的字段与校验和位于同一个数据包中,因此 NAT 可以修改数据包并更新校验和,而无需完全重新组装数据包。(不幸的是,所有其他片段都没有 NAT 路由数据包所需的完整信息,因此 NAT 设备仍然需要保留有关其他片段的状态,并且在某些情况下缓冲片段,直到它知道将它们发送到哪里。)
防火墙可能希望对包含多个片段数据的数据包执行检查。如果要检查整个重新组装的数据包,那么验证校验和也是一个好主意,否则可能会构造无效数据包,这些数据包将通过防火墙的验证,然后只需一个位翻转即可变成具有有效校验和的恶意数据包。要利用这一点需要很大的运气,但如果防火墙无论如何都要重新组装数据包进行检查,那么还是值得防范的。(这样的防火墙可能会通过缓冲数据包来增加延迟,但它不必这样做,因为它可以转发除最后一个数据包之外的所有数据包,这样防火墙发现的恶意数据包就永远无法在目的地重新组装。)
还有其他校验和确实由路由器验证。在 IPv4 中,每个数据包都有一个报头校验和,路由器应该在转发之前验证该校验和。由于必须更新报头中的 TTL 字段,因此也必须在每次跳跃时更新校验和。
在 IPv6 中,报头校验和被视为不必要的,因此被取消了。路由器中需要额外的处理是一个问题,而由于 IP 上下层的校验和覆盖了 IP 报头中的重要字段,因此校验和并不重要。因此,UDP 中的校验和是强制性的,而在 IPv4 中,UDP 校验和是可选的。
如果底层是以太网,则它具有数据包校验和,这些校验和在路径上的每跳上进行计算和验证。与传输层校验和不同,以太网层校验和涵盖单个片段。