summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2021-01-05 18:59:10 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-01-05 18:59:10 +0000
commit9714eb844668f93ad9fd9fb3713bfe4be6286bb1 (patch)
treec38b60ecb5325a4306af8886368c90655ed22a39
parent9a192e894b5906efb6e23d8a7d27ffc57a99366d (diff)
parent5cd56ee08c7b318b20c8e961cd3c09b67cc99af5 (diff)
downloaddnsmasq-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.h2
-rw-r--r--src/network.c15
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;
}
/**