During reformulation of tcp_usr_detach(), the call to initiate TCP

disconnect for fully connected sockets was dropped, meaning that if
the socket was closed while the connection was alive, it would be
leaked.  Structure tcp_usr_detach() so that there are two clear
parts: initiating disconnect, and reclaiming state, and reintroduce
the tcp_disconnect() call in the first part.

MFC after:	3 months
This commit is contained in:
Robert Watson 2006-04-02 16:42:51 +00:00
parent 7d5bf96f77
commit 953b5606df
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157410

View File

@ -161,10 +161,24 @@ tcp_usr_detach(struct socket *so)
INP_LOCK(inp);
KASSERT(inp->inp_socket != NULL,
("tcp_usr_detach: inp_socket == NULL"));
TCPDEBUG1();
tp = intotcpcb(inp);
/*
* First, if we still have full TCP state, and we're not dropped,
* initiate a disconnect.
*/
if (!(inp->inp_vflag & INP_TIMEWAIT) &&
!(inp->inp_vflag & INP_DROPPED)) {
tp = intotcpcb(inp);
tcp_disconnect(tp);
}
/*
* Second, release any protocol state that we can reasonably release.
* Note that the call to tcp_disconnect() may actually have changed
* the TCP state, so we have to re-evaluate INP_TIMEWAIT and
* INP_DROPPED.
*/
if (inp->inp_vflag & INP_TIMEWAIT) {
if (inp->inp_vflag & INP_DROPPED) {
/*
@ -225,10 +239,6 @@ tcp_usr_detach(struct socket *so)
}
#endif
} else {
/*
* Connection state still required, as is socket, so
* mark socket for TCP to free later.
*/
SOCK_LOCK(so);
so->so_state |= SS_PROTOREF;
SOCK_UNLOCK(so);
@ -1450,7 +1460,8 @@ tcp_disconnect(tp)
soisdisconnecting(so);
sbflush(&so->so_rcv);
tcp_usrclosed(tp);
tcp_output(tp);
if (!(inp->inp_vflag & INP_DROPPED))
tcp_output(tp);
}
}