net/rds: RDS-TCP: Always create a new rds_sock for an incoming connection.
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Tue, 5 May 2015 19:20:51 +0000 (15:20 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 9 May 2015 20:03:27 +0000 (16:03 -0400)
commitf711a6ae062caeee46067b2f2f12ffda319ae73c
tree518c5041d8e081998cae22c4b43a32338f148bf7
parente16e888b525503be05b3aea64190e8b3bdef44d0
net/rds: RDS-TCP: Always create a new rds_sock for an incoming connection.

When running RDS over TCP, the active (client) side connects to the
listening ("passive") side at the RDS_TCP_PORT.  After the connection
is established, if the client side reboots (potentially without even
sending a FIN) the server still has a TCP socket in the esablished
state.  If the server-side now gets a new SYN comes from the client
with a different client port, TCP will create a new socket-pair, but
the RDS layer will incorrectly pull up the old rds_connection (which
is still associated with the stale t_sock and RDS socket state).

This patch corrects this behavior by having rds_tcp_accept_one()
always create a new connection for an incoming TCP SYN.
The rds and tcp state associated with the old socket-pair is cleaned
up via the rds_tcp_state_change() callback which would typically be
invoked in most cases when the client-TCP sends a FIN on TCP restart,
triggering a transition to CLOSE_WAIT state. In the rarer event of client
death without a FIN, TCP_KEEPALIVE probes on the socket will detect
the stale socket, and the TCP transition to CLOSE state will trigger
the RDS state cleanup.

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rds/connection.c
net/rds/tcp_connect.c
net/rds/tcp_listen.c