Linux三次握手源码分析

TCP_STATES

三次握手过程分析【V5.8,正常流程】
1、客户端发起第一次握手,状态调变为TCP_SYN_SENT,发送SYN包

connect->__sys_connect->__sys_connect_file->【sock->ops->connect】tcp_v4_connect
A、状态变化
->tcp_set_state(sk, TCP_SYN_SENT);
B、发送SYN
->tcp_connect->tcp_send_syn_data

2、服务端收到客户端的SYN包,初始化socket,状态从TCP_LISTEN变为TCP_NEW_SYN_RECV,发送第二次握手SYN_ACK包

A、收到连接,初始化socket
accept->__sys_accept4->__sys_accept4_file->【sock->ops->accept】inet_csk_accept

B、收到SYN,改变状态
【tcp_protocol.handler】tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_state_process->
->case TCP_LISTEN:
->[sock->ops->conn_request]tcp_v4_conn_request->tcp_conn_request
->->inet_reqsk_alloc
->->->ireq->ireq_state = TCP_NEW_SYN_RECV;

C、发送SYN_ACK包
->[sock->ops->conn_request]tcp_v4_conn_request->tcp_conn_request【和B路径一样】
->->【af_ops->send_synack】tcp_v4_send_synack
->->->tcp_make_synack
->->->__tcp_v4_send_check

3、客户端收到SYN_ACK包,状态从TCP_SYN_SENT变为TCP_ESTABLISHED,并发送ACK包

A、收到SYN_ACK包
【tcp_protocol.handler】tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_state_process
->case TCP_SYN_SENT:
->tcp_rcv_synsent_state_process->tcp_finish_connect
->->tcp_set_state(sk, TCP_ESTABLISHED);

B、发送ACK包
->tcp_rcv_synsent_state_process->tcp_send_ack->__tcp_send_ack

4、服务端收到ACK包,状态从TCP_NEW_SYN_RECV变为TCP_SYN_RECV【实际上是新建了一个sock】

【tcp_protocol.handler】tcp_v4_rcv->
->if (sk->sk_state == TCP_NEW_SYN_RECV)
->tcp_check_req
->->【inet_csk(sk)->icsk_af_ops->syn_recv_sock】tcp_v4_syn_recv_sock->tcp_create_openreq_child->inet_csk_clone_lock
->->->inet_sk_set_state(newsk, TCP_SYN_RECV);

5、服务端状态从TCP_SYN_RECV变为TCP_ESTABLISHED

【tcp_protocol.handler】tcp_v4_rcv->tcp_v4_do_rcv->tcp_rcv_state_process
->case TCP_SYN_RECV:
->tcp_set_state(sk, TCP_ESTABLISHED);

Leave a Reply

Your email address will not be published. Required fields are marked *

*