changeset 4:9a1ee735f28f

Patch to allow redis connections by a Unix socket. Also document the new "socket" keyword for redis connections in the example configuration file.
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 27 Mar 2020 15:07:57 +0100
parents 244ecaf25a6f
children 8133ddc49506
files files/patch-examples_etc_turnserver.conf files/patch-src_apps_common_hiredis__libevent2.c files/patch-src_apps_common_hiredis__libevent2.h files/patch-src_apps_relay_dbdrivers_dbd__redis.c
diffstat 4 files changed, 217 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/files/patch-examples_etc_turnserver.conf	Fri Mar 27 15:07:57 2020 +0100
@@ -0,0 +1,24 @@
+--- examples/etc/turnserver.conf.orig	2019-03-02 21:06:19 UTC
++++ examples/etc/turnserver.conf
+@@ -315,17 +315,17 @@
+ # as the user database.
+ # This database can be used for long-term credential mechanism
+ # and it can store the secret value for secret-based timed authentication in TURN RESP API. 
+-# Use string format as below (space separated parameters, all optional):
++# Use string format as below (space separated parameters, all optional, "socket" has higher prio than "ip"):
+ #
+-#redis-userdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
++#redis-userdb="ip=<ip-address> socket=<unix-domain-socket-path> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
+ 
+ # Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used).
+ # This database keeps allocations status information, and it can be also used for publishing
+ # and delivering traffic and allocation event notifications.
+ # The connection string has the same parameters as redis-userdb connection string. 
+-# Use string format as below (space separated parameters, all optional):
++# Use string format as below (space separated parameters, all optional, "socket" has higher prio than "ip"):
+ #
+-#redis-statsdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
++#redis-statsdb="ip=<ip-address> socket=<unix-domain-socket-path> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
+ 
+ # The default realm to be used for the users when no explicit 
+ # origin/realm relationship was found in the database, or if the TURN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/files/patch-src_apps_common_hiredis__libevent2.c	Fri Mar 27 15:07:57 2020 +0100
@@ -0,0 +1,74 @@
+--- src/apps/common/hiredis_libevent2.c.orig	2019-03-02 21:06:19 UTC
++++ src/apps/common/hiredis_libevent2.c
+@@ -55,6 +55,7 @@ struct redisLibeventEvents
+ 	char *ip;
+ 	int port;
+ 	char *pwd;
++	char *usocket;
+ 	int db;
+ };
+ 
+@@ -223,12 +224,13 @@ void send_message_to_redis(redis_context_handle rch, c
+ 
+ ///////////////////////// Attach /////////////////////////////////
+ 
+-redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db)
++redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, char *usocket, int db)
+ {
+ 
+   struct redisLibeventEvents *e = NULL;
+   redisAsyncContext *ac = NULL;
+ 
++  char sockpath[256] = "\0";
+   char ip[256];
+   if(ip0 && ip0[0])
+ 	  STRCPY(ip,ip0);
+@@ -239,7 +241,14 @@ redis_context_handle redisLibeventAttach(struct event_
+   if(port0>0)
+ 	  port=port0;
+ 
+-  ac = redisAsyncConnect(ip, port);
++  if(usocket)
++	  STRCPY(sockpath, usocket);
++
++  if(usocket) {
++	ac = redisAsyncConnectUnix(sockpath);
++  } else {
++	ac = redisAsyncConnect(ip, port);
++  }
+   if (!ac) {
+   	fprintf(stderr,"Error: %s:%s\n", ac->errstr, ac->c.errstr);
+   	return NULL;
+@@ -256,6 +265,11 @@ redis_context_handle redisLibeventAttach(struct event_
+   e->port = port;
+   if(pwd)
+ 	  e->pwd = turn_strdup(pwd);
++  if (usocket) {
++	  e->usocket = turn_strdup(usocket);
++  } else {
++	  e->usocket = NULL;
++  }
+   e->db = db;
+ 
+   /* Register functions to start/stop listening for events */
+@@ -277,6 +291,7 @@ redis_context_handle redisLibeventAttach(struct event_
+   		     e);
+ 
+   if (e->rev == NULL || e->wev == NULL) {
++	  /* XXX FIXME TBD: free e->ip, e->pwd, e->usocket */
+ 	  turn_free(e, sizeof(struct redisLibeventEvents));
+ 	  return NULL;
+   }
+@@ -327,7 +342,11 @@ static void redis_reconnect(struct redisLibeventEvents
+ 	  e->context = NULL;
+   }
+ 
+-  ac = redisAsyncConnect(e->ip, e->port);
++  if(e->usocket) {
++	ac = redisAsyncConnectUnix(e->usocket);
++  } else {
++	ac = redisAsyncConnect(e->ip, e->port);
++  }
+   if(!ac) {
+ 	  return;
+   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/files/patch-src_apps_common_hiredis__libevent2.h	Fri Mar 27 15:07:57 2020 +0100
@@ -0,0 +1,11 @@
+--- src/apps/common/hiredis_libevent2.h.orig	2019-03-02 21:06:19 UTC
++++ src/apps/common/hiredis_libevent2.h
+@@ -50,7 +50,7 @@ typedef void* redis_context_handle;
+ 
+ void redis_async_init(void);
+ 
+-redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, int db);
++redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, char *usocket, int db);
+ 
+ void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format,...);
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/files/patch-src_apps_relay_dbdrivers_dbd__redis.c	Fri Mar 27 15:07:57 2020 +0100
@@ -0,0 +1,108 @@
+--- src/apps/relay/dbdrivers/dbd_redis.c.orig	2019-03-02 21:06:19 UTC
++++ src/apps/relay/dbdrivers/dbd_redis.c
+@@ -50,6 +50,7 @@ struct _Ryconninfo {
+ 	char *host;
+ 	char *dbname;
+ 	char *password;
++	char *usocket;
+ 	unsigned int connect_timeout;
+ 	unsigned int port;
+ };
+@@ -61,6 +62,7 @@ static void RyconninfoFree(Ryconninfo *co) {
+ 		if(co->host) turn_free(co->host, strlen(co->host)+1);
+ 		if(co->dbname) turn_free(co->dbname, strlen(co->dbname)+1);
+ 		if(co->password) turn_free(co->password, strlen(co->password)+1);
++		if(co->usocket) turn_free(co->usocket, strlen(co->usocket)+1);
+ 		ns_bzero(co,sizeof(Ryconninfo));
+ 	}
+ }
+@@ -103,6 +105,8 @@ static Ryconninfo *RyconninfoParse(const char *userdb,
+ 				co->host = turn_strdup(seq + 1);
+ 			else if (!strcmp(s, "hostaddr"))
+ 				co->host = turn_strdup(seq + 1);
++			else if (!strcmp(s, "socket"))
++				co->usocket = turn_strdup(seq + 1);
+ 			else if (!strcmp(s, "dbname"))
+ 				co->dbname = turn_strdup(seq + 1);
+ 			else if (!strcmp(s, "db"))
+@@ -185,6 +189,7 @@ redis_context_handle get_redis_async_connection(struct
+ 				redisContext *rc = NULL;
+ 
+ 				char ip[256] = "\0";
++				char sockpath[256] = "\0";
+ 				int port = DEFAULT_REDIS_PORT;
+ 				if (co->host)
+ 					STRCPY(ip,co->host);
+@@ -194,13 +199,24 @@ redis_context_handle get_redis_async_connection(struct
+ 				if (co->port)
+ 					port = (int) (co->port);
+ 
++				if (co->usocket)
++					STRCPY(sockpath,co->usocket);
++
+ 				if (co->connect_timeout) {
+ 					struct timeval tv;
+ 					tv.tv_usec = 0;
+ 					tv.tv_sec = (time_t) (co->connect_timeout);
+-					rc = redisConnectWithTimeout(ip, port, tv);
++					if (co->usocket) {
++						rc = redisConnectUnixWithTimeout(sockpath, tv);
++					} else {
++						rc = redisConnectWithTimeout(ip, port, tv);
++					}
+ 				} else {
+-					rc = redisConnect(ip, port);
++					if (co->usocket) {
++						rc = redisConnectUnix(sockpath);
++					} else {
++						rc = redisConnect(ip, port);
++					}
+ 				}
+ 
+ 				if (!rc) {
+@@ -248,7 +264,7 @@ redis_context_handle get_redis_async_connection(struct
+ 				}
+ 			}
+ 
+-			ret = redisLibeventAttach(base, co->host, co->port, co->password, atoi(co->dbname));
++			ret = redisLibeventAttach(base, co->host, co->port, co->password, co->usocket, atoi(co->dbname));
+ 
+ 			if (!ret) {
+ 				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n");
+@@ -294,12 +310,16 @@ static redisContext *get_redis_connection(void) {
+ 			RyconninfoFree(co);
+ 		} else {
+ 			char ip[256] = "\0";
++			char sockpath[256] = "\0";
+ 			int port = DEFAULT_REDIS_PORT;
+ 			if (co->host)
+ 				STRCPY(ip,co->host);
+ 			if (!ip[0])
+ 				STRCPY(ip,"127.0.0.1");
+ 
++			if (co->usocket)
++				STRCPY(sockpath,co->usocket);
++
+ 			if (co->port)
+ 				port = (int) (co->port);
+ 
+@@ -307,9 +327,17 @@ static redisContext *get_redis_connection(void) {
+ 				struct timeval tv;
+ 				tv.tv_usec = 0;
+ 				tv.tv_sec = (time_t) (co->connect_timeout);
+-				redisconnection = redisConnectWithTimeout(ip, port, tv);
++				if (co->usocket) {
++					redisconnection = redisConnectUnixWithTimeout(sockpath, tv);
++				} else {
++					redisconnection = redisConnectWithTimeout(ip, port, tv);
++				}
+ 			} else {
+-				redisconnection = redisConnect(ip, port);
++				if (co->usocket) {
++					redisconnection = redisConnectUnix(sockpath);
++				} else {
++					redisconnection = redisConnect(ip, port);
++				}
+ 			}
+ 
+ 			if (redisconnection) {