[tor-commits] [tor/master] We can now match our transports with our bridges.

nickm at torproject.org nickm at torproject.org
Mon Jul 11 20:01:36 UTC 2011


commit e09f302589dc3e46edccf366595392f2dd9b43e3
Author: George Kadianakis <desnacked at gmail.com>
Date:   Sat Jun 11 23:20:39 2011 +0200

    We can now match our transports with our bridges.
---
 src/or/circuitbuild.c |  117 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/or/circuitbuild.h |   24 ++++++++++-
 src/or/config.c       |   14 +++++-
 3 files changed, 150 insertions(+), 5 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 68ca569..c07e890 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -4511,6 +4511,15 @@ typedef struct {
   /** Expected identity digest, or all zero bytes if we don't know what the
    * digest should be. */
   char identity[DIGEST_LEN];
+
+  /** Name of pluggable transport protocol taken from its config line.
+      Free'd when we match the bridge with a transport at 
+      match_bridges_with_transports(). */
+  char *transport_name_config;
+
+  /** Pluggable transport proxy this bridge uses. */
+  transport_info_t *transport;
+
   /** When should we next try to fetch a descriptor for this bridge? */
   download_status_t fetch_status;
 } bridge_info_t;
@@ -4557,6 +4566,109 @@ clear_bridge_list(void)
   smartlist_clear(bridge_list);
 }
 
+/** A list of pluggable transports found in torrc. */
+static smartlist_t *transport_list = NULL;
+
+/** Initialize the pluggable transports list to empty, creating it if
+    needed. */
+void
+clear_transport_list(void)
+{
+  if (!transport_list)
+    transport_list = smartlist_create();
+  SMARTLIST_FOREACH(transport_list, transport_info_t *, t, transport_free(t));
+  smartlist_clear(transport_list);
+}
+
+/**
+   Free the transport_info_t <b>transport</b>.
+*/
+static void
+transport_free(transport_info_t *transport)
+{
+  tor_free(transport->name);
+  tor_free(transport);
+}
+
+/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
+    <b>name</b> is set to the name of the protocol this proxy uses.
+    <b>socks_ver</b> is set to the SOCKS version of the proxy.
+*/
+void
+transport_add_from_config(const tor_addr_t *addr, uint16_t port,
+                          const char *name, int socks_ver)
+{
+  transport_info_t *t = tor_malloc_zero(sizeof(transport_info_t));
+
+  tor_addr_copy(&t->addr, addr);
+  t->port = port;
+  /** check strdup return */
+  t->name = strdup(name);
+  t->socks_version = socks_ver;
+  if (!transport_list)
+    transport_list = smartlist_create();
+
+  smartlist_add(transport_list, t);
+}
+
+/**
+   Attempts to map every transport found on torrc to it's
+   corresponding bridge.
+   Returns 1 on a succesfull bijective map, otherwise it returns -1.
+*/
+int
+match_bridges_with_transports(void)
+{
+  /* Used to check if a transport was finally found for a bridge */ 
+  int found_match=0;
+  /* Number of matches. */
+  int n_matches=0;
+  /* Number of transports. */
+  int n_transports=0;
+
+  tor_assert(transport_list);
+  tor_assert(bridge_list);
+  
+  /* Iterate bridges */
+  SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) 
+    {
+      /* Skip bridges without transports. */
+      if (!b->transport_name_config)
+        continue;
+      found_match=0;
+      /* Iterate transports */
+      SMARTLIST_FOREACH_BEGIN(transport_list, transport_info_t *, t) 
+        {
+          /* If the transport name of the transport is the same as the
+             transport name of the bridge, we have a match. */
+          if (!strcmp(b->transport_name_config, t->name)) {
+            found_match=1;
+            n_matches++;
+            b->transport = t;
+            tor_free(b->transport_name_config);
+            log_warn(LD_CONFIG, "Matched transport '%s'", t->name); 
+            continue;
+          }
+        } SMARTLIST_FOREACH_END(t);
+      if (!found_match) {
+        log_warn(LD_CONFIG, "Couldn't find transport "
+                 "match for %s!\n", b->transport_name_config);
+        return -1;
+      }
+    }  SMARTLIST_FOREACH_END(b);
+
+  /* count number of transports to see if there were transports 
+     that didn't get matched to a bridge. */
+  SMARTLIST_FOREACH(transport_list, transport_info_t *, t, n_transports++);
+  if (n_transports != n_matches) {
+    log_warn(LD_CONFIG, "You have %d transports and we only "
+             "managed to match %d of them!\n", n_transports, n_matches);
+    return -1;
+  }
+
+  return 1;
+}                    
+
 /** Return a bridge pointer if <b>ri</b> is one of our known bridges
  * (either by comparing keys if possible, else by comparing addr/port).
  * Else return NULL. */
