Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sctp: cancel a blocking accept when shutdown a listen socket

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>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
cda91d5b 2e3ed20c

+10 -4
+10 -4
net/sctp/socket.c
··· 4834 4834 return sctp_connect(sock->sk, uaddr, addr_len, flags); 4835 4835 } 4836 4836 4837 - /* FIXME: Write comments. */ 4837 + /* Only called when shutdown a listening SCTP socket. */ 4838 4838 static int sctp_disconnect(struct sock *sk, int flags) 4839 4839 { 4840 - return -EOPNOTSUPP; /* STUB */ 4840 + if (!sctp_style(sk, TCP)) 4841 + return -EOPNOTSUPP; 4842 + 4843 + sk->sk_shutdown |= RCV_SHUTDOWN; 4844 + return 0; 4841 4845 } 4842 4846 4843 4847 /* 4.1.4 accept() - TCP Style Syntax ··· 4870 4866 goto out; 4871 4867 } 4872 4868 4873 - if (!sctp_sstate(sk, LISTENING)) { 4869 + if (!sctp_sstate(sk, LISTENING) || 4870 + (sk->sk_shutdown & RCV_SHUTDOWN)) { 4874 4871 error = -EINVAL; 4875 4872 goto out; 4876 4873 } ··· 9398 9393 } 9399 9394 9400 9395 err = -EINVAL; 9401 - if (!sctp_sstate(sk, LISTENING)) 9396 + if (!sctp_sstate(sk, LISTENING) || 9397 + (sk->sk_shutdown & RCV_SHUTDOWN)) 9402 9398 break; 9403 9399 9404 9400 err = 0;