免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3311 | 回复: 10
打印 上一主题 下一主题

[网络子系统] 请教一个TCP原理问题,请各位帮忙解决下. [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-08 22:36 |只看该作者 |倒序浏览
本帖最后由 通信工程师 于 2013-10-08 22:56 编辑

   
     如果 说在 TCP业务正常建链ok并且业务中后,Server端 更改了网络侧和链路侧,主要就是驱动重新卸载加载和ip和路由被修改了.在client端依旧按照原有的4元组发对应包过来时, Server侧会不会直接发reset过去并且中断tcp链路 ..  
   
    测试结果是会的,但是没弄明白原理,l3,l2难道会影响到l4吗?    udp是更改网络侧和链路侧是没有关系的,所以看起来并不像是socket被关闭了.

    看了linux os原码不过没找到对应的reset地方??具体是在哪个流程中发出的呢??, 请高手指导下,谢了 ...

   

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2013-10-09 10:07 |只看该作者
理论上说,应该不会。
更新驱动只会影响服务端的硬件识别和底层处理;而修改ip则应只会影响ip层的处理,理论上说,如果服务端ip修改,而客户端的arp缓存没有更新的话,当带有原来ip报文到达服务端后,在IP层,应该就会被丢弃,而接下来可能发生的是,客户端根据tcp协议进行超时重传、最终关闭连接;也可能服务端发送arp报文导致客户端缓存更新,此时客户端再以原有IP发送则可能收到目的不可达的ICMP响应。
可以将抓包序列发来看看~~

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
3 [报告]
发表于 2013-10-09 13:26 |只看该作者
本帖最后由 瀚海书香 于 2013-10-10 08:13 编辑

回复 1# 通信工程师
如果 说在 TCP业务正常建链ok并且业务中后,Server端 更改了网络侧和链路侧,主要就是驱动重新卸载加载和ip和路由被修改了.在client端依旧按照原有的4元组发对应包过来时, Server侧会不会直接发reset过去并且中断tcp链路 ..  
   
    测试结果是会的,但是没弄明白原理,l3,l2难道会影响到l4吗?    udp是更改网络侧和链路侧是没有关系的,所以看起来并不像是socket被关闭了.

    看了linux os原码不过没找到对应的reset地方??具体是在哪个流程中发出的呢??, 请高手指导下,谢了 ...


如果网卡驱动重新加载,那么网卡状态从on-->off-->on的状态。这会触发NETDEV_CHANGE事件,而上层协议注册了相应的事件处理函数,会将对应的socket连接设置为error。

可以看看函数 packet_notifier的实现

   

论坛徽章:
0
4 [报告]
发表于 2013-10-09 19:21 |只看该作者
本帖最后由 通信工程师 于 2013-10-09 19:27 编辑

回复 3# 瀚海书香


我还有个不明白的地方,我用的是TCP,TCP应该是socket(AF_INET,SOCK_STREAM,0) 而不是socket(PF_INET,SOCK_PACKET ....)

PF_PACKET  我看到了 驱动的变化确实会引起packet_notifier回调,进而struct net *net = dev_net(dev) ...sk_for_each(sk, node, &net->packet.sklist) ...sk->sk_err = ENETDOWN。。。这是因为socket创建是packet_create会sk_add_node(sk, &net->packet.sklist) 把sk添加到net->packet.sklist中.

但是AF_INET我在inet_create中没有找到把sk添加到net->packet.sklist中,仅仅sk_alloc看到sk->sk_net = net;  


这是可以理解的,因为PF_PACKET 是驱动层透传到用户态的。所以它的接口更改肯定会影响socket。 但是af_inet的TCP,UDP之前就是不变的


求进一步指导,多谢 !!!!!!


   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
5 [报告]
发表于 2013-10-10 08:13 |只看该作者
回复 4# 通信工程师
我还有个不明白的地方,我用的是TCP,TCP应该是socket(AF_INET,SOCK_STREAM,0) 而不是socket(PF_INET,SOCK_PACKET ....)

PF_PACKET  我看到了 驱动的变化确实会引起packet_notifier回调,进而struct net *net = dev_net(dev) ...sk_for_each(sk, node, &net->packet.sklist) ...sk->sk_err = ENETDOWN。。。这是因为socket创建是packet_create会sk_add_node(sk, &net->packet.sklist) 把sk添加到net->packet.sklist中.

但是AF_INET我在inet_create中没有找到把sk添加到net->packet.sklist中,仅仅sk_alloc看到sk->sk_net = net;  


这是可以理解的,因为PF_PACKET 是驱动层透传到用户态的。所以它的接口更改肯定会影响socket。 但是af_inet的TCP,UDP之前就是不变的


求进一步指导,多谢 !!!!!!


你的理解是对的。对于AF_PACKET的类型,并没有监听网卡的up/down事件。

这边进行了测试,测试步骤和结果如下:

1. A和B服务器之间建立tcp连接,A向B不断发送数据包,在B可以看到不断有数据包到达。通过ss命令查看连接状态为ESTAB

2. ifconfig down A的网卡,观察两边的连接状态仍然是ESTAB,在B段接收不到数据,但是A的Send-Q不断增加。(由于网卡down,无法把数据包发出,所有数据包被放到了发送队列中)

3. ifconfig up A的网卡,观察两边的连接状态仍然是ESTAB,在B段再次收到数据,A的Send-Q开始减少到0。

网卡状态的改变不影响AF_PACKET类型的socket。
   

论坛徽章:
0
6 [报告]
发表于 2013-10-10 09:29 |只看该作者
本帖最后由 通信工程师 于 2013-10-10 11:23 编辑

回复 5# 瀚海书香

你好,多谢为我解疑  :)

