From e83915d10d7180c40b5cb14fc7a47eac23cfc270 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Tue, 10 Apr 2018 21:27:26 +0100 Subject: [PATCH] Set V6ONLY on DNS upstream socket. If query-port is set, we create sockets bound to the wildcard address and the query port for IPv4 and IPv6, but the IPv6 one fails, because is covers IPv4 as well, and an IPv4 socket already exists (it gets created first). Set V6ONLY to avoid this. --- src/network.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/network.c b/src/network.c index 0381513..1af4dbc 100644 --- a/src/network.c +++ b/src/network.c @@ -1234,7 +1234,8 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) struct serverfd *sfd; unsigned int ifindex = 0; int errsave; - + int opt = 1; + /* when using random ports, servers which would otherwise use the INADDR_ANY/port0 socket have sfd set to NULL */ if (!daemon->osport && intname[0] == 0) @@ -1274,10 +1275,11 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) free(sfd); return NULL; } - - if (!local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd)) + + if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) || + !local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd)) { - errsave = errno; /* save error from bind. */ + errsave = errno; /* save error from bind/setsockopt. */ close(sfd->fd); free(sfd); errno = errsave;