我读过许多关于UDP数据包大小的文章,但一直无法得出正确的结论。
许多服务将最大的UDP数据包限制在512字节(如dns)
假定internet上的最小MTU是576,IPv4报头的大小是20字节,UDP报头的大小是8字节。这就为用户数据留下了548个字节可用
我是否能够使用548大小的数据包而不产生数据包碎片?或者DNS的创造者知道一些事情,这就是为什么他们把它限制在512字节。
我能安全的把数据设置在548字节以上吗?
我读过许多关于UDP数据包大小的文章,但一直无法得出正确的结论。
许多服务将最大的UDP数据包限制在512字节(如dns)
假定internet上的最小MTU是576,IPv4报头的大小是20字节,UDP报头的大小是8字节。这就为用户数据留下了548个字节可用
我是否能够使用548大小的数据包而不产生数据包碎片?或者DNS的创造者知道一些事情,这就是为什么他们把它限制在512字节。
我能安全的把数据设置在548字节以上吗?
当前回答
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个片段。请记住,这些片段中的任何一个丢失都会导致整个包无用。
其他回答
根本没有。
我将完全撇开任何“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最大安全负载是508字节。这是一个576(“最小最大重组缓冲区大小”)的数据包大小,减去最大60字节的IP头和8字节的UDP头。
任何这种大小或更小的UDP有效载荷都保证可以通过IP传递(尽管不保证传递)。任何更大的值都允许被任何路由器以任何理由直接丢弃。只有ipv6路由例外,ipv6路由最大负载为1212字节。正如其他人所提到的,在某些情况下可以添加额外的协议头。更保守的大约300-400字节的值可能是首选的。
最大可能的UDP负载是67 KB,分成45个IP包,增加额外的900字节开销(IPv4, MTU 1500,最小20字节IP头)。
任何UDP报文都可能被分片。但这并不太重要,因为丢失一个片段与丢失一个未分片的数据包具有相同的影响:整个数据包被丢弃。使用UDP,这将发生任何一种方式。
IP报文中包含一个分片偏移字段,表示UDP分片相对于其UDP报文的字节偏移量。该字段是13位的,允许8192个值,这些值以8字节为单位。所以IP包可以引用的偏移量范围是0…65528字节。作为偏移量,我们为最后一个UDP片段添加1480,得到67,008。减去第一个片段中的UDP头,我们得到了一个漂亮的约67 KB。
来源:RFC 791, RFC 1122, RFC 2460
IPv4最小重组缓冲区大小为576,IPv6为1500。从这里减去标题大小。参见W. Richard Stevens的UNIX网络编程:)
576是最小的最大重组缓冲区大小,也就是说,每个实现必须能够重组至少这个大小的数据包。详见IETF RFC 1122。
考虑到IPV6的大小为1500,我认为运营商不会为IPV4和IPV6提供单独的路径(它们都是不同类型的IP),迫使它们使用旧的、冗余的、维护成本更高、可靠性更低的IPV4设备。这没有任何意义。此外,这样做可能很容易被认为是为某些流量提供优惠待遇——在他们可能不太关心的规则下(除非他们被抓住),这是不允许的。
因此,1472对于外部使用应该是安全的(尽管这并不意味着像DNS这样的应用程序不知道EDNS将接受它),如果你谈论的是内部网络,你更可能知道你的网络布局,在这种情况下,巨型数据包大小适用于非碎片数据包,因此对于4096 - 4068字节,对于英特尔卡的9014字节缓冲区,包大小为…… 等待……8086字节,是最大的…巧合吗?窃笑
* * * * * * * *更新
各种答案给出软件供应商允许的最大值或假设封装的各种答案。用户并没有要求尽可能低的值(比如安全的UDP大小为“0”),而是要求最大的安全数据包大小。
各个层的封装值可以被多次包含。因为一旦封装了一个流,就没有什么可以禁止的了,比如说,在它下面有一个VPN层,在它上面有一个完全复制的封装层。
由于这个问题是关于最大安全值的,我假设他们谈论的是可以接收的UDP数据包的最大安全值。由于没有UDP数据包是保证的,如果你收到一个UDP数据包,最大的安全大小将是IPv4上的1个数据包或1472字节。
注意——如果你使用IPv6,最大大小将是1452字节,因为IPv6的报头大小是40字节,IPv4是20字节(无论哪种方式,仍然必须允许8字节的UDP报头)。