[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor/master] config: Move server transport config into the relay module



commit 11f283f56139e823d77942276d6229d6c39abd9f
Author: teor <teor@xxxxxxxxxxxxxx>
Date:   Tue Oct 29 16:25:08 2019 +1000

    config: Move server transport config into the relay module
    
    This commit:
    * creates feature/relay/transport_config.[ch],
    * moves server transport config checks into them,
    * exposes some code from src/app/config.c
      (we'll refactor it later in 29211), and
    * adds thin wrappers to make the moved code compile.
    
    No functional changes: the moved code is still enabled,
    even if the relay module is disabled. (Some of the checks
    are re-ordered, so the order of some warnings may change.)
    
    Part of 32213.
---
 src/app/config/config.c              | 199 +---------------------------
 src/app/config/config.h              |  11 +-
 src/app/config/statefile.c           |   1 +
 src/core/include.am                  |   2 +
 src/feature/client/transports.c      |   2 +
 src/feature/relay/transport_config.c | 247 +++++++++++++++++++++++++++++++++++
 src/feature/relay/transport_config.h |  27 ++++
 src/test/test_config.c               |   1 +
 8 files changed, 287 insertions(+), 203 deletions(-)

diff --git a/src/app/config/config.c b/src/app/config/config.c
index 3d6ba00ef..4ec38e30c 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -103,6 +103,7 @@
 #include "feature/relay/ext_orport.h"
 #include "feature/relay/routermode.h"
 #include "feature/relay/relay_config.h"
+#include "feature/relay/transport_config.h"
 #include "feature/rend/rendclient.h"
 #include "feature/rend/rendservice.h"
 #include "lib/geoip/geoip.h"
@@ -827,8 +828,6 @@ static int options_transition_affects_workers(
       const or_options_t *old_options, const or_options_t *new_options);
 static int options_transition_affects_descriptor(
       const or_options_t *old_options, const or_options_t *new_options);
-static char *get_bindaddr_from_transport_listen_line(const char *line,
-                                                     const char *transport);
 static int parse_ports(or_options_t *options, int validate_only,
                               char **msg_out, int *n_ports_out,
                               int *world_writable_control_socket);
@@ -4108,46 +4107,8 @@ options_validate_cb(const void *old_options_, void *options_, char **msg)
       REJECT("Invalid client transport line. See logs for details.");
   }
 
