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:
Lorenzo Colitti
2015-12-16 12:30:05 +09:00
committed by David S. Miller
parent 6eb5d2e08f
commit c1e64e298b
6 changed files with 68 additions and 0 deletions

View File

@@ -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;