Ability to bind multiple addresses.

This commit is contained in:
antirez 2013-07-04 18:50:15 +02:00
parent 016ac38a21
commit 90b0d66cce
3 changed files with 43 additions and 8 deletions

View File

@ -125,8 +125,15 @@ void loadServerConfigFromString(char *config) {
if (server.port < 0 || server.port > 65535) { if (server.port < 0 || server.port > 65535) {
err = "Invalid port"; goto loaderr; err = "Invalid port"; goto loaderr;
} }
} else if (!strcasecmp(argv[0],"bind") && argc == 2) { } else if (!strcasecmp(argv[0],"bind") && argc >= 2) {
server.bindaddr = zstrdup(argv[1]); int j, addresses = argc-1;
if (addresses > REDIS_BINDADDR_MAX) {
err = "Too many bind addresses specified"; goto loaderr;
}
for (j = 0; j < addresses; j++)
server.bindaddr[j] = zstrdup(argv[j+1]);
server.bindaddr_count = addresses;
} else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) { } else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) {
server.unixsocket = zstrdup(argv[1]); server.unixsocket = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) { } else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
@ -917,7 +924,6 @@ void configGetCommand(redisClient *c) {
config_get_string_field("dbfilename",server.rdb_filename); config_get_string_field("dbfilename",server.rdb_filename);
config_get_string_field("requirepass",server.requirepass); config_get_string_field("requirepass",server.requirepass);
config_get_string_field("masterauth",server.masterauth); config_get_string_field("masterauth",server.masterauth);
config_get_string_field("bind",server.bindaddr);
config_get_string_field("unixsocket",server.unixsocket); config_get_string_field("unixsocket",server.unixsocket);
config_get_string_field("logfile",server.logfile); config_get_string_field("logfile",server.logfile);
config_get_string_field("pidfile",server.pidfile); config_get_string_field("pidfile",server.pidfile);
@ -1104,6 +1110,14 @@ void configGetCommand(redisClient *c) {
decrRefCount(flagsobj); decrRefCount(flagsobj);
matches++; matches++;
} }
if (stringmatch(pattern,"bind",0)) {
sds aux = sdsjoin(server.bindaddr,server.bindaddr_count," ");
addReplyBulkCString(c,"bind");
addReplyBulkCString(c,aux);
sdsfree(aux);
matches++;
}
setDeferredMultiBulkLength(c,replylen,matches*2); setDeferredMultiBulkLength(c,replylen,matches*2);
} }
@ -1495,6 +1509,25 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state
} }
} }
/* Rewrite the bind option. */
void rewriteConfigBindOption(struct rewriteConfigState *state) {
int force = 1;
sds line, addresses;
char *option = "bind";
/* Nothing to rewrite if we don't have bind addresses. */
if (server.bindaddr_count == 0) return;
/* Rewrite as bind <addr1> <addr2> ... <addrN> */
addresses = sdsjoin(server.bindaddr,server.bindaddr_count," ");
line = sdsnew(option);
line = sdscatlen(line, " ", 1);
line = sdscatsds(line, addresses);
sdsfree(addresses);
rewriteConfigRewriteLine(state,option,line,force);
}
/* Glue together the configuration lines in the current configuration /* Glue together the configuration lines in the current configuration
* rewrite state into a single string, stripping multiple empty lines. */ * rewrite state into a single string, stripping multiple empty lines. */
sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) { sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) {
@ -1630,7 +1663,7 @@ int rewriteConfig(char *path) {
rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0); rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0);
rewriteConfigStringOption(state,"pidfile",server.pidfile,REDIS_DEFAULT_PID_FILE); rewriteConfigStringOption(state,"pidfile",server.pidfile,REDIS_DEFAULT_PID_FILE);
rewriteConfigNumericalOption(state,"port",server.port,REDIS_SERVERPORT); rewriteConfigNumericalOption(state,"port",server.port,REDIS_SERVERPORT);
rewriteConfigStringOption(state,"bind",server.bindaddr,NULL); rewriteConfigBindOption(state);
rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL); rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL);
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,REDIS_DEFAULT_UNIX_SOCKET_PERM); rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,REDIS_DEFAULT_UNIX_SOCKET_PERM);
rewriteConfigNumericalOption(state,"timeout",server.maxidletime,REDIS_MAXIDLETIME); rewriteConfigNumericalOption(state,"timeout",server.maxidletime,REDIS_MAXIDLETIME);

