diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 21018dcc71..4dcc685bca 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4514,7 +4514,7 @@ typedef struct { 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 + Free'd when we match the bridge with a transport at match_bridges_with_transports(). */ char *transport_name_config; @@ -4603,8 +4603,7 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, tor_addr_copy(&t->addr, addr); t->port = port; - /** check strdup return */ - t->name = strdup(name); + t->name = tor_strdup(name); t->socks_version = socks_ver; if (!transport_list) transport_list = smartlist_create(); @@ -4620,7 +4619,7 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, int match_bridges_with_transports(void) { - /* Used to check if a transport was finally found for a bridge */ + /* Used to check if a transport was finally found for a bridge */ int found_match=0; /* Number of matches. */ int n_matches=0; @@ -4629,16 +4628,16 @@ match_bridges_with_transports(void) tor_assert(transport_list); tor_assert(bridge_list); - + /* Iterate bridges */ - SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) + 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) + 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. */ @@ -4647,28 +4646,29 @@ match_bridges_with_transports(void) n_matches++; b->transport = t; tor_free(b->transport_name_config); - log_warn(LD_CONFIG, "Matched transport '%s'", t->name); + 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); + /* tor_free(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. */ + /* Count number of transports to make sure that all transports got + matched to bridges. */ 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 " + log_warn(LD_CONFIG, "You have %d transports but we only " "managed to match %d of them!\n", n_transports, n_matches); return -1; } return 1; -} +} /** Return a bridge pointer if ri is one of our known bridges * (either by comparing keys if possible, else by comparing addr/port). @@ -4748,7 +4748,10 @@ learned_router_identity(const tor_addr_t *addr, uint16_t port, /** Remember a new bridge at addr:port. If digest * 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. */ + * 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. + */ void bridge_add_from_config(const tor_addr_t *addr, uint16_t port, const char *digest, const char *transport_name) @@ -4805,11 +4808,12 @@ find_bridge_by_digest(const char *digest) } /** If addr and port match one of our known bridges, - * returns it's transport protocol if it has one, else returns NULL. + * returns its transport protocol if it has one, else returns NULL. */ transport_info_t * -find_bridge_transport_by_addrport(const tor_addr_t *addr, uint16_t port) +find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port) { + assert(bridge_list); SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { if (tor_addr_eq(&bridge->addr, addr) && diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 047de117f5..c1833d23e5 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -17,13 +17,10 @@ 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; @@ -86,7 +83,7 @@ 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); @@ -143,13 +140,12 @@ 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); transport_info_t * -find_bridge_transport_by_addrport(const tor_addr_t *addr, uint16_t port); +find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port); #endif diff --git a/src/or/config.c b/src/or/config.c index 39d7f5b589..b659d9b7a9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -205,7 +205,7 @@ static config_var_t _option_vars[] = { V(ClientDNSRejectInternalAddresses, BOOL,"1"), V(ClientOnly, BOOL, "0"), V(ClientRejectInternalAddresses, BOOL, "1"), - VAR("ClientTransportPlugin", LINELIST, ClientTransportPlugin, NULL), + VAR("ClientTransportPlugin", LINELIST, ClientTransportPlugin, NULL), V(ConsensusParams, STRING, NULL), V(ConnLimit, UINT, "1000"), V(ConnDirectionStatistics, BOOL, "0"), @@ -571,7 +571,7 @@ static int check_nickname_list(const char *lst, const char *name, char **msg); static void config_register_addressmaps(or_options_t *options); static int parse_bridge_line(const char *line, int validate_only); -static int parse_transport_line(const char *line, int validate_only); +static int parse_client_transport_line(const char *line, int validate_only); static int parse_dir_server_line(const char *line, dirinfo_type_t required_type, int validate_only); @@ -1210,7 +1210,7 @@ options_act(or_options_t *old_options) if (options->ClientTransportPlugin) { clear_transport_list(); for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { - if (parse_transport_line(cl->value, 0)<0) { + if (parse_client_transport_line(cl->value, 0)<0) { log_warn(LD_BUG, "Previously validated ClientTransportPlugin line " "could not be added!"); @@ -1218,7 +1218,7 @@ options_act(or_options_t *old_options) } } } - + if (options->Bridges) { mark_bridge_list(); for (cl = options->Bridges; cl; cl = cl->next) { @@ -1234,6 +1234,7 @@ options_act(or_options_t *old_options) /** Okay, we have Bridges and we have ClientTransportPlugins. Let's match them together. */ if (options->Bridges && options->ClientTransportPlugin) { + assert(!server_mode(options)); if (match_bridges_with_transports() < 0) return -1; } @@ -3688,8 +3689,11 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->ClientTransportPlugin) { if (!options->Bridges) REJECT("ClientTransportPlugin found without any bridges."); + if (server_mode(options)) + REJECT("ClientTransportPlugin found but we are a server."); + for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { - if (parse_transport_line(cl->value, 1)<0) + if (parse_client_transport_line(cl->value, 1)<0) REJECT("Transport line did not parse. See logs for details."); } } @@ -4633,10 +4637,10 @@ parse_bridge_line(const char *line, int validate_only) } if (!validate_only) { - log_warn(LD_DIR, "Bridge at %s:%d with transport %s (%s)", + log_debug(LD_DIR, "Bridge at %s:%d with transport %s (%s)", fmt_addr(&addr), (int)port, transport_name, fingerprint ? fingerprint : "no key listed"); - bridge_add_from_config(&addr, port, + bridge_add_from_config(&addr, port, fingerprint ? digest : NULL, transport_name); } @@ -4655,8 +4659,14 @@ parse_bridge_line(const char *line, int validate_only) return r; } +/** Read the contents of a ClientTransportPlugin line from + * line. Return 0 if the line is well-formed, and -1 if it + * isn't. If validate_only is 0, and the line is well-formed, + * then add the transport described in the line to our internal + * transport list. +*/ static int -parse_transport_line(const char *line, int validate_only) +parse_client_transport_line(const char *line, int validate_only) { smartlist_t *items = NULL; int r; @@ -4665,24 +4675,24 @@ parse_transport_line(const char *line, int validate_only) char *addrport=NULL; int socks_ver; tor_addr_t addr; - uint16_t port = 0; + uint16_t port = 0; items = smartlist_create(); smartlist_split_string(items, line, NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); - + if (smartlist_len(items) < 3) { - log_warn(LD_CONFIG, "parse_transport_line(): " + log_warn(LD_CONFIG, "parse_client_transport_line(): " "Too few arguments on ClientTransportPlugin line."); goto err; } - + name = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); - + socks_ver_str = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); - + if (!strcmp(socks_ver_str,"socks4")) socks_ver = PROXY_SOCKS4; else if (!strcmp(socks_ver_str,"socks5")) @@ -4706,9 +4716,9 @@ parse_transport_line(const char *line, int validate_only) "Transport address '%s' has no port.", addrport); goto err; } - + if (!validate_only) { - log_warn(LD_DIR, "Transport %s at %s:%d", name, + log_debug(LD_DIR, "Transport %s found at %s:%d", name, fmt_addr(&addr), (int)port); transport_add_from_config(&addr, port, name, socks_ver); @@ -4727,7 +4737,7 @@ parse_transport_line(const char *line, int validate_only) tor_free(name); tor_free(addrport); return r; -} +} /** Read the contents of a DirServer line from line. If * validate_only is 0, and the line is well-formed, and it diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 7cfe2e7689..cca7c9f8e9 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -335,11 +335,11 @@ connection_or_finished_connecting(or_connection_t *or_conn) proxy_type = PROXY_SOCKS4; else if (get_options()->Socks5Proxy) proxy_type = PROXY_SOCKS5; - else if (get_options()->UseBridges) { + else if (get_options()->ClientTransportPlugin) { transport_info_t *transport; - transport = find_bridge_transport_by_addrport(&conn->addr,conn->port); + transport = find_transport_by_bridge_addrport(&conn->addr,conn->port); if (transport) { /* this bridge supports transports. use proxy. */ - log_warn(LD_GENERAL, "Setting up pluggable transport plugin proxy type!\n"); + log_debug(LD_GENERAL, "Found transport. Setting proxy type!\n"); proxy_type = transport->socks_version; } } @@ -871,10 +871,9 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, port = options->Socks5ProxyPort; } else if (options->ClientTransportPlugin) { transport_info_t *transport; - transport = find_bridge_transport_by_addrport(&addr, port); + transport = find_transport_by_bridge_addrport(&addr, port); if (transport) { - log_warn(LD_GENERAL, "Our bridge uses a pluggable transport plugin. " - "Setting up proxying!"); + log_debug(LD_GENERAL, "Found transport. Setting up proxying!"); using_proxy = 1; tor_addr_copy(&addr, &transport->addr); port = transport->port; diff --git a/src/or/or.h b/src/or/or.h index 062352aee3..8cc2af2e83 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2660,7 +2660,8 @@ typedef struct { config_line_t *Bridges; /**< List of bootstrap bridge addresses. */ - config_line_t *ClientTransportPlugin; /**< List of client transport plugins. */ + config_line_t *ClientTransportPlugin; /**< List of client + transport plugins. */ int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make * this explicit so we can change how we behave in the