diff options
author | silby <silby@FreeBSD.org> | 2003-11-01 07:30:08 +0000 |
---|---|---|
committer | silby <silby@FreeBSD.org> | 2003-11-01 07:30:08 +0000 |
commit | 34fc0661fd7ffdd72ebd690082b4490b2a198754 (patch) | |
tree | 243678db3e842414f07bf976a824feb772294945 /sys/netinet/in_pcb.c | |
parent | 2cedc070de4852174973d34b8317ff273d31ca54 (diff) | |
download | FreeBSD-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.c | 12 |
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) { |