标签:== 定时 state init 一点 tran nat oid tom
假定客户端执行主动打开,并且已经收到服务器发送的第二次握手包SYN+ACK,在经过一系列处理之后,客户端发送第三次握手包ACK到服务器;其流程比较简单,主要是分配skb,初始化ack包并发送;需要注意的一点是,标记纯ACK包竟然用了skb->truesize=2,好吧;
1 void tcp_send_ack(struct sock *sk) 2 { 3 struct sk_buff *buff; 4 5 /* If we have been reset, we may not send again. */ 6 7 /* 已经是CLOSE状态 */ 8 if (sk->sk_state == TCP_CLOSE) 9 return; 10 11 /* 拥塞控制处理 */ 12 tcp_ca_event(sk, CA_EVENT_NON_DELAYED_ACK); 13 14 /* We are not putting this on the write queue, so 15 * tcp_transmit_skb() will set the ownership to this 16 * sock. 17 */ 18 19 /* 分配skb,失败需要启用延迟ack定时器 */ 20 buff = alloc_skb(MAX_TCP_HEADER, 21 sk_gfp_mask(sk, GFP_ATOMIC | __GFP_NOWARN)); 22 if (unlikely(!buff)) { 23 inet_csk_schedule_ack(sk); 24 inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN; 25 inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 26 TCP_DELACK_MAX, TCP_RTO_MAX); 27 return; 28 } 29 30 /* Reserve space for headers and prepare control bits. */ 31 32 /* 预留头部空间,准备控制信息 */ 33 skb_reserve(buff, MAX_TCP_HEADER); 34 tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK); 35 36 /* We do not want pure acks influencing TCP Small Queues or fq/pacing 37 * too much. 38 * SKB_TRUESIZE(max(1 .. 66, MAX_TCP_HEADER)) is unfortunately ~784 39 */ 40 /* 标记纯ack,做法是将skb->truesize设置为2 */ 41 skb_set_tcp_pure_ack(buff); 42 43 /* Send it off, this clears delayed acks for us. */ 44 /* 记录时间戳,发送skb */ 45 skb_mstamp_get(&buff->skb_mstamp); 46 tcp_transmit_skb(sk, buff, 0, (__force gfp_t)0); 47 }
标签:== 定时 state init 一点 tran nat oid tom
原文地址:https://www.cnblogs.com/wanpengcoder/p/11750700.html