在tcp_data_queue_ofo中根据序号,查找到合适位置,合并或者添加到rbtree中。 同时设置dsack和sack,准备ack给发送方。 //http://abcdxyzk.github.io/blog/2015/04/01/kernel-net-data-queue/staticvoidtcp_data_queue_ofo(structsock *sk,structsk_buff *skb) {structtcp_sock *tp =tcp_sk(sk);structrb_n...
在上面的 tcp_data_queue 函数里,如果收到的报文的序列号是我们预期的,也就是有序的话: 会判断该报文有没有 FIN 标志,如果有的话就会调用 tcp_fin 函数,这个函数负责将 FIN_WAIT_2 状态转换为 TIME_WAIT。 接着还会看乱序队列有没有数据,如果有的话会调用 tcp_ofo_queue 函数,这个函数负责检查乱序队列中...
由于收到S2-S3报文后,期待的序号成为了S3,这样,out_of_order队列里的唯一报文S3-S4报文将会移出本队列而插入到receive队列中(这件事由tcp_ofo_queue方法完成)。 5、终于有用户进程开始读取socket了。做过应用端编程的同学都知道,先要在进程里分配一块内存,接着调用read或者recv等方法,把内存的首地址和内存长度传...
如果是,那么直接将该报文存入队列(sk_receive_queue),然后继续判断直到序列号不是期望的。这样在保证了数据顺序的同时也提升了性能,因为不需要客户端重传之前发送的数据报文了。 struct tcp_sock { struct rb_root out_of_order_queue; }; 将乱序数据包添加到乱序恢复队列中的函数是tcp_data_queue_ofo。而从乱序...
在上面的 tcp_data_queue 函数里,如果收到的报文的序列号是我们预期的,也就是有序的话: 会判断该报文有没有 FIN 标志,如果有的话就会调用 tcp_fin 函数,这个函数负责将 FIN_WAIT_2 状态转换为 TIME_WAIT。 接着还会看乱序队列有没有数据,如果有的话会调用 tcp_ofo_queue 函数,这个函数负责检查乱序队列中...
在上面的 tcp_data_queue 函数里,如果收到的报文的序列号是我们预期的,也就是有序的话: 会判断该报文有没有 FIN 标志,如果有的话就会调用 tcp_fin 函数,这个函数负责将 FIN_WAIT_2 状态转换为 TIME_WAIT。 接着还会看乱序队列有没有数据,如果有的话会调用 tcp_ofo_queue 函数,这个函数负责检查乱序队列中...
4、每次向receive队列插入报文时都会检查out_of_order队列。由于收到S2-S3报文后,期待的序号成为了S3,这样,out_of_order队列里的唯一报文S3-S4报文将会移出本队列而插入到receive队列中(这件事由tcp_ofo_queue方法完成)。 5、终于有用户进程开始读取socket了。做过应用端编程的同学都知道,先要在进程里分配一块内...
在上面的 tcp_data_queue 函数里,如果收到的报文的序列号是我们预期的,也就是有序的话: 会判断该报文有没有 FIN 标志,如果有的话就会调用 tcp_fin 函数,这个函数负责将 FIN_WAIT_2 状态转换为 TIME_WAIT。 接着还会看乱序队列有没有数据,如果有的话会调用 tcp_ofo_queue 函数,这个函数负责检查乱序队列中...
1 我们在tcp_data_queue中接收到了一个ofo的段。 2 当我们调用tcp_prune_queue中协议栈的内存不够用了并且开始丢包。 3 我们通过调用tcp_urg_check发现是一个urgent段。而处理erg段是在tcp_urg函数中。 4 我们的发送窗口已经为0了。然后在tcp_select_window判断,然后打开slow path。
然后sk->sk_state == TCP_ESTABLISHED,调用tcp_rcv_builted,调用 tcp_data_queue 方法将消息放入队列。然后使用 tcp_ofo_queue 方法将消息插入接收到 Queued 。 应用层 应用程序调用读取或者 recv 的时候,该调用被映射到 /net/socket.c 中的sys_recv系统调用,然后调用 sock_recvmsg 函数。