SO_REUSEADDR选项会影响数据包的分片吗?

3
我遇到了一个有趣的UDP套接字行为,它设置了SO_REUSEADDR选项...如果我通过IP/UDP发送1472字节,我会在一个帧中收到所有数据 - 这是预期的...但是当数据量为1473时,启用和不启用该选项会导致分段方式不同。有人知道为什么会出现这种情况吗?(我使用的是Debian 2.6.32-5-amd64)。 启用SO_REUSEADDR: 帧#1
Internet Protocol Version 4, Src: 173.59.3.22 (173.59.3.22), Dst: 173.70.1.5 (173.70.1.5)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
    Total Length: **1476**
    Identification: 0x214d (8525)
    Flags: 0x01 (More Fragments)
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..1. .... = More fragments: Set
    Fragment offset: 0
    Time to live: 64
    Protocol: UDP (17)
    Header checksum: 0xd53f [correct]
        [Good: True]
        [Bad: False]
    Source: 173.59.3.22 (173.59.3.22)
    Destination: 173.70.1.5 (173.70.1.5)
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
User Datagram Protocol (**8** bytes)
    Source port: icl-twobase1 (25000)
    Destination port: 5000 (5000)
    Length: **1481**
    Checksum: 0x3cac [unchecked, not all data available]
        [Good Checksum: False]
        [Bad Checksum: False]
Data (**1448** bytes)

FRAME#2

Internet Protocol Version 4, Src: 173.59.3.22 (173.59.3.22), Dst: 173.70.1.5 (173.70.1.5)br/>
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
    Total Length: **45**
    Identification: 0x214d (8525)
    Flags: 0x00
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    Fragment offset: 1456
    Time to live: 64
    Protocol: UDP (17)
    Header checksum: 0xfa20 [correct]
        [Good: True]
        [Bad: False]
    Source: 173.59.3.22 (173.59.3.22)
    Destination: 173.70.1.5 (173.70.1.5)
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Data (**25** bytes)

SO_REUSEADDR未启用:

FRAME#1

Internet Protocol Version 4, Src: 173.59.3.22 (173.59.3.22), Dst: 173.70.1.5 (173.70.1.5)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
    Total Length: **1500**
    Identification: 0x214a (8522)
    Flags: 0x01 (More Fragments)
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..1. .... = More fragments: Set
    Fragment offset: 0
    Time to live: 64
    Protocol: UDP (17)
    Header checksum: 0xd52a [correct]
        [Good: True]
        [Bad: False]
    Source: 173.59.3.22 (173.59.3.22)
    Destination: 173.70.1.5 (173.70.1.5)
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]

User Datagram Protocol (**8** bytes)
    Source port: icl-twobase1 (25000)
    Destination port: 5000 (5000)
    Length: **1481**
    Checksum: 0x3cac [unchecked, not all data available]
        [Good Checksum: False]
        [Bad Checksum: False]
Data (**1472** bytes)

FRAME#2

Internet Protocol Version 4, Src: 173.59.3.22 (173.59.3.22), Dst: 173.70.1.5 (173.70.1.5)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
    Total Length: **21**
    Identification: 0x214a (8522)
    Flags: 0x00
        0... .... = Reserved bit: Not set
        .0.. .... = Don't fragment: Not set
        ..0. .... = More fragments: Not set
    Fragment offset: 1480
    Time to live: 64
    Protocol: UDP (17)
    Header checksum: 0xfa38 [correct]
        [Good: True]
        [Bad: False]
    Source: 173.59.3.22 (173.59.3.22)
    Destination: 173.70.1.5 (173.70.1.5)
    [Source GeoIP: Unknown]
    [Destination GeoIP: Unknown]
Data (**1** byte)

好问题。1.启用SO_REUSEADDR和禁用SO_REUSEADDR时的源端口和目标端口是什么?您的跟踪似乎没有包含它们。2.这个跟踪是在发送方附近还是接收方附近进行的?如果是在接收方附近进行的,则片段排列可能已经在途中发生了变化(尽管这实际上不应该发生-路由器不应该重新组装)。 - Celada
谢谢回答!跟踪是在发送机器上收集的。源端口为25000,目标端口为5000。根据netstat输出,没有打开这样的源端口。 - Pavel Kozlov
我想不出任何导致不同碎片化的原因。希望其他人能知道答案。当然,两种方式的碎片化都是有效的,所以我认为无论哪种方式都不会有问题。 - Celada
这是我测试应用程序IP分段功能时的一个惊喜,下一跳的MTU小于1500,并且在设置选项后我未能测试它,直到找到原因。只是想知道为什么会发生这种情况。不过,还是要感谢! - Pavel Kozlov
1个回答

1
答案是不行 - SO_REUSEADDR不影响分段...


关键在于IP头中的MTU发现不要分段标志。 如果使用MTU发现 = ON发送1472字节的情况下:
使用Don't Frag Flag ON发送1500字节 => 我会收到ICMP:

Internet控制消息协议
类型:3(目标不可达)
代码:4(需要分段)
校验和:0x90db [正确]
下一跳的MTU为1480

之后,发送方对所有数据包进行分段以适应1480 MTU,同时保留该接收者的路由\arp缓存信息(路由5分钟,arp 30秒 - 在我的系统上配置默认值)。

这就是为什么我看到了1473字节(1456 + 25字节在两个帧中)的意外分段(在该实验中,SO_REUSEADDR为ON)...

下一次我尝试发送相同的1473字节(SO_REUSEADDR关闭)时,路由/arp缓存释放了有关接收器的信息,我看到了不同的混乱分段(在两个帧中分别为1480 + 1字节)。
对于造成困惑的每个人,我很抱歉......然而,这对我来说是非常有启发性的,可以深入挖掘这种行为并澄清我观察到的事情。这里没有奇迹。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接