From 757b03aacbf7051194bbe9faa2bfcc59e4cc3392 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Mon, 17 Dec 2012 14:31:13 +0200 Subject: [PATCH] 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 31695baa73..3e7535966c 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 4ca56cbacf..63545ce9b8 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 transport_name 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 transport_name is non-NULL - the bridge is associated + * with a pluggable transport - we assign the transport to the bridge. + * If socks_args 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 b673d02681..6865231f57 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);