Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Apr 2005 14:16:50 +0200 (CEST)
From:      Jan Srzednicki <w@expro.pl>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/80322: TCP socket support broken on a busy port
Message-ID:  <20050425121650.68D6E153CA@miranda.expro.pl>
Resent-Message-ID: <200504251220.j3PCKRr5075682@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         80322
>Category:       kern
>Synopsis:       TCP socket support broken on a busy port
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 25 12:20:26 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Jan Srzednicki
>Release:        FreeBSD 4.10-RELEASE i386
>Organization:
Expro
>Environment:
System: FreeBSD miranda 4.10-RELEASE FreeBSD 4.10-RELEASE #19: Tue Jan 4 12:11:01 CET 2005 


	
>Description:

There appears to be a rather weird problem with TCP sockets implementation.
After a server daemon listening on a very busy unprivileged (>1024) port
dies (I'm not able to repeat that with a low-usage port), the port is
closed as it should, sockstat doesn't show anything listening on it,
everything looks fine. But an attempt to bind to that port with UID != 0
results in failure -- EADDRINUSE. Here is a strace snap from a netcat
process trying to bind to that port (UID!=0):

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EADDRINUSE (Address already in use)

But, when I swich to root everything is fine:

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1)                            = 0

(I can repeat that subsequently, once for root, once for user; it's not
a timeout issue of any kind)

There are no ipfw nor ipf rules on that host. There's no apparent reason
why the 3306 port is treated in a different way, provided that in the
begining the server daemon started succesfully. So, it appears that the
dead server daemon leaves the port in some weird state. Maybe it's some
socket cleaning issue.

I haven't found any way to fix this behaviour except rebooting that
machine. I have checked the CVS tree for RELENG_4, but I haven't found
any relevant changes since 4.10-RELEASE in that area.

>How-To-Repeat:

1. Get a quite busy machine with a very busy port (SQL port is a good
example)
2. Kill the server. Don't let it shutdown cleanly.
3. Try binding to that port first with UID!=0, then with UID==0.
	
>Fix:
	


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050425121650.68D6E153CA>