检查socket状态从而做出不同处理(这里是状态是TCP_LISTEN,直接调用函数tcp_v4_do_rcv,接着是调用tcp_rcv_state_process) tcp_rcv_state_process源代码的重要部分如下 复制inttcp_rcv_state_process(structsock *sk,structsk_buff *skb){ ...switch(sk->sk_state) {//SYN_RECV状态的处理caseTCP_CLOSE:gotodis...
在tcp_v4_do_rcv 中判断当前 socket 是 listen 状态后,首先会到 tcp_v4_hnd_req 去查看半连接队列。服务器第一次响应 SYN 的时候,半连接队列里必然是空空如也,所以相当于什么也没干就返回了。 //file:net/ipv4/tcp_ipv4.c static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb...
在tcp_v4_do_rcv 中判断当前 socket 是 listen 状态后,首先会到 tcp_v4_hnd_req 去查看半连接队列。服务器第一次响应 SYN 的时候,半连接队列里必然是空空如也,所以相当于什么也没干就返回了。 //file:net/ipv4/tcp_ipv4.cstaticstructsock*tcp_v4_hnd_req(structsock*sk,structsk_buff*skb) {// 查找 ...
tcp_v4_do_rcv() 具体过程与收到SYN报文相同,不同点在于syn_table中已经插入了有关该连接的条目,tcp_v4_hnd_req()会返回一个新的sock: nsk,然后会调用tcp_child_process()来进行处理。在tcp_v4_hnd_req()中会创建新的sock,下面详细看下这个函数。
在tcp_v4_do_rcv 中判断当前 socket 是 listen 状态后,首先会到 tcp_v4_hnd_req 去查看半连接队列。服务器第一次响应 SYN 的时候,半连接队列里必然是空空如也,所以相当于什么也没干就返回了。 //file:net/ipv4/tcp_ipv4.c staticstruct sock *tcp_v4_hnd_r...
tcp_v4_do_rcv()是TCP模块接收的入口函数,客户端发起请求的对象是listen fd,所以sk->sk_state == TCP_LISTEN,调用tcp_v4_hnd_req()来检查是否处于半连接,只要三次握手没有完成,这样的连接就称为半连接,具体而言就是收到了SYN,但还没有收到ACK的连接,所以对于这个查找函数,如果是SYN报文,则会返回listen的...
服务器响应第三次握手的 ack 时同样会进入到 tcp_v4_do_rcv 不过由于这已经是第三次握手了,半连接队列里会存在上次第一次握手时留下的半连接信息。所以 tcp_v4_hnd_req 的执行逻辑会不太一样。 inet_csk_search_req 负责在半连接队列里进行查找,找到以后返回一个半连接 request_sock 对象。然后...
->tcp_v4_do_rcv ->tcp_rcv_established, 在tcp_rcv_establisheed函数中处理TCP_ESTABLISHED状态的包 ,并根据pred_flags预测字段来选择着采用快路径或慢路径。 二、首部预测字段-pred_flags 预测字段存储在struct tcp_sock中,pred_flag为0表示关闭首部预测使用慢速路径,非0表示开启快速路径的前提,如果开启会对该变...
->tcp_v4_do_rcv ->tcp_rcv_established, 在tcp_rcv_establisheed函数中处理TCP_ESTABLISHED状态的包,并根据pred_flags预测字段来选择着采用快路径或慢路径。 二、首部预测字段-pred_flags 预测字段存储在struct tcp_sock中,pred_flag为0表示关闭首部预测使用慢速路径,非0表示开启快速路径的前提,如果开启会对该变量...
在该层,我们会做一些完整性检查,如果发现问题就丢包。如果是tcp,则调用tcp_v4_do_rcv。 然后sk->sk_state == TCP_ESTABLISHED,调用tcp_rcv_builted,调用 tcp_data_queue 方法将消息放入队列。然后使用 tcp_ofo_queue 方法将消息插入接收到 Queued 。