我读过许多关于UDP数据包大小的文章,但一直无法得出正确的结论。

许多服务将最大的UDP数据包限制在512字节(如dns)

假定internet上的最小MTU是576,IPv4报头的大小是20字节,UDP报头的大小是8字节。这就为用户数据留下了548个字节可用

我是否能够使用548大小的数据包而不产生数据包碎片?或者DNS的创造者知道一些事情,这就是为什么他们把它限制在512字节。

我能安全的把数据设置在548字节以上吗?


当前回答

I've read some good answers here; however, there are some minor mistakes. Some have answered that the Message Length field in the UDP header is a max of 65535 (0xFFFF); this is technically true. Some have answered that the actual maximum is (65535 - IPHL - UDPHL = 65507). The mistake, is that the Message Length field in the UDP Header includes all payload (Layers 5-7), plus the length of the UDP Header (8 Bytes). What this means is that if the message length field is 200 Bytes (0x00C8), the payload is actually 192 Bytes (0x00C0).

固定不变的是IP数据报的最大大小是65535字节。这个数字是L3和L4报头加上5-7层有效载荷的总和。IP头+ UDP头+层5-7 = 65535(最大)。

UDP数据报的最大大小最正确的答案是65515字节(0xFFEB),因为UDP数据报包括UDP头。UDP有效载荷最大大小的最正确答案是65507字节,因为UDP有效载荷不包括UDP头。

其他回答

我担心我会引起不安的反应,但尽管如此,为了澄清我是否错了,或者那些看到这个问题并对答案感兴趣的人:

我对https://www.rfc-editor.org/rfc/rfc1122的理解,它的状态是“官方规范”,因此是这个问题中使用的术语的参考,它既没有被另一个RFC取代,也没有与以下内容相矛盾的错误:

从理论上讲,ie。根据书面规范,像https://www.rfc-editor.org/rfc/rfc1122#section-4这样的UDP没有“数据包大小”。因此答案可能是“不确定的”

在实践中,这就是这个问题可能寻求的(以及可以根据当前的技术进行更新),这可能是不同的,我不知道。

如果我造成了困扰,我道歉。https://www.rfc-editor.org/rfc/rfc1122#page-8“互联网协议套件”和“架构假设”并没有让我清楚地知道我所做的“假设”,基于我所听到的,这些层是分开的。Ie。UDP所在的层不需要关心IP所在的层(IP层确实有像重组,EMTU_R,碎片和MMS_R (https://www.rfc-editor.org/rfc/rfc1122#page-56))

It is true that a typical IPv4 header is 20 bytes, and the UDP header is 8 bytes. However it is possible to include IP options which can increase the size of the IP header to as much as 60 bytes. In addition, sometimes it is necessary for intermediate nodes to encapsulate datagrams inside of another protocol such as IPsec (used for VPNs and the like) in order to route the packet to its destination. So if you do not know the MTU on your particular network path, it is best to leave a reasonable margin for other header information that you may not have anticipated. A 512-byte UDP payload is generally considered to do that, although even that does not leave quite enough space for a maximum size IP header.

根本没有。

我将完全撇开任何“UDP是最好的努力”的推理,只关注“最大安全UDP数据包大小”,这意味着“小到足以完全避免路径上的任何碎片”。

重要背景:

在没有分片的情况下,你唯一可以依赖的可传输的数据包大小是IPv4的24字节和IPv6的56字节,因为一个分片的最小IP头是20/48字节(v4/v6),并且一个分片必须至少有4/8字节(v4/v6)的有效载荷数据。因此,IP层以下的传输系统不能传输至少这些大小的数据包,不能用于传输IP流量。-回答“UDP中的MTU 65507如何?”

根据上面的答案,这是因为在这样的长度下,IP分片机制无法运行——它只能生成单个分片。

…IP标准要求每个IP主机能够接收总大小为576字节的IP数据包....然而,请注意,标准并没有说576没有分片,因此即使是576字节的IP数据包也可能在两台主机之间(源和目的地之间路径的某个位置)发现自己被分片了。

因此,任何比互联网协议可能做的最小值更大的东西,实际上可能会发现自己被“无形地”临时封装到路径上的某个地方,仅仅高于限制,即使你选择了最小的UDP有效载荷,这将是:576 - 8 (UDP报头)- 20 (IPv4)或40 (IPv6) = 528的min(以防你不确定是v4还是v6将被使用)。

您可能试图避免碎片化的一个原因是,它确实增加了数据包完整丢失的可能性。更多的数据包,仅仅是由于更高的开销,就意味着更大的失败可能性,更不用说每个数据包(甚至是一个片段)代表着另一个丢失的“机会”。当然,如果它碰巧被传递给某个链接,因为它太大而丢弃它……

