SO_REUSEADDR and SO_V6ONLY options on DHCPv6 socket.

This commit is contained in:
Simon Kelley
2012-10-15 10:41:17 +01:00
parent 657ed09693
commit 2022310f95
2 changed files with 22 additions and 1 deletions

View File

@@ -32,6 +32,11 @@ version 2.64
infinte loop at startup. Regression in 2.63. Thanks to
Haim Gelfenbeyn for spotting this.
Set SO_REUSEADDRESS and SO_V6ONLY options on the DHCPv6
socket, this allows multiple instances of dnsmasq on a
single machine, in the same way as for DHCPv4. Thanks to
Gene Czarcinski and Vladislav Grishenko for work on this.
version 2.63
Do duplicate dhcp-host address check in --test mode.

View File

@@ -36,15 +36,31 @@ void dhcp6_init(void)
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
int class = IPTOS_CLASS_CS6;
#endif
int oneopt = 1;
if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
#if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
#endif
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &oneopt, sizeof(oneopt)) == -1 ||
!fix_fd(fd) ||
!set_ipv6pktinfo(fd))
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
/* When bind-interfaces is set, there might be more than one dnmsasq
instance binding port 547. That's OK if they serve different networks.
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
{
#ifdef SO_REUSEPORT
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
#else
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
#endif
if (rc == -1)
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
}
memset(&saddr, 0, sizeof(saddr));
#ifdef HAVE_SOCKADDR_SA_LEN
saddr.sin6_len = sizeof(struct sockaddr_in6);