在将状态设置为TCP_SYN_RECV之后,内核如何继续三次握手

sli*_*ter 1 c tcp linux-kernel

我试图了解如何在Linux内核版本2.6.33中实现TCP三次握手.

我从函数accept()开始,它引导我:

接受()==> sys_accept()==> sys_accept4()==> inet_accept()==> inet_csk_accept()

现在我被困在inet_csk_accept()中.

struct sock *inet_csk_accept(struct sock *sk, int flags, int *err)
 {
     struct inet_connection_sock *icsk = inet_csk(sk);
     struct sock *newsk;
     int error;

     lock_sock(sk);

     /* We need to make sure that this socket is listening,
      * and that it has something pending.
      */
     error = -EINVAL;
     if (sk->sk_state != TCP_LISTEN)
             goto out_err;

     /* Find already established connection */
     if (reqsk_queue_empty(&icsk->icsk_accept_queue)) {
             long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);

             /* If this is a non blocking socket don't sleep */
             error = -EAGAIN;
             if (!timeo)
                     goto out_err;

             error = inet_csk_wait_for_connect(sk, timeo);
             if (error)
                     goto out_err;
     }

     newsk = reqsk_queue_get_child(&icsk->icsk_accept_queue, sk);
     WARN_ON(newsk->sk_state == TCP_SYN_RECV);
 out:
     release_sock(sk);
     return newsk;
 out_err:
     newsk = NULL;
     *err = error;
     goto out;
 }
Run Code Online (Sandbox Code Playgroud)

我的问题是程序何时进行

WARN_ON(newsk->sk_state == TCP_SYN_RECV);
Run Code Online (Sandbox Code Playgroud)
  1. 三方握手已经完成了吗?

  2. 服务器发送ACK的代码在哪里?

  3. 服务器从客户端确认ACK的代码在哪里?

  4. 或者如果我一开始就错了,那么在accpet()中是否实现了三次握手?

谢谢

wer*_*dle 5

TCP的实际套接字逻辑位于

net/ipv4/tcp_input.c
Run Code Online (Sandbox Code Playgroud)

插座的状态机位于功能中

int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
              struct tcphdr *th, unsigned len)
Run Code Online (Sandbox Code Playgroud)

它实现所有套接字状态转换(包括三次握手).这个函数以这种方式调用:

tcp_v4_rcv => tcp_v4_do_rcv => tcp_rcv_state_process
Run Code Online (Sandbox Code Playgroud)

对于每个收到的TCP数据包.此调用由接口驱动程序(即网络适配器的驱动程序)启动.

accept()只有等待套接字状态从改变TCP_LISTENTCP_ESTABLISHED.并且状态TCP_LISTEN由设置listen().实际状态更改在tcp_rcv_state_process.中执行.

所以这个过程是异步的.呼叫accept()不直接导致呼叫tcp_rcv_state_process