2010-01-30 15:57:28
本过程分析的基础建立在本地TCP已经调用了listen进入了监听状态,至于数据包如何进入tcp这里暂且不表。
tcp数据包的入口函数tcp_v4_rcv,该函数在检验数据包的正确性后,找到对应的INET SOCKET,对于SYN包,
找到的是对应的Listen状态的sock。后面的处理无论是数据包进入backlog,还是prequeue,最后都会进入
tcp_v4_do_rcv函数进行处理。
现在进入tcp_v4_hnd_req函数,该函数处理listen sock的连接请求。
很显然,由于是第一次连接,所以该sock没有此次请求的信息,所以该函数返回参数中sk。
然后在tcp_v4_do_rcv中进入tcp_rcv_state_process。
tcp_rcv_state_process函数是个状态机。对该函数我们分开来说,对于此次连接进入下面的case语句中。
icsk_af_ops是有连接类型的SOCKET的特点操作符,在tcp连接时对于的是
所以对应的函数是tcp_v4_conn_request
linux中的做法是监听方对于新建的连接在3步握手完成前不建立对于的INET SOCKET,而是建立一个request_sock结构。该结构保存了
连接双方的相关信息,相互的结构关系如下图
另外tcp中对synflood的应当机制也是在这里实现的,如果系统设置了syn_cookies的话。对于没有启用syn_cookies时,这该函数中会对应建立
一个request_sock结构,并加入到hash表中;否则,该函数并不建立这样一个结构,而是运用syn_cookies机制产生一个isn,然后发送了syn/ack
包后就直接返回,当下次client发送ACK包过来时,在tcp_v4_hnd_req函数中调用cookie_v4_check,该函数在验证通过后建立INET socket结构。
主动连接方收到SYNACK包后,也进入tcp_rcv_state_process,不过它有自己对应的INET SOCKET,并且处于SYN_SENT状态
tcp_rcv_synsent_state_process函数处理在SYN_SENT状态的SOCKET。
接下来继续第3步,也就是上面的主动连接方发出的ACK到对方