linux下的实验没有来得及做

刚才做了下Windows下的试验 ,我是这么做的, 两台PC机器,都静态分配地址,都用Iperf建立TCP连接 ,一台做Server, 一台做client, 在client机器抓包  

    1.首先建立TCP连接,正常跑业务
    2.接下来把SERVER的网卡禁用 ,可以看到Server没挂,Client没挂
    3.再次把SERVER的网卡启用,可以看到Server程序没挂,Client程序挂了,原因 write failed: Connection reset by peer
                                                                                                                    read on server close failed: Connection reset by peer
                                                                                                                     Done.
          抓包看到Server发了rst给Client.
   
      
     请问这个rst怎么来的,,Windows下的网卡禁用和linuxi下的ifconfig down/up 的行为区别在哪里呢??linux下的ifconfig down/up是否等同于删除驱动/重新加载呢?


另:补充做了下linux的实验,linux机器做Server,在client侧抓包,使用脚本ifconfig xxx down && sleep XX && ifconfig xxx up的方式。

   发现,当sleep 的时间小于8-9时,TCP业务就不会断,否则client就会抓到rst的包,断开TCP链接。同时无论如何,LINUX的Server程序都可再次连接。

    在Server上用ss查看,发现当sleep时间8-9即发送异常rst包给client时,就会多出一个establish的TCP连接,好像是废TCP连接,不会被删除了???????。

    估计Windows下实验也是这个原因。请问下,是否这说明了 TCP中的保活定时器超时,但不应该这么短时间啊???,在内核中这块代码在哪个部分呢,时间怎么设置呢?是否还有其他定时器导致这个测试结果呢?
    求解答,谢谢!!!



   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
7 [报告]
发表于 2013-10-10 12:32 |只看该作者
回复 6# 通信工程师
发现,当sleep 的时间小于8-9时,TCP业务就不会断,否则client就会抓到rst的包,断开TCP链接。同时无论如何,LINUX的Server程序都可再次连接。

应该不是保活探测引起,这个默认是7200秒才会触发的。
猜测是重传超时引起,可以修改参数net.ipv4.tcp_retries1进行验证;


   

论坛徽章:
0
8 [报告]
发表于 2013-10-11 09:37 |只看该作者
本帖最后由 通信工程师 于 2013-10-11 09:38 编辑

回复 7# 瀚海书香


    你好,你说的net.ipv4.tcp_retries1我昨天设置过了 echo X > /proc/sys/net/ipv4/tcp_retries1  试图调>3的值 如10,还是sleep8 后会有RST,这时候看到TCP链接已经废弃了。

   另外,另一个问题,ifconfig xx down/up和 register_netdevice_notifier/unregister_netdevice_notifier 这两个应该不一样吧。我看到后两个函数中,都会把netdev_chain中所有的网络注册函数都回调一遍。  我是在android终端侧测试的,如果3g断开,重新接入wlan,那么实际上在之前3g中成功建立的tcp状态为ESTABLISHED 肯定会断开。反过来wlan切到3g 也是如此。我猜测是不是linux 驱动卸载/加载时 会通知删除tcp连接???但是在内核代码中没找到具体的部分。请教下。

   感谢无私的分享!

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
9 [报告]
发表于 2013-10-11 10:28 |只看该作者
回复 8# 通信工程师
你好,你说的net.ipv4.tcp_retries1我昨天设置过了 echo X > /proc/sys/net/ipv4/tcp_retries1  试图调>3的值 如10,还是sleep8 后会有RST,这时候看到TCP链接已经废弃了。

   另外,另一个问题,ifconfig xx down/up和 register_netdevice_notifier/unregister_netdevice_notifier 这两个应该不一样吧。我看到后两个函数中,都会把netdev_chain中所有的网络注册函数都回调一遍。  我是在android终端侧测试的,如果3g断开,重新接入wlan,那么实际上在之前3g中成功建立的tcp状态为ESTABLISHED 肯定会断开。反过来wlan切到3g 也是如此。我猜测是不是linux 驱动卸载/加载时 会通知删除tcp连接???但是在内核代码中没找到具体的部分。请教下。


切换3g/wlan后,你的源ip都变化了,原来的tcp连接(5元组)肯定废弃了啊。

路由会关注网卡的up/down时间来动态的修改路由表,tcp层应该不会关心的。
   

论坛徽章:
0
10 [报告]
发表于 2013-10-11 11:08 |只看该作者
本帖最后由 通信工程师 于 2013-10-11 16:18 编辑

回复 9# 瀚海书香


  忘了说了,我做了一个程序,把上下组包全部给改掉了,android侧抓包能看到,不管是GTP-U下来的包还是WIFI下来的包,都是同样的五元组。可是切换时连接还是断了。。。。。

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP