Bug 531 - unbound doesn't set SO_REUSEADDR on UDP sockets
unbound doesn't set SO_REUSEADDR on UDP sockets
Status: RESOLVED FIXED
Product: unbound
Classification: Unclassified
Component: server
unspecified
Other All
: P5 enhancement
Assigned To: unbound team
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-10-28 18:33 CET by John Graham-Cumming
Modified: 2013-10-31 16:22 CET (History)
1 user (show)

See Also:


Attachments
Patch for UDP SO_REUSEADDR (854 bytes, application/octet-stream)
2013-10-28 18:33 CET, John Graham-Cumming
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Graham-Cumming 2013-10-28 18:33:29 CET
Created attachment 240 [details]
Patch for UDP SO_REUSEADDR

I have attached a patch for this.
Comment 1 Wouter Wijngaards 2013-10-29 09:14:07 CET
Hi John,

Your patch looks very good.

But I do not understand why I want to set REUSEADDR on UDP sockets?  For TCP sockets it avoids failure on rebinding, but this is for UDP sockets?  Presumably they are not in use by anyone else, and if they are, unbound should not bind them for itself, but fail.  Such failures are soft (another random port is chosen).  What does REUSEADDR really do for UDP, allow you to bind the same port multiple times I seem to find as only reason to do it, but unbound does not need that functionality, it would be a superfluous system call in that case.  Is there some reason you think that REUSEADDR is useful here?

Best regards,
   Wouter
Comment 2 John Graham-Cumming 2013-10-29 13:52:11 CET
Wouter,

There are situations where SO_REUSEADDR is useful with UDP. Specifically, when you want to bind multiple services to the same UDP port number. In our case we are binding unbound and another, different, service to the port 53 using different IP addresses (one is a specific IP address, the other is 0.0.0.0). 

If all the sockets have SO_REUSEADDR then this is allowed.

There's a great StackOverflow on this: http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t

John.
Comment 3 Wouter Wijngaards 2013-10-29 14:28:08 CET
Hi John,

That is a good article.  And I see you want it for listening sockets.  This option must not be sent for outgoing sockets - because then there can be collisions between new outgoing sockets and other server's sockets (who are then partially, or for Linux, fully hijacked for half the traffic).  Thus, the patch needs to be modified that make_sock() adds these options for UDP sockets (if fd != -1), or calls a function to do so.

I see that Linux performs load balancing for REUSE_PORT options, and this is very desirable, but the effects on other OSes are not so wonderful (duplicate port binding with other servers is confusing for the operator).  So I do not think I can easily call that one.

Best regards,
   Wouter
Comment 4 Wouter Wijngaards 2013-10-31 15:48:34 CET
Hi John,

On closer inspection, it turns out that on Linux this would make unbound hijack another server's ports (i.e. another unbound instance) without any feedback, and thus the two servers would respond to UDP queries intermixed randomly.

On BSD, it does exactly what we want, i.e. allow more specific IP addresses to be bound by unbound.

But still this is likely to be very useful as an option, so I think I should set it by default, for listening sockets (e.g. on port 53).

Best regards,
   Wouter
Comment 5 Wouter Wijngaards 2013-10-31 16:07:59 CET
Hi John,

Implemented and committed, only for port53 (interface: config) is it applied.

Best regards, Wouter
Comment 6 John Graham-Cumming 2013-10-31 16:22:37 CET
Thanks!