ip碎片有多糟糕

Mat*_*nti 2 sockets ip networking routing ip-fragmentation

据我所知,当发送ip消息时,be和我的数据包目的地之间的网络路径中的每一跳都将检查下一跳的MTU是否大于我发送的数据包的大小.如果是这样,则数据包将被分段,并且两个数据包将分别发送到下一跳,仅在目的地重新组装(或者,在某些情况下,在遇到的第一个NAT路由器处).据我所知,这件事情可能非常糟糕,但我并不理解为什么.

  • 我知道如果连接往往会丢弃很多数据包,丢失一个片段意味着我必须重新发送整个数据包(这实际上是我自己想出的唯一的事情)
  • 是否有可能不会被分割,我的数据包将被丢弃?
  • 如何识别数据包片段?我可以100%确定它们会被正确重新组装吗?例如,如果我将两个相同长度的ip数据包几乎同时发送到同一个目的地,那么两个片段的可能性有多大,如AAA,BBB重新组装成ABA,BAB?

原则上,如果数据包没有被丢弃并且片段被正确地重新组装,实际上使用数据包分段似乎是一个好主意,可以节省本地带宽并避免发送越来越多的头而不仅仅是一个大数据包.

谢谢

Hug*_*ite 7

IP碎片可能会导致几个问题:

1)应用层损失增加

如前所述,如果删除单个片段,则整个第4层数据包将丢失.因此,对于具有小的随机分组丢失率的网络,应用层丢失率增加了大约等于每个第4层分组的分段数的因子.

2)并非所有网络都处理分段数据包

某些系统(如Google的计算引擎)不会重新组合碎片数据包.

3)碎片可能导致重新排序

当路由器将流量拆分为并行路径时,它们可能会尝试将来自同一流的数据包保留在单个路径上.因为只有第一个片段具有像UDP/TCP端口号这样的第4层信息,所以后续片段可以沿不同的路径路由,延迟第4层数据包的组装并导致重新排序.

4)碎片可能导致难以调试的混乱行为

例如,如果从一个源向运行Linux的目标发送两个UDP流A和B,则目标可能会丢弃其中一个流的数据包.这是因为默认情况下,如果从同一源接收到超过64个其他片段,则Linux会"超时"片段队列.如果流A具有比流B高得多的数据速率,则来自流A的64个片段可以到达来自流B的片段之间,导致B片段被丢弃.

因此,虽然IP碎片可以通过最小化用户标头来减少开销,但它可能会导致比它的价值更多的麻烦.


小智 5

据我所知,唯一会丢弃数据包而不是分段的情况(除非无论如何都会丢弃数据包的情况)是标记为“不分段”的数据包。这些数据包将被丢弃而不是被分段。

分段数据包在其标头中具有标识符、分段偏移量和更多分段字段,这些字段组合在一起后,允许目标主机在收到所有分段后可靠地重新组装数据包。第一个片段的偏移量为零,最后一个片段的更多片段标志设置为零。如果两个数据包的标头发生突变,从而交换了它们的片段偏移量,但它们的校验和仍然有效,仍然有可能(尽管不太可能)重新组装错误的数据包。这种情况发生的概率基本上为零。请记住,IP 不提供任何机制来确保数据有效负载的完整性,只提供标头中控制信息的完整性。

数据包分段必然会浪费带宽,因为每个片段都有原始数据报标头的[大部分]副本。数据包可以分段为每个片段仅 8 个字节,因此我们可以将最大大小的数据包(60 + 65536 字节)分段为 60 * 8192 + 65536 字节,在最坏的情况下,有效负载增加约 750%。我能想到的唯一一个你会领先的例子是,如果你对一个数据包进行分段,以便使用某种频分复用方案并行发送其片段,并且知道其他通道是空闲的。到那时,似乎仍然需要更多的工作来检测这种情况并分割数据包而不是仅仅发送它。

如果您渴望了解更多信息,则可以在IETF RFC 791中找到有关 IP 数据包分段机制的所有基本详细信息。