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
  • 相关阅读:
    try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
    BigDecimal 使用 静态方法总结
    成员内部类里面为什么不能有静态成员和方法?
    浅谈多态机制的意义及实现
    Java接口中的成员变量的意义
    IDEA 打包和导入 Jar 包
    Java static关键字
    Java this关键字
    Java 匿名对象
    Java JOptionPane 对话框
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8821984.html
Copyright © 2011-2022 走看看