diff options
author | 2019-05-28 22:45:15 +0200 | |
---|---|---|
committer | 2019-05-29 01:23:24 +0200 | |
commit | a1a1c1723b6423e43d71cfa52862fad9bbcd265b (patch) | |
tree | 13f43adf8bbd15da7eff9b383f84ed1da9357973 | |
parent | zinc: update copyright (diff) | |
download | wireguard-monolithic-historical-a1a1c1723b6423e43d71cfa52862fad9bbcd265b.tar.xz wireguard-monolithic-historical-a1a1c1723b6423e43d71cfa52862fad9bbcd265b.zip |
tools: allow setting WG_ENDPOINT_RESOLUTION_RETRIES
-rw-r--r-- | src/tools/config.c | 26 | ||||
-rw-r--r-- | src/tools/man/wg.8 | 3 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/tools/config.c b/src/tools/config.c index d510ea7..db90228 100644 --- a/src/tools/config.c +++ b/src/tools/config.c @@ -174,11 +174,29 @@ static inline bool parse_ip(struct wgallowedip *allowedip, const char *value) return true; } +static inline int parse_dns_retries(void) +{ + unsigned long ret; + char *retries = getenv("WG_ENDPOINT_RESOLUTION_RETRIES"), *end; + + if (!retries) + return 15; + if (!strcmp(retries, "infinity")) + return -1; + + ret = strtoul(retries, &end, 10); + if (*end || ret > INT_MAX) { + fprintf(stderr, "Unable to parse WG_ENDPOINT_RESOLUTION_RETRIES: `%s'\n", retries); + exit(1); + } + return (int)ret; +} + static inline bool parse_endpoint(struct sockaddr *endpoint, const char *value) { char *mutable = strdup(value); char *begin, *end; - int ret; + int ret, retries = parse_dns_retries(); struct addrinfo *resolved; struct addrinfo hints = { .ai_family = AF_UNSPEC, @@ -219,11 +237,11 @@ static inline bool parse_endpoint(struct sockaddr *endpoint, const char *value) *end++ = '\0'; } - for (unsigned int timeout = 1000000;;) { + #define min(a, b) ((a) < (b) ? (a) : (b)) + for (unsigned int timeout = 1000000;; timeout = min(20000000, timeout * 6 / 5)) { ret = getaddrinfo(begin, end, &hints, &resolved); if (!ret) break; - timeout = timeout * 3 / 2; /* The set of return codes that are "permanent failures". All other possibilities are potentially transient. * * This is according to https://sourceware.org/glibc/wiki/NameResolver which states: @@ -238,7 +256,7 @@ static inline bool parse_endpoint(struct sockaddr *endpoint, const char *value) #ifdef EAI_NODATA ret == EAI_NODATA || #endif - timeout >= 90000000) { + (retries >= 0 && !retries--)) { free(mutable); fprintf(stderr, "%s: `%s'\n", ret == EAI_SYSTEM ? strerror(errno) : gai_strerror(ret), value); return false; diff --git a/src/tools/man/wg.8 b/src/tools/man/wg.8 index 2013825..afff749 100644 --- a/src/tools/man/wg.8 +++ b/src/tools/man/wg.8 @@ -211,6 +211,9 @@ If set to \fIalways\fP, always print ANSI colorized output. If set to \fInever\f .TP .I WG_HIDE_KEYS If set to \fInever\fP, then the pretty-printing \fBshow\fP sub-command will show private and preshared keys in the output. If set to \fIalways\fP, something invalid, or unset, then private and preshared keys will be printed as "(hidden)". +.TP +.I WG_ENDPOINT_RESOLUTION_RETRIES +If set to an integer or to \fIinfinity\fP, DNS resolution for each peer's endpoint will be retried that many times for non-permanent errors, with an increasing delay between retries. If unset, the default is 15 retries. .SH SEE ALSO .BR ip (8), |