zoukankan      html  css  js  c++  java
  • 随手记之TCP Keepalive笔记-tcp_keepalive_timer

    这里可以找到大部分处理逻辑,net/ipv4/Tcp_timer.c:

    static void tcp_keepalive_timer (unsigned long data)
    {
         struct sock *sk = (struct sock *) data;
         struct inet_connection_sock *icsk = inet_csk(sk);
         struct tcp_sock *tp = tcp_sk(sk);
         __u32 elapsed;
    
         /* Only process if socket is not in use. */
         bh_lock_sock(sk);
         if (sock_owned_by_user(sk)) {
              /* Try again later. */
              inet_csk_reset_keepalive_timer (sk, HZ/20);
              goto out;
         }
    
         if (sk->sk_state == TCP_LISTEN) {
              tcp_synack_timer(sk);
              goto out;
         }
        // 关闭状态的处理
         if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) {
              if (tp->linger2 >= 0) {
                   const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN;
    
                   if (tmo > 0) {
                        tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
                        goto out;
                   }
              }
              tcp_send_active_reset(sk, GFP_ATOMIC);
              goto death;
         }
    
         if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE)
              goto out;
    
         elapsed = keepalive_time_when(tp);
    
         /* It is alive without keepalive 8) */
         if (tp->packets_out || sk->sk_send_head)
              goto resched;
    
         elapsed = tcp_time_stamp - tp->rcv_tstamp;
    
         if (elapsed >= keepalive_time_when(tp)) {
              if ((!tp->keepalive_probes && icsk->icsk_probes_out >= sysctl_tcp_keepalive_probes) ||
                   (tp->keepalive_probes && icsk->icsk_probes_out >= tp->keepalive_probes)) {
                   tcp_send_active_reset(sk, GFP_ATOMIC);
                   tcp_write_err(sk); // 向上层应用汇报连接异常
                   goto out;
              }
              if (tcp_write_wakeup(sk) <= 0) {
                   icsk->icsk_probes_out++; // 这里仅仅是计数,并没有再次发送保活探测包
                   elapsed = keepalive_intvl_when(tp);
              } else {
                   /* If keepalive was lost due to local congestion,
                   * try harder.
                   */
                   elapsed = TCP_RESOURCE_PROBE_INTERVAL;
              }
         } else {
              /* It is tp->rcv_tstamp + keepalive_time_when(tp) */
              elapsed = keepalive_time_when(tp) - elapsed;
         }
    
         TCP_CHECK_TIMER(sk);
         sk_stream_mem_reclaim(sk);
    
    resched:
         inet_csk_reset_keepalive_timer (sk, elapsed);
         goto out;
    
    death:    
         tcp_done(sk);
    
    out:
         bh_unlock_sock(sk);
         sock_put(sk);
    }
    http://www.blogjava.net/yongboy/archive/2015/04/14/424413.html
  • 相关阅读:
    Hexo+Github 搭建一个自己的博客
    vue中sessionStorage存储的用法和问题
    vue 页面刷新
    vue渲染完页面后div滚动条定位在底部
    vue 定义全局函数
    vue filter过滤器用法
    vue中bus.$on事件被多次绑定
    vue中引入jQuery的方法
    vue2.0传值方式:父传子、子传父、非父子组件、路由跳转传参
    vue打包后显示为空白页的解决办法
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8821984.html
Copyright © 2011-2022 走看看