net: diag: Support destroying TCP sockets.
This implements SOCK_DESTROY for TCP sockets. It causes all blocking calls on the socket to fail fast with ECONNABORTED and causes a protocol close of the socket. It informs the other end of the connection by sending a RST, i.e., initiating a TCP ABORT as per RFC 793. ECONNABORTED was chosen for consistency with FreeBSD. Signed-off-by: Lorenzo Colitti <lorenzo@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
6eb5d2e08f
commit
c1e64e298b
@@ -3080,6 +3080,38 @@ void tcp_done(struct sock *sk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_done);
|
||||
|
||||
int tcp_abort(struct sock *sk, int err)
|
||||
{
|
||||
if (!sk_fullsock(sk)) {
|
||||
sock_gen_put(sk);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* Don't race with userspace socket closes such as tcp_close. */
|
||||
lock_sock(sk);
|
||||
|
||||
/* Don't race with BH socket closes such as inet_csk_listen_stop. */
|
||||
local_bh_disable();
|
||||
bh_lock_sock(sk);
|
||||
|
||||
if (!sock_flag(sk, SOCK_DEAD)) {
|
||||
sk->sk_err = err;
|
||||
/* This barrier is coupled with smp_rmb() in tcp_poll() */
|
||||
smp_wmb();
|
||||
sk->sk_error_report(sk);
|
||||
if (tcp_need_reset(sk->sk_state))
|
||||
tcp_send_active_reset(sk, GFP_ATOMIC);
|
||||
tcp_done(sk);
|
||||
}
|
||||
|
||||
bh_unlock_sock(sk);
|
||||
local_bh_enable();
|
||||
release_sock(sk);
|
||||
sock_put(sk);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_abort);
|
||||
|
||||
extern struct tcp_congestion_ops tcp_reno;
|
||||
|
||||
static __initdata unsigned long thash_entries;
|
||||
|
Reference in New Issue
Block a user