diff options
author | Maciej Żenczykowski <maze@google.com> | 2021-01-05 18:59:10 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-01-05 18:59:10 +0000 |
commit | 9714eb844668f93ad9fd9fb3713bfe4be6286bb1 (patch) | |
tree | c38b60ecb5325a4306af8886368c90655ed22a39 | |
parent | 9a192e894b5906efb6e23d8a7d27ffc57a99366d (diff) | |
parent | 5cd56ee08c7b318b20c8e961cd3c09b67cc99af5 (diff) | |
download | dnsmasq-9714eb844668f93ad9fd9fb3713bfe4be6286bb1.tar.gz |
Merge "dnsmasq: Remove DAD Retry" am: 5cd56ee08c
Original change: https://android-review.googlesource.com/c/platform/external/dnsmasq/+/1496463
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I5c7878d66b8bc5d931ddea7f4d761d2a42294090
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/network.c | 15 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/config.h b/src/config.h index 05d74ae..14b5c98 100644 --- a/src/config.h +++ b/src/config.h @@ -69,7 +69,7 @@ #define DHCP_CLIENT_ALTPORT 1068 #define LOG_MAX 5 /* log-queue length */ #define RANDFILE "/dev/urandom" -#define DAD_WAIT 20 /* retry binding IPv6 sockets for this long */ +#define DAD_WAIT 1 /* retry binding IPv6 sockets for this long */ /* A small collection of RR-types which are missing on some platforms */ diff --git a/src/network.c b/src/network.c index d542c94..1bc3c21 100644 --- a/src/network.c +++ b/src/network.c @@ -360,7 +360,6 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { new->next = *listeners; new->tcpfd = -1; new->fd = -1; - *listeners = new; if (daemon->port != 0) { if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 || @@ -378,12 +377,17 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { } #endif + /* Unless the IPv6 address is added with IFA_F_NODAD, bind() can fail even if DAD + is disabled on the interface. This is because without IFA_F_NODAD the IPv6 + address creation call moves the IPv6 address to tentative. A timer will + fire to immediately remove the tentative flag, but this is not sufficient to + avoid a race condition (see comments in tun_interface.cpp and iproute.py). */ while (1) { if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break; #ifdef HAVE_IPV6 /* An interface may have an IPv6 address which is still undergoing DAD. - If so, the bind will fail until the DAD completes, so we try over 20 seconds + If so, the bind will fail until the DAD completes, so we try again before failing. */ /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so bind() will only fail if the address has already failed DAD, in which case retrying @@ -399,7 +403,11 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) { prettyprint_addr(&iface->addr, daemon->namebuff); - die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET); + close(new->fd); + close(new->tcpfd); + free(new); + syslog(LOG_ERR, _("failed to bind listening socket for %s"), daemon->namebuff); + return; } uint32_t mark = daemon->listen_mark; @@ -409,6 +417,7 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { if (listen(new->tcpfd, 5) == -1) die(_("failed to listen on socket: %s"), NULL, EC_BADNET); } + *listeners = new; } /** |