SO_REUSEADDR选项会影响碎片吗?

时间:2013-03-26 07:52:01

标签: sockets

我已经面临UDP套接字的有趣行为,并设置了SO_REUSEADDR选项...

如果我通过IP / UDP发送1472个字节,我会在一个帧中得到所有这些 - 这就是'预期...

但对于1473碎片,有/没有该选项会有所不同。有没有人知道为什么会发生这种情况(我使用的是Debian 2.6.32-5-amd64)?

* SO_REUSEADDR已启用:*

FRAME#1
Internet协议版本4,Src:173.59.3.22(173.59.3.22),Dst:173.70.1.5(173.70.1.5)
    版本:4
    标题长度:20个字节
    差分服务字段:0x00(DSCP 0x00:默认; ECN:0x00:非ECT(不支持ECN))
        0000 00 .. =差分服务代码点:默认值(0x00)
        .... .. =显式拥塞通知:非-ECT(不支持ECN)(0x00)
    总长度: 1476
    识别:0x214d(8525)
    标志:0x01(更多片段)
        0 ...... .... =保留位:未设置
        .0 .. .... =不要片段:未设置
        ..1。 .... =更多片段:设置
    片段偏移量:0
    生存时间:64
    协议:UDP(17)
    标头校验和:0xd53f [正确]
        [好:是的]
        [差:错误]
    资料来源:173.59.3.22(173.59.3.22)
    目的地:173.70.1.5(173.70.1.5)
    [来源GeoIP:未知]
    [目的地GeoIP:未知]

用户数据报协议( 8 字节)
    源端口:icl-twobase1(25000)
    目的港:5000(5000)
    长度: 1481
    校验和:0x3cac [未选中,并非所有可用数据]
        [好的校验和:错误]
        [Bad Checksum:False]

数据( 1448 字节)

FRAME#2
因特网协议版本4,Src:173.59.3.22(173.59.3.22),Dst:173.70.1.5(173.70.1.5)br />     版本:4

    标题长度:20个字节
    差分服务字段:0x00(DSCP 0x00:默认; ECN:0x00:非ECT(不支持ECN))
        0000 00 .. =差分服务代码点:默认值(0x00)
        .... .. =显式拥塞通知:非-ECT(不支持ECN)(0x00)
    总长度: 45
    识别:0x214d(8525)
    标志:0x00
        0 ...... .... =保留位:未设置
        .0 .. .... =不要片段:未设置
        ..0。 .... =更多片段:未设置
    碎片偏移量:1456
    生存时间:64
    协议:UDP(17)
    标头校验和:0xfa20 [正确]
        [好:是的]
        [差:错误]
    资料来源:173.59.3.22(173.59.3.22)
    目的地:173.70.1.5(173.70.1.5)
    [来源GeoIP:未知]
    [目的地GeoIP:未知]

数据( 25 字节)

* SO_REUSEADDR已停用:*

FRAME#1
Internet协议版本4,Src:173.59.3.22(173.59.3.22),Dst:173.70.1.5(173.70.1.5)
    版本:4
    标题长度:20个字节
    差分服务字段:0x00(DSCP 0x00:默认; ECN:0x00:非ECT(不支持ECN))
        0000 00 .. =差分服务代码点:默认值(0x00)
        .... .. =显式拥塞通知:非-ECT(不支持ECN的传输)
(0x00)     总长度: 1500
    识别:0x214a(8522)
    标志:0x01(更多片段)
        0 ...... .... =保留位:未设置
        .0 .. .... =不要片段:未设置
        ..1。 .... =更多片段:设置
    片段偏移量:0
    生存时间:64
    协议:UDP(17)
    标头校验和:0xd52a [正确]
        [好:是的]
        [差:错误]
    资料来源:173.59.3.22(173.59.3.22)
    目的地:173.70.1.5(173.70.1.5)
    [来源GeoIP:未知]
    [目的地GeoIP:未知]

用户数据报协议( 8 字节)
    源端口:icl-twobase1(25000)
    目的港:5000(5000)
    长度: 1481
    校验和:0x3cac [未选中,并非所有可用数据]
        [好的校验和:错误]
        [Bad Checksum:False]

数据( 1472 字节)

FRAME#2
Internet协议版本4,Src:173.59.3.22(173.59.3.22),Dst:173.70.1.5(173.70.1.5)
    版本:4
    标题长度:20个字节
    差分服务字段:0x00(DSCP 0x00:默认; ECN:0x00:非ECT(不支持ECN))
        0000 00 .. =差分服务代码点:默认值(0x00)
        .... .. =显式拥塞通知:非-ECT(不支持ECN)(0x00)
    总长度: 21
    识别:0x214a(8522)
    标志:0x00
        0 ...... .... =保留位:未设置
        .0 .. .... =不要片段:未设置
        ..0。 .... =更多片段:未设置
    碎片偏移量:1480
    生存时间:64
    协议:UDP(17)
    标头校验和:0xfa38 [正确]
        [好:是的]
        [差:错误]
    资料来源:173.59.3.22(173.59.3.22)
    目的地:173.70.1.5(173.70.1.5)
    [来源GeoIP:未知]
    [目的地GeoIP:未知]

数据( 1 字节)

1 个答案:

答案 0 :(得分:1)

答案是 - SO_REUSEADDR不会影响碎片 ...


线索在IP标头中 MTU发现不分段标记
如果发送1472字节,MTU Discovery = ON:
使用Do not Frag Flag ON发送1500字节=>我得到了ICMP:

互联网控制消息协议
    类型:3(目的地无法到达)
    代码:4(需要碎片)
    校验和:0x90db [正确]
    下一跳的MTU:1480

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

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

下次我尝试发送相同的1473个字节(SO_REUSEADDR为OFF)时,路由\ arp缓存释放了有关接收器的信息,我看到了不同的混乱碎片(两帧中1480 + 1个字节)。

对不起大家的混乱......
然而,对于我来说,深入了解这种行为并澄清我观察到的事情是非常认知的。这里没有奇迹。