ip碎片有多糟糕

时间:2015-02-12 11:37:57

标签: sockets networking routing ip ip-fragmentation

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

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

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

谢谢

2 个答案:

答案 0 :(得分:6)

IP碎片可能会导致一些问题:

1)应用程序层丢失增加

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

2)并非所有网络都处理碎片数据包

某些系统such as Google's Compute Engine不会重新组合碎片数据包。

3)碎片会导致重新排序

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

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

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

因此,虽然IP碎片可以通过最小化用户标题来减少开销,但它可能会带来比实际值更多的麻烦。

答案 1 :(得分:4)

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

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

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

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