tcp: rstreason: introduce SK_RST_REASON_TCP_DISCONNECT_WITH_DATA for active reset
authorJason Xing <kernelxing@tencent.com>
Fri, 2 Aug 2024 10:21:11 +0000 (18:21 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Aug 2024 09:24:46 +0000 (10:24 +0100)
When user tries to disconnect a socket and there are more data written
into tcp write queue, we should tell users about this reset reason.

Signed-off-by: Jason Xing <kernelxing@tencent.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/rstreason.h
net/ipv4/tcp.c

index 9c0c46d..69cb2e5 100644 (file)
@@ -22,6 +22,7 @@
        FN(TCP_ABORT_ON_MEMORY)         \
        FN(TCP_STATE)                   \
        FN(TCP_KEEPALIVE_TIMEOUT)       \
+       FN(TCP_DISCONNECT_WITH_DATA)    \
        FN(MPTCP_RST_EUNSPEC)           \
        FN(MPTCP_RST_EMPTCP)            \
        FN(MPTCP_RST_ERESOURCE)         \
@@ -115,6 +116,13 @@ enum sk_rst_reason {
         * keepalive timeout, we have to reset the connection
         */
        SK_RST_REASON_TCP_KEEPALIVE_TIMEOUT,
+       /**
+        * @SK_RST_REASON_TCP_DISCONNECT_WITH_DATA: disconnect when write
+        * queue is not empty
+        * It means user has written data into the write queue when doing
+        * disconnecting, so we have to send an RST.
+        */
+       SK_RST_REASON_TCP_DISCONNECT_WITH_DATA,
 
        /* Copy from include/uapi/linux/mptcp.h.
         * These reset fields will not be changed since they adhere to
index 24777e4..8514257 100644 (file)
@@ -3033,7 +3033,8 @@ int tcp_disconnect(struct sock *sk, int flags)
                /* The last check adjusts for discrepancy of Linux wrt. RFC
                 * states
                 */
-               tcp_send_active_reset(sk, gfp_any(), SK_RST_REASON_NOT_SPECIFIED);
+               tcp_send_active_reset(sk, gfp_any(),
+                                     SK_RST_REASON_TCP_DISCONNECT_WITH_DATA);
                WRITE_ONCE(sk->sk_err, ECONNRESET);
        } else if (old_state == TCP_SYN_SENT)
                WRITE_ONCE(sk->sk_err, ECONNRESET);