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) {
err = "Invalid port"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"bind") && argc == 2) {
server.bindaddr = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"bind") && argc >= 2) {
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) {
server.unixsocket = zstrdup(argv[1]);
} 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("requirepass",server.requirepass);
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("logfile",server.logfile);
config_get_string_field("pidfile",server.pidfile);
@ -1104,6 +1110,14 @@ void configGetCommand(redisClient *c) {
decrRefCount(flagsobj);
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);
}
@ -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
* rewrite state into a single string, stripping multiple empty lines. */
sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) {
@ -1630,7 +1663,7 @@ int rewriteConfig(char *path) {
rewriteConfigYesNoOption(state,"daemonize",server.daemonize,0);
rewriteConfigStringOption(state,"pidfile",server.pidfile,REDIS_DEFAULT_PID_FILE);
rewriteConfigNumericalOption(state,"port",server.port,REDIS_SERVERPORT);
rewriteConfigStringOption(state,"bind",server.bindaddr,NULL);
rewriteConfigBindOption(state);
rewriteConfigStringOption(state,"unixsocket",server.unixsocket,NULL);
rewriteConfigOctalOption(state,"unixsocketperm",server.unixsocketperm,REDIS_DEFAULT_UNIX_SOCKET_PERM);
rewriteConfigNumericalOption(state,"timeout",server.maxidletime,REDIS_MAXIDLETIME);

View File

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

View File

@ -121,6 +121,7 @@
#define REDIS_DEFAULT_MIN_SLAVES_TO_WRITE 0
#define REDIS_DEFAULT_MIN_SLAVES_MAX_LAG 10
#define REDIS_IP_STR_LEN 16
#define REDIS_BINDADDR_MAX 16
/* Protocol and I/O related defines */
#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. */
/* Networking */
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 */
mode_t unixsocketperm; /* UNIX socket permission */
int ipfd; /* TCP socket file descriptor */