未使用SYN Cookies时,TCP三次握手接收方子套接字创建时机?
一、SYN报文处理流程的理解
当客户端发起三次握手时,会向服务器发送SYN报文。服务器端TCP层的入口是tcp_v4_rcv函数,接收到报文后会查找监听套接字:
- 若找到目标套接字,其状态应为TCP_LISTEN;
- 通过
tcp_v4_do_rcv()辅助函数进入tcp_rcv_state_process(),随后通过tcp_v4_conn_request()进入tcp_conn_request()。
在未使用SYN Cookies的场景下(want_cookie为false):
- 创建请求套接字(request socket),将其
ireq_state设为TCP_NEW_SYN_RECV; - 该请求套接字关联监听套接字,并保存收到的SYN报文;
- 最后将request_sock加入哈希表(逻辑上的“队列”),并向客户端发送SYN-ACK报文。
目前我未发现SYN报文处理阶段有创建子套接字的操作。
二、ACK报文处理阶段的疑问
客户端发送ACK报文后,服务器端同样会执行套接字查找流程:
- 我观察到此时查到的仍是监听套接字,但代码中存在一个判断分支:检查
sk->sk_state == TCP_NEW_SYN_RECV; - 我仅在SYN报文处理阶段找到将request_sock的
ireq_state设为TCP_NEW_SYN_RECV的代码,未发现监听套接字状态被设为该值的逻辑。
这里的核心疑问:
__inet_lookup_skb函数返回的是SYN阶段创建的request_sock(封装在sock结构体中),还是仍然返回监听套接字?- 如果返回的是监听套接字,它真的会处于TCP_NEW_SYN_RECV状态吗?
我倾向于认为这个判断分支就是处理ACK的关键路径,因为此处调用的tcp_check_req会通过克隆监听套接字来创建子套接字。
如果该分支未执行,流程会再次进入tcp_v4_do_rcv:
- 这里会检查SYN Cookie,若存在则克隆监听套接字(
tcp_get_cookie_sock()的克隆方式与tcp_check_req中的一致); - 但在无SYN Cookies的场景下,最终会进入
tcp_rcv_state_process(),此时监听套接字状态为TCP_LISTEN,函数会直接返回,无法完成子套接字的创建。
三、我的困惑
整个流程中,我显然忽略了某个关键环节,否则ACK报文无法触发子套接字的创建。请问有什么线索或思路吗?
内容的提问来源于stack exchange,提问作者Vadim Samokhin
相关产品推荐
相关产品推荐

