Date: Wed, 25 Aug 2004 18:32:47 +0300 From: Peter Pentchev <roam@ringlet.net> To: net@FreeBSD.org Subject: [CFR] Fix sockstat's handling of closed connections Message-ID: <20040825153247.GI1009@straylight.m.ringlet.net>
next in thread | raw e-mail | index | archive | help
--pE2VAHO2njSJCslu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi, I first came across this a couple of months ago, but today I finally took the time to look into it. Basically, if a program has recently closed a TCP connection or three and they are currently in CLOSED or TIME_WAIT state, sockstat(1) will report them as active connected sockets and link them to completely bogus programs and file descriptors. Here's a demonstration, taken immediately after a completed fetchmail poll of three POP3 servers: [roam@straylight ~/fbsd/r/src/usr.bin/sockstat]> sockstat -4c USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS www httpd 5408 3 tcp4 217.75.134.254:58889 217.75.134.1:110 roam ssh 939 3 tcp4 192.168.11.36:55794 192.168.9.48:22 www httpd 604 3 tcp4 217.75.134.254:58889 217.75.134.1:110 nobody dictd 596 26 tcp4 217.75.134.254:58889 217.75.134.1:110 qmails tcpserver 548 0 tcp4 217.75.134.254:58889 217.75.134.1:110 [roam@straylight ~/fbsd/r/src/usr.bin/sockstat]> ./sockstat -4c USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS roam ssh 939 3 tcp4 192.168.11.36:55794 192.168.9.48:22 [roam@straylight ~/fbsd/r/src/usr.bin/sockstat]> netstat -n | egrep '^tcp.*= 110' tcp4 0 0 217.75.134.254.49857 195.24.32.2.110 TIME_WAIT tcp4 0 0 217.75.134.254.54159 217.75.128.9.110 TIME_WAIT tcp4 0 0 217.75.134.254.58889 217.75.134.1.110 TIME_WAIT [roam@straylight ~/fbsd/r/src/usr.bin/sockstat]> The first 'sockstat' run was the "real" sockstat(1) from FreeBSD 5.3-BETA1 as of today; as you can see, it reports the three TIME_WAIT sockets as very much active and attributes them to totally unrelated processes. I must admit this gave me quite a scare the first time I saw this: what in the name of $DEITY are all those servers doing opening *outgoing* connections, or, alternatively and even worse, why are they listening on high ports? Luckily, the fix is simple, or at least so it seems to me. It turns out that those connections have a xt_socket->xso_so set to NULL, and the false positive comes from sockstat's matching them to a similarly NULL xf_data members of 'kern.files'. What do people think about the following patch? I could commit it if nobody has any objections, but being a ports/doc committer, I would need an explicit approval to do that :) G'luck, Peter Index: src/usr.bin/sockstat/sockstat.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/usr.bin/sockstat/sockstat.c,v retrieving revision 1.9 diff -u -r1.9 sockstat.c --- src/usr.bin/sockstat/sockstat.c 19 Jul 2003 06:23:56 -0000 1.9 +++ src/usr.bin/sockstat/sockstat.c 25 Aug 2004 15:14:24 -0000 @@ -494,6 +494,8 @@ "LOCAL ADDRESS", "FOREIGN ADDRESS"); setpassent(1); for (xf =3D xfiles, n =3D 0; n < nxfiles; ++n, ++xf) { + if (xf->xf_data =3D=3D NULL) + continue; hash =3D (int)((uintptr_t)xf->xf_data % HASHSIZE); for (s =3D sockhash[hash]; s !=3D NULL; s =3D s->next) if ((void *)s->socket =3D=3D xf->xf_data) --=20 Peter Pentchev roam@ringlet.net roam@cnsys.bg roam@FreeBSD.org PGP key: http://people.FreeBSD.org/~roam/roam.key.asc Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553 =2Esiht ekil ti gnidaer eb d'uoy ,werbeH ni erew ecnetnes siht fI --pE2VAHO2njSJCslu Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (FreeBSD) iD8DBQFBLLEf7Ri2jRYZRVMRArJ/AJ9jrkruiudcS2hY6tuOTyAJ3j7+qQCfcubV UDh4h8p4RjUeZrWQ3Cf4c0c= =UYw9 -----END PGP SIGNATURE----- --pE2VAHO2njSJCslu--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040825153247.GI1009>