[tor-commits] [tor/master] Add support for parsing SOCKS arguments.

nickm at torproject.org nickm at torproject.org
Tue Mar 19 17:25:51 UTC 2013


commit 757b03aacbf7051194bbe9faa2bfcc59e4cc3392
Author: George Kadianakis <desnacked at riseup.net>
Date:   Mon Dec 17 14:31:13 2012 +0200

    Add support for parsing SOCKS arguments.
---
 src/or/config.c     |   71 +++++++++++++++++++++++++++++++++++++++++++++------
 src/or/entrynodes.c |   20 +++++++++++++-
 src/or/entrynodes.h |    4 ++-
 3 files changed, 84 insertions(+), 11 deletions(-)

diff --git a/src/or/config.c b/src/or/config.c
index 31695ba..3e75359 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -4036,10 +4036,11 @@ parse_bridge_line(const char *line, int validate_only)
   int r;
   char *addrport=NULL, *fingerprint=NULL;
   char *transport_name=NULL;
-  char *field1=NULL;
+  char *field=NULL;
   tor_addr_t addr;
   uint16_t port = 0;
   char digest[DIGEST_LEN];
+  smartlist_t *socks_args = NULL;
 
   items = smartlist_new();
   smartlist_split_string(items, line, NULL,
@@ -4049,13 +4050,13 @@ parse_bridge_line(const char *line, int validate_only)
     goto err;
   }
 
-  /* field1 is either a transport name or addrport */
-  field1 = smartlist_get(items, 0);
+  /* field is either a transport name or addrport */
+  field = smartlist_get(items, 0);
   smartlist_del_keeporder(items, 0);
 
-  if (!(strstr(field1, ".") || strstr(field1, ":"))) {
+  if (!(strstr(field, ".") || strstr(field, ":"))) {
     /* new-style bridge line */
-    transport_name = field1;
+    transport_name = field;
     if (smartlist_len(items) < 1) {
       log_warn(LD_CONFIG, "Too few items to Bridge line.");
       goto err;
@@ -4063,7 +4064,7 @@ parse_bridge_line(const char *line, int validate_only)
     addrport = smartlist_get(items, 0);
     smartlist_del_keeporder(items, 0);
   } else {
-    addrport = field1;
+    addrport = field;
   }
 
   if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
@@ -4077,8 +4078,28 @@ parse_bridge_line(const char *line, int validate_only)
     port = 443;
   }
 
+  /* If transports are enabled, next field could be a fingerprint or a
+     socks argument. If transports are disabled, next field should be
+     a fingerprint. */
   if (smartlist_len(items)) {
-    fingerprint = smartlist_join_strings(items, "", 0, NULL);
+    if (transport_name) { /* transports enabled: */
+      field = smartlist_get(items, 0);
+      smartlist_del_keeporder(items, 0);
+
+      /* If '=', it's a k=v value pair. */
+      if (strchr(field, '=')) {
+        socks_args = smartlist_new();
+        smartlist_add(socks_args, field);
+      } else { /* If no '=', it's the fingerprint. */
+        fingerprint = field;
+      }
+
+    } else { /* transports disabled: */
+      fingerprint = smartlist_join_strings(items, "", 0, NULL);
+    }
+  }
+
+  if (fingerprint) {
     if (strlen(fingerprint) != HEX_DIGEST_LEN) {
       log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
       goto err;
@@ -4089,13 +4110,39 @@ parse_bridge_line(const char *line, int validate_only)
     }
   }
 
+  /* If we are using transports, any remaining items in the smartlist
+     must be k=v values. */
+  if (transport_name && smartlist_len(items)) {
+    if (!socks_args)
+      socks_args = smartlist_new();
+
+    /* append remaining items of 'items' to 'socks_args' */
+    smartlist_add_all(socks_args, items);
+    smartlist_clear(items);
+
+    tor_assert(smartlist_len(socks_args) > 0);
+  }
+
   if (!validate_only) {
     log_debug(LD_DIR, "Bridge at %s (transport: %s) (%s)",
               fmt_addrport(&addr, port),
               transport_name ? transport_name : "no transport",
               fingerprint ? fingerprint : "no key listed");
+
+    if (socks_args) { /* print socks arguments */
+      int i = 0;
+
+      tor_assert(smartlist_len(socks_args) > 0);
+
+      log_debug(LD_DIR, "Bridge uses %d SOCKS arguments:",
+                smartlist_len(socks_args));
+      SMARTLIST_FOREACH(socks_args, const char *, arg,
+                        log_debug(LD_CONFIG, "%d: %s", ++i, arg));
+    }
+
     bridge_add_from_config(&addr, port,
-                           fingerprint ? digest : NULL, transport_name);
+                           fingerprint ? digest : NULL,
+                           transport_name, socks_args);
   }
 
   r = 0;
