= TCP_SKB_CB(skb)->seq && after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { //经过分析,不符合该条件 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); tcp_reset(sk); return 1; } } fallthrough; case TCP_ESTABLISHED: tcp_data_queue(sk, skb); //如果进入了...
如果是第一次握手,就是TCP_LISTEN状态,进入: acceptable = icsk->icsk_af_ops->conn_request(sk, skb) >= 0; 此时conn_request为tcp_v4_conn_request(),在这个方法中进行第一次握手的处理。如果是第三次握手,此时tcp状态应为:TCP_SYN_RECV。 服务端在SYN RECVED的状态下,要在缓存中纪录客户端syn包中...
tp->rx_opt.saw_tstamp =0;//处理SYN_SENT状态下接收到的TCP段queued = tcp_rcv_synsent_state_process(sk, skb, th);if(queued >=0)returnqueued;/* Do step6 onward by hand. *///处理完第二次握手后,还需要处理带外数据tcp_urg(sk, skb, th); __kfree_skb(skb);//检测是否有数据需要发送...
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); TCP_SKB_CB(skb)->when = 0; TCP_SKB_CB(skb)->flags = skb->nh.iph->tos; TCP_SKB_CB(skb)->sacked = 0; ... ... ... } 如果想要了解cb中的参数是如何被取出的,可以查看net/ipv4/tcp_output.c中的tcp_transmit_skb函数。这个函数...
if(TCP_SKB_CB(skb)->seq == tp->rcv_nxt) tcp_reset(sk); else tcp_send_challenge_ack(sk); gotodiscard; } } 收到RST包,第一步会通过tcp_sequence先看下这个seq是否合法,其实主要是看下这个seq是否在合法接收窗口范围内。如果不在范围内,这个RST包就会被丢弃。
为了可以正确统计这些数据,内核给每个 tcp 包(tcp_skb_cb)添加了sacked字段标记该数据包当前的状态。 __u8 sacked; /* State flags for SACK. */ #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ #define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ ...
为了可以正确统计这些数据,内核给每个 tcp 包(tcp_skb_cb)添加了sacked字段标记该数据包当前的状态。 __u8 sacked; /* State flags for SACK. */ #define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */ #define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */ #define TCPCB_LOST...
为了可以正确统计这些数据,内核给每个 tcp 包(tcp_skb_cb)添加了sacked字段标记该数据包当前的状态。 __u8 sacked; /* State flags for SACK. */#define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */#define TCPCB_SACKED_RETRANS 0x02 /* SKB retransmitted */#define TCPCB_LOST 0x...
...struct tcp_skb_cb { __u32 seq; Starting sequence number __u32 end_seq; SEQ + FIN + SYN + datalen __u8 tcp_flags; tcp头部标志,位于第13个字节tcp[13]) ... }; 然后,tcp_push调用了__tcp_push_pending_frames(sk, mss_now, nonagle);函数发送数据: void ...
tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); 1. 2. 3. 4. 5. 6. 最终,函数tcp_store_ts_recent使用选项结构rx_opt中保存的TSval值更新ts_recent时间戳。 static void tcp_store_ts_recent(struct tcp_sock *tp) { tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; ...