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 <redacted>
---
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