-  for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
-    if (parse_transport_line(options, cl->value, 1, 1) < 0)
-      REJECT("Invalid server transport line. See logs for details.");
-  }
-
-  if (options->ServerTransportPlugin && !server_mode(options)) {
-    log_notice(LD_GENERAL, "Tor is not configured as a relay but you specified"
-               " a ServerTransportPlugin line (%s). The ServerTransportPlugin "
-               "line will be ignored.",
-               escaped(options->ServerTransportPlugin->value));
-  }
-
-  for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
-    /** If get_bindaddr_from_transport_listen_line() fails with
-        'transport' being NULL, it means that something went wrong
-        while parsing the ServerTransportListenAddr line. */
-    char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
-    if (!bindaddr)
-      REJECT("ServerTransportListenAddr did not parse. See logs for details.");
-    tor_free(bindaddr);
-  }
-
-  if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
-    log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
-               "specify a transport listen address. The "
-               "ServerTransportListenAddr line will be ignored.");
-  }
-
-  for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
-    /** If get_options_from_transport_options_line() fails with
-        'transport' being NULL, it means that something went wrong
-        while parsing the ServerTransportOptions line. */
-    smartlist_t *options_sl =
-      get_options_from_transport_options_line(cl->value, NULL);
-    if (!options_sl)
-      REJECT("ServerTransportOptions did not parse. See logs for details.");
-
-    SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
-    smartlist_free(options_sl);
-  }
+  if (options_validate_server_transport(old_options, options, msg) < 0)
+    return -1;
 
   if (options->ConstrainedSockets) {
     /* If the user wants to constrain socket buffer use, make sure the desired
@@ -5564,8 +5525,7 @@ parse_bridge_line(const char *line)
  * our internal transport list.
  * - If it's a managed proxy line, launch the managed proxy.
  */
-
-STATIC int
+int
 parse_transport_line(const or_options_t *options,
                      const char *line, int validate_only,
                      int server)
@@ -5759,157 +5719,6 @@ parse_transport_line(const or_options_t *options,
   return r;
 }
 
-/** Given a ServerTransportListenAddr <b>line</b>, return its
- *  <address:port> string. Return NULL if the line was not
- *  well-formed.
- *
- *  If <b>transport</b> is set, return NULL if the line is not
- *  referring to <b>transport</b>.
- *
- *  The returned string is allocated on the heap and it's the
- *  responsibility of the caller to free it. */
-static char *
-get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
-{
-  smartlist_t *items = NULL;
-  const char *parsed_transport = NULL;
-  char *addrport = NULL;
-  tor_addr_t addr;
-  uint16_t port = 0;
-
-  items = smartlist_new();
-  smartlist_split_string(items, line, NULL,
-                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
-
-  if (smartlist_len(items) < 2) {
-    log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
-    goto err;
-  }
-
-  parsed_transport = smartlist_get(items, 0);
-  addrport = tor_strdup(smartlist_get(items, 1));
-
-  /* If 'transport' is given, check if it matches the one on the line */
-  if (transport && strcmp(transport, parsed_transport))
-    goto err;
-
-  /* Validate addrport */
-  if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
-    log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
-             "address '%s'", addrport);
-    goto err;
-  }
-
-  goto done;
-
- err:
-  tor_free(addrport);
-  addrport = NULL;
-
- done:
-  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
-  smartlist_free(items);
-
-  return addrport;
-}
-
-/** Given a ServerTransportOptions <b>line</b>, return a smartlist
- *  with the options. Return NULL if the line was not well-formed.
- *
- *  If <b>transport</b> is set, return NULL if the line is not
- *  referring to <b>transport</b>.
- *
- *  The returned smartlist and its strings are allocated on the heap
- *  and it's the responsibility of the caller to free it. */
-smartlist_t *
-get_options_from_transport_options_line(const char *line,const char *transport)
-{
-  smartlist_t *items = smartlist_new();
-  smartlist_t *options = smartlist_new();
-  const char *parsed_transport = NULL;
-
-  smartlist_split_string(items, line, NULL,
-                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
-
-  if (smartlist_len(items) < 2) {
-    log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
-    goto err;
-  }
-
-  parsed_transport = smartlist_get(items, 0);
-  /* If 'transport' is given, check if it matches the one on the line */
-  if (transport && strcmp(transport, parsed_transport))
-    goto err;
-
-  SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
-    if (option_sl_idx == 0) /* skip the transport field (first field)*/
-      continue;
-
-    /* validate that it's a k=v value */
-    if (!string_is_key_value(LOG_WARN, option)) {
-      log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
-      goto err;
-    }
-
-    /* add it to the options smartlist */
-    smartlist_add_strdup(options, option);
-    log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
-  } SMARTLIST_FOREACH_END(option);
-
-  goto done;
-
- err:
-  SMARTLIST_FOREACH(options, char*, s, tor_free(s));
-  smartlist_free(options);
-  options = NULL;
-
- done:
-  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
-  smartlist_free(items);
-
-  return options;
-}
-
-/** Given the name of a pluggable transport in <b>transport</b>, check
- *  the configuration file to see if the user has explicitly asked for
- *  it to listen on a specific port. Return a <address:port> string if
- *  so, otherwise NULL. */
-char *
-get_transport_bindaddr_from_config(const char *transport)
-{
-  config_line_t *cl;
-  const or_options_t *options = get_options();
-
-  for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
-    char *bindaddr =
-      get_bindaddr_from_transport_listen_line(cl->value, transport);
-    if (bindaddr)
-      return bindaddr;
-  }
-
-  return NULL;
-}
-
-/** Given the name of a pluggable transport in <b>transport</b>, check
- *  the configuration file to see if the user has asked us to pass any
- *  parameters to the pluggable transport. Return a smartlist
- *  containing the parameters, otherwise NULL. */
-smartlist_t *
-get_options_for_server_transport(const char *transport)
-{
-  config_line_t *cl;
-  const or_options_t *options = get_options();
-
-  for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
-    smartlist_t *options_sl =
-      get_options_from_transport_options_line(cl->value, transport);
-    if (options_sl)
-      return options_sl;
-  }
-
-  return NULL;
-}
-
 /** Read the contents of a DirAuthority line from <b>line</b>. If
  * <b>validate_only</b> is 0, and the line is well-formed, and it
  * shares any bits with <b>required_type</b> or <b>required_type</b>
diff --git a/src/app/config/config.h b/src/app/config/config.h
index e2174b127..0ab25344a 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -192,8 +192,6 @@ int getinfo_helper_config(control_connection_t *conn,
 uint32_t get_effective_bwrate(const or_options_t *options);
 uint32_t get_effective_bwburst(const or_options_t *options);
 
-char *get_transport_bindaddr_from_config(const char *transport);
-
 int init_cookie_authentication(const char *fname, const char *header,
                                int cookie_len, int group_readable,
                                uint8_t **cookie_out, int *cookie_is_set_out);
@@ -248,9 +246,6 @@ void bridge_line_free_(bridge_line_t *bridge_line);
 #define bridge_line_free(line) \
   FREE_AND_NULL(bridge_line_t, bridge_line_free_, (line))
 bridge_line_t *parse_bridge_line(const char *line);
-smartlist_t *get_options_from_transport_options_line(const char *line,
-                                                     const char *transport);
-smartlist_t *get_options_for_server_transport(const char *transport);
 
 /* Port helper functions. */
 int options_any_client_port_set(const or_options_t *options);
