Add possibility to prefer IPv6, IPv4 or unspecified
This commit is contained in:
parent
1abe0c8285
commit
10c78c6e17
@ -814,6 +814,12 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
|
|||||||
if (options->options & REDIS_OPT_NOAUTOFREEREPLIES) {
|
if (options->options & REDIS_OPT_NOAUTOFREEREPLIES) {
|
||||||
c->flags |= REDIS_NO_AUTO_FREE_REPLIES;
|
c->flags |= REDIS_NO_AUTO_FREE_REPLIES;
|
||||||
}
|
}
|
||||||
|
if (options->options & REDIS_OPT_PREFER_IPV4) {
|
||||||
|
c->flags |= REDIS_PREFER_IPV4;
|
||||||
|
}
|
||||||
|
if (options->options & REDIS_OPT_PREFER_IPV6) {
|
||||||
|
c->flags |= REDIS_PREFER_IPV6;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
|
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
|
||||||
* as a default unless specifically flagged that we don't want one. */
|
* as a default unless specifically flagged that we don't want one. */
|
||||||
|
@ -92,6 +92,11 @@ typedef long long ssize_t;
|
|||||||
/* Flag that indicates the user does not want replies to be automatically freed */
|
/* Flag that indicates the user does not want replies to be automatically freed */
|
||||||
#define REDIS_NO_AUTO_FREE_REPLIES 0x400
|
#define REDIS_NO_AUTO_FREE_REPLIES 0x400
|
||||||
|
|
||||||
|
/* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set,
|
||||||
|
* AF_UNSPEC is used.) */
|
||||||
|
#define REDIS_PREFER_IPV4 0x800
|
||||||
|
#define REDIS_PREFER_IPV6 0x1000
|
||||||
|
|
||||||
#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
|
#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
|
||||||
|
|
||||||
/* number of times we retry to connect in the case of EADDRNOTAVAIL and
|
/* number of times we retry to connect in the case of EADDRNOTAVAIL and
|
||||||
@ -149,6 +154,8 @@ struct redisSsl;
|
|||||||
|
|
||||||
#define REDIS_OPT_NONBLOCK 0x01
|
#define REDIS_OPT_NONBLOCK 0x01
|
||||||
#define REDIS_OPT_REUSEADDR 0x02
|
#define REDIS_OPT_REUSEADDR 0x02
|
||||||
|
#define REDIS_OPT_PREFER_IPV4 0x04
|
||||||
|
#define REDIS_OPT_PREFER_IPV6 0x08
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't automatically free the async object on a connection failure,
|
* Don't automatically free the async object on a connection failure,
|
||||||
|
26
net.c
26
net.c
@ -439,17 +439,25 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
|
|||||||
hints.ai_family = AF_INET;
|
hints.ai_family = AF_INET;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
/* Try with IPv6 if no IPv4 address was found. We do it in this order since
|
/* DNS lookup. To use dual stack, set both flags to prefer both IPv4 and
|
||||||
* in a Redis client you can't afford to test if you have IPv6 connectivity
|
* IPv6. By default, for historical reasons, we try IPv4 first and then we
|
||||||
* as this would add latency to every connect. Otherwise a more sensible
|
* try IPv6 only if no IPv4 address was found. */
|
||||||
* route could be: Use IPv6 if both addresses are available and there is IPv6
|
if (c->flags & REDIS_PREFER_IPV6 && c->flags & REDIS_PREFER_IPV4)
|
||||||
* connectivity. */
|
hints.ai_family = AF_UNSPEC;
|
||||||
if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
|
else if (c->flags & REDIS_PREFER_IPV6)
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
|
else
|
||||||
__redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
|
hints.ai_family = AF_INET;
|
||||||
return REDIS_ERR;
|
|
||||||
|
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) {
|
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||||
addrretry:
|
addrretry:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user