我正在开发一个在虚拟TAP接口和物理接口之间进行NAT的应用程序,我不确定应该为IP分段分配多less缓冲区。
根据维基百科,“片段偏移量”的最大值限制为8189,但是源可能同时发送2个或多个分片数据包? 或者它会按顺序发送它们(即不发送另一个碎片包,直到完成第一个包)。
片段偏移量
片段偏移量是一个13位的字段,如果将这些位解释为一个无符号整数,最大值将是8191.但实际上它是对8个字节的倍数进行计数,所以说这些值从0到65528,步数为8。
该字段本身的最大有效值到底是什么并不特别相关。 重要的是偏移量和长度字段之和的最大值。 如果这个数额太大,那么这个数据包是无效的。 即使每个字段单独在有效范围内,它们的总和仍然可以超过有效值。 未能validation收到的金额可能导致安全漏洞。
一个利用这个特殊安全漏洞的数据包被命名为“死亡之谜”(ping-of-death)。 这有点误导,因为它与ping无关,并导致普遍的误认为ping包是危险的。
以上所有都涉及您的问题中提到的片段偏移量,但与您的实际问题无关。
IP ID字段
你问是否一个源可以同时发送两个分段的数据包。 根据标准,在发送方交织两个分片数据包当然是可以接受的。 尽pipe这样做很less有意义。 但是不能对此作出任何假设。
在涉及到NAT的情况下,从两个具有不同IP地址的不同主机发送的两个分组在到达目的地后可能会具有相同的源IP。 一旦来自两个不同来源的碎片stream相遇,它们可能最终被交织。
即使不包含这样的NAT,数据包仍然可能被networking重新sorting(例如,如果它们通过不同path路由)。 因此,一旦到达目的地,由于多种原因,它们最终可能会被交织。
为确保接收方能够正确地重新组装数据包,头部有一个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(除非你喜欢debugging由NAT引入的问题)。