@@ -4638,7 +4750,7 @@ learned_router_identity(const tor_addr_t *addr, uint16_t port,
  * bridge in our list, unmark it, and don't actually add anything new. */
 void
 bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
-                       const char *digest)
+                       const char *digest, const char *transport_name)
 {
   bridge_info_t *b;
 
@@ -4652,6 +4764,8 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
   b->port = port;
   if (digest)
     memcpy(b->identity, digest, DIGEST_LEN);
+  if (transport_name)
+    b->transport_name_config = strdup(transport_name);
   b->fetch_status.schedule = DL_SCHED_BRIDGE;
   if (!bridge_list)
     bridge_list = smartlist_create();
@@ -4994,6 +5108,7 @@ entry_guards_free_all(void)
     entry_guards = NULL;
   }
   clear_bridge_list();
+  clear_transport_list();
   smartlist_free(bridge_list);
   bridge_list = NULL;
 }
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index b1eb5a6..eb6fdba 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -12,6 +12,22 @@
 #ifndef _TOR_CIRCUITBUILD_H
 #define _TOR_CIRCUITBUILD_H
 
+/**
+   Represents a pluggable transport proxy used by a bridge. */
+typedef struct {
+  /* SOCKS version */
+  int socks_version;
+
+  /* Name of pluggable transport protocol */
+  char *name;
+
+  /* Address of proxy */
+  tor_addr_t addr;
+
+  /* Port of proxy */
+  uint16_t port;
+} transport_info_t;
+
 char *circuit_list_path(origin_circuit_t *circ, int verbose);
 char *circuit_list_path_for_controller(origin_circuit_t *circ);
 void circuit_log_path(int severity, unsigned int domain,
@@ -70,7 +86,8 @@ int node_is_a_configured_bridge(const node_t *node);
 void learned_router_identity(const tor_addr_t *addr, uint16_t port,
                              const char *digest);
 void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
-                            const char *digest);
+                            const char *digest, 
+                            const char *transport_name);
 void retry_bridge_descriptor_fetch_directly(const char *digest);
 void fetch_bridge_descriptors(or_options_t *options, time_t now);
 void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
@@ -126,5 +143,10 @@ void circuit_build_times_network_circ_success(circuit_build_times_t *cbt);
 
 int circuit_build_times_get_bw_scale(networkstatus_t *ns);
 
+
+void clear_transport_list(void);
+int match_bridges_with_transports(void);
+void transport_add_from_config(const tor_addr_t *addr, uint16_t port,
+                               const char *name, int socks_ver);
 #endif
 
diff --git a/src/or/config.c b/src/or/config.c
index a1960dd..39d7f5b 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1208,6 +1208,7 @@ options_act(or_options_t *old_options)
     return -1;
 
   if (options->ClientTransportPlugin) {
+    clear_transport_list();
     for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
       if (parse_transport_line(cl->value, 0)<0) {
         log_warn(LD_BUG,
@@ -1230,6 +1231,13 @@ options_act(or_options_t *old_options)
     sweep_bridge_list();
   }
 
+  /** Okay, we have Bridges and we have ClientTransportPlugins. Let's
+      match them together. */
+  if (options->Bridges && options->ClientTransportPlugin) {
+    if (match_bridges_with_transports() < 0)
+      return -1;
+  }
+
   if (running_tor && rend_config_services(options, 0)<0) {
     log_warn(LD_BUG,
        "Previously validated hidden services line could not be added!");
@@ -4629,7 +4637,7 @@ parse_bridge_line(const char *line, int validate_only)
               fmt_addr(&addr), (int)port, transport_name,
               fingerprint ? fingerprint : "no key listed");
     bridge_add_from_config(&addr, port, 
-                           fingerprint ? digest : NULL/*, transport_name*/);
+                           fingerprint ? digest : NULL, transport_name);
   }
 
   r = 0;
@@ -4702,8 +4710,8 @@ parse_transport_line(const char *line, int validate_only)
   if (!validate_only) {
     log_warn(LD_DIR, "Transport %s at %s:%d", name,
               fmt_addr(&addr), (int)port);
-    /*    transport_add_from_config(&addr, port, 
-          fingerprint ? digest : NULL, transport); */
+    transport_add_from_config(&addr, port, name,
+                              socks_ver);
   }
 
   r = 0;





More information about the tor-commits mailing list