[tor-commits] [tor/master] Handle config options for AF_UNIX hidden services rendservice.c

nickm at torproject.org nickm at torproject.org
Wed Jan 28 19:33:29 UTC 2015


commit 6564291601540bf61c1ca3294b6c22f0c5021a20
Author: Andrea Shepard <andrea at torproject.org>
Date:   Fri Jan 23 14:45:12 2015 +0000

    Handle config options for AF_UNIX hidden services rendservice.c
---
 src/or/rendservice.c |   58 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 2e0f83c..fac782b 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -308,10 +308,26 @@ rend_add_service(rend_service_t *service)
   }
 }
 
+/** Return a new rend_service_port_config_t with its path set to
+ * <b>socket_path</b> or empty if <b>socket_path</b> is NULL */
+static rend_service_port_config_t *
+rend_service_port_config_new(const char *socket_path)
+{
+  if (!socket_path)
+    return tor_malloc_zero(sizeof(rend_service_port_config_t));
+
+  const size_t pathlen = strlen(socket_path) + 1;
+  rend_service_port_config_t *conf =
+    tor_malloc_zero(sizeof(rend_service_port_config_t) + pathlen);
+  memcpy(conf->unix_addr, socket_path, pathlen);
+  conf->is_unix_addr = 1;
+  return conf;
+}
+
 /** Parses a real-port to virtual-port mapping and returns a new
  * rend_service_port_config_t.
  *
- * The format is: VirtualPort (IP|RealPort|IP:RealPort)?
+ * The format is: VirtualPort (IP|RealPort|IP:RealPort|'socket':path)?
  *
  * IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
  */
@@ -325,6 +341,9 @@ parse_port_config(const char *string)
   tor_addr_t addr;
   const char *addrport;
   rend_service_port_config_t *result = NULL;
+  const char *socket_prefix = "socket:";
+  unsigned int is_unix_addr = 0;
+  char *socket_path = NULL;
 
   sl = smartlist_new();
   smartlist_split_string(sl, string, " ",
@@ -347,7 +366,26 @@ parse_port_config(const char *string)
     tor_addr_from_ipv4h(&addr, 0x7F000001u); /* 127.0.0.1 */
   } else {
     addrport = smartlist_get(sl,1);
-    if (strchr(addrport, ':') || strchr(addrport, '.')) {
+    /* If it starts with socket:, try to parse it as a socket path */
+    if (!strcmpstart(addrport, socket_prefix)) {
+      if (strlen(addrport + strlen(socket_prefix)) > 0) {
+#ifdef HAVE_SYS_UN_H
+        is_unix_addr = 1;
+        socket_path = tor_strdup(addrport + strlen(socket_prefix));
+#else
+        log_warn(LD_CONFIG,
+                 "Hidden service port configuration %s is for an AF_UNIX "
+                 "socket, but we have no support available on this platform",
+                 escaped(addrport));
+        goto err;
+#endif /* defined(HAVE_SYS_UN_H) */
+      } else {
+        log_warn(LD_CONFIG,
+                 "Empty socket path in hidden service port configuration.");
+        goto err;
+      }
+    } else if (strchr(addrport, ':') || strchr(addrport, '.')) {
+      /* else try it as an IP:port pair if it has a : or . in it */
       if (tor_addr_port_lookup(addrport, &addr, &p)<0) {
         log_warn(LD_CONFIG,"Unparseable address in hidden service port "
                  "configuration.");
@@ -366,15 +404,21 @@ parse_port_config(const char *string)
     }
   }
 
-  result = tor_malloc(sizeof(rend_service_port_config_t));
+  /* Allow room for unix_addr */
+  result = rend_service_port_config_new(socket_path);
   result->virtual_port = virtport;
-  /* TODO actually support AF_UNIX here */
-  result->is_unix_addr = 0;
-  result->real_port = realport;
-  tor_addr_copy(&result->real_addr, &addr);
+  result->is_unix_addr = is_unix_addr;
+  if (!is_unix_addr) {
+    result->real_port = realport;
+    tor_addr_copy(&result->real_addr, &addr);
+    result->unix_addr[0] = '\0';
+  }
+
  err:
   SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
   smartlist_free(sl);
+  if (socket_path) tor_free(socket_path);
+
   return result;
 }
 





More information about the tor-commits mailing list