diff --git a/src/networking.c b/src/networking.c index 5a465c460..50e4b71bc 100644 --- a/src/networking.c +++ b/src/networking.c @@ -155,7 +155,7 @@ client *createClient(connection *conn) { c->repl_ack_off = 0; c->repl_ack_time = 0; c->slave_listening_port = 0; - c->slave_ip[0] = '\0'; + c->slave_addr = NULL; c->slave_capa = SLAVE_CAPA_NONE; c->reply = listCreate(); c->reply_bytes = 0; @@ -1400,6 +1400,7 @@ void freeClient(client *c) { freeClientMultiState(c); sdsfree(c->peerid); sdsfree(c->sockname); + sdsfree(c->slave_addr); zfree(c); } diff --git a/src/replication.c b/src/replication.c index 90fa6c782..eb5fa54c0 100644 --- a/src/replication.c +++ b/src/replication.c @@ -57,21 +57,19 @@ int RDBGeneratedByReplication = 0; * IP address and its listening port which is more clear for the user, for * example: "Closing connection with replica 10.1.2.3:6380". */ char *replicationGetSlaveName(client *c) { - static char buf[NET_ADDR_STR_LEN]; + static char buf[NET_HOST_PORT_STR_LEN]; char ip[NET_IP_STR_LEN]; ip[0] = '\0'; buf[0] = '\0'; - if (c->slave_ip[0] != '\0' || + if (c->slave_addr || connPeerToString(c->conn,ip,sizeof(ip),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)); - + char *addr = c->slave_addr ? c->slave_addr : ip; if (c->slave_listening_port) - anetFormatAddr(buf,sizeof(buf),ip,c->slave_listening_port); + anetFormatAddr(buf,sizeof(buf),addr,c->slave_listening_port); else - snprintf(buf,sizeof(buf),"%s:",ip); + snprintf(buf,sizeof(buf),"%s:",addr); } else { snprintf(buf,sizeof(buf),"client id #%llu", (unsigned long long) c->id); @@ -925,12 +923,13 @@ void replconfCommand(client *c) { 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); + sds addr = c->argv[j+1]->ptr; + if (sdslen(addr) < NET_HOST_STR_LEN) { + if (c->slave_addr) sdsfree(c->slave_addr); + c->slave_addr = sdsdup(addr); } else { addReplyErrorFormat(c,"REPLCONF ip-address provided by " - "replica instance is too long: %zd bytes", sdslen(ip)); + "replica instance is too long: %zd bytes", sdslen(addr)); return; } } else if (!strcasecmp(c->argv[j]->ptr,"capa")) { @@ -2797,16 +2796,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 ip[NET_IP_STR_LEN], *slaveaddr = slave->slave_addr; - if (slaveip[0] == '\0') { + if (!slaveaddr) { if (connPeerToString(slave->conn,ip,sizeof(ip),NULL) == -1) continue; - slaveip = ip; + slaveaddr = ip; } if (slave->replstate != SLAVE_STATE_ONLINE) continue; addReplyArrayLen(c,3); - addReplyBulkCString(c,slaveip); + addReplyBulkCString(c,slaveaddr); addReplyBulkLongLong(c,slave->slave_listening_port); addReplyBulkLongLong(c,slave->repl_ack_off); slaves++; @@ -3492,9 +3491,9 @@ static client *findReplica(char *host, int port) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { replica = ln->value; - char ip[NET_IP_STR_LEN], *replicaip = replica->slave_ip; + char ip[NET_IP_STR_LEN], *replicaip = replica->slave_addr; - if (replicaip[0] == '\0') { + if (!replicaip) { if (connPeerToString(replica->conn, ip, sizeof(ip), NULL) == -1) continue; replicaip = ip; @@ -3723,16 +3722,16 @@ void updateFailoverStatus(void) { while((ln = listNext(&li))) { replica = ln->value; if (replica->repl_ack_off == server.master_repl_offset) { - char ip[NET_IP_STR_LEN], *replicaip = replica->slave_ip; + char ip[NET_IP_STR_LEN], *replicaaddr = replica->slave_addr; - if (replicaip[0] == '\0') { + if (!replicaaddr) { if (connPeerToString(replica->conn,ip,sizeof(ip),NULL) == -1) continue; - replicaip = ip; + replicaaddr = ip; } /* We are now failing over to this specific node */ - server.target_replica_host = zstrdup(replicaip); + server.target_replica_host = zstrdup(replicaaddr); server.target_replica_port = replica->slave_listening_port; break; } diff --git a/src/server.c b/src/server.c index 17a25168f..b22af980b 100644 --- a/src/server.c +++ b/src/server.c @@ -5062,11 +5062,11 @@ sds genRedisInfoString(const char *section) { while((ln = listNext(&li))) { client *slave = listNodeValue(ln); char *state = NULL; - char ip[NET_IP_STR_LEN], *slaveip = slave->slave_ip; + char ip[NET_IP_STR_LEN], *slaveip = slave->slave_addr; int port; long lag = 0; - if (slaveip[0] == '\0') { + if (!slaveip) { if (connPeerToString(slave->conn,ip,sizeof(ip),&port) == -1) continue; slaveip = ip; diff --git a/src/server.h b/src/server.h index 8f7e70261..55f718111 100644 --- a/src/server.h +++ b/src/server.h @@ -111,8 +111,10 @@ typedef long long ustime_t; /* microsecond time type. */ #define CONFIG_DEFAULT_CLUSTER_CONFIG_FILE "nodes.conf" #define CONFIG_DEFAULT_UNIX_SOCKET_PERM 0 #define CONFIG_DEFAULT_LOGFILE "" +#define NET_HOST_STR_LEN 256 /* Longest valid hostname */ #define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */ #define NET_ADDR_STR_LEN (NET_IP_STR_LEN+32) /* Must be enough for ip:port */ +#define NET_HOST_PORT_STR_LEN (NET_HOST_STR_LEN+32) /* Must be enough for hostname:port */ #define CONFIG_BINDADDR_MAX 16 #define CONFIG_MIN_RESERVED_FDS 32 #define CONFIG_DEFAULT_PROC_TITLE_TEMPLATE "{title} {listen-addr} {server-mode}" @@ -901,7 +903,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: REPLCONF listening-port */ - char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */ + char *slave_addr; /* 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. */