Commit 56a1142f authored by Simon Kelley's avatar Simon Kelley

SO_REUSEPORT may be defined, but not supported.

parent 5b37aa8c
...@@ -52,6 +52,11 @@ version 2.66 ...@@ -52,6 +52,11 @@ version 2.66
Allow a trailing '*' wildcard in all interface-name Allow a trailing '*' wildcard in all interface-name
configurations. Thanks to Christian Parpart for the patch. configurations. Thanks to Christian Parpart for the patch.
Handle the situation where libc headers define
SO_REUSEPORT, but the kernel in use doesn't, to cope with
the introduction of this option to Linux. Thanks to Rich
Felker for the bug report.
version 2.65 version 2.65
Fix regression which broke forwarding of queries sent via Fix regression which broke forwarding of queries sent via
......
...@@ -65,14 +65,22 @@ static int make_fd(int port) ...@@ -65,14 +65,22 @@ static int make_fd(int port)
/* When bind-interfaces is set, there might be more than one dnmsasq /* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 67. That's OK if they serve different networks. instance binding port 67. That's OK if they serve different networks.
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */ Need to set REUSEADDR|REUSEPORT to make this posible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
support it. This handles the introduction of REUSEPORT on Linux. */
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{ {
int rc = -1, porterr = 0;
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt)); if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
#else errno != ENOPROTOOPT)
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt)); porterr = 1;
#endif #endif
if (rc == -1 && !porterr)
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if (rc == -1) if (rc == -1)
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET); die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
} }
......
...@@ -48,16 +48,24 @@ void dhcp6_init(void) ...@@ -48,16 +48,24 @@ void dhcp6_init(void)
!set_ipv6pktinfo(fd)) !set_ipv6pktinfo(fd))
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET); die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
/* When bind-interfaces is set, there might be more than one dnmsasq /* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 547. That's OK if they serve different networks. instance binding port 547. That's OK if they serve different networks.
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */ Need to set REUSEADDR|REUSEPORT to make this posible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
support it. This handles the introduction of REUSEPORT on Linux. */
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{ {
int rc = -1, porterr = 0;
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt)); if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
#else errno != ENOPROTOOPT)
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt)); porterr = 1;
#endif #endif
if (rc == -1 && !porterr)
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
if (rc == -1) if (rc == -1)
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET); die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment