您现在的位置: 爱51代码网 >> 范文 >> 文章正文
TIME_WAIT状态下对接收到的数据包如何处理
p;   return TCP_TW_ACK; 
17.  } 
18.  inet_twsk_put(tw); 
19.  return TCP_TW_SUCCESS; 
  if (!th->rst) {
        /* In this case we must reset the TIMEWAIT timer.
         *
         * If it is ACKless SYN it may be both old duplicate
         * and new good SYN with random sequence number <rcv_nxt.
         * Do not reschedule in the last case.
         */
        if (paws_reject || th->ack)
            inet_twsk_schedule(tw, &tcp_death_row, TCP_TIMEWAIT_LEN,
                       TCP_TIMEWAIT_LEN);


        /* Send ACK. Note, we do not put the bucket,
         * it will be released by caller.
         */
        return TCP_TW_ACK;
    }
    inet_twsk_put(tw);
    return TCP_TW_SUCCESS;  如果是RST包,即第3种情况,则直接返回TCP_TW_SUCCESS,丢掉RST包。
  如果带有ACK标志的话,则会启动TIME_WAIT定时器,然后给对端发送ACK。我们知道SYN包正常情况下不会设置ACK标志,所以如果是SYN包不会启动TIME_WAIT定时器,只会给对端发送ACK,告诉对端已经收到SYN包,避免重传,但连接应该不会继续建立。
  还有一个细节需要提醒下,就是我们看到在返回TCP_TW_ACK时,没有调用inet_twsk_put()释放对time_wait控制块的引用。这时因为在tcp_v4_rcv()中调用tcp_v4_timewait_ack()发送ACK时会用到time_wait控制块,所以需要保持对time_wait控制块的引用。在tcp_v4_timewait_ack()中发送完ACK后,会调用inet_twsk_put()释放对time_wait控制块的引用。
  OK,现在我们对TIME_WAIT状态下接收到数据包的情况有了一个了解,知道内核会如何来处理这些包。但是看到的这些更多的是以服务器端的角度来看的,如果客户端主动关闭连接的话,进入TIME_WAIT状态的是客户端。如果客户端在TIME_WAIT状态下重用端口号来和服务器建立连接,内核会如何处理呢?
  我编写了一个测试程序:创建一个套接字,设置SO_REUSEADDR选项,建立连接后立即关闭,关闭后立即又重复同样的过程,发现在第二次调用connect()的时候返回EADDRNOTAVAIL错误。这个测试程序很容易理解,写起来也很容易,就不贴出来了。
  要找到这个错误是怎么返回的,需要从TCP层的连接函数tcp_4_connect()开始。在tcp_v4_connect()中没有显示返回EADDRNOTAVAIL错误的地方,可能的地方就是在调用inet_hash_connect()返回的。为了确定是不是在inet_hash_connect()中返回的,使用systemtap编写了一个脚本,发现确实是在这个函数中返回的-99错误(EADDRNOTAVAIL的值为99)。其实这个通过代码也可以看出来,在这个函数之前会先查找目的主机的路由缓存项,调用的是ip_route_connect()函数,跟着这个函数的调用轨迹,没有发现返回EADDRNOTAVAIL错误的地方。
  inet_hash_connect()函数只是对__inet_hash_connect()函数进行了简单的封装。论文网 在__inet_hash_connect()中如果已绑定了端口号,并且是和其他传输控制块共享绑定的端口号,则会调用check_established参数指向的函数来检查这个绑定的端口号是否可用,代码如下所示:

[cpp] view plaincopyprint?
01.int __inet_hash_connect(struct inet_timewait_death_row *death_row, 
02.        struct sock *sk, u32 port_offset, 
03.        int (*che

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]  ... 下一页  >> 

  • 上一篇文章:

  • 下一篇文章: 没有了
  • 最新文章 热点文章 相关文章
    sharepoint 2010 获取用户信息Us
    设计包含max函数的队列
    随机从数组中取出指定的不重复的
    mysql主从同步延迟方案解决的学习
    青岛科学六年级下册教材分析
    生日旅行总结
    中小板生日快乐随感
    送生日快乐桑葚乳酪小蛋糕
    写给女儿的生日快乐
    总分公司财务核算
    mysql主从同步延迟方案解决的学习
    生日旅行总结
    中小板生日快乐随感
    送生日快乐桑葚乳酪小蛋糕
    写给女儿的生日快乐
    总分公司财务核算
    恢复使用繁体字可行性研究报告
    保险受益人制度相关问题的探讨
    初中生地理读图能力培养的研究
    搞笑生日祝福
    The layout of PID & PORT i
    hadoop核心逻辑shuffle代码分
    The layout of PID & PORT i
    The layout of PID & PORT i
    The layout of PID & PORT i
    MapReduce错误任务失败处理 
    Oracle恢复内部原理(介质恢
    在 Oracle 中如何确定远程 s
    为什么RHEL 6上没有ASMLIB?
    sharepoint 2010 获取用户信
     



    设为首页 | 加入收藏 | 网站地图 | 友情链接 |