@@ -279,6 +274,9 @@ void port_cfg_free_(port_cfg_t *port);
 int count_real_listeners(const smartlist_t *ports,
                          int listenertype,
                          int count_sockets);
+int parse_transport_line(const or_options_t *options,
+                         const char *line, int validate_only,
+                         int server);
 
 #ifdef CONFIG_PRIVATE
 
@@ -293,9 +291,6 @@ STATIC const struct config_mgr_t *get_options_mgr(void);
 STATIC void or_options_free_(or_options_t *options);
 STATIC int options_validate_single_onion(or_options_t *options,
                                          char **msg);
-STATIC int parse_transport_line(const or_options_t *options,
-                                const char *line, int validate_only,
-                                int server);
 STATIC int consider_adding_dir_servers(const or_options_t *options,
                                        const or_options_t *old_options);
 STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type);
diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c
index 1d6f63cde..c4504b3ca 100644
--- a/src/app/config/statefile.c
+++ b/src/app/config/statefile.c
@@ -32,6 +32,7 @@
 #include "core/or/or.h"
 #include "core/or/circuitstats.h"
 #include "app/config/config.h"
+#include "feature/relay/transport_config.h"
 #include "lib/confmgt/confmgt.h"
 #include "core/mainloop/mainloop.h"
 #include "core/mainloop/netstatus.h"
diff --git a/src/core/include.am b/src/core/include.am
index b08f14d49..eda929df4 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -149,6 +149,7 @@ LIBTOR_APP_A_SOURCES = 				\
 	src/feature/relay/router.c		\
 	src/feature/relay/routerkeys.c		\
 	src/feature/relay/selftest.c		\
+	src/feature/relay/transport_config.c		\
 	src/feature/rend/rendcache.c		\
 	src/feature/rend/rendclient.c		\
 	src/feature/rend/rendcommon.c		\
@@ -438,6 +439,7 @@ noinst_HEADERS +=					\
 	src/feature/relay/routerkeys.h			\
 	src/feature/relay/routermode.h			\
 	src/feature/relay/selftest.h			\
+	src/feature/relay/transport_config.h	\
 	src/feature/rend/rend_authorized_client_st.h	\
 	src/feature/rend/rend_encoded_v2_service_descriptor_st.h	\
 	src/feature/rend/rend_intro_point_st.h		\
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index 3f731ac7d..1640c943a 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -97,6 +97,8 @@
 #include "core/or/circuitbuild.h"
 #include "feature/client/transports.h"
 #include "feature/relay/router.h"
+/* 31851: split the server transport code out of the client module */
+#include "feature/relay/transport_config.h"
 #include "app/config/statefile.h"
 #include "core/or/connection_or.h"
 #include "feature/relay/ext_orport.h"
