From nobody@FreeBSD.org  Wed Mar 28 00:53:04 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 072BB106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Mar 2012 00:53:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id CAA818FC19
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Mar 2012 00:53:03 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q2S0r3Hd070060
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 28 Mar 2012 00:53:03 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q2S0r3LR070049;
	Wed, 28 Mar 2012 00:53:03 GMT
	(envelope-from nobody)
Message-Id: <201203280053.q2S0r3LR070049@red.freebsd.org>
Date: Wed, 28 Mar 2012 00:53:03 GMT
From: Sean Bruno <sbruno@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: bind() incorrectly interprets SO_REUSEADDR option as also implying SO_REUSEPORT on FreeBSD
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         166458
>Category:       kern
>Synopsis:       [libc] bind(2) incorrectly interprets SO_REUSEADDR option as also implying SO_REUSEPORT on FreeBSD
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          analyzed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 28 01:00:25 UTC 2012
>Closed-Date:    
>Last-Modified:  Wed Mar 28 09:10:10 UTC 2012
>Originator:     Sean Bruno
>Release:        9.0
>Organization:
Yahoo! Inc
>Environment:
FreeBSD xxxxxxxxxxxxx 9.0-RELEASE FreeBSD 9.0-RELEASE #3: Tue Dec 27 14:14:29 PST 2011     root@build9x64.pcbsd.org:/usr/obj/builds/amd64/pcbsd-build90/fbsd-source/9.0/sys/GENERIC  amd64
>Description:
<attempting to duplicate internal bug and loop in submitter>

<There> ... seems to be a bug in FreeBSD when specifying port number 0 in the 
socket address passed to the bind system call in order to let the kernel
select a free port number.

The semantics of SO_REUSEADDR is inconsistently implemented on FreeBSD.

FreeBSD 4 jail environment (on a FreeBSD 4 host):

dev-tegge:~$ ./bindbug 
serversock addr is 10.76.250.174:40328
dup bind: Address already in use
This error was expected, tried to bind to used addr/port
dup2 bind: Address already in use
This error was expected, tried to bind to used port without SO_REUSEPORT
autosock addr is 10.76.250.174:40328
bug triggered, port number conflict on sockets without SO_REUSEPORT
listen succeded after implicitly overlapping port bind

FreeBSD 6 host enironment:

tegge-store1:~:$ ./bindbug 
serversock addr is 127.0.0.1:59073
dup bind: Address already in use
This error was expected, tried to bind to used addr/port
BUG: binding duplicate socket to server port succeeded
dup2sock addr is 0.0.0.0:59073
overlapping explicit bind to same port number succeeded without SO_REUSEPORT
listen succeeded after explicitly overlapping port bind
autosock addr is 0.0.0.0:59073
bug triggered, port number conflict on sockets without SO_REUSEPORT
listen succeded after implicitly overlapping port bind

RHEL4 host environment:

[tegge@dell-bl1s3 ~]$ time ./bindbug 
serversock addr is 127.0.0.1:43270
dup bind: Address already in use
This error was expected, tried to bind to used addr/port
dup2 bind: Address already in use
This error was expected, tried to bind to used port without SO_REUSEPORT
bug not triggered after 16777216 iterations

real    1m12.753s
user    0m4.695s
sys     1m8.037s
>How-To-Repeat:
Use test code that is attached, compile and run on a fbsd box vs a linux box.

test case is at http://people.freebsd.org/~sbruno/bind_test.c
>Fix:


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: glebius 
State-Changed-When: Wed Mar 28 09:02:08 UTC 2012 
State-Changed-Why:  
This PR needs discussion. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=166458 

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Sean Bruno <sbruno@FreeBSD.org>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: kern/166458: bind() incorrectly interprets SO_REUSEADDR option
 as also implying SO_REUSEPORT on FreeBSD
Date: Wed, 28 Mar 2012 13:01:40 +0400

   Sean,
 
 On Wed, Mar 28, 2012 at 12:53:03AM +0000, Sean Bruno wrote:
 S> <There> ... seems to be a bug in FreeBSD when specifying port number 0 in the 
 S> socket address passed to the bind system call in order to let the kernel
 S> select a free port number.
 S> 
 S> The semantics of SO_REUSEADDR is inconsistently implemented on FreeBSD.
 S> 
 S> FreeBSD 4 jail environment (on a FreeBSD 4 host):
 S> 
 S> dev-tegge:~$ ./bindbug 
 S> serversock addr is 10.76.250.174:40328
 S> dup bind: Address already in use
 S> This error was expected, tried to bind to used addr/port
 S> dup2 bind: Address already in use
 S> This error was expected, tried to bind to used port without SO_REUSEPORT
 S> autosock addr is 10.76.250.174:40328
 S> bug triggered, port number conflict on sockets without SO_REUSEPORT
 S> listen succeded after implicitly overlapping port bind
 S> 
 S> FreeBSD 6 host enironment:
 S> 
 S> tegge-store1:~:$ ./bindbug 
 S> serversock addr is 127.0.0.1:59073
 S> dup bind: Address already in use
 S> This error was expected, tried to bind to used addr/port
 S> BUG: binding duplicate socket to server port succeeded
 S> dup2sock addr is 0.0.0.0:59073
 S> overlapping explicit bind to same port number succeeded without SO_REUSEPORT
 S> listen succeeded after explicitly overlapping port bind
 S> autosock addr is 0.0.0.0:59073
 S> bug triggered, port number conflict on sockets without SO_REUSEPORT
 S> listen succeded after implicitly overlapping port bind
 S> 
 S> RHEL4 host environment:
 S> 
 S> [tegge@dell-bl1s3 ~]$ time ./bindbug 
 S> serversock addr is 127.0.0.1:43270
 S> dup bind: Address already in use
 S> This error was expected, tried to bind to used addr/port
 S> dup2 bind: Address already in use
 S> This error was expected, tried to bind to used port without SO_REUSEPORT
 S> bug not triggered after 16777216 iterations
 
 I don't see a bug in FreeBSD 6 behavior.
 
 To speak about bug we need to have a clear description of correct behavior.
 Unfortunately the SO_REUSEADDR option is tersely documented in our manuals,
 as well as in POSIX. Thus I will advocate to the TCP/IP Book by Stevens
 as documentation, quoting it, page 720:
 
 SO_REUSEADDR	Allows the process to bind to a port number that is already in use, but
 		the IP address being bound (including the wildcard) must not already
 		be bound to that same port.
 		For example, if an attached interface has the IP address 140.252.1.29
 		then one socket can be bound to 140.252.1.29, port 5555; another
 		socket can be bound to 127.0.0.1, port 5555; and another socket can be
 		bound to the wildcard IP address, port 5555. The call to bind for the
 		second and third cases must be preceeded by a call to setsockopt,
 		setting the SO_REUSEADDR option.
 
 http://books.google.ru/books?id=ESM3CWY5xRYC&pg=PA720&hl=ru&source=gbs_toc_r&cad=4#v=onepage&q&f=false
 
 -- 
 Totus tuus, Glebius.
>Unformatted:
