Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!bloom-beacon!wesommer From: wesommer@bloom-beacon.UUCP Newsgroups: comp.unix.wizards Subject: Re: Sockets stuck in FIN_WAIT_2 Message-ID: <886@bloom-beacon.MIT.EDU> Date: Wed, 10-Jun-87 23:18:56 EDT Article-I.D.: bloom-be.886 Posted: Wed Jun 10 23:18:56 1987 Date-Received: Sat, 13-Jun-87 07:01:41 EDT References: <1556@aw.sei.cmu.edu> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: wesommer@athena.mit.edu (William Sommerfeld) Organization: Massachusetts Institute of Technology Lines: 149 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? Our local network wizard, Jeff Schiller, wrote one once. It works on 4.2 and 4.3 and Ultrix (several flavors); I'm posting it here because its so short. Just compile it with cc -O -o fixfin2 fixfin2.c and run it as root. Please, no flames about the style or lack of comments (the author will ignore the flames anyway). Bill Sommerfeld wesommer@athena.mit.edu #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # fixfin2.c # This archive created: Wed Jun 10 23:05:01 1987 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'fixfin2.c'" '(3047 characters)' if test -f 'fixfin2.c' then echo shar: "will not over-write existing file 'fixfin2.c'" else sed 's/^ X//' << \SHAR_EOF > 'fixfin2.c' X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include Xextern int errno; Xstruct inpcb inpcb; Xstruct tcpcb tcpcb; Xint kmem; Xstruct nlist nl[] = { X#define N_TCB 0 X { "_tcb" }, X "", X}; Xmain () X{ X register int err; X register struct inpcb *next, *prev; X register int stateoff; X struct inpcb *tcbaddr; X int testfirst; X short fstate; X stateoff = 0; X nlist("/vmunix", nl); X if (nl[0].n_type == 0) { X fprintf(stderr, "/vmunix: no namelist\n"); X exit (1); X } X tcbaddr = (struct inpcb *) nl[N_TCB].n_value; X kmem = open ("/dev/kmem", O_RDWR, 0644); X check_error(kmem, "Opening /dev/kmem", errno); X (void) lseek (kmem, (off_t)tcbaddr, 0); X check_error((errno != 0) ? -1 : 0, "seeking for tcbaddr", errno); X err = read (kmem, (caddr_t)&inpcb, sizeof (struct inpcb)); X check_error(err, "reading tcb", errno); X if (inpcb.inp_next == (struct inpcb *)tcbaddr) exit (3); X prev = tcbaddr; X while (inpcb.inp_next != (struct inpcb *)tcbaddr) { X next = inpcb.inp_next; X (void) lseek (kmem, (off_t)next, 0); X check_error((errno != 0) ? -1 : 0, "seeking for next inpcb", errno); X err = read(kmem, (char *)&inpcb, sizeof(inpcb)); X check_error(err, "reading next inpcb", errno); X if (inpcb.inp_prev != prev) { X fprintf(stderr,"Bad sample after %x\n", prev); X exit (4); X } X (void) lseek(kmem, (off_t)inpcb.inp_ppcb, 0); X check_error((errno != 0) ? -1 : 0, "Seeking tcpcb", errno); X err = read (kmem, (char *)&tcpcb, sizeof(tcpcb)); X check_error(err, "Reading tcpcb", errno); X if (stateoff == 0) { X stateoff = (int) &tcpcb.t_state - (int) &tcpcb; X } X if (tcpcb.t_state == TCPS_FIN_WAIT_2) { X testfirst = 1; X doitagain: X (void) lseek (kmem, (off_t) ((int) inpcb.inp_ppcb + stateoff), 0); X check_error ((errno != 0) ? -1 : 0, "seeking to tcp state variable", errno); X if (testfirst) { X err = read (kmem, (char *)&fstate, sizeof (short)); X } else { X/* fprintf(stderr, "Would write %d, &tcpcb = %X, stateoff= %d\n", X fstate, inpcb.inp_ppcb, stateoff); */ X err = write (kmem, (char *)&fstate, sizeof (short)); X } X check_error (err, testfirst ? "reading tcp state variable" : X "Writing tcp state variable", errno); X if (testfirst) { X if (fstate != TCPS_FIN_WAIT_2) { X fprintf(stderr, "Connection changed state!\n"); X } else { X testfirst = 0; X fstate = 0; X } X goto doitagain; X } X } X prev = next; X } X (void) close (kmem); X exit (0); X} X Xcheck_error(err, msg, code) Xint err; Xchar *msg; Xint code; X{ X if (err < 0) { X fprintf (stderr, "finfix2: Error: %s\n", msg); X errno = code; X perror("fixfin2"); X exit (1); X } X return; X} SHAR_EOF if test 3047 -ne "`wc -c < 'fixfin2.c'`" then echo shar: "error transmitting 'fixfin2.c'" '(should have been 3047 characters)' fi fi exit 0 # End of shell archive