@@ -4110,6 +4157,14 @@ parse_bridge_line(const char *line, int validate_only)
   tor_free(addrport);
   tor_free(transport_name);
   tor_free(fingerprint);
+
+  /* We only have to free socks_args if we are validating, since
+     otherwise bridge_add_from_config() steals its reference. */
+  if (socks_args && validate_only) {
+    SMARTLIST_FOREACH(socks_args, char*, s, tor_free(s));
+    smartlist_free(socks_args);
+  }
+
   return r;
 }
 
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 4ca56cb..63545ce 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -52,6 +52,10 @@ typedef struct {
 
   /** When should we next try to fetch a descriptor for this bridge? */
   download_status_t fetch_status;
+
+  /** A smartlist of k=v values to be passed to the SOCKS proxy, if
+      transports are used for this bridge. */
+  smartlist_t *socks_args;
 } bridge_info_t;
 
 /** A list of our chosen entry guards. */
@@ -1446,6 +1450,11 @@ bridge_free(bridge_info_t *bridge)
     return;
 
   tor_free(bridge->transport_name);
+  if (bridge->socks_args) {
+    SMARTLIST_FOREACH(bridge->socks_args, char*, s, tor_free(s));
+    smartlist_free(bridge->socks_args);
+  }
+
   tor_free(bridge);
 }
 
@@ -1628,10 +1637,16 @@ bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
  * is set, it tells us the identity key too.  If we already had the
  * bridge in our list, unmark it, and don't actually add anything new.
  * If <b>transport_name</b> is non-NULL - the bridge is associated with a
- * pluggable transport - we assign the transport to the bridge. */
+ * pluggable transport - we assign the transport to the bridge.
+ * If <b>transport_name</b> is non-NULL - the bridge is associated
+ * with a pluggable transport - we assign the transport to the bridge.
+ * If <b>socks_args</b> is non-NULL, it's a smartlist carrying
+ * key=value pairs to be passed to the pluggable transports
+ * proxy. This function steals reference of the smartlist. */
 void
 bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
-                       const char *digest, const char *transport_name)
+                       const char *digest, const char *transport_name,
+                       smartlist_t *socks_args)
 {
   bridge_info_t *b;
 
@@ -1645,6 +1660,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
   if (transport_name)
     b->transport_name = tor_strdup(transport_name);
   b->fetch_status.schedule = DL_SCHED_BRIDGE;
+  b->socks_args = socks_args;
   if (!bridge_list)
     bridge_list = smartlist_new();
 
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index b673d02..6865231 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -97,9 +97,11 @@ int routerinfo_is_a_configured_bridge(const routerinfo_t *ri);
 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);
+struct smartlist_t;
 void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
                             const char *digest,
-                            const char *transport_name);
+                            const char *transport_name,
+                            struct smartlist_t *socks_args);
 void retry_bridge_descriptor_fetch_directly(const char *digest);
 void fetch_bridge_descriptors(const or_options_t *options, time_t now);
 void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);





More information about the tor-commits mailing list