wg: allow setting WG_ENDPOINT_RESOLUTION_RETRIES
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									604b5a9fa7
								
							
						
					
					
						commit
						10487e7215
					
				
							
								
								
									
										26
									
								
								src/config.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/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;
 | 
			
		||||
 | 
			
		||||
@ -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),
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user