TCP listen 过程分析

TCP listen 系统调用过程
__sys__listen --> inet_listen -->inet_csk_listen_start-->inet_hash-->__inet_hash
1.在 inet_listen函数中,检查sock状态是否为 TCPF_CLOSE或者TCPF_LISTEN状态,只有这两个状态的sock才能listen。如果已经处于listen状态,则只修改backlog,否则需要执行inet_csk_listen_start函数将sock添加到listen hash table中
2.inet_csk_listen_start函数会改变sock状态,改为TCP_LISTEN状态。
3.inet_hash函数将sock 添加到listen hash table中,备查。如果设置了sk_reuseport标志位,则会调用inet_reuseport_add_sock函数处理reuseport
具体细节可以沿着这个调用栈看代码。

TCP listen 收到 syn包后的执行的动作

tcp_v4_rcv --> tcp_v4_do_rcv --> tcp_rcv_state_process --> tcp_v4_conn_request --> tcp_conn_request -->tcp_v4_send_synack

1.tcp_v4_rcv 函数在listen hash table中找到对应的 sock。调用 tcp_v4_do_rcv函数
2.tcp_v4_do_rcv 函数判断有没有开启tcp cookie。在收到syn 包的过程中 cookie开启不开启没有影响
3.tcp_rcv_state_process函数根据sock状态及 来包状态,决定调用tcp_connect_request函数。
4.tcp_conn_request 函数
a.如果没有开启tcp cookie和fastopen的情况下,会创建一个request_sock的sock,并将sk_state设置为 TCP_NEW_SYN_RECV状态。
b.调用inet_csk_reqsk_queue_hash_add将 req sock 添加到 establish hash table中,并发送 synack。

TCP listen 收到 ack执行动作。
tcp_v4_rcv --> tcp_check_req --> tcp_v4_syn_recv_sock-->tcp_create_openreq_child-->inet_csk_clone_lock
1.tcp_check_req 函数检查ack包是否有问题,并将tcp_v4_syn_recv_sock创建的sock 通过inet_csk_reqsk_queue_add放到 accept队列中。
2.tcp_v4_syn_recv_sock 函数创建child sock。
3. inet_csk_cloen_lock函数会设置child sock 状态为TCP_SYN_RECV
4.最后调用 tcp_child_process,对ack 进行处理,当sock正在被调用时 把包放到backlog里面,否则唤醒listen的进程。
我分析的过程中 忽略了 tcp cookie 和 fastopen。不过主线流程情况以后,这些附加功能可以慢慢通过看代码了解。

喜欢 3

这篇文章还没有评论

发表评论