我正在开发一个在虚拟 TAP 接口和物理接口之间进行 NAT 的应用程序,但我不确定应该为 IP 分段分配多少缓冲区。
根据 Wikipedia,“Fragment Offset”的最大值限制为 8189,但源是否有可能同时发送 2 个或更多分段数据包?或者它会按顺序发送它们(即在完成第一个之前不发送另一个分段数据包)?
我正在开发一个在虚拟 TAP 接口和物理接口之间进行 NAT 的应用程序,但我不确定应该为 IP 分段分配多少缓冲区。
根据 Wikipedia,“Fragment Offset”的最大值限制为 8189,但源是否有可能同时发送 2 个或更多分段数据包?或者它会按顺序发送它们(即在完成第一个之前不发送另一个分段数据包)?
片段偏移
片段偏移量是一个 13 位字段,如果您将这些位解释为无符号整数,则最大值将为 8191。但实际上它计算的是 8 个字节的倍数,因此说这些值来自0 到 65528,步长为 8。
该字段本身的最大有效值究竟是什么并不特别相关。重要的是偏移量和长度字段之和的最大值。如果该总和太大,则数据包无效。即使每个字段单独在有效范围内,它们的总和仍然可能超过有效值。未能在收货时验证金额可能会导致安全漏洞。
利用此特定安全漏洞的数据包已被命名为 ping-of-death。这有点误导,因为它首先与 ping 无关,并导致人们普遍误解 ping 数据包是危险的。
以上所有内容都与您的问题中提到的片段偏移量有关,但与您的实际问题无关。
IP ID 字段
您在询问源是否可以同时发送两个分段数据包。根据标准,在发送方交错两个分段数据包当然是可以接受的。但是,这样做很少有意义。但是不能对此做出任何假设。
如果涉及 NAT,则从具有不同 IP 地址的两个不同主机发送的两个数据包可能会在到达目的地后最终具有相同的源 IP。一旦来自两个不同来源的片段流相遇,它们最终可能会被交错。
即使不涉及这样的 NAT,数据包仍然有可能被网络重新排序(例如,如果它们通过不同的路径路由)。因此,由于多种原因,一旦到达目的地,它们最终可能会被交错。
为了确保接收方能够正确重组数据包,报头有一个 IP ID 字段(在 IPv4 上为 16 位,在 IPv6 上为 32 位)。为了重组,接收方必须考虑源 IP、目标 IP 和 IP ID。这原则上足以重新组装在传输过程中交错的有效载荷。
不幸的是,在 NAT 的情况下,事情并不是那么简单。两个不同 IP 的主机同时发送一个数据包是有效的,它们的 IP ID 相同。(这显然是必须允许的,因为双方都不知道对方正在发送的数据包)。但是,如果数据包的源 IP 被 NAT 更改,使得它们现在具有相同的源 IP,它们可能不再是可区分的。
在 NAT 中纠正这个问题不是很实用。因此,NAT 简单地忽略它并希望获得最好的结果并不罕见。这意味着通过 NAT 发送的分段数据包可能会被错误地重组,并可能将数据从一个连接泄漏到另一个连接。
由于 IP ID 字段更大,这种风险对于 IPv6 来说要小得多。它也更小,因为在 IPv6 中您不使用 NAT(除非您喜欢调试 NAT 引入的问题)。