summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_usrreq.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-04-02 16:42:51 +0000
committerrwatson <rwatson@FreeBSD.org>2006-04-02 16:42:51 +0000
commitcce79b77fe6cf41d33a3e78b9094492e51e42513 (patch)
treece7ccb5a61bc221536d7be8afa6dd74597aee1f4 /sys/netinet/tcp_usrreq.c
parentb93d36449d6fde60fa737733dba9c068e761cfa4 (diff)
downloadFreeBSD-src-cce79b77fe6cf41d33a3e78b9094492e51e42513.zip
FreeBSD-src-cce79b77fe6cf41d33a3e78b9094492e51e42513.tar.gz
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
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r--sys/netinet/tcp_usrreq.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 29c0da8..daec08e 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -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);
}
}
OpenPOWER on IntegriCloud