]> git.ipfire.org Git - thirdparty/wireguard-tools.git/commitdiff
wg: allow setting WG_ENDPOINT_RESOLUTION_RETRIES
authorJason A. Donenfeld <Jason@zx2c4.com>
Tue, 28 May 2019 20:45:15 +0000 (22:45 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Tue, 28 May 2019 23:23:24 +0000 (01:23 +0200)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
src/config.c
src/man/wg.8

index d510ea79ff44170039c5e8ceb00906bf8a15ad09..db902289450182b9d6189670c6762ea1c8bd4d67 100644 (file)
@@ -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;
index 2013825b439a9310dc91fd3ab6c9d40fff2faa8d..afff74939bb40b0a2b48b555e29829bb125e4f16 100644 (file)
@@ -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),