tcp. do not accept packets beyond window
判断tcp seq 是否在正常范围内的时候;
只要报文在
[RCV.WUP, RCV.NXT + RCV.WND]这个区间内,就认为“sequence 合法”RCV.WUP:最后一次 window update 使用的接收点
旧内核代码;
static inline bool tcp_sequence(const struct tcp_sock *tp, u32 seq, u32 end_seq) { return !before(end_seq, tp->rcv_wup) && !after(seq, tp->rcv_nxt + tcp_receive_window(tp)); }
新的代码:
/* Check segment sequence number for validity. * * Segment controls are considered valid, if the segment * fits to the window after truncation to the window. Acceptability * of data (and SYN, FIN, of course) is checked separately. * See tcp_data_queue(), for example. * * Also, controls (RST is main one) are accepted using RCV.WUP instead * of RCV.NXT. Peer still did not advance his SND.UNA when we * delayed ACK, so that hisSND.UNA<=ourRCV.WUP. * (borrowed from freebsd) */ static enum skb_drop_reason tcp_sequence(const struct sock *sk, u32 seq, u32 end_seq) { const struct tcp_sock *tp = tcp_sk(sk); /*整个 segment 完全落在窗口左侧 典型场景:重传延迟;ACK 延迟导致对端误判;reordered + delayed ACK*/ if (before(end_seq, tp->rcv_wup)) return SKB_DROP_REASON_TCP_OLD_SEQUENCE; if (after(end_seq, tp->rcv_nxt + tcp_receive_window(tp))) { if (after(seq, tp->rcv_nxt + tcp_receive_window(tp))) return SKB_DROP_REASON_TCP_INVALID_SEQUENCE;//整个 segment 完全在窗口右边之外 /* Only accept this packet if receive queue is empty. seq <= rcv_nxt + rcv_wnd end_seq > rcv_nxt + rcv_wnd; segment 的头在窗口内,但尾巴越界 */ if (skb_queue_len(&sk->sk_receive_queue)) return SKB_DROP_REASON_TCP_INVALID_END_SEQUENCE; //不为空直接丢弃 /*为什么要“接收队列为空”才允许? 这是为了解决一个非常真实的 TCP 边界场景: 应用层消费慢;RCV.WND 很小 对端发了一个 稍微大一点的 segment segment 头部是我们想要的数据 但尾部越界;如果:接收队列是空的 说明:没有 out-of-order 数据;没有乱序复杂性 那么:允许这个 segment 进入后续逻辑 在 tcp_data_queue() 中做 truncation*/ } /**减少“窗口边界抖动”导致的误丢包 特别是在:小窗口、高 RTT、delayed ACK、应用读慢的情况下。 避免对“可部分接受的 segment”过早判死刑*/ return SKB_NOT_DROPPED_YET; }
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子

浙公网安备 33010602011771号