zoukankan      html  css  js  c++  java
  • TCP 之 TCP_NEW_SYN_RECV状态

    概述

    以前的TCP请求控制块没有独立的状态,而是依赖于他们的父控制块的状态,也就是TCP_LISTEN状态,现在要把请求控制块加入到全局的ehash中,所以需要一个状态,而TCP_SYN_RECV状态被fast open sokets使用了,所以新加了一个TCP_NEW_SYN_RECV状态;

    以下截取在kernel git,地址:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/log/?qt=grep&q=TCP_NEW_SYN_RECV

    TCP_SYN_RECV state is currently used by fast open sockets.
    
    Initial TCP requests (the pseudo sockets created when a SYN is received)
    are not yet associated to a state. They are attached to their parent,
    and the parent is in TCP_LISTEN state.
    
    This commit adds TCP_NEW_SYN_RECV state, so that we can convert
    TCP stack to a different schem gradually.
    
    ------------------------
    We need to identify request sock when they'll be visible in
    global ehash table.
    
    ireq_state is an alias to req.__req_common.skc_state.
    
    Its value is set to TCP_NEW_SYN_RECV
    代码分析

    以下代码以服务器端处于LISTEN状态,等待接收syn为前提;

    接收SYN

    在服务器接收了syn之后,会调用tcp_conn_request来处理连接请求,其中调用inet_reqsk_alloc来创建请求控制块,可见请求控制块的ireq_state被初始化为TCP_NEW_SYN_RECV;

     1 struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
     2                       struct sock *sk_listener,
     3                       bool attach_listener)
     4 {
     5     struct request_sock *req = reqsk_alloc(ops, sk_listener,
     6                            attach_listener);
     7 
     8     if (req) {
     9         struct inet_request_sock *ireq = inet_rsk(req);
    10 
    11         kmemcheck_annotate_bitfield(ireq, flags);
    12         ireq->opt = NULL;
    13 #if IS_ENABLED(CONFIG_IPV6)
    14         ireq->pktopts = NULL;
    15 #endif
    16         atomic64_set(&ireq->ir_cookie, 0);
    17         ireq->ireq_state = TCP_NEW_SYN_RECV;
    18         write_pnet(&ireq->ireq_net, sock_net(sk_listener));
    19         ireq->ireq_family = sk_listener->sk_family;
    20     }
    21 
    22     return req;
    23 }

    该部分详细分析请移步:<TCP被动打开 之 第一次握手-接收SYN>;

    接收ACK

    tcp_v4_rcv函数中会对TCP_NEW_SYN_RECV进行处理,如果连接检查成功,则需要新建控制块来处理连接,这个新建控制块的状态将会使用TCP_SYN_RECV状态;

    该部分详细分析请移步:<TCP被动打开 之 第三次握手-接收ACK>;

  • 相关阅读:
    戴尔服务器状态信息和简单处理
    zabbix3.2通过snmp v2采集Dell服务器iDRAC口信息监控硬件
    戴尔服务器使用omreport(OMSA)查看监控硬件信息
    SVN主从高可用
    Linux下ping命令参数详细解析
    记录脚本运行时间
    Centos6优化系统服务脚本
    git分支管理
    git基本操作
    开源CMDB详细安装使用
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11751740.html
Copyright © 2011-2022 走看看