Since commit 3d501dd326fb ("tcp: do not accept ACK of bytes we never sent"), tcp_ack() bounds the acceptable old ACK window by min(tp->max_window, tp->bytes_acked). When sk->sk_state == TCP_SYN_RECV, tp->bytes_acked is always 0, so any segment with before(ack, prior_snd_una) immediately returns -SKB_DROP_REASON_TCP_TOO_OLD_ACK and never reaches the old_ack label (which returns 0). Therefore, tcp_ack() can only return 0 in closing states (where old ACKs are accepted), and can never return 0 in TCP_SYN_RECV. Simplify the tcp_ack() return value check in tcp_rcv_state_process() to only check for negative return values and remove the unreachable !reason branch. Signed-off-by: Eric Dumazet --- net/ipv4/tcp_input.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 92bc60716f33d81e9ce90d9de2e5d989ba71c8a3..892ff256e235272a8483a11949cc98b319dd7cc9 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -7233,19 +7233,14 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) FLAG_UPDATE_TS_RECENT | FLAG_NO_CHALLENGE_ACK); - if ((int)reason <= 0) { - if (sk->sk_state == TCP_SYN_RECV) { + /* accept old ack (reason == 0) during closing */ + if ((int)reason < 0) { + reason = -reason; + if (sk->sk_state == TCP_SYN_RECV) /* send one RST */ - if (!reason) - return SKB_DROP_REASON_TCP_OLD_ACK; - return -reason; - } - /* accept old ack during closing */ - if ((int)reason < 0) { - tcp_send_challenge_ack(sk, false); - reason = -reason; - goto discard; - } + return reason; + tcp_send_challenge_ack(sk, false); + goto discard; } SKB_DR_SET(reason, NOT_SPECIFIED); switch (sk->sk_state) { -- 2.55.0.1082.g2b9226bbc0-goog