rds: tcp: Set linger when rejecting an incoming conn in rds_tcp_accept_one
Each time we get an incoming SYN to the RDS_TCP_PORT, the TCP
layer accepts the connection and then the rds_tcp_accept_one()
callback is invoked to process the incoming connection.
rds_tcp_accept_one() may reject the incoming syn for a number of
reasons, e.g., commit 1a0e100fb2
("RDS: TCP: Force every connection
to be initiated by numerically smaller IP address"), or because
we are getting spammed by a malicious node that is triggering
a flood of connection attempts to RDS_TCP_PORT. If the incoming
syn is rejected, no data would have been sent on the TCP socket,
and we do not need to be in TIME_WAIT state, so we set linger on
the TCP socket before closing, thereby closing the socket efficiently
with a RST.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Tested-by: Imanti Mendez <imanti.mendez@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
00354de577
commit
10beea7d74
@ -112,6 +112,17 @@ struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rds_tcp_set_linger(struct socket *sock)
|
||||
{
|
||||
struct linger no_linger = {
|
||||
.l_onoff = 1,
|
||||
.l_linger = 0,
|
||||
};
|
||||
|
||||
kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
|
||||
(char *)&no_linger, sizeof(no_linger));
|
||||
}
|
||||
|
||||
int rds_tcp_accept_one(struct socket *sock)
|
||||
{
|
||||
struct socket *new_sock = NULL;
|
||||
@ -183,7 +194,13 @@ int rds_tcp_accept_one(struct socket *sock)
|
||||
ret = 0;
|
||||
goto out;
|
||||
rst_nsk:
|
||||
/* reset the newly returned accept sock and bail */
|
||||
/* reset the newly returned accept sock and bail.
|
||||
* It is safe to set linger on new_sock because the RDS connection
|
||||
* has not been brought up on new_sock, so no RDS-level data could
|
||||
* be pending on it. By setting linger, we achieve the side-effect
|
||||
* of avoiding TIME_WAIT state on new_sock.
|
||||
*/
|
||||
rds_tcp_set_linger(new_sock);
|
||||
kernel_sock_shutdown(new_sock, SHUT_RDWR);
|
||||
ret = 0;
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user