diff --git a/redis.conf b/redis.conf index b087417a8ca81fc16714bba1cf0e7f4e0fdb372e..75420f64913e56364d1aa1ced631276cf4e2da7c 100644 --- a/redis.conf +++ b/redis.conf @@ -20,7 +20,8 @@ daemonize no # default. You can specify a custom pid file location here. pidfile /var/run/redis.pid -# Accept connections on the specified port, default is 6379 +# Accept connections on the specified port, default is 6379. +# Use port -1 to disable listening on a network interface. port 6379 # If you want you can bind a single interface, if the bind option is not @@ -28,6 +29,11 @@ port 6379 # # bind 127.0.0.1 +# Specify the path for the domain socket that will be used to listen for +# incoming connections. If not specified, Redis will not use a domain socket. +# +# socket /tmp/redis.sock + # Close the connection after a client is idle for N seconds (0 to disable) timeout 300 diff --git a/src/aof.c b/src/aof.c index f8b92d2d3301ebee556c02612c0123461b195728..942d4afd20a064dd12a0096974e410ef36cac8e5 100644 --- a/src/aof.c +++ b/src/aof.c @@ -588,7 +588,8 @@ int rewriteAppendOnlyFileBackground(void) { char tmpfile[256]; if (server.vm_enabled) vmReopenSwapFile(); - close(server.fd); + if (server.ipfd > 0) close(server.ipfd); + if (server.sofd > 0) close(server.sofd); snprintf(tmpfile,256,"temp-rewriteaof-bg-%d.aof", (int) getpid()); if (rewriteAppendOnlyFile(tmpfile) == REDIS_OK) { _exit(0); diff --git a/src/config.c b/src/config.c index 6d946ee0cbe237e0b485d5fcdd97377f48908ddd..b11bbd0f557494b051c57bc1ad6d0ae9f48c31be 100644 --- a/src/config.c +++ b/src/config.c @@ -66,11 +66,15 @@ void loadServerConfig(char *filename) { } } else if (!strcasecmp(argv[0],"port") && argc == 2) { server.port = atoi(argv[1]); - if (server.port < 1 || server.port > 65535) { + if (server.port != -1 && + (server.port < 1 || 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],"socket") && argc == 2) { + server.sockpath = zstrdup(argv[1]); } else if (!strcasecmp(argv[0],"save") && argc == 3) { int seconds = atoi(argv[1]); int changes = atoi(argv[2]); diff --git a/src/rdb.c b/src/rdb.c index 509c70c307f378d417dedc4032ba4c59e9edcb7e..3fa284e127be9cd78a1a6bc9c5a7dfaa492189df 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -448,7 +448,8 @@ int rdbSaveBackground(char *filename) { if ((childpid = fork()) == 0) { /* Child */ if (server.vm_enabled) vmReopenSwapFile(); - close(server.fd); + if (server.ipfd > 0) close(server.ipfd); + if (server.sofd > 0) close(server.sofd); if (rdbSave(filename) == REDIS_OK) { _exit(0); } else { diff --git a/src/redis.c b/src/redis.c index 397dd65a98db11f2f1bd94717c27ad98ec150cb1..65675cdf3f85db17e1f6c74850d338fa99e65741 100644 --- a/src/redis.c +++ b/src/redis.c @@ -696,13 +696,16 @@ void createSharedObjects(void) { } void initServerConfig() { - server.dbnum = REDIS_DEFAULT_DBNUM; server.port = REDIS_SERVERPORT; + server.bindaddr = NULL; + server.sockpath = NULL; + server.ipfd = -1; + server.sofd = -1; + server.dbnum = REDIS_DEFAULT_DBNUM; server.verbosity = REDIS_VERBOSE; server.maxidletime = REDIS_MAXIDLETIME; server.saveparams = NULL; server.logfile = NULL; /* NULL = log on standard output */ - server.bindaddr = NULL; server.glueoutputbuf = 1; server.daemonize = 0; server.appendonly = 0; @@ -773,16 +776,23 @@ void initServer() { createSharedObjects(); server.el = aeCreateEventLoop(); server.db = zmalloc(sizeof(redisDb)*server.dbnum); - if (server.bindaddr == NULL || inet_aton(server.bindaddr,NULL)) { - /* Either no address given, or it can be correctly parsed. */ - server.fd = anetTcpServer(server.neterr, server.port, server.bindaddr); - } else { - /* Bind to a socket */ - unlink(server.bindaddr); /* don't care if this fails */ - server.fd = anetUnixServer(server.neterr,server.bindaddr); + if (server.port > 0) { + server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr); + if (server.ipfd == ANET_ERR) { + redisLog(REDIS_WARNING, "Opening port: %s", server.neterr); + exit(1); + } + } + if (server.sockpath != NULL) { + unlink(server.sockpath); /* don't care if this fails */ + server.sofd = anetUnixServer(server.neterr,server.sockpath); + if (server.sofd == ANET_ERR) { + redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr); + exit(1); + } } - if (server.fd == -1) { - redisLog(REDIS_WARNING, "Opening port/socket: %s", server.neterr); + if (server.ipfd < 0 && server.sofd < 0) { + redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting."); exit(1); } for (j = 0; j < server.dbnum; j++) { @@ -811,8 +821,10 @@ void initServer() { server.stat_starttime = time(NULL); server.unixtime = time(NULL); aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL); - if (aeCreateFileEvent(server.el, server.fd, AE_READABLE, - acceptHandler, NULL) == AE_ERR) oom("creating file event"); + if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE, + acceptHandler,NULL) == AE_ERR) oom("creating file event"); + if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE, + acceptHandler,NULL) == AE_ERR) oom("creating file event"); if (server.appendonly) { server.appendfd = open(server.appendfilename,O_WRONLY|O_APPEND|O_CREAT,0644); @@ -1423,7 +1435,10 @@ int main(int argc, char **argv) { if (rdbLoad(server.dbfilename) == REDIS_OK) redisLog(REDIS_NOTICE,"DB loaded from disk: %ld seconds",time(NULL)-start); } - redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port); + if (server.ipfd > 0) + redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port); + if (server.sofd > 0) + redisLog(REDIS_NOTICE,"The server is now ready to accept connections at %s", server.sockpath); aeSetBeforeSleepProc(server.el,beforeSleep); aeMain(server.el); aeDeleteEventLoop(server.el); diff --git a/src/redis.h b/src/redis.h index fb051f8ebc6d07bdd58e5d5831ad0ede9703c83a..079a67ba7704f597190c4c85534ab014248b8c9b 100644 --- a/src/redis.h +++ b/src/redis.h @@ -329,7 +329,10 @@ struct sharedObjectsStruct { struct redisServer { pthread_t mainthread; int port; - int fd; + char *bindaddr; + char *sockpath; + int ipfd; + int sofd; redisDb *db; long long dirty; /* changes to DB from the last save */ list *clients; @@ -365,7 +368,6 @@ struct redisServer { struct saveparam *saveparams; int saveparamslen; char *logfile; - char *bindaddr; char *dbfilename; char *appendfilename; char *requirepass;