why do you have a lot of connections in 'fin-wait-2 state? do you have windows clients? how many is 'a lot' if you leave the console on and so NOT have X11 runjing you may see mesages on the console. (possibly install DDB so that it doesn't fully reboot, but stops in the debugger) I have a patch to fix the fin-wait-2 problem.. I have included it. (It was last tested in 3.2) What it does is allow probing of the client so that the client will send an RST if the session is really closed, and if no response for a while, it will time out. You need to enable it in the config file too julian On Mon, 25 Oct 1999, Min Wei (Exchange) wrote: > Hi. I have a situation where FreeBSD 3.2 reboots once a while (less than > every > 12 hours). My net environment is, FreeBSD 3.2 sits behind a Cisco > LocalDirector. > The FreeBSD machine is a Dell dual-proc with 512M RAM. I recompiled the > kernel > with SMP options and set MAXMEM to 512M (since by default FreeBSD thinks it > only > has 64M). I have apache installed as the Web server. > > However during our Web stress run, FreeBSD reboots periodically. I wonder > if it's because a lot of TCP connections at FIN_WAIT_2 state, which causes > the kernel crash. The load on the machine is not high (CPU is about 90% idle > from > top). I could only guess Cisco LD might not be configured properly which > causes > a lot of open connections. > > Anyone sees this kind of problem before? Any advice would be greatly > appreciated. > > Thanks, > --min > > > To Unsubscribe: send mail to [EMAIL PROTECTED] > with "unsubscribe freebsd-net" in the body of the message >
Index: netinet/tcp_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.84 diff -c -r1.84 netinet/tcp_input.c *** netinet/tcp_input.c 1999/02/06 00:47:45 1.84 --- netinet/tcp_input.c 1999/04/08 00:45:54 *************** *** 88,93 **** --- 88,99 ---- SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, &tcp_delack_enabled, 0, ""); + #ifdef TCP_USOFT_BUG + int tcp_fin_retry_enable = 0; + SYSCTL_INT(_net_inet_tcp, OID_AUTO, fin_retry, CTLFLAG_RW, + &tcp_fin_retry_enable, 0, ""); + #endif /* TCP_USOFT_BUG */ + u_long tcp_now; struct inpcbhead tcb; struct inpcbinfo tcbinfo; *************** *** 1495,1504 **** --- 1501,1540 ---- * specification, but if we don't get a FIN * we'll hang forever. */ + #ifdef TCP_USOFT_BUG + /* + * Wait longer and longer for the other + * end to respond with something. + * Eventually they should either + * RST or FIN. If they are still alive + * and actually want us to remain in this + * state, they will keep ACKing and + * we'll stay here indefinitly. + * If they don't respond at all, we will + * revert to FIN_WAIT_1 and eventually + * time out as it would. How to cope with + * the case of broken clients who are still + * alive but never FIN is arguable. Certainly + * if we've closed our end entirely, we + * might as well just close the connection. + */ + if (tcp_fin_retry_enable) { + tp->t_timer[TCPT_2MSL] = + ((tp->t_idle > TCPTV_MSL) ? + tp->t_idle : TCPTV_MSL); + } else { + if (so->so_state & SS_CANTRCVMORE) { + soisdisconnected(so); + tp->t_timer[TCPT_2MSL] + = tcp_maxidle; + } + } + #else /* TCP_USOFT_BUG */ if (so->so_state & SS_CANTRCVMORE) { soisdisconnected(so); tp->t_timer[TCPT_2MSL] = tcp_maxidle; } + #endif /* TCP_USOFT_BUG */ tp->t_state = TCPS_FIN_WAIT_2; } break; Index: netinet/tcp_timer.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_timer.c,v retrieving revision 1.28 diff -c -r1.28 netinet/tcp_timer.c *** netinet/tcp_timer.c 1998/04/24 09:25:35 1.28 --- netinet/tcp_timer.c 1999/04/08 00:45:54 *************** *** 213,222 **** * control block. Otherwise, check again in a bit. */ case TCPT_2MSL: ! if (tp->t_state != TCPS_TIME_WAIT && ! tp->t_idle <= tcp_maxidle) ! tp->t_timer[TCPT_2MSL] = tcp_keepintvl; ! else tp = tcp_close(tp); break; --- 213,246 ---- * control block. Otherwise, check again in a bit. */ case TCPT_2MSL: ! if (tp->t_state != TCPS_TIME_WAIT ! && tp->t_idle <= tcp_maxidle) { ! #ifdef TCP_USOFT_BUG ! if (tcp_fin_retry_enable ! && (tp->t_state == TCPS_FIN_WAIT_2)) { ! /* ! * We've timed out waiting for the other end ! * to finish up. Quite possibly it's a Win9x ! * machine. ! * If so we could be waiting here forever. ! * Pretend we were never ack'd and reset ! * ourselves to a retry of FIN_WAIT_1. If ! * it's still alive, this should at least ! * elicit a RST from it which ! * will let us know we can shut down. ! * If it has only done a half close, ! * it'll ACK our retries so we'll ! * keep waiting in FIN_WAIT_2. ! * If it's dead, we'll time out. ! */ ! tp->t_state = TCPS_FIN_WAIT_1; ! tp->t_flags &= ~TF_SENTFIN; ! tp->snd_una = (tp->snd_nxt -= 1); ! tcp_output(tp); ! } else ! #endif ! tp->t_timer[TCPT_2MSL] = tcp_keepintvl; ! } else tp = tcp_close(tp); break; Index: netinet/tcp_var.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_var.h,v retrieving revision 1.50 diff -c -r1.50 netinet/tcp_var.h *** netinet/tcp_var.h 1999/02/16 10:49:52 1.50 --- netinet/tcp_var.h 1999/04/08 00:45:54 *************** *** 334,339 **** --- 334,340 ---- extern int tcp_mssdflt; /* XXX */ extern u_long tcp_now; /* for RFC 1323 timestamps */ extern int tcp_delack_enabled; + extern int tcp_fin_retry_enable; void tcp_canceltimers __P((struct tcpcb *)); struct tcpcb *