From fae6f1ab823ff29d6165da7eb2dcae9534b1428c Mon Sep 17 00:00:00 2001 From: rwatson Date: Wed, 11 Mar 2009 00:29:22 +0000 Subject: Add INP_INHASHLIST flag for inpcb->inp_flags to indicate whether or not the inpcb is currenty on various hash lookup lists, rather than using (lport != 0) to detect this. This means that the full 4-tuple of a connection can be retained after close, which should lead to more sensible netstat output in the window between TCP close and socket close. MFC after: 2 weeks --- sys/netinet/in_pcb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sys/netinet/in_pcb.c') diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 3014bc3..6703c88 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 1982, 1986, 1991, 1993, 1995 * The Regents of the University of California. - * Copyright (c) 2007-2008 Robert N. M. Watson + * Copyright (c) 2007-2009 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1032,7 +1032,7 @@ in_pcbdrop(struct inpcb *inp) INP_WLOCK_ASSERT(inp); inp->inp_vflag |= INP_DROPPED; - if (inp->inp_lport) { + if (inp->inp_flags & INP_INHASHLIST) { struct inpcbport *phd = inp->inp_phd; LIST_REMOVE(inp, inp_hash); @@ -1041,7 +1041,7 @@ in_pcbdrop(struct inpcb *inp) LIST_REMOVE(phd, phd_hash); free(phd, M_PCB); } - inp->inp_lport = 0; + inp->inp_flags &= ~INP_INHASHLIST; } } @@ -1421,6 +1421,8 @@ in_pcbinshash(struct inpcb *inp) INP_INFO_WLOCK_ASSERT(pcbinfo); INP_WLOCK_ASSERT(inp); + KASSERT((inp->inp_flags & INP_INHASHLIST) == 0, + ("in_pcbinshash: INP_INHASHLIST")); #ifdef INET6 if (inp->inp_vflag & INP_IPV6) @@ -1457,6 +1459,7 @@ in_pcbinshash(struct inpcb *inp) inp->inp_phd = phd; LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); LIST_INSERT_HEAD(pcbhash, inp, inp_hash); + inp->inp_flags |= INP_INHASHLIST; return (0); } @@ -1475,6 +1478,8 @@ in_pcbrehash(struct inpcb *inp) INP_INFO_WLOCK_ASSERT(pcbinfo); INP_WLOCK_ASSERT(inp); + KASSERT(inp->inp_flags & INP_INHASHLIST, + ("in_pcbrehash: !INP_INHASHLIST")); #ifdef INET6 if (inp->inp_vflag & INP_IPV6) @@ -1502,7 +1507,7 @@ in_pcbremlists(struct inpcb *inp) INP_WLOCK_ASSERT(inp); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; - if (inp->inp_lport) { + if (inp->inp_flags & INP_INHASHLIST) { struct inpcbport *phd = inp->inp_phd; LIST_REMOVE(inp, inp_hash); @@ -1511,6 +1516,7 @@ in_pcbremlists(struct inpcb *inp) LIST_REMOVE(phd, phd_hash); free(phd, M_PCB); } + inp->inp_flags &= ~INP_INHASHLIST; } LIST_REMOVE(inp, inp_list); pcbinfo->ipi_count--; -- cgit v1.1