summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2003-11-01 07:30:08 +0000
committersilby <silby@FreeBSD.org>2003-11-01 07:30:08 +0000
commit34fc0661fd7ffdd72ebd690082b4490b2a198754 (patch)
tree243678db3e842414f07bf976a824feb772294945 /sys/netinet/in_pcb.c
parent2cedc070de4852174973d34b8317ff273d31ca54 (diff)
downloadFreeBSD-src-34fc0661fd7ffdd72ebd690082b4490b2a198754.zip
FreeBSD-src-34fc0661fd7ffdd72ebd690082b4490b2a198754.tar.gz
- Add a new function tcp_twrecycleable, which tells us if the ISN which
we will generate for a given ip/port tuple has advanced far enough for the time_wait socket in question to be safely recycled. - Have in_pcblookup_local use tcp_twrecycleable to determine if time_Wait sockets which are hogging local ports can be safely freed. This change preserves proper TIME_WAIT behavior under normal circumstances while allowing for safe and fast recycling whenever ephemeral port space is scarce.
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index a1490c4..ec51ad4 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -950,6 +950,7 @@ in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay)
* First see if this local port is in use by looking on the
* port hash list.
*/
+ retrylookup:
porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport,
pcbinfo->porthashmask)];
LIST_FOREACH(phd, porthash, phd_hash) {
@@ -967,6 +968,17 @@ in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay)
if ((inp->inp_vflag & INP_IPV4) == 0)
continue;
#endif
+ /*
+ * Clean out old time_wait sockets if they
+ * are clogging up needed local ports.
+ */
+ if ((inp->inp_vflag & INP_TIMEWAIT) != 0) {
+ if (tcp_twrecycleable((struct tcptw *)inp->inp_ppcb)) {
+ tcp_twclose((struct tcptw *)inp->inp_ppcb, 0);
+ match = NULL;
+ goto retrylookup;
+ }
+ }
if (inp->inp_faddr.s_addr != INADDR_ANY)
wildcard++;
if (inp->inp_laddr.s_addr != INADDR_ANY) {
OpenPOWER on IntegriCloud