Commit 65642916 authored by Andrea Shepard's avatar Andrea Shepard Committed by Nick Mathewson
Browse files

Handle config options for AF_UNIX hidden services rendservice.c

parent 03d6a317
Loading
Loading
Loading
Loading
+51 −7
Original line number Diff line number Diff line
@@ -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->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;
}