操作系统级别的TCP实现尝试在TCP层中选择最高的安全MTU,包括有时动态地处理它,因为源和目的地之间的部分路径可能逐包不同。

对于UDP,这整个问题也变成了你的:它不是那么简单,只是“使用最大的,肯定不会碎片”。

RFC2460第5节是这么说的(关于IPv6的最小MTU)。

IPv6要求互联网上的每条链路都有1280的MTU 八位或更大。在任何不能传输1280字节的链路上 数据包在一块,链路特定的碎片和重组必须 在IPv6以下的层提供。

因此,碎片也可能发生在IP级别以下,在路径上的两个主机之间的特定链接决定将其碎片化,然后可能将碎片推到平行管道中……在这条链路的另一端把它们重新组装成一个数据包。

如果这些片段的顺序不正确,那么记录机制可能会错误地重新组装数据包,甚至没有意识到它重新排序了其中的一部分。

当然,如果硬件坚持IP规范,它应该能够通过检查IP报头的片段偏移部分来注意到数据包无序,但是大多数链路协议只是按照接收的顺序重新组装片段,而不担心无序的数据包接收。

现在,如果“较低水平”的互连本身被用作网络……例如,在一个大型开关的核心内部,那么在重载和许多并行路径下,这些碎片可能在重新组装之前就失去了秩序。

这是超级邪恶的,但可能有时确实会发生,导致偶尔仍然交付,但严重损坏的数据包,仍然通过简单的基于xor的校验和测试……也就是IP校验和。

TCP只是设置“不分片”并处理它,但UDP留下了清晰的bit…所以如果你使用UDP,你也应该假设你的字节流有时可能会被重新排序,甚至在数据包中…所以你应该使用校验和方法来验证你的数据,这个方法可以捕捉到重新排序。

大多数链路无论如何都会做1500 MTU,但链路层有不同的最小和最大数据报大小:

以太网:64到1500(或更高,具有更高的MTU能力) ATM: 53字节/数据报 帧中继:46 ~ 4470字节 (参考:IP碎片破碎

不幸的是,UDP头本身是8字节…所以这意味着,唯一能够避免碎片的UDP有效载荷…是零!(并且无论如何只适合最小的IPv6数据包)。

最好的/合理的方法可能是对UDP数据报使用512,并自己检查数据报中的数据是否无序,以及处理无序到达的数据包。(也就是说,完全不依赖IP为你丢弃坏掉的数据包)。

udp有不同的最大值。最后,这是你的选择,你认为足够安全的限制。注意:UDP本身是不安全的,因此您的数据包可能在任何时候丢失。

注意:所有这些都有一个范围。具体有多大取决于你的IP选项。一般情况下,可以这样计算:[upper maximum]-[IP-Options长度,以字节为单位]。这里列出的所有范围都不包括UDP-Header(8字节)

最小最大传输限制(或类似的东西,我忘记了实际的名称,在任何地方都找不到它):512-552字节

这可能是最安全的尺寸。IPv4协议要求所有跳来传输这个大小的数据包,更大的数据包可能在任何时间被任何主机丢弃。

最大传输单元:1432-1472:

这种大小的数据包可以在单个以太网帧中发送,而不会被分割。任何一个片段的丢失都会导致整个数据包无用。因此,当超过这个限制时,由于单个片段的碎片和潜在损失,您的数据包变得无用的机会增加。

绝对限制:65467-65507:

没有数据包可以超过这个限制,因为在这个限制下,IPv4协议达到了它的全部潜力。不能发送更大的数据包。这是因为IPv4协议只保留2个字节(16位)作为总长度。将所有这些位都设置为1,就得到65535。减去IP(20-60字节)和UDP头(8字节),就得到了这个限制。这种大小的数据包将导致至少44个片段。请记住,这些片段中的任何一个丢失都会导致整个包无用。

本文介绍了最大传输单元(MTU) http://en.wikipedia.org/wiki/Maximum_transmission_unit。它规定IP主机必须能够处理576字节的IP数据包。然而,它指出,最低是68。RFC 791:“每个互联网模块必须能够转发一个68字节的数据报,而不会产生进一步的碎片。这是因为一个互联网报头可能高达60个字节,而最小的片段是8个字节。”

因此,安全数据包大小508 = 576 - 60 (IP头)- 8 (udp头)是合理的。

正如user607811所提到的,其他网络层的碎片必须重新组合。 https://www.rfc-editor.org/rfc/rfc1122#page-56 3.3.2重新组装 IP层必须实现IP数据报的重组。 我们指定可以重新组合的最大数据报大小 通过EMTU_R(“有效MTU接收”);有时候 称为“重组缓冲区大小”。EMTU_R必须更大 大于或等于576