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>
