summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
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