View File

@ -1221,7 +1221,7 @@ void initServerConfig() {
server.runid[REDIS_RUN_ID_SIZE] = '\0'; server.runid[REDIS_RUN_ID_SIZE] = '\0';
server.arch_bits = (sizeof(long) == 8) ? 64 : 32; server.arch_bits = (sizeof(long) == 8) ? 64 : 32;
server.port = REDIS_SERVERPORT; server.port = REDIS_SERVERPORT;
server.bindaddr = NULL; server.bindaddr_count = 0;
server.unixsocket = NULL; server.unixsocket = NULL;
server.unixsocketperm = REDIS_DEFAULT_UNIX_SOCKET_PERM; server.unixsocketperm = REDIS_DEFAULT_UNIX_SOCKET_PERM;
server.ipfd = -1; server.ipfd = -1;
@ -1426,7 +1426,7 @@ void initServer() {
server.db = zmalloc(sizeof(redisDb)*server.dbnum); server.db = zmalloc(sizeof(redisDb)*server.dbnum);
if (server.port != 0) { if (server.port != 0) {
server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr); server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr,server.bindaddr_count);
if (server.ipfd == ANET_ERR) { if (server.ipfd == ANET_ERR) {
redisLog(REDIS_WARNING, "Opening port %d: %s", redisLog(REDIS_WARNING, "Opening port %d: %s",
server.port, server.neterr); server.port, server.neterr);
@ -2837,7 +2837,7 @@ void redisSetProcTitle(char *title) {
#ifdef USE_SETPROCTITLE #ifdef USE_SETPROCTITLE
setproctitle("%s %s:%d", setproctitle("%s %s:%d",
title, title,
server.bindaddr ? server.bindaddr : "*", server.bindaddr_count ? server.bindaddr[0] : "*",
server.port); server.port);
#else #else
REDIS_NOTUSED(title); REDIS_NOTUSED(title);

View File

@ -121,6 +121,7 @@
#define REDIS_DEFAULT_MIN_SLAVES_TO_WRITE 0 #define REDIS_DEFAULT_MIN_SLAVES_TO_WRITE 0
#define REDIS_DEFAULT_MIN_SLAVES_MAX_LAG 10 #define REDIS_DEFAULT_MIN_SLAVES_MAX_LAG 10
#define REDIS_IP_STR_LEN 16 #define REDIS_IP_STR_LEN 16
#define REDIS_BINDADDR_MAX 16
/* Protocol and I/O related defines */ /* Protocol and I/O related defines */
#define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */ #define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
@ -730,7 +731,8 @@ struct redisServer {
int sentinel_mode; /* True if this instance is a Sentinel. */ int sentinel_mode; /* True if this instance is a Sentinel. */
/* Networking */ /* Networking */
int port; /* TCP listening port */ int port; /* TCP listening port */
char *bindaddr; /* Bind address or NULL */ char *bindaddr[REDIS_BINDADDR_MAX]; /* Addresses we should bind to */
int bindaddr_count; /* Number of addresses in server.bindaddr[] */
char *unixsocket; /* UNIX socket path */ char *unixsocket; /* UNIX socket path */
mode_t unixsocketperm; /* UNIX socket permission */ mode_t unixsocketperm; /* UNIX socket permission */
int ipfd; /* TCP socket file descriptor */ int ipfd; /* TCP socket file descriptor */