diff --git a/src/feature/relay/transport_config.c b/src/feature/relay/transport_config.c
new file mode 100644
index 000000000..b323f4299
--- /dev/null
+++ b/src/feature/relay/transport_config.c
@@ -0,0 +1,247 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file transport_config.c
+ * @brief Code to interpret the user's configuration of Tor's server
+ *        pluggable transports.
+ **/
+
+#include "orconfig.h"
+#include "feature/relay/transport_config.h"
+
+#include "lib/encoding/confline.h"
+#include "lib/encoding/keyval.h"
+
+#include "lib/container/smartlist.h"
+
+/* Required for dirinfo_type_t in or_options_t */
+#include "core/or/or.h"
+#include "app/config/config.h"
+
+#include "feature/relay/ext_orport.h"
+#include "feature/relay/routermode.h"
+
+/* Copied from config.c, we will refactor later in 29211. */
+#define REJECT(arg) \
+  STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
+
+/** Given a ServerTransportListenAddr <b>line</b>, return its
+ *  <address:port> string. Return NULL if the line was not
+ *  well-formed.
+ *
+ *  If <b>transport</b> is set, return NULL if the line is not
+ *  referring to <b>transport</b>.
+ *
+ *  The returned string is allocated on the heap and it's the
+ *  responsibility of the caller to free it. */
+static char *
+get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
+{
+  smartlist_t *items = NULL;
+  const char *parsed_transport = NULL;
+  char *addrport = NULL;
+  tor_addr_t addr;
+  uint16_t port = 0;
+
+  items = smartlist_new();
+  smartlist_split_string(items, line, NULL,
+                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+
+  if (smartlist_len(items) < 2) {
+    log_warn(LD_CONFIG,"Too few arguments on ServerTransportListenAddr line.");
+    goto err;
+  }
+
+  parsed_transport = smartlist_get(items, 0);
+  addrport = tor_strdup(smartlist_get(items, 1));
+
+  /* If 'transport' is given, check if it matches the one on the line */
+  if (transport && strcmp(transport, parsed_transport))
+    goto err;
+
+  /* Validate addrport */
+  if (tor_addr_port_parse(LOG_WARN, addrport, &addr, &port, -1)<0) {
+    log_warn(LD_CONFIG, "Error parsing ServerTransportListenAddr "
+             "address '%s'", addrport);
+    goto err;
+  }
+
+  goto done;
+
+ err:
+  tor_free(addrport);
+  addrport = NULL;
+
+ done:
+  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
+  smartlist_free(items);
+
+  return addrport;
+}
+
+/** Given the name of a pluggable transport in <b>transport</b>, check
+ *  the configuration file to see if the user has explicitly asked for
+ *  it to listen on a specific port. Return a <address:port> string if
+ *  so, otherwise NULL. */
+char *
+get_transport_bindaddr_from_config(const char *transport)
+{
+  config_line_t *cl;
+  const or_options_t *options = get_options();
+
+  for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
+    char *bindaddr =
+      get_bindaddr_from_transport_listen_line(cl->value, transport);
+    if (bindaddr)
+      return bindaddr;
+  }
+
+  return NULL;
+}
+
+/** Given a ServerTransportOptions <b>line</b>, return a smartlist
+ *  with the options. Return NULL if the line was not well-formed.
+ *
+ *  If <b>transport</b> is set, return NULL if the line is not
+ *  referring to <b>transport</b>.
+ *
+ *  The returned smartlist and its strings are allocated on the heap
+ *  and it's the responsibility of the caller to free it. */
+smartlist_t *
+get_options_from_transport_options_line(const char *line,const char *transport)
+{
+  smartlist_t *items = smartlist_new();
+  smartlist_t *options = smartlist_new();
+  const char *parsed_transport = NULL;
+
+  smartlist_split_string(items, line, NULL,
+                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
+
+  if (smartlist_len(items) < 2) {
+    log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
+    goto err;
+  }
+
+  parsed_transport = smartlist_get(items, 0);
+  /* If 'transport' is given, check if it matches the one on the line */
+  if (transport && strcmp(transport, parsed_transport))
+    goto err;
+
+  SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
+    if (option_sl_idx == 0) /* skip the transport field (first field)*/
+      continue;
+
+    /* validate that it's a k=v value */
+    if (!string_is_key_value(LOG_WARN, option)) {
+      log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
+      goto err;
+    }
+
+    /* add it to the options smartlist */
+    smartlist_add_strdup(options, option);
+    log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
+  } SMARTLIST_FOREACH_END(option);
+
+  goto done;
+
+ err:
+  SMARTLIST_FOREACH(options, char*, s, tor_free(s));
+  smartlist_free(options);
+  options = NULL;
+
+ done:
+  SMARTLIST_FOREACH(items, char*, s, tor_free(s));
+  smartlist_free(items);
+
+  return options;
+}
+
+/** Given the name of a pluggable transport in <b>transport</b>, check
+ *  the configuration file to see if the user has asked us to pass any
+ *  parameters to the pluggable transport. Return a smartlist
+ *  containing the parameters, otherwise NULL. */
+smartlist_t *
+get_options_for_server_transport(const char *transport)
+{
+  config_line_t *cl;
+  const or_options_t *options = get_options();
+
+  for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
+    smartlist_t *options_sl =
+      get_options_from_transport_options_line(cl->value, transport);
+    if (options_sl)
+      return options_sl;
+  }
+
+  return NULL;
+}
+
+/**
+ * Legacy validation/normalization function for the server transport options.
+ * Uses old_options as the previous options.
+ *
+ * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
+ * on error.
+ */
+int
+options_validate_server_transport(const or_options_t *old_options,
+                                  or_options_t *options,
+                                  char **msg)
+{
+  (void)old_options;
+
+  if (BUG(!options))
+    return -1;
+
+  if (BUG(!msg))
+    return -1;
+
+  config_line_t *cl;
+
+  for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
+    if (parse_transport_line(options, cl->value, 1, 1) < 0)
+      REJECT("Invalid server transport line. See logs for details.");
+  }
+
+  if (options->ServerTransportPlugin && !server_mode(options)) {
+    log_notice(LD_GENERAL, "Tor is not configured as a relay but you specified"
+               " a ServerTransportPlugin line (%s). The ServerTransportPlugin "
+               "line will be ignored.",
+               escaped(options->ServerTransportPlugin->value));
+  }
+
+  for (cl = options->ServerTransportListenAddr; cl; cl = cl->next) {
+    /** If get_bindaddr_from_transport_listen_line() fails with
+        'transport' being NULL, it means that something went wrong
+        while parsing the ServerTransportListenAddr line. */
+    char *bindaddr = get_bindaddr_from_transport_listen_line(cl->value, NULL);
+    if (!bindaddr)
+      REJECT("ServerTransportListenAddr did not parse. See logs for details.");
+    tor_free(bindaddr);
+  }
+
+  if (options->ServerTransportListenAddr && !options->ServerTransportPlugin) {
+    log_notice(LD_GENERAL, "You need at least a single managed-proxy to "
+               "specify a transport listen address. The "
+               "ServerTransportListenAddr line will be ignored.");
+  }
+
+  for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
+    /** If get_options_from_transport_options_line() fails with
+        'transport' being NULL, it means that something went wrong
+        while parsing the ServerTransportOptions line. */
+    smartlist_t *options_sl =
+      get_options_from_transport_options_line(cl->value, NULL);
+    if (!options_sl)
+      REJECT("ServerTransportOptions did not parse. See logs for details.");
+
+    SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
+    smartlist_free(options_sl);
+  }
+
+  return 0;
+}
diff --git a/src/feature/relay/transport_config.h b/src/feature/relay/transport_config.h
new file mode 100644
index 000000000..6ef1bc402
--- /dev/null
+++ b/src/feature/relay/transport_config.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file transport_config.h
+ * @brief Header for feature/relay/transport_config.c
+ **/
+
+#ifndef TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H
+#define TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H
+
+typedef struct or_options_t or_options_t;
+typedef struct smartlist_t smartlist_t;
+
+char *get_transport_bindaddr_from_config(const char *transport);
+smartlist_t *get_options_from_transport_options_line(const char *line,
+                                                     const char *transport);
+smartlist_t *get_options_for_server_transport(const char *transport);
+
+int options_validate_server_transport(const or_options_t *old_options,
+                                      or_options_t *options,
+                                      char **msg);
+
+#endif /* !defined(TOR_FEATURE_RELAY_TRANSPORT_CONFIG_H) */
diff --git a/src/test/test_config.c b/src/test/test_config.c
index df025fb8f..fce6ad97d 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -18,6 +18,7 @@
 #include "core/or/circuitbuild.h"
 #include "app/config/config.h"
 #include "feature/relay/relay_config.h"
+#include "feature/relay/transport_config.h"
 #include "lib/confmgt/confmgt.h"
 #include "core/mainloop/connection.h"
 #include "core/or/connection_edge.h"



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits