Thread (8 messages) 8 messages, 2 authors, 2026-07-16

Re: [RFC PATCH net-next v2 1/2] tcp: Add net.ipv4.tcp_purge_receive_queue sysctl

flat view

From: Leon Hwang <hidden>
Date: 2026-07-15 15:26:16
Also in: linux-doc, linux-kselftest, lkml

On 2026/7/15 23:15, Eric Dumazet wrote:
On Wed, Jul 15, 2026 at 4:54 PM Leon Hwang [off-list ref] wrote:
[...]
quoted
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 61045a8886e4..4f1027173e95 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4853,6 +4853,7 @@ void tcp_done_with_error(struct sock *sk, int err)
 /* When we get a reset we do this. */
 void tcp_reset(struct sock *sk, struct sk_buff *skb)
 {
+       const struct net *net = sock_net(sk);
        int err;

        trace_tcp_receive_reset(sk);
@@ -4869,6 +4870,27 @@ void tcp_reset(struct sock *sk, struct sk_buff *skb)
                err = ECONNREFUSED;
                break;
        case TCP_CLOSE_WAIT:
+               /* RFC9293 3.10.7.4. Other States
+                *   Second, check the RST bit:
+                *     CLOSE-WAIT STATE
+                *
+                * If the RST bit is set, then any outstanding RECEIVEs and
+                * SEND should receive "reset" responses.  All segment queues
+                * should be flushed.  Users should also receive an unsolicited
+                * general "connection reset" signal.  Enter the CLOSED state,
+                * delete the TCB, and return.
+                *
+                * If net.ipv4.tcp_purge_receive_queue is enabled,
+                * sk_receive_queue will be flushed too.
+                */
+               if (unlikely(READ_ONCE(net->ipv4.sysctl_tcp_purge_receive_queue))) {
+                       struct tcp_sock *tp = tcp_sk(sk);
+
+                       skb_queue_purge(&sk->sk_receive_queue);
+                       WRITE_ONCE(tp->copied_seq, tp->rcv_nxt);
+                       WRITE_ONCE(tp->urg_data, 0);
+                       sk_set_peek_off(sk, -1);
+               }
                err = EPIPE;
                break;
        case TCP_CLOSE:
--
2.55.0
My thoughts are:

out_of_order_queue has been forgotten. skbs could be there and still
'block devmem'

WRITE_ONCE(tp->copied_seq, tp->rcv_nxt) is certainly wrong, because
read() will return 0, instead of -1 (errno = EPIPE or ECONNRESET)
So the application will not know a RST was received :/

I think that BSD and linux implementations have historically retained
acknowledged,
buffered receive data upon RST to allow applications to drain data
already ACKed prior to the reset.

Adding a narrow sysctl specifically for CLOSE_WAIT creates
inconsistent behavior across TCP states.

Got it. I won't pursue this sysctl approach in the future. Thanks for
the review.

Leon
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help