summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timewait.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-08-02 16:18:05 +0000
committerrwatson <rwatson@FreeBSD.org>2006-08-02 16:18:05 +0000
commit6b1ac9e903103d45d09ca423857dfbfa987d11d7 (patch)
treedf26127afc16f3a9d63b6725fbd2323b53fa1e3e /sys/netinet/tcp_timewait.c
parent70c20770c028d13d688eb1e7b4e45395a06624d5 (diff)
downloadFreeBSD-src-6b1ac9e903103d45d09ca423857dfbfa987d11d7.zip
FreeBSD-src-6b1ac9e903103d45d09ca423857dfbfa987d11d7.tar.gz
Move soisdisconnected() in tcp_discardcb() to one of its calling contexts,
tcp_twstart(), but not to the other, tcp_detach(), as the socket is already being torn down and therefore there are no listeners. This avoids a panic if kqueue state is registered on the socket at close(), and eliminates to XXX comments. There is one case remaining in which tcp_discardcb() reaches up to the socket layer as part of the TCP host cache, which would be good to avoid. Reported by: Goran Gajic <ggajic at afrodita dot rcub dot bg dot ac dot yu>
Diffstat (limited to 'sys/netinet/tcp_timewait.c')
-rw-r--r--sys/netinet/tcp_timewait.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 64574cf..2a95f7c 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -693,12 +693,6 @@ tcp_discardcb(struct tcpcb *tp)
int isipv6 = (inp->inp_vflag & INP_IPV6) != 0;
#endif /* INET6 */
- /*
- * XXXRW: This is all very well and good, but actually, we might be
- * discarding the tcpcb after the socket is gone, so we can't do
- * this:
- KASSERT(so != NULL, ("tcp_discardcb: so == NULL"));
- */
INP_LOCK_ASSERT(inp);
/*
@@ -731,6 +725,9 @@ tcp_discardcb(struct tcpcb *tp)
* are satisfied. This gives us better new start value
* for the congestion avoidance for new connections.
* ssthresh is only set if packet loss occured on a session.
+ *
+ * XXXRW: 'so' may be NULL here, and/or socket buffer may be
+ * being torn down. Ideally this code would not use 'so'.
*/
ssthresh = tp->snd_ssthresh;
if (ssthresh != 0 && ssthresh < so->so_snd.sb_hiwat / 2) {
@@ -778,12 +775,6 @@ tcp_discardcb(struct tcpcb *tp)
inp->inp_ppcb = NULL;
tp->t_inpcb = NULL;
uma_zfree(tcpcb_zone, tp);
-
- /*
- * XXXRW: This seems a bit unclean.
- */
- if (so != NULL)
- soisdisconnected(so);
}
/*
@@ -1757,9 +1748,13 @@ tcp_twstart(struct tcpcb *tp)
* First, discard tcpcb state, which includes stopping its timers and
* freeing it. tcp_discardcb() used to also release the inpcb, but
* that work is now done in the caller.
+ *
+ * Note: soisdisconnected() call used to be made in tcp_discardcb(),
+ * and might not be needed here any longer.
*/
tcp_discardcb(tp);
so = inp->inp_socket;
+ soisdisconnected(so);
SOCK_LOCK(so);
tw->tw_cred = crhold(so->so_cred);
tw->tw_so_options = so->so_options;
OpenPOWER on IntegriCloud