Message ID | ee35ac9d519708ea0ba16f8288e42f215a0dbbcf.1719856129.git.lucien.xin@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | cda91d5b911a5a168a1c6e6917afda43b0e458c8 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] sctp: cancel a blocking accept when shutdown a listen socket | expand |
Hello: This patch was applied to netdev/net-next.git (main) by David S. Miller <davem@davemloft.net>: On Mon, 1 Jul 2024 13:48:49 -0400 you wrote: > As David Laight noticed, > > "In a multithreaded program it is reasonable to have a thread blocked in > accept(). With TCP a subsequent shutdown(listen_fd, SHUT_RDWR) causes > the accept to fail. But nothing happens for SCTP." > > sctp_disconnect() is eventually called when shutdown a listen socket, > but nothing is done in this function. This patch sets RCV_SHUTDOWN > flag in sk->sk_shutdown there, and adds the check (sk->sk_shutdown & > RCV_SHUTDOWN) to break and return in sctp_accept(). > > [...] Here is the summary with links: - [net-next] sctp: cancel a blocking accept when shutdown a listen socket https://git.kernel.org/netdev/net-next/c/cda91d5b911a You are awesome, thank you!
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c67679a41044..da299455cd10 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4834,10 +4834,14 @@ int sctp_inet_connect(struct socket *sock, struct sockaddr *uaddr, return sctp_connect(sock->sk, uaddr, addr_len, flags); } -/* FIXME: Write comments. */ +/* Only called when shutdown a listening SCTP socket. */ static int sctp_disconnect(struct sock *sk, int flags) { - return -EOPNOTSUPP; /* STUB */ + if (!sctp_style(sk, TCP)) + return -EOPNOTSUPP; + + sk->sk_shutdown |= RCV_SHUTDOWN; + return 0; } /* 4.1.4 accept() - TCP Style Syntax @@ -4866,7 +4870,8 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern) goto out; } - if (!sctp_sstate(sk, LISTENING)) { + if (!sctp_sstate(sk, LISTENING) || + (sk->sk_shutdown & RCV_SHUTDOWN)) { error = -EINVAL; goto out; } @@ -9392,7 +9397,8 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) } err = -EINVAL; - if (!sctp_sstate(sk, LISTENING)) + if (!sctp_sstate(sk, LISTENING) || + (sk->sk_shutdown & RCV_SHUTDOWN)) break; err = 0;
As David Laight noticed, "In a multithreaded program it is reasonable to have a thread blocked in accept(). With TCP a subsequent shutdown(listen_fd, SHUT_RDWR) causes the accept to fail. But nothing happens for SCTP." sctp_disconnect() is eventually called when shutdown a listen socket, but nothing is done in this function. This patch sets RCV_SHUTDOWN flag in sk->sk_shutdown there, and adds the check (sk->sk_shutdown & RCV_SHUTDOWN) to break and return in sctp_accept(). Note that shutdown() is only supported on TCP-style SCTP socket. Reported-by: David Laight <David.Laight@aculab.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> --- net/sctp/socket.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)