From: Tobias S. Josefowitz <hidden> Date: 2012-08-01 11:36:50
Hey all,
I recently noticed that binding UDP port 0 with SO_REUSEADDR yields
unexpected results for me - the kernel occasionally gives out UDP
ports used by other processes, if they were bound with SO_REUSEADDR,
too.
I did some digging, it seems that
f24d43c07e208372aa3d3bff419afbf43ba87698 introduced this behaviour.
I'm not at all sure if this could/should be called a bug, but I need
to say, it was severly unexpected at my side, and that probably goes
for others, too.
Just bringing this to your attention, I have no suggestions on it whatsoever.
Best,
Tobi
From: Eric Dumazet <hidden> Date: 2012-08-01 19:03:00
On Wed, 2012-08-01 at 13:36 +0200, Tobias S. Josefowitz wrote:
Hey all,
I recently noticed that binding UDP port 0 with SO_REUSEADDR yields
unexpected results for me - the kernel occasionally gives out UDP
ports used by other processes, if they were bound with SO_REUSEADDR,
too.
I did some digging, it seems that
f24d43c07e208372aa3d3bff419afbf43ba87698 introduced this behaviour.
I'm not at all sure if this could/should be called a bug, but I need
to say, it was severly unexpected at my side, and that probably goes
for others, too.
Just bringing this to your attention, I have no suggestions on it whatsoever.
And why are you using SO_REUSEADDR on UDP unicast sockets ?
I mean, this is exactly saying " By using this REUSEADDR, I am allowing
this port being used by another process, even from another user"
From: Tobias S. Josefowitz <hidden> Date: 2012-08-01 19:38:54
On Wed, Aug 1, 2012 at 9:02 PM, Eric Dumazet [off-list ref] wrote:
And why are you using SO_REUSEADDR on UDP unicast sockets ?
Simple. This happens in a "scripting" language. The wrapper code
assumes that it is better to set SO_REUSEADDR than not (which might be
argued, but backwards-compat can be nice) and at the time the code was
written the author must have assumed that even if the 'user' aka
programmer wants to bind to port 0, SO_REUSEADDR doesn't hurt, because
port 0 implicitly meant "please, a free one".
I mean, this is exactly saying " By using this REUSEADDR, I am allowing
this port being used by another process, even from another user"
I know. Still, while binding port 0 means "give me any port", I'm
quite sure most people would assume they get a free one. And maybe,
for whatever reasons, you want to share your random port later and
need SO_REUSEADDR because of that. A usecase where someone wants a
randomly chosen free or used port does not come to my mind, though.
Of course, I'm not relying on the kernel to revert back, I adapted the
wrapper code I mentioned above. I still felt like mentioning that it
was kind of unexpected, that's all.
Best,
Tobi
From: Tobias S. Josefowitz <hidden> Date: 2012-08-02 16:33:44
Hi again,
I need to say, after looking at "my" socket(7),
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
I think the surprise-factor of the bind-0-behaviour even increased for
me. Is there a specific reason for handing out used ports when binding
port 0 with REUSEADDR?
Best,
Tobi
From: Eric Dumazet <hidden> Date: 2012-08-02 16:57:29
On Thu, 2012-08-02 at 18:33 +0200, Tobias S. Josefowitz wrote:
Hi again,
I need to say, after looking at "my" socket(7),
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
I think the surprise-factor of the bind-0-behaviour even increased for
me. Is there a specific reason for handing out used ports when binding
port 0 with REUSEADDR?
There is no concept of listening sockets for UDP.
This documentation applies for TCP, and makes no sense for UDP.
There is no value using 'port 0' and REUSEADDR on UDP, really.
From: Tobias S. Josefowitz <hidden> Date: 2012-08-02 19:05:20
On Thu, Aug 2, 2012 at 6:57 PM, Eric Dumazet [off-list ref] wrote:
There is no value using 'port 0' and REUSEADDR on UDP, really.
And nobody ever makes mistakes, so why not surprise them for even more
than they are in for.
"Looking into src/pkg/net/sock.go (func socket) I see that SO_REUSEADDR
is set unconditionally to all types of sockets." --
http://code.google.com/p/go/issues/detail?id=1692
Anyway, I'm out of this now.
Tobi
From: Jan Engelhardt <hidden> Date: 2012-08-21 09:09:57
On Thursday 2012-08-02 18:57, Eric Dumazet wrote:
quoted
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
I think the surprise-factor of the bind-0-behaviour even increased for
me. Is there a specific reason for handing out used ports when binding
port 0 with REUSEADDR?
There is no concept of listening sockets for UDP.
This documentation applies for TCP, and makes no sense for UDP.
There is no value using 'port 0' and REUSEADDR on UDP, really.
Setting REUSEADDR on one UDP socket currently has the added effect
that bind(2) on another UDP socket for the same tuple will never
complain with -EADDRINUSE.
This behavior - willingly or not - is used in practice by socat(1)'s
udp-listen mode.