Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!mit-eddie!bloom-beacon!ambar From: ambar@bloom-beacon.UUCP Newsgroups: comp.unix.wizards Subject: Re: Sockets stuck in FIN_WAIT_2 Message-ID: <910@bloom-beacon.MIT.EDU> Date: Sat, 13-Jun-87 18:12:16 EDT Article-I.D.: bloom-be.910 Posted: Sat Jun 13 18:12:16 1987 Date-Received: Sun, 14-Jun-87 03:52:56 EDT References: <1556@aw.sei.cmu.edu> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: ambar@athena.mit.edu (Jean Marie Diaz) Organization: Madhouse International Technologies Lines: 128 Summary: here's a program In article <1556@aw.sei.cmu.edu> pdb@sei.cmu.edu (Patrick Barron) writes: > >If I shutdown sendmail on my Ultrix VAX and there is still a socket out there >bound to the local smtp service in FIN_WAIT_2 (waiting for a FIN from the >remote host), then I'll never be able to restart mail unless I reboot the >machine. Does anyone have a program, or the proper "adb -k" incantations, >to force a stuck FIN_WAIT_2 socket into CLOSED state? fixfin2 was written by our local network wizard, Jeff Schiller. He makes it available via anonymous ftp from bitsy.mit.edu, so posting it isn't a problem. It works on 4.[23]BSD, and Ultrix. However, it assumes that your header files match your kernel. Be careful. (and don't forget to nuke the .signature at the end..) #include #include "/sys/h/types.h" #include "/sys/h/file.h" #include "/sys/h/param.h" #include "/sys/h/socket.h" #include "/sys/h/socketvar.h" #include "/sys/h/mbuf.h" #include "/sys/h/protosw.h" #include "/sys/netinet/in.h" #include "/sys/netinet/in_systm.h" #include "/sys/net/route.h" #include "/sys/netinet/in_pcb.h" #include "/sys/netinet/ip.h" #include "/sys/netinet/tcp.h" #include "/sys/netinet/tcp_fsm.h" #include "/sys/netinet/tcp_timer.h" #include "/sys/netinet/tcp_var.h" #include extern int errno; struct inpcb inpcb; struct tcpcb tcpcb; int kmem; struct nlist nl[] = { #define N_TCB 0 { "_tcb" }, "", }; main () { register int err; register struct inpcb *next, *prev; register int stateoff; struct inpcb *tcbaddr; int testfirst; short fstate; stateoff = 0; nlist("/vmunix", nl); if (nl[0].n_type == 0) { fprintf(stderr, "/vmunix: no namelist\n"); exit (1); } tcbaddr = (struct inpcb *) nl[N_TCB].n_value; kmem = open ("/dev/kmem", O_RDWR, 0644); check_error(kmem, "Opening /dev/kmem", errno); (void) lseek (kmem, (off_t)tcbaddr, 0); check_error((errno != 0) ? -1 : 0, "seeking for tcbaddr", errno); err = read (kmem, (caddr_t)&inpcb, sizeof (struct inpcb)); check_error(err, "reading tcb", errno); if (inpcb.inp_next == (struct inpcb *)tcbaddr) exit (3); prev = tcbaddr; while (inpcb.inp_next != (struct inpcb *)tcbaddr) { next = inpcb.inp_next; (void) lseek (kmem, (off_t)next, 0); check_error((errno != 0) ? -1 : 0, "seeking for next inpcb", errno); err = read(kmem, (char *)&inpcb, sizeof(inpcb)); check_error(err, "reading next inpcb", errno); if (inpcb.inp_prev != prev) { fprintf(stderr,"Bad sample after %x\n", prev); exit (4); } (void) lseek(kmem, (off_t)inpcb.inp_ppcb, 0); check_error((errno != 0) ? -1 : 0, "Seeking tcpcb", errno); err = read (kmem, (char *)&tcpcb, sizeof(tcpcb)); check_error(err, "Reading tcpcb", errno); if (stateoff == 0) { stateoff = (int) &tcpcb.t_state - (int) &tcpcb; } if (tcpcb.t_state == TCPS_FIN_WAIT_2) { testfirst = 1; doitagain: (void) lseek (kmem, (off_t) ((int) inpcb.inp_ppcb + stateoff), 0); check_error ((errno != 0) ? -1 : 0, "seeking to tcp state variable", errno); if (testfirst) { err = read (kmem, (char *)&fstate, sizeof (short)); } else { /* fprintf(stderr, "Would write %d, &tcpcb = %X, stateoff= %d\n", fstate, inpcb.inp_ppcb, stateoff); */ err = write (kmem, (char *)&fstate, sizeof (short)); } check_error (err, testfirst ? "reading tcp state variable" : "Writing tcp state variable", errno); if (testfirst) { if (fstate != TCPS_FIN_WAIT_2) { fprintf(stderr, "Connection changed state!\n"); } else { testfirst = 0; fstate = 0; } goto doitagain; } } prev = next; } (void) close (kmem); exit (0); } check_error(err, msg, code) int err; char *msg; int code; { if (err < 0) { fprintf (stderr, "finfix2: Error: %s\n", msg); errno = code; perror("fixfin2"); exit (1); } return; } AMBAR ARPA: ambar@eddie.mit.edu UUCP: {backbones}!mit-eddie!ambar