diff options
author | Viktor Söderqvist <viktor.soderqvist@est.tech> | 2022-09-01 12:04:59 +0200 |
---|---|---|
committer | Michael Grunder <michael.grunder@gmail.com> | 2022-09-01 10:42:36 -0700 |
commit | 10c78c6e179a32b3e1f9cd99bf18dcf0c37d295e (patch) | |
tree | 36ea03abf4c9351a374e92a201c3c8cdc60788a3 /net.c | |
parent | 1abe0c8285100e31a4688b3b09023eb3ad942394 (diff) |
Add possibility to prefer IPv6, IPv4 or unspecified
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -439,17 +439,25 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; - /* Try with IPv6 if no IPv4 address was found. We do it in this order since - * in a Redis client you can't afford to test if you have IPv6 connectivity - * as this would add latency to every connect. Otherwise a more sensible - * route could be: Use IPv6 if both addresses are available and there is IPv6 - * connectivity. */ - if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) { - hints.ai_family = AF_INET6; - if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) { - __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); - return REDIS_ERR; - } + /* DNS lookup. To use dual stack, set both flags to prefer both IPv4 and + * IPv6. By default, for historical reasons, we try IPv4 first and then we + * try IPv6 only if no IPv4 address was found. */ + if (c->flags & REDIS_PREFER_IPV6 && c->flags & REDIS_PREFER_IPV4) + hints.ai_family = AF_UNSPEC; + else if (c->flags & REDIS_PREFER_IPV6) + hints.ai_family = AF_INET6; + else + hints.ai_family = AF_INET; + + rv = getaddrinfo(c->tcp.host, _port, &hints, &servinfo); + if (rv != 0 && hints.ai_family != AF_UNSPEC) { + /* Try again with the other IP version. */ + hints.ai_family = (hints.ai_family == AF_INET) ? AF_INET6 : AF_INET; + rv = getaddrinfo(c->tcp.host, _port, &hints, &servinfo); + } + if (rv != 0) { + __redisSetError(c, REDIS_ERR_OTHER, gai_strerror(rv)); + return REDIS_ERR; } for (p = servinfo; p != NULL; p = p->ai_next) { addrretry: |