diff --git a/deps/hiredis/net.c b/deps/hiredis/net.c index 7d41209854c3..14640d7a15e9 100644 --- a/deps/hiredis/net.c +++ b/deps/hiredis/net.c @@ -306,7 +306,8 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) { __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified"); - goto error; + freeaddrinfo(servinfo); + return REDIS_ERR; } if (source_addr == NULL) { @@ -319,29 +320,28 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, snprintf(_port, 6, "%d", port); memset(&hints,0,sizeof(hints)); - hints.ai_family = AF_INET; + hints.ai_family = AF_UNSPEC; 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. */ + /* In an earlier version, IPv6 was only tried if no IPv4 address was + * available, to reduce latency for Redis clients. This breaks setups with + * e.g. AAAA records but not IPv6 connectivity. Therefore, we're just using + * the regular addrinfo struct returned by getaddrinfo() instead and loop + * over the the responses in the order the kernel gave us. + * Hopefully, the latency introduced by this isn't too bad. + */ 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; - } + __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv)); + return REDIS_ERR; } + for (p = servinfo; p != NULL; p = p->ai_next) { -addrretry: if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; c->fd = s; if (redisSetBlocking(c,0) != REDIS_OK) - goto error; + continue; if (c->tcp.source_addr) { int bound = 0; /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ @@ -349,14 +349,14 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, char buf[128]; snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv)); __redisSetError(c,REDIS_ERR_OTHER,buf); - goto error; + continue; } if (reuseaddr) { n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n, sizeof(n)) < 0) { - goto error; + continue; } } @@ -371,48 +371,57 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port, char buf[128]; snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno)); __redisSetError(c,REDIS_ERR_OTHER,buf); - goto error; + continue; } } if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { redisContextCloseFd(c); continue; - } else if (errno == EINPROGRESS && !blocking) { - /* This is ok. */ + } else if (errno == EINPROGRESS) { + /* This breaks nonblocking, but seems to be the only way to + * retry other addresses? + * This was partially backported from + * https://github.com/redis/hiredis/pull/578 + */ + goto wait_for_ready; } else if (errno == EADDRNOTAVAIL && reuseaddr) { if (++reuses >= REDIS_CONNECT_RETRIES) { - goto error; + break; } else { redisContextCloseFd(c); - goto addrretry; + continue; } } else { - if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) - goto error; +wait_for_ready: + if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) continue; } } if (blocking && redisSetBlocking(c,1) != REDIS_OK) - goto error; + continue; if (redisSetTcpNoDelay(c) != REDIS_OK) - goto error; + continue; c->flags |= REDIS_CONNECTED; - rv = REDIS_OK; - goto end; - } - if (p == NULL) { - char buf[128]; - snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno)); - __redisSetError(c,REDIS_ERR_OTHER,buf); - goto error; + + /* This is needed because c->err is set using __redisSetError on + * connection failures. This can be called by various functions. + * We shall have a clear function that would ideally clean the struct + * of all past errors which have been put into or somehow only set the + * error flag and message after looping through all IP addresses and + * not finding any REDIS_OK. + * Also, we're cleaning c->errstr, analogue to redisReconnect() + */ + c->err = 0; + memset(c->errstr, '\0', strlen(c->errstr)); + + freeaddrinfo(servinfo); + return REDIS_OK; // Need to return REDIS_OK if alright } -error: - rv = REDIS_ERR; -end: + // No address could be reached freeaddrinfo(servinfo); - return rv; // Need to return REDIS_OK if alright + return REDIS_ERR; } int redisContextConnectTcp(redisContext *c, const char *addr, int port, diff --git a/src/anet.c b/src/anet.c index dc88eb74ed1e..c3412c6f2171 100644 --- a/src/anet.c +++ b/src/anet.c @@ -194,16 +194,17 @@ int anetSendTimeout(char *err, int fd, long long ms) { } /* anetGenericResolve() is called by anetResolve() and anetResolveIP() to - * do the actual work. It resolves the hostname "host" and set the string - * representation of the IP address into the buffer pointed by "ipbuf". + * do the actual work. It resolves the hostname "host" and returns the addrinfo + * struct pointer. * * If flags is set to ANET_IP_ONLY the function only resolves hostnames * that are actually already IPv4 or IPv6 addresses. This turns the function - * into a validating / normalizing function. */ -int anetGenericResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, - int flags) + * into a validating / normalizing function. + * + * NOTE: Caller needs to make sure to use freeaddrinfo(info) */ +int anetGenericResolve(char *err, char *host, struct addrinfo **info, int flags) { - struct addrinfo hints, *info; + struct addrinfo hints; int rv; memset(&hints,0,sizeof(hints)); @@ -211,28 +212,20 @@ int anetGenericResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len, hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* specify socktype to avoid dups */ - if ((rv = getaddrinfo(host, NULL, &hints, &info)) != 0) { + if ((rv = getaddrinfo(host, NULL, &hints, info)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); return ANET_ERR; } - if (info->ai_family == AF_INET) { - struct sockaddr_in *sa = (struct sockaddr_in *)info->ai_addr; - inet_ntop(AF_INET, &(sa->sin_addr), ipbuf, ipbuf_len); - } else { - struct sockaddr_in6 *sa = (struct sockaddr_in6 *)info->ai_addr; - inet_ntop(AF_INET6, &(sa->sin6_addr), ipbuf, ipbuf_len); - } - freeaddrinfo(info); return ANET_OK; } -int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len) { - return anetGenericResolve(err,host,ipbuf,ipbuf_len,ANET_NONE); +int anetResolve(char *err, char *host, struct addrinfo **info) { + return anetGenericResolve(err,host,info,ANET_NONE); } -int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len) { - return anetGenericResolve(err,host,ipbuf,ipbuf_len,ANET_IP_ONLY); +int anetResolveIP(char *err, char *host, struct addrinfo **info) { + return anetGenericResolve(err,host,info,ANET_IP_ONLY); } static int anetSetReuseAddr(char *err, int fd) { @@ -287,16 +280,25 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, * the next entry in servinfo. */ if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) continue; - if (anetSetReuseAddr(err,s) == ANET_ERR) goto error; - if (flags & ANET_CONNECT_NONBLOCK && anetNonBlock(err,s) != ANET_OK) - goto error; + + if (anetSetReuseAddr(err,s) == ANET_ERR) { + close(s); + continue; + } + + if (flags & ANET_CONNECT_NONBLOCK && anetNonBlock(err,s) != ANET_OK) { + close(s); + continue; + } + if (source_addr) { int bound = 0; /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */ if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) { anetSetError(err, "%s", gai_strerror(rv)); - goto error; + close(s); + continue; } for (b = bservinfo; b != NULL; b = b->ai_next) { if (bind(s,b->ai_addr,b->ai_addrlen) != -1) { @@ -307,42 +309,26 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, freeaddrinfo(bservinfo); if (!bound) { anetSetError(err, "bind: %s", strerror(errno)); - goto error; + close(s); + continue; } } + if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { /* If the socket is non-blocking, it is ok for connect() to * return an EINPROGRESS error here. */ - if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) - goto end; + if (errno == EINPROGRESS && flags & ANET_CONNECT_NONBLOCK) { + freeaddrinfo(servinfo); + return s; + } + close(s); - s = ANET_ERR; continue; } - - /* If we ended an iteration of the for loop without errors, we - * have a connected socket. Let's return to the caller. */ - goto end; } - if (p == NULL) - anetSetError(err, "creating socket: %s", strerror(errno)); -error: - if (s != ANET_ERR) { - close(s); - s = ANET_ERR; - } - -end: freeaddrinfo(servinfo); - - /* Handle best effort binding: if a binding address was used, but it is - * not possible to create a socket, try again without a binding address. */ - if (s == ANET_ERR && source_addr && (flags & ANET_CONNECT_BE_BINDING)) { - return anetTcpGenericConnect(err,addr,port,NULL,flags); - } else { - return s; - } + return -1; } int anetTcpConnect(char *err, char *addr, int port) diff --git a/src/anet.h b/src/anet.h index 7142f78d22fc..305c83028e6a 100644 --- a/src/anet.h +++ b/src/anet.h @@ -32,6 +32,7 @@ #define ANET_H #include +#include #define ANET_OK 0 #define ANET_ERR -1 @@ -56,8 +57,8 @@ int anetTcpNonBlockBestEffortBindConnect(char *err, char *addr, int port, char * int anetUnixConnect(char *err, char *path); int anetUnixNonBlockConnect(char *err, char *path); int anetRead(int fd, char *buf, int count); -int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len); -int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len); +int anetResolve(char *err, char *host, struct addrinfo **info); +int anetResolveIP(char *err, char *host, struct addrinfo **info); int anetTcpServer(char *err, int port, char *bindaddr, int backlog); int anetTcp6Server(char *err, int port, char *bindaddr, int backlog); int anetUnixServer(char *err, char *path, mode_t perm, int backlog); diff --git a/src/networking.c b/src/networking.c index 00f5bab027e4..b79570208b7b 100644 --- a/src/networking.c +++ b/src/networking.c @@ -125,7 +125,7 @@ client *createClient(int fd) { c->repl_ack_off = 0; c->repl_ack_time = 0; c->slave_listening_port = 0; - c->slave_ip[0] = '\0'; + c->slave_hostname[0] = '\0'; c->slave_capa = SLAVE_CAPA_NONE; c->reply = listCreate(); c->reply_bytes = 0; diff --git a/src/rdb.c b/src/rdb.c index be3927ff0a18..2f01605a0b01 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -1724,7 +1724,7 @@ void backgroundSaveDoneHandlerDisk(int exitcode, int bysignal) { } /* A background saving child (BGSAVE) terminated its work. Handle this. - * This function covers the case of RDB -> Salves socket transfers for + * This function covers the case of RDB -> Slaves socket transfers for * diskless replication. */ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) { uint64_t *ok_slaves; diff --git a/src/replication.c b/src/replication.c index 5de4b9d7e672..554c3947a306 100644 --- a/src/replication.c +++ b/src/replication.c @@ -45,26 +45,26 @@ int cancelReplicationHandshake(void); /* --------------------------- Utility functions ---------------------------- */ -/* Return the pointer to a string representing the slave ip:listening_port +/* Return the pointer to a string representing the slave hostname:listening_port * pair. Mostly useful for logging, since we want to log a slave using its - * IP address and its listening port which is more clear for the user, for + * Hostname and its listening port which is more clear for the user, for * example: "Closing connection with slave 10.1.2.3:6380". */ char *replicationGetSlaveName(client *c) { static char buf[NET_PEER_ID_LEN]; - char ip[NET_IP_STR_LEN]; + char hostname[NET_IP_STR_LEN]; - ip[0] = '\0'; + hostname[0] = '\0'; buf[0] = '\0'; - if (c->slave_ip[0] != '\0' || - anetPeerToString(c->fd,ip,sizeof(ip),NULL) != -1) + if (c->slave_hostname[0] != '\0' || + anetPeerToString(c->fd,hostname,sizeof(hostname),NULL) != -1) { - /* Note that the 'ip' buffer is always larger than 'c->slave_ip' */ - if (c->slave_ip[0] != '\0') memcpy(ip,c->slave_ip,sizeof(c->slave_ip)); + /* Note that the 'hostname' buffer is always larger than 'c->slave_hostname' */ + if (c->slave_hostname[0] != '\0') memcpy(hostname,c->slave_hostname,sizeof(c->slave_hostname)); if (c->slave_listening_port) - anetFormatAddr(buf,sizeof(buf),ip,c->slave_listening_port); + anetFormatAddr(buf,sizeof(buf),hostname,c->slave_listening_port); else - snprintf(buf,sizeof(buf),"%s:",ip); + snprintf(buf,sizeof(buf),"%s:",hostname); } else { snprintf(buf,sizeof(buf),"client id #%llu", (unsigned long long) c->id); @@ -584,7 +584,7 @@ int startBgsaveForReplication(int mincapa) { } /* If we failed to BGSAVE, remove the slaves waiting for a full - * resynchorinization from the list of salves, inform them with + * resynchorinization from the list of slaves, inform them with * an error about what happened, close the connection ASAP. */ if (retval == C_ERR) { serverLog(LL_WARNING,"BGSAVE for replication failed"); @@ -604,7 +604,7 @@ int startBgsaveForReplication(int mincapa) { } /* If the target is socket, rdbSaveToSlavesSockets() already setup - * the salves for a full resync. Otherwise for disk target do it now.*/ + * the slaves for a full resync. Otherwise for disk target do it now.*/ if (!socket_target) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { @@ -792,13 +792,13 @@ void replconfCommand(client *c) { &port,NULL) != C_OK)) return; c->slave_listening_port = port; - } else if (!strcasecmp(c->argv[j]->ptr,"ip-address")) { - sds ip = c->argv[j+1]->ptr; - if (sdslen(ip) < sizeof(c->slave_ip)) { - memcpy(c->slave_ip,ip,sdslen(ip)+1); + } else if (!strcasecmp(c->argv[j]->ptr,"ip-address")) { // TODO + sds hostname = c->argv[j+1]->ptr; + if (sdslen(hostname) < sizeof(c->slave_hostname)) { + memcpy(c->slave_hostname,hostname,sdslen(hostname)+1); } else { - addReplyErrorFormat(c,"REPLCONF ip-address provided by " - "slave instance is too long: %zd bytes", sdslen(ip)); + addReplyErrorFormat(c,"REPLCONF ip-address provided by " // TODO + "slave instance is too long: %zd bytes", sdslen(hostname)); return; } } else if (!strcasecmp(c->argv[j]->ptr,"capa")) { @@ -1344,7 +1344,7 @@ char *sendSynchronousCommand(int flags, int fd, ...) { } cmd = sdscatlen(cmd,"\r\n",2); va_end(ap); - + /* Transfer command to the server. */ if (syncWrite(fd,cmd,sdslen(cmd),server.repl_syncio_timeout*1000) == -1) @@ -1936,11 +1936,11 @@ int cancelReplicationHandshake(void) { } /* Set replication to the specified master address and port. */ -void replicationSetMaster(char *ip, int port) { +void replicationSetMaster(char *hostname, int port) { int was_master = server.masterhost == NULL; sdsfree(server.masterhost); - server.masterhost = sdsnew(ip); + server.masterhost = sdsnew(hostname); server.masterport = port; if (server.master) { freeClient(server.master); @@ -2070,16 +2070,16 @@ void roleCommand(client *c) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { client *slave = ln->value; - char ip[NET_IP_STR_LEN], *slaveip = slave->slave_ip; + char hostname[NET_IP_STR_LEN], *slavehostname = slave->slave_hostname; - if (slaveip[0] == '\0') { - if (anetPeerToString(slave->fd,ip,sizeof(ip),NULL) == -1) + if (slavehostname[0] == '\0') { + if (anetPeerToString(slave->fd,hostname,sizeof(hostname),NULL) == -1) continue; - slaveip = ip; + slavehostname = hostname; } if (slave->replstate != SLAVE_STATE_ONLINE) continue; addReplyMultiBulkLen(c,3); - addReplyBulkCString(c,slaveip); + addReplyBulkCString(c,slavehostname); addReplyBulkLongLong(c,slave->slave_listening_port); addReplyBulkLongLong(c,slave->repl_ack_off); slaves++; diff --git a/src/sentinel.c b/src/sentinel.c index d3818707b1ac..01e7aac9f824 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -44,9 +44,9 @@ extern char **environ; /* ======================== Sentinel global state =========================== */ -/* Address object, used to describe an ip:port pair. */ +/* Address object, used to describe an hostname:port pair. */ typedef struct sentinelAddr { - char *ip; + char *hostname; int port; } sentinelAddr; @@ -519,19 +519,27 @@ void sentinelIsRunning(void) { * EINVAL: Invalid port number. */ sentinelAddr *createSentinelAddr(char *hostname, int port) { - char ip[NET_IP_STR_LEN]; sentinelAddr *sa; if (port < 0 || port > 65535) { errno = EINVAL; return NULL; } - if (anetResolve(NULL,hostname,ip,sizeof(ip)) == ANET_ERR) { + + /* Check whether host can be resolved. This is just a sanity test, only the + * hostname will be stored in sentinelAddr, not the addrinfo struct + */ + struct addrinfo *info; + + if (anetResolve(NULL,hostname, &info) == ANET_ERR) { errno = ENOENT; return NULL; } + + freeaddrinfo(info); + sa = zmalloc(sizeof(*sa)); - sa->ip = sdsnew(ip); + sa->hostname = sdsnew(hostname); sa->port = port; return sa; } @@ -541,20 +549,20 @@ sentinelAddr *dupSentinelAddr(sentinelAddr *src) { sentinelAddr *sa; sa = zmalloc(sizeof(*sa)); - sa->ip = sdsnew(src->ip); + sa->hostname = sdsnew(src->hostname); sa->port = src->port; return sa; } /* Free a Sentinel address. Can't fail. */ void releaseSentinelAddr(sentinelAddr *sa) { - sdsfree(sa->ip); + sdsfree(sa->hostname); zfree(sa); } /* Return non-zero if two addresses are equal. */ int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) { - return a->port == b->port && !strcasecmp(a->ip,b->ip); + return a->port == b->port && !strcasecmp(a->hostname,b->hostname); } /* =========================== Events notification ========================== */ @@ -597,12 +605,12 @@ void sentinelEvent(int level, char *type, sentinelRedisInstance *ri, if (master) { snprintf(msg, sizeof(msg), "%s %s %s %d @ %s %s %d", sentinelRedisInstanceTypeStr(ri), - ri->name, ri->addr->ip, ri->addr->port, - master->name, master->addr->ip, master->addr->port); + ri->name, ri->addr->hostname, ri->addr->port, + master->name, master->addr->hostname, master->addr->port); } else { snprintf(msg, sizeof(msg), "%s %s %s %d", sentinelRedisInstanceTypeStr(ri), - ri->name, ri->addr->ip, ri->addr->port); + ri->name, ri->addr->hostname, ri->addr->port); } fmt += 2; } else { @@ -924,7 +932,7 @@ void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, cha sentinelScheduleScriptExecution(master->client_reconfig_script, master->name, (role == SENTINEL_LEADER) ? "leader" : "observer", - state, from->ip, fromport, to->ip, toport, NULL); + state, from->hostname, fromport, to->hostname, toport, NULL); } /* =============================== instanceLink ============================= */ @@ -1339,7 +1347,7 @@ sentinelRedisInstance *getSentinelRedisInstanceByAddrAndRunID(dict *instances, c if (runid && !ri->runid) continue; if ((runid == NULL || strcmp(ri->runid, runid) == 0) && - (ip == NULL || (strcmp(ri->addr->ip, ip) == 0 && + (ip == NULL || (strcmp(ri->addr->hostname, ip) == 0 && ri->addr->port == port))) { instance = ri; @@ -1479,7 +1487,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, if (sentinelAddrIsEqual(slave->addr,newaddr)) continue; slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1)); - slaves[numslaves++] = createSentinelAddr(slave->addr->ip, + slaves[numslaves++] = createSentinelAddr(slave->addr->hostname, slave->addr->port); } dictReleaseIterator(di); @@ -1489,7 +1497,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, * the old master. */ if (!sentinelAddrIsEqual(newaddr,master->addr)) { slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1)); - slaves[numslaves++] = createSentinelAddr(master->addr->ip, + slaves[numslaves++] = createSentinelAddr(master->addr->hostname, master->addr->port); } @@ -1504,7 +1512,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, for (j = 0; j < numslaves; j++) { sentinelRedisInstance *slave; - slave = createSentinelRedisInstance(NULL,SRI_SLAVE,slaves[j]->ip, + slave = createSentinelRedisInstance(NULL,SRI_SLAVE,slaves[j]->hostname, slaves[j]->port, master->quorum, master); releaseSentinelAddr(slaves[j]); if (slave) sentinelEvent(LL_NOTICE,"+slave",slave,"%@"); @@ -1512,7 +1520,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, zfree(slaves); /* Release the old address at the end so we are safe even if the function - * gets the master->addr->ip and master->addr->port as arguments. */ + * gets the master->addr->hostname and master->addr->port as arguments. */ releaseSentinelAddr(oldaddr); sentinelFlushConfig(); return C_OK; @@ -1730,7 +1738,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { master = dictGetVal(de); master_addr = sentinelGetCurrentMasterAddress(master); line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d", - master->name, master_addr->ip, master_addr->port, + master->name, master_addr->hostname, master_addr->port, master->quorum); rewriteConfigRewriteLine(state,"sentinel",line,1); @@ -1811,7 +1819,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { slave_addr = master->addr; line = sdscatprintf(sdsempty(), "sentinel known-slave %s %s %d", - master->name, slave_addr->ip, slave_addr->port); + master->name, slave_addr->hostname, slave_addr->port); rewriteConfigRewriteLine(state,"sentinel",line,1); } dictReleaseIterator(di2); @@ -1823,7 +1831,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { if (ri->runid == NULL) continue; line = sdscatprintf(sdsempty(), "sentinel known-sentinel %s %s %d %s", - master->name, ri->addr->ip, ri->addr->port, ri->runid); + master->name, ri->addr->hostname, ri->addr->port, ri->runid); rewriteConfigRewriteLine(state,"sentinel",line,1); } dictReleaseIterator(di2); @@ -1927,7 +1935,7 @@ void sentinelReconnectInstance(sentinelRedisInstance *ri) { /* Commands connection. */ if (link->cc == NULL) { - link->cc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,NET_FIRST_BIND_ADDR); + link->cc = redisAsyncConnectBind(ri->addr->hostname,ri->addr->port,NET_FIRST_BIND_ADDR); if (link->cc->err) { sentinelEvent(LL_DEBUG,"-cmd-link-reconnection",ri,"%@ #%s", link->cc->errstr); @@ -1950,7 +1958,7 @@ void sentinelReconnectInstance(sentinelRedisInstance *ri) { } /* Pub / Sub */ if ((ri->flags & (SRI_MASTER|SRI_SLAVE)) && link->pc == NULL) { - link->pc = redisAsyncConnectBind(ri->addr->ip,ri->addr->port,NET_FIRST_BIND_ADDR); + link->pc = redisAsyncConnectBind(ri->addr->hostname,ri->addr->port,NET_FIRST_BIND_ADDR); if (link->pc->err) { sentinelEvent(LL_DEBUG,"-pubsub-link-reconnection",ri,"%@ #%s", link->pc->errstr); @@ -2195,7 +2203,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) { mstime() - ri->role_reported_time > wait_time) { int retval = sentinelSendSlaveOf(ri, - ri->master->addr->ip, + ri->master->addr->hostname, ri->master->addr->port); if (retval == C_OK) sentinelEvent(LL_NOTICE,"+convert-to-slave",ri,"%@"); @@ -2207,7 +2215,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) { if ((ri->flags & SRI_SLAVE) && role == SRI_SLAVE && (ri->slave_master_port != ri->master->addr->port || - strcasecmp(ri->slave_master_host,ri->master->addr->ip))) + strcasecmp(ri->slave_master_host,ri->master->addr->hostname))) { mstime_t wait_time = ri->master->failover_timeout; @@ -2218,7 +2226,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) { mstime() - ri->slave_conf_change_time > wait_time) { int retval = sentinelSendSlaveOf(ri, - ri->master->addr->ip, + ri->master->addr->hostname, ri->master->addr->port); if (retval == C_OK) sentinelEvent(LL_NOTICE,"+fix-slave-config",ri,"%@"); @@ -2234,7 +2242,7 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) { if ((ri->flags & SRI_RECONF_SENT) && ri->slave_master_host && strcmp(ri->slave_master_host, - ri->master->promoted_slave->addr->ip) == 0 && + ri->master->promoted_slave->addr->hostname) == 0 && ri->slave_master_port == ri->master->promoted_slave->addr->port) { ri->flags &= ~SRI_RECONF_SENT; @@ -2408,7 +2416,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) { if (si && master->config_epoch < master_config_epoch) { master->config_epoch = master_config_epoch; if (master_port != master->addr->port || - strcmp(master->addr->ip, token[5])) + strcmp(master->addr->hostname, token[5])) { sentinelAddr *old_addr; @@ -2416,7 +2424,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) { sentinelEvent(LL_WARNING,"+switch-master", master,"%s %s %d %s %d", master->name, - master->addr->ip, master->addr->port, + master->addr->hostname, master->addr->port, token[5], master_port); old_addr = dupSentinelAddr(master->addr); @@ -2508,7 +2516,7 @@ int sentinelSendHello(sentinelRedisInstance *ri) { announce_ip, announce_port, sentinel.myid, (unsigned long long) sentinel.current_epoch, /* --- */ - master->name,master_addr->ip,master_addr->port, + master->name,master_addr->hostname,master_addr->port, (unsigned long long) master->config_epoch); retval = redisAsyncCommand(ri->link->cc, sentinelPublishReplyCallback, ri, "PUBLISH %s %s", @@ -2665,7 +2673,7 @@ void addReplySentinelRedisInstance(client *c, sentinelRedisInstance *ri) { fields++; addReplyBulkCString(c,"ip"); - addReplyBulkCString(c,ri->addr->ip); + addReplyBulkCString(c,ri->addr->hostname); fields++; addReplyBulkCString(c,"port"); @@ -2998,7 +3006,7 @@ void sentinelCommand(client *c) { sentinelAddr *addr = sentinelGetCurrentMasterAddress(ri); addReplyMultiBulkLen(c,2); - addReplyBulkCString(c,addr->ip); + addReplyBulkCString(c,addr->hostname); addReplyBulkLongLong(c,addr->port); } } else if (!strcasecmp(c->argv[1]->ptr,"failover")) { @@ -3030,7 +3038,6 @@ void sentinelCommand(client *c) { /* SENTINEL MONITOR */ sentinelRedisInstance *ri; long quorum, port; - char ip[NET_IP_STR_LEN]; if (c->argc != 6) goto numargserr; if (getLongFromObjectOrReply(c,c->argv[5],&quorum,"Invalid quorum") @@ -3043,14 +3050,6 @@ void sentinelCommand(client *c) { return; } - /* Make sure the IP field is actually a valid IP before passing it - * to createSentinelRedisInstance(), otherwise we may trigger a - * DNS lookup at runtime. */ - if (anetResolveIP(NULL,c->argv[3]->ptr,ip,sizeof(ip)) == ANET_ERR) { - addReplyError(c,"Invalid IP address specified"); - return; - } - /* Parameters are valid. Try to create the master instance. */ ri = createSentinelRedisInstance(c->argv[2]->ptr,SRI_MASTER, c->argv[3]->ptr,port,quorum,NULL); @@ -3281,7 +3280,7 @@ void sentinelInfoCommand(client *c) { "master%d:name=%s,status=%s,address=%s:%d," "slaves=%lu,sentinels=%lu\r\n", master_id++, ri->name, status, - ri->addr->ip, ri->addr->port, + ri->addr->hostname, ri->addr->port, dictSize(ri->slaves), dictSize(ri->sentinels)+1); } @@ -3618,7 +3617,7 @@ void sentinelAskMasterStateToOtherSentinels(sentinelRedisInstance *master, int f retval = redisAsyncCommand(ri->link->cc, sentinelReceiveIsMasterDownReply, ri, "SENTINEL is-master-down-by-addr %s %s %llu %s", - master->addr->ip, port, + master->addr->hostname, port, sentinel.current_epoch, (master->failover_state > SENTINEL_FAILOVER_STATE_NONE) ? sentinel.myid : "*"); @@ -4129,7 +4128,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) { if (slave->link->disconnected) continue; retval = sentinelSendSlaveOf(slave, - master->promoted_slave->addr->ip, + master->promoted_slave->addr->hostname, master->promoted_slave->addr->port); if (retval == C_OK) { sentinelEvent(LL_NOTICE,"+slave-reconf-sent-be",slave,"%@"); @@ -4186,7 +4185,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) { /* Send SLAVEOF . */ retval = sentinelSendSlaveOf(slave, - master->promoted_slave->addr->ip, + master->promoted_slave->addr->hostname, master->promoted_slave->addr->port); if (retval == C_OK) { slave->flags |= SRI_RECONF_SENT; @@ -4209,10 +4208,10 @@ void sentinelFailoverSwitchToPromotedSlave(sentinelRedisInstance *master) { master->promoted_slave : master; sentinelEvent(LL_WARNING,"+switch-master",master,"%s %s %d %s %d", - master->name, master->addr->ip, master->addr->port, - ref->addr->ip, ref->addr->port); + master->name, master->addr->hostname, master->addr->port, + ref->addr->hostname, ref->addr->port); - sentinelResetMasterAndChangeAddress(master,ref->addr->ip,ref->addr->port); + sentinelResetMasterAndChangeAddress(master,ref->addr->hostname,ref->addr->port); } void sentinelFailoverStateMachine(sentinelRedisInstance *ri) { @@ -4369,4 +4368,3 @@ void sentinelTimer(void) { * election because of split brain voting). */ server.hz = CONFIG_DEFAULT_HZ + rand() % CONFIG_DEFAULT_HZ; } - diff --git a/src/server.c b/src/server.c index 9117245b8ff8..adec1f4b7b1b 100644 --- a/src/server.c +++ b/src/server.c @@ -2180,7 +2180,7 @@ void preventCommandReplication(client *c) { * CMD_CALL_STATS Populate command stats. * CMD_CALL_PROPAGATE_AOF Append command to AOF if it modified the dataset * or if the client flags are forcing propagation. - * CMD_CALL_PROPAGATE_REPL Send command to salves if it modified the dataset + * CMD_CALL_PROPAGATE_REPL Send command to slaves if it modified the dataset * or if the client flags are forcing propagation. * CMD_CALL_PROPAGATE Alias for PROPAGATE_AOF|PROPAGATE_REPL. * CMD_CALL_FULL Alias for SLOWLOG|STATS|PROPAGATE. @@ -3236,14 +3236,14 @@ sds genRedisInfoString(char *section) { while((ln = listNext(&li))) { client *slave = listNodeValue(ln); char *state = NULL; - char ip[NET_IP_STR_LEN], *slaveip = slave->slave_ip; + char hostname[NET_IP_STR_LEN], *slavehostname = slave->slave_hostname; int port; long lag = 0; - if (slaveip[0] == '\0') { - if (anetPeerToString(slave->fd,ip,sizeof(ip),&port) == -1) + if (slavehostname[0] == '\0') { + if (anetPeerToString(slave->fd,hostname,sizeof(hostname),&port) == -1) continue; - slaveip = ip; + slavehostname = hostname; } switch(slave->replstate) { case SLAVE_STATE_WAIT_BGSAVE_START: @@ -3264,7 +3264,7 @@ sds genRedisInfoString(char *section) { info = sdscatprintf(info, "slave%d:ip=%s,port=%d,state=%s," "offset=%lld,lag=%ld\r\n", - slaveid,slaveip,slave->slave_listening_port,state, + slaveid,slavehostname,slave->slave_listening_port,state, slave->repl_ack_off, lag); slaveid++; } diff --git a/src/server.h b/src/server.h index c0e2b9aafcb9..d5ce2dc8b685 100644 --- a/src/server.h +++ b/src/server.h @@ -145,7 +145,7 @@ typedef long long mstime_t; /* millisecond time type. */ #define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0 #define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10 #define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */ -#define NET_PEER_ID_LEN (NET_IP_STR_LEN+32) /* Must be enough for ip:port */ +#define NET_PEER_ID_LEN (NET_IP_STR_LEN+32) /* Must be enough for hostname:port */ #define CONFIG_BINDADDR_MAX 16 #define CONFIG_MIN_RESERVED_FDS 32 #define CONFIG_DEFAULT_LATENCY_MONITOR_THRESHOLD 0 @@ -713,7 +713,7 @@ typedef struct client { should use. */ char replid[CONFIG_RUN_ID_SIZE+1]; /* Master replication ID (if master). */ int slave_listening_port; /* As configured with: SLAVECONF listening-port */ - char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */ + char slave_hostname[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */ int slave_capa; /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */ multiState mstate; /* MULTI/EXEC state */ int btype; /* Type of blocking op if CLIENT_BLOCKED. */ diff --git a/tests/integration/psync2.tcl b/tests/integration/psync2.tcl index 3d9e5527a12f..6c121b878608 100644 --- a/tests/integration/psync2.tcl +++ b/tests/integration/psync2.tcl @@ -180,7 +180,7 @@ start_server {} { set slave_id [expr {($master_id+1)%5}] set sync_count [status $R($master_id) sync_full] - # Make sure to replicate the first EVAL while the salve is online + # Make sure to replicate the first EVAL while the slave is online # so that it's part of the scripts the master believes it's safe # to propagate as EVALSHA. $R($master_id) EVAL {return redis.call("incr","__mycounter")} 0