Bugzilla – Bug 531
unbound doesn't set SO_REUSEADDR on UDP sockets
Last modified: 2013-10-31 16:22:37 CET
Created attachment 240 [details]
Patch for UDP SO_REUSEADDR
I have attached a patch for this.
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?
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
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.
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).
Implemented and committed, only for port53 (interface: config) is it applied.
Best regards, Wouter