From 20c31c80fb7265e8987747b3cdba04f16c352b15 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Sat, 11 Jun 2011 17:08:31 +0200 Subject: ClientTransportPlugin parsing done. --- src/or/config.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/or/or.h | 2 + 2 files changed, 118 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index d663336796..a1960dd8fc 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -203,8 +203,9 @@ static config_var_t _option_vars[] = { V(CircuitStreamTimeout, INTERVAL, "0"), V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/ V(ClientDNSRejectInternalAddresses, BOOL,"1"), - V(ClientRejectInternalAddresses, BOOL, "1"), V(ClientOnly, BOOL, "0"), + V(ClientRejectInternalAddresses, BOOL, "1"), + VAR("ClientTransportPlugin", LINELIST, ClientTransportPlugin, NULL), V(ConsensusParams, STRING, NULL), V(ConnLimit, UINT, "1000"), V(ConnDirectionStatistics, BOOL, "0"), @@ -570,6 +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_dir_server_line(const char *line, dirinfo_type_t required_type, int validate_only); @@ -1205,6 +1207,17 @@ options_act(or_options_t *old_options) if (consider_adding_dir_authorities(options, old_options) < 0) return -1; + if (options->ClientTransportPlugin) { + for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { + if (parse_transport_line(cl->value, 0)<0) { + log_warn(LD_BUG, + "Previously validated ClientTransportPlugin line " + "could not be added!"); + return -1; + } + } + } + if (options->Bridges) { mark_bridge_list(); for (cl = options->Bridges; cl; cl = cl->next) { @@ -3663,6 +3676,16 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->UseBridges && !options->TunnelDirConns) REJECT("TunnelDirConns set to 0 only works with UseBridges set to 0"); + + if (options->ClientTransportPlugin) { + if (!options->Bridges) + REJECT("ClientTransportPlugin found without any bridges."); + for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { + if (parse_transport_line(cl->value, 1)<0) + REJECT("Transport line did not parse. See logs for details."); + } + } + if (options->Bridges) { for (cl = options->Bridges; cl; cl = cl->next) { if (parse_bridge_line(cl->value, 1)<0) @@ -4553,6 +4576,8 @@ parse_bridge_line(const char *line, int validate_only) smartlist_t *items = NULL; int r; char *addrport=NULL, *fingerprint=NULL; + char *transport_name=NULL; + char *field1=NULL; tor_addr_t addr; uint16_t port = 0; char digest[DIGEST_LEN]; @@ -4564,8 +4589,18 @@ parse_bridge_line(const char *line, int validate_only) log_warn(LD_CONFIG, "Too few arguments to Bridge line."); goto err; } - addrport = smartlist_get(items, 0); + + /* field1 is either a transport name or addrport */ + field1 = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); + + if (!strstr(field1, ".")) { /* new-style bridge line */ + transport_name = field1; + addrport = smartlist_get(items, 0); + smartlist_del_keeporder(items, 0); + } else + addrport = field1; + if (tor_addr_port_parse(addrport, &addr, &port)<0) { log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport); goto err; @@ -4590,10 +4625,11 @@ parse_bridge_line(const char *line, int validate_only) } if (!validate_only) { - log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr), - (int)port, + log_warn(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, fingerprint ? digest : NULL); + bridge_add_from_config(&addr, port, + fingerprint ? digest : NULL/*, transport_name*/); } r = 0; @@ -4607,9 +4643,84 @@ parse_bridge_line(const char *line, int validate_only) smartlist_free(items); tor_free(addrport); tor_free(fingerprint); + tor_free(transport_name); return r; } +static int +parse_transport_line(const char *line, int validate_only) +{ + smartlist_t *items = NULL; + int r; + char *socks_ver_str=NULL; + char *name=NULL; + char *addrport=NULL; + int socks_ver; + tor_addr_t addr; + 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(): " + "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")) + socks_ver = PROXY_SOCKS5; + else { + log_warn(LD_CONFIG, "Strange transport proxy type."); + goto err; + } + + addrport = smartlist_get(items, 0); + smartlist_del_keeporder(items, 0); + + if (tor_addr_port_parse(addrport, &addr, &port)<0) { + log_warn(LD_CONFIG, "Error parsing transport " + "address '%s'", addrport); + goto err; + } + + if (!port) { + log_warn(LD_CONFIG, + "Transport address '%s' has no port.", addrport); + goto err; + } + + 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); */ + } + + r = 0; + goto done; + + err: + r = -1; + + done: + SMARTLIST_FOREACH(items, char*, s, tor_free(s)); + smartlist_free(items); + tor_free(socks_ver_str); + 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 * shares any bits with required_type or required_type diff --git a/src/or/or.h b/src/or/or.h index b4000add81..062352aee3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2660,6 +2660,8 @@ typedef struct { config_line_t *Bridges; /**< List of bootstrap bridge addresses. */ + 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 * future. */ -- cgit v1.2.3-54-g00ecf From e09f302589dc3e46edccf366595392f2dd9b43e3 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Sat, 11 Jun 2011 23:20:39 +0200 Subject: 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(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 68ca569649..c07e890c07 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 transport. +*/ +static void +transport_free(transport_info_t *transport) +{ + tor_free(transport->name); + tor_free(transport); +} + +/** Remember a new pluggable transport proxy at addr:port. + name is set to the name of the protocol this proxy uses. + socks_ver 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 ri 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 b1eb5a6cad..eb6fdbaf3f 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 a1960dd8fc..39d7f5b589 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; -- cgit v1.2.3-54-g00ecf From 29203b7f3f6d07dec1cede65f118aa450ac7712d Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Sun, 12 Jun 2011 00:14:11 +0200 Subject: We can now connect using transports as well! --- src/or/circuitbuild.c | 21 +++++++++++++++++++++ src/or/circuitbuild.h | 3 +++ src/or/connection_or.c | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index c07e890c07..21018dcc71 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -100,6 +100,7 @@ static int count_acceptable_nodes(smartlist_t *routers); static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice); static void entry_guards_changed(void); +static void transport_free(transport_info_t *transport); /** * This function decides if CBT learning should be disabled. It returns @@ -4803,6 +4804,26 @@ find_bridge_by_digest(const char *digest) return NULL; } +/** If addr and port match one of our known bridges, + * returns it's 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) +{ + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) + { + if (tor_addr_eq(&bridge->addr, addr) && + (bridge->port == port)) { + if (bridge->transport) { + log_debug(LD_GENERAL, "Found matching bridge!\n"); + return bridge->transport; + } else /* bridge found, but it had no transport */ + return NULL; + } + } SMARTLIST_FOREACH_END(bridge); + return NULL; +} + /** We need to ask bridge for its server descriptor. */ static void launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index eb6fdbaf3f..047de117f5 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -148,5 +148,8 @@ 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); + #endif diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 73aad7e485..7cfe2e7689 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -335,6 +335,14 @@ 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) { + transport_info_t *transport; + transport = find_bridge_transport_by_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"); + proxy_type = transport->socks_version; + } + } if (proxy_type != PROXY_NONE) { /* start proxy handshake */ @@ -861,6 +869,16 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, using_proxy = 1; tor_addr_copy(&addr, &options->Socks5ProxyAddr); port = options->Socks5ProxyPort; + } else if (options->ClientTransportPlugin) { + transport_info_t *transport; + transport = find_bridge_transport_by_addrport(&addr, port); + if (transport) { + log_warn(LD_GENERAL, "Our bridge uses a pluggable transport plugin. " + "Setting up proxying!"); + using_proxy = 1; + tor_addr_copy(&addr, &transport->addr); + port = transport->port; + } } switch (connection_connect(TO_CONN(conn), conn->_base.address, -- cgit v1.2.3-54-g00ecf From 00ec4b2c002928f1a901950e2cc851578f295b1b Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Sun, 12 Jun 2011 16:41:32 +0200 Subject: Various trivial changes. * Improved function documentation. * Renamed find_bridge_transport_by_addrport() to find_transport_by_bridge_addrport(). * Sanitized log severities we use. * Ran check-spaces. --- src/or/circuitbuild.c | 34 +++++++++++++++++++--------------- src/or/circuitbuild.h | 8 ++------ src/or/config.c | 44 +++++++++++++++++++++++++++----------------- src/or/connection_or.c | 11 +++++------ src/or/or.h | 3 ++- 5 files changed, 55 insertions(+), 45 deletions(-) (limited to 'src') 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 -- cgit v1.2.3-54-g00ecf From a79bea40d84fd369ef4df950765afc4c635f9b31 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 14 Jun 2011 02:51:59 +0200 Subject: We now warn the user if a proxy server is not up when we try to connect with it. --- src/or/config.c | 13 +++++++++++-- src/or/connection.c | 1 + src/or/connection_or.c | 11 +++++------ src/or/main.c | 10 ++++++++++ src/or/or.h | 25 ++++++++++++++++++------- 5 files changed, 45 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index b659d9b7a9..47702873bb 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -3565,8 +3565,17 @@ options_validate(or_options_t *old_options, or_options_t *options, } } - if (options->Socks4Proxy && options->Socks5Proxy) - REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy"); + /* Check if more than one proxy type has been enabled. This looks REALLY ugly! */ + if ((options->Socks4Proxy && (options->Socks5Proxy || options->HTTPSProxy + || options->ClientTransportPlugin)) || + (options->Socks5Proxy && (options->Socks4Proxy || options->HTTPSProxy + || options->ClientTransportPlugin)) || + (options->HTTPSProxy && (options->Socks4Proxy || options->Socks5Proxy + || options->ClientTransportPlugin)) || + (options->ClientTransportPlugin && (options->Socks4Proxy + || options->Socks5Proxy || options->HTTPSProxy))) + REJECT("You have configured more than one proxy types. " + "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)"); if (options->Socks5ProxyUsername) { size_t len; diff --git a/src/or/connection.c b/src/or/connection.c index 81f0cdf812..ae6950254d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1461,6 +1461,7 @@ connection_proxy_state_to_string(int state) static const char *unknown = "???"; static const char *states[] = { "PROXY_NONE", + "PROXY_INFANT", "PROXY_HTTPS_WANT_CONNECT_OK", "PROXY_SOCKS4_WANT_CONNECT_OK", "PROXY_SOCKS5_WANT_AUTH_METHOD_NONE", diff --git a/src/or/connection_or.c b/src/or/connection_or.c index cca7c9f8e9..b72cd77e46 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -837,7 +837,6 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, or_connection_t *conn; or_options_t *options = get_options(); int socket_error = 0; - int using_proxy = 0; tor_addr_t addr; tor_assert(_addr); @@ -858,15 +857,15 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, /* use a proxy server if available */ if (options->HTTPSProxy) { - using_proxy = 1; + conn->_base.proxy_state = PROXY_INFANT; tor_addr_copy(&addr, &options->HTTPSProxyAddr); port = options->HTTPSProxyPort; } else if (options->Socks4Proxy) { - using_proxy = 1; + conn->_base.proxy_state = PROXY_INFANT; tor_addr_copy(&addr, &options->Socks4ProxyAddr); port = options->Socks4ProxyPort; } else if (options->Socks5Proxy) { - using_proxy = 1; + conn->_base.proxy_state = PROXY_INFANT; tor_addr_copy(&addr, &options->Socks5ProxyAddr); port = options->Socks5ProxyPort; } else if (options->ClientTransportPlugin) { @@ -874,7 +873,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, transport = find_transport_by_bridge_addrport(&addr, port); if (transport) { log_debug(LD_GENERAL, "Found transport. Setting up proxying!"); - using_proxy = 1; + conn->_base.proxy_state = PROXY_INFANT; tor_addr_copy(&addr, &transport->addr); port = transport->port; } @@ -885,7 +884,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, case -1: /* If the connection failed immediately, and we're using * a proxy, our proxy is down. Don't blame the Tor server. */ - if (!using_proxy) + if (conn->_base.proxy_state == PROXY_INFANT) entry_guard_register_connect_status(conn->identity_digest, 0, 1, time(NULL)); connection_or_connect_failed(conn, diff --git a/src/or/main.c b/src/or/main.c index bb56be7c94..09d35ed46f 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -757,6 +757,16 @@ conn_close_if_marked(int i) #endif log_debug(LD_NET,"Cleaning up connection (fd %d).",conn->s); + + /* If the connection we are about to close was trying to connect to + a proxy server and failed, the client won't be able to use that + proxy. We should warn him about this. */ + if (conn->proxy_state == PROXY_INFANT) { + log_warn(LD_NET, + "The connection to a configured proxy server just failed. " + "Make sure that the proxy server is up and running."); + } + IF_HAS_BUFFEREVENT(conn, goto unlink); if ((SOCKET_OK(conn->s) || conn->linked_conn) && connection_wants_to_flush(conn)) { diff --git a/src/or/or.h b/src/or/or.h index 8cc2af2e83..6f056b24dc 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -232,13 +232,24 @@ typedef enum { #define PROXY_SOCKS5 3 /* Proxy client handshake states */ -#define PROXY_HTTPS_WANT_CONNECT_OK 1 -#define PROXY_SOCKS4_WANT_CONNECT_OK 2 -#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 3 -#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 4 -#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 5 -#define PROXY_SOCKS5_WANT_CONNECT_OK 6 -#define PROXY_CONNECTED 7 +/* We use a proxy but we haven't even connected to it yet. */ +#define PROXY_INFANT 1 +/* We use an HTTP proxy and we've sent the CONNECT command. */ +#define PROXY_HTTPS_WANT_CONNECT_OK 2 +/* We use a SOCKS4 proxy and we've sent the CONNECT command. */ +#define PROXY_SOCKS4_WANT_CONNECT_OK 3 +/* We use a SOCKS5 proxy and we try to negotiate without + any authentication . */ +#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 4 +/* We use a SOCKS5 proxy and we try to negotiate with + Username/Password authentication . */ +#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 5 +/* We use a SOCKS5 proxy and we just sent our credentials. */ +#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 6 +/* We use a SOCKS5 proxy and we just sent our CONNECT command. */ +#define PROXY_SOCKS5_WANT_CONNECT_OK 7 +/* We use a proxy and we CONNECTed successfully!. */ +#define PROXY_CONNECTED 8 /** True iff x is an edge connection. */ #define CONN_IS_EDGE(x) \ -- cgit v1.2.3-54-g00ecf From abe03f494321c985f5909558b5b476269982a894 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 14 Jun 2011 03:27:07 +0200 Subject: Our warning now is much more specific, mentioning proxy type/addr/port. Not included in the previous commit, because the implementation is ugly; I see no other way of doing this though. --- src/or/connection.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/or/connection.h | 1 + src/or/main.c | 7 ++----- src/or/or.h | 2 ++ 4 files changed, 59 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/or/connection.c b/src/or/connection.c index ae6950254d..087ee29ca0 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -66,6 +66,8 @@ static void set_constrained_socket_buffers(tor_socket_t sock, int size); static const char *connection_proxy_state_to_string(int state); static int connection_read_https_proxy_response(connection_t *conn); static void connection_send_socks5_connect(connection_t *conn); +static const char *proxy_type_to_string(int proxy_type); + /** The last IPv4 address that our network interface seemed to have been * binding to, in host order. We use this to detect when our IP changes. */ @@ -3936,7 +3938,7 @@ connection_dump_buffer_mem_stats(int severity) U64_PRINTF_ARG(used_by_type[i]), U64_PRINTF_ARG(alloc_by_type[i])); } } - + /** Verify that connection conn has all of its invariants * correct. Trigger an assert if anything is invalid. */ @@ -4099,3 +4101,54 @@ assert_connection_ok(connection_t *conn, time_t now) } } +void +log_failed_proxy_connection(connection_t *conn) +{ + or_options_t *options = get_options(); + int proxy_type; + tor_addr_t proxy_addr; + int proxy_port; + + if (options->HTTPSProxy) { + tor_addr_copy(&proxy_addr, &options->HTTPSProxyAddr); + proxy_port = options->HTTPSProxyPort; + proxy_type = PROXY_CONNECT; + } else if (options->Socks4Proxy) { + tor_addr_copy(&proxy_addr, &options->Socks4ProxyAddr); + proxy_port = options->Socks4ProxyPort; + proxy_type = PROXY_SOCKS4; + } else if (options->Socks5Proxy) { + tor_addr_copy(&proxy_addr, &options->Socks5ProxyAddr); + proxy_port = options->Socks5ProxyPort; + proxy_type = PROXY_SOCKS5; + } else if (options->ClientTransportPlugin) { + transport_info_t *transport; + transport = find_transport_by_bridge_addrport(&conn->addr, conn->port); + if (transport) { + tor_addr_copy(&proxy_addr, &transport->addr); + proxy_port = transport->port; + proxy_type = PROXY_PLUGGABLE; + } else + return; + } else + tor_assert(0); + + log_warn(LD_NET, + "The connection to the %s proxy server at %s:%u just failed. " + "Make sure that the proxy server is up and running.", + proxy_type_to_string(proxy_type), fmt_addr(&proxy_addr), + proxy_port); +} + +static const char * +proxy_type_to_string(int proxy_type) +{ + switch (proxy_type) { + case PROXY_CONNECT: return "HTTP"; + case PROXY_SOCKS4: return "SOCKS4"; + case PROXY_SOCKS5: return "SOCKS5"; + case PROXY_PLUGGABLE: return "pluggable transports SOCKS"; + case PROXY_NONE: return "NULL"; /* probably a bug */ + default: tor_assert(0); + } +} diff --git a/src/or/connection.h b/src/or/connection.h index 94ae64591f..ba6a258af3 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -57,6 +57,7 @@ int connection_connect(connection_t *conn, const char *address, int connection_proxy_connect(connection_t *conn, int type); int connection_read_proxy_handshake(connection_t *conn); +void log_failed_proxy_connection(connection_t *conn); int retry_all_listeners(smartlist_t *replaced_conns, smartlist_t *new_conns); diff --git a/src/or/main.c b/src/or/main.c index 09d35ed46f..f456b03d74 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -761,11 +761,8 @@ conn_close_if_marked(int i) /* If the connection we are about to close was trying to connect to a proxy server and failed, the client won't be able to use that proxy. We should warn him about this. */ - if (conn->proxy_state == PROXY_INFANT) { - log_warn(LD_NET, - "The connection to a configured proxy server just failed. " - "Make sure that the proxy server is up and running."); - } + if (conn->proxy_state == PROXY_INFANT) + log_failed_proxy_connection(conn); IF_HAS_BUFFEREVENT(conn, goto unlink); if ((SOCKET_OK(conn->s) || conn->linked_conn) && diff --git a/src/or/or.h b/src/or/or.h index 6f056b24dc..f713db7887 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -230,6 +230,8 @@ typedef enum { #define PROXY_CONNECT 1 #define PROXY_SOCKS4 2 #define PROXY_SOCKS5 3 +/* pluggable transports proxy type */ +#define PROXY_PLUGGABLE 4 /* Proxy client handshake states */ /* We use a proxy but we haven't even connected to it yet. */ -- cgit v1.2.3-54-g00ecf From 5b050a9b08fa81421d7e923ef04d06b569f5f742 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 14 Jun 2011 04:28:36 +0200 Subject: This commit is an attempt to beautify the previous commit. It creates some helper functions that return the proxy type, proxy addr/port, etc. --- src/or/connection.c | 98 +++++++++++++++++++++++++++++++++++++------------- src/or/connection.h | 3 ++ src/or/connection_or.c | 34 +++++++----------- 3 files changed, 88 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/or/connection.c b/src/or/connection.c index 087ee29ca0..f7ad84a088 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4101,37 +4101,82 @@ assert_connection_ok(connection_t *conn, time_t now) } } -void -log_failed_proxy_connection(connection_t *conn) +/** + Fills addr and port with the details of the proxy + server of type 'proxy_type' we are using. + 'conn' contains a connection_t and is used for finding pluggable + transports proxies. + + Returns 1 if we were successfull, 0 if we are not using a proxy + server and -1 if something went wrong. +*/ +int +get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, + connection_t *conn) { - or_options_t *options = get_options(); - int proxy_type; - tor_addr_t proxy_addr; - int proxy_port; - - if (options->HTTPSProxy) { - tor_addr_copy(&proxy_addr, &options->HTTPSProxyAddr); - proxy_port = options->HTTPSProxyPort; - proxy_type = PROXY_CONNECT; - } else if (options->Socks4Proxy) { - tor_addr_copy(&proxy_addr, &options->Socks4ProxyAddr); - proxy_port = options->Socks4ProxyPort; - proxy_type = PROXY_SOCKS4; - } else if (options->Socks5Proxy) { - tor_addr_copy(&proxy_addr, &options->Socks5ProxyAddr); - proxy_port = options->Socks5ProxyPort; - proxy_type = PROXY_SOCKS5; - } else if (options->ClientTransportPlugin) { + or_options_t *options; + + if (proxy_type == PROXY_NONE) + return 0; + + options = get_options(); + + if (proxy_type == PROXY_CONNECT) { + tor_addr_copy(addr, &options->HTTPSProxyAddr); + *port = options->HTTPSProxyPort; + } else if (proxy_type == PROXY_SOCKS4) { + tor_addr_copy(addr, &options->Socks4ProxyAddr); + *port = options->Socks4ProxyPort; + } else if (proxy_type == PROXY_SOCKS5) { + tor_addr_copy(addr, &options->Socks5ProxyAddr); + *port = options->Socks5ProxyPort; + } else if (proxy_type == PROXY_PLUGGABLE) { transport_info_t *transport; transport = find_transport_by_bridge_addrport(&conn->addr, conn->port); if (transport) { - tor_addr_copy(&proxy_addr, &transport->addr); - proxy_port = transport->port; - proxy_type = PROXY_PLUGGABLE; + tor_addr_copy(addr, &transport->addr); + *port = transport->port; } else - return; + return -1; } else - tor_assert(0); + return -1; + + return 1; +} + +/** + Returns the proxy type used by tor. +*/ +int +get_proxy_type(void) +{ + or_options_t *options = get_options(); + + if (options->HTTPSProxy) + return PROXY_CONNECT; + else if (options->Socks4Proxy) + return PROXY_SOCKS4; + else if (options->Socks5Proxy) + return PROXY_SOCKS5; + else if (options->ClientTransportPlugin) + return PROXY_PLUGGABLE; + else + return PROXY_NONE; +} + +/** + Log a failed connection to a proxy server. +*/ +void +log_failed_proxy_connection(connection_t *conn) +{ + int proxy_type; + tor_addr_t proxy_addr; + uint16_t proxy_port; + + proxy_type = get_proxy_type(); + if (get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, conn) <= 0) + return; log_warn(LD_NET, "The connection to the %s proxy server at %s:%u just failed. " @@ -4140,6 +4185,9 @@ log_failed_proxy_connection(connection_t *conn) proxy_port); } +/** + Transforms 'proxy_type' to it's string representation/ +*/ static const char * proxy_type_to_string(int proxy_type) { diff --git a/src/or/connection.h b/src/or/connection.h index ba6a258af3..544e9392d0 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -58,6 +58,9 @@ int connection_connect(connection_t *conn, const char *address, int connection_proxy_connect(connection_t *conn, int type); int connection_read_proxy_handshake(connection_t *conn); void log_failed_proxy_connection(connection_t *conn); +int get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, connection_t *conn); +int get_proxy_type(void); + int retry_all_listeners(smartlist_t *replaced_conns, smartlist_t *new_conns); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index b72cd77e46..f111bc12d3 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -839,6 +839,11 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, int socket_error = 0; tor_addr_t addr; + int r; + int proxy_type; + tor_addr_t proxy_addr; + uint16_t proxy_port; + tor_assert(_addr); tor_assert(id_digest); tor_addr_copy(&addr, _addr); @@ -855,29 +860,14 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, conn->_base.state = OR_CONN_STATE_CONNECTING; control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0); - /* use a proxy server if available */ - if (options->HTTPSProxy) { - conn->_base.proxy_state = PROXY_INFANT; - tor_addr_copy(&addr, &options->HTTPSProxyAddr); - port = options->HTTPSProxyPort; - } else if (options->Socks4Proxy) { - conn->_base.proxy_state = PROXY_INFANT; - tor_addr_copy(&addr, &options->Socks4ProxyAddr); - port = options->Socks4ProxyPort; - } else if (options->Socks5Proxy) { + proxy_type = get_proxy_type(); + r = get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, TO_CONN(conn)); + if (r == 1) { /* proxy found. */ + addr = proxy_addr; + port = proxy_port; conn->_base.proxy_state = PROXY_INFANT; - tor_addr_copy(&addr, &options->Socks5ProxyAddr); - port = options->Socks5ProxyPort; - } else if (options->ClientTransportPlugin) { - transport_info_t *transport; - transport = find_transport_by_bridge_addrport(&addr, port); - if (transport) { - log_debug(LD_GENERAL, "Found transport. Setting up proxying!"); - conn->_base.proxy_state = PROXY_INFANT; - tor_addr_copy(&addr, &transport->addr); - port = transport->port; - } - } + } else if (r < 0) + return NULL; switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr, port, &socket_error)) { -- cgit v1.2.3-54-g00ecf From 93526cdf0b9a9df1bcb69454060d24d819c15024 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 14 Jun 2011 16:00:55 +0200 Subject: Fixes small bugs. --- src/or/circuitbuild.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ src/or/circuitbuild.h | 4 ++-- src/or/config.c | 28 ++++++++++++++++++++-------- src/or/connection.c | 5 ++--- src/or/connection_or.c | 5 ++++- 5 files changed, 72 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 4dcc685bca..53a3063c59 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4594,21 +4594,39 @@ transport_free(transport_info_t *transport) /** Remember a new pluggable transport proxy at addr:port. name is set to the name of the protocol this proxy uses. socks_ver is set to the SOCKS version of the proxy. + + Returns 1 on success, -1 on fail. */ -void +int 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)); + if (transport_list) { /*check out for duplicate transport names*/ + SMARTLIST_FOREACH_BEGIN(transport_list, transport_info_t *, transport) { + if (!strcmp(transport->name, name)) { + log_notice(LD_CONFIG, "More than one transports have '%s' as " + "their name.", transport->name); + goto err; + } + } SMARTLIST_FOREACH_END(transport); + } + tor_addr_copy(&t->addr, addr); t->port = port; t->name = tor_strdup(name); + t->socks_version = socks_ver; if (!transport_list) transport_list = smartlist_create(); smartlist_add(transport_list, t); + return 1; + + err: + tor_free(t); + return -1; } /** @@ -4645,9 +4663,8 @@ match_bridges_with_transports(void) found_match=1; n_matches++; b->transport = t; - tor_free(b->transport_name_config); log_warn(LD_CONFIG, "Matched transport '%s'", t->name); - continue; + break; } } SMARTLIST_FOREACH_END(t); if (!found_match) { @@ -4667,6 +4684,10 @@ match_bridges_with_transports(void) return -1; } + /* clear the method names taken from the config, we no longer need them. */ + SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, + tor_free(b->transport_name_config)); + return 1; } @@ -4751,8 +4772,10 @@ learned_router_identity(const tor_addr_t *addr, uint16_t port, * 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. + * + * Returns 1 on success, -1 on fail. */ -void +int bridge_add_from_config(const tor_addr_t *addr, uint16_t port, const char *digest, const char *transport_name) { @@ -4760,7 +4783,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, if ((b = get_configured_bridge_by_addr_port_digest(addr, port, digest))) { b->marked_for_removal = 0; - return; + return 1; } b = tor_malloc_zero(sizeof(bridge_info_t)); @@ -4768,13 +4791,28 @@ 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) + if (transport_name) { + if (bridge_list) { /*check out for duplicate transport names*/ + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { + if (!strcmp(bridge->transport_name_config, transport_name)) { + log_notice(LD_CONFIG, "More than one bridges have '%s' as " + "their transport name.", transport_name); + goto err; + } + } SMARTLIST_FOREACH_END(bridge); + } b->transport_name_config = strdup(transport_name); + } b->fetch_status.schedule = DL_SCHED_BRIDGE; if (!bridge_list) bridge_list = smartlist_create(); smartlist_add(bridge_list, b); + return 1; + + err: + tor_free(b); + return -1; } /** Return true iff routerset contains the bridge bridge. */ diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index c1833d23e5..9e05d6e142 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -82,7 +82,7 @@ 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); -void bridge_add_from_config(const tor_addr_t *addr, uint16_t port, +int bridge_add_from_config(const tor_addr_t *addr, uint16_t port, const char *digest, const char *transport_name); void retry_bridge_descriptor_fetch_directly(const char *digest); @@ -142,7 +142,7 @@ 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, +int transport_add_from_config(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver); transport_info_t * find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port); diff --git a/src/or/config.c b/src/or/config.c index 47702873bb..a78252c6c5 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -570,7 +570,8 @@ static int options_transition_affects_descriptor(or_options_t *old_options, 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_bridge_line(const char *line, int validate_only, + or_options_t *options); 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, @@ -1222,7 +1223,7 @@ options_act(or_options_t *old_options) if (options->Bridges) { mark_bridge_list(); for (cl = options->Bridges; cl; cl = cl->next) { - if (parse_bridge_line(cl->value, 0)<0) { + if (parse_bridge_line(cl->value, 0, options)<0) { log_warn(LD_BUG, "Previously validated Bridge line could not be added!"); return -1; @@ -3709,7 +3710,7 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->Bridges) { for (cl = options->Bridges; cl; cl = cl->next) { - if (parse_bridge_line(cl->value, 1)<0) + if (parse_bridge_line(cl->value, 1, options)<0) REJECT("Bridge line did not parse. See logs for details."); } } @@ -4592,7 +4593,8 @@ options_init_logs(or_options_t *options, int validate_only) * validate_only is 0, and the line is well-formed, then add * the bridge described in the line to our internal bridge list. */ static int -parse_bridge_line(const char *line, int validate_only) +parse_bridge_line(const char *line, int validate_only, + or_options_t *options) { smartlist_t *items = NULL; int r; @@ -4616,6 +4618,12 @@ parse_bridge_line(const char *line, int validate_only) smartlist_del_keeporder(items, 0); if (!strstr(field1, ".")) { /* new-style bridge line */ + if (!options->ClientTransportPlugin) { + log_warn(LD_CONFIG, "Pluggable transports protocol found " + "in bridge line, but no ClientTransportPlugin lines found."); + goto err; + } + transport_name = field1; addrport = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); @@ -4649,8 +4657,10 @@ parse_bridge_line(const char *line, int validate_only) 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, - fingerprint ? digest : NULL, transport_name); + + if (bridge_add_from_config(&addr, port, + fingerprint ? digest : NULL,transport_name) < 0) + goto err; } r = 0; @@ -4729,8 +4739,10 @@ parse_client_transport_line(const char *line, int validate_only) if (!validate_only) { 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); + + if (transport_add_from_config(&addr, port, name, + socks_ver) < 0) + goto err; } r = 0; diff --git a/src/or/connection.c b/src/or/connection.c index f7ad84a088..898f242f7b 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4104,8 +4104,7 @@ assert_connection_ok(connection_t *conn, time_t now) /** Fills addr and port with the details of the proxy server of type 'proxy_type' we are using. - 'conn' contains a connection_t and is used for finding pluggable - transports proxies. + 'conn' contains the connection_t we are using the proxy for. Returns 1 if we were successfull, 0 if we are not using a proxy server and -1 if something went wrong. @@ -4186,7 +4185,7 @@ log_failed_proxy_connection(connection_t *conn) } /** - Transforms 'proxy_type' to it's string representation/ + Return string representation of proxy_type. */ static const char * proxy_type_to_string(int proxy_type) diff --git a/src/or/connection_or.c b/src/or/connection_or.c index f111bc12d3..4ed4723fed 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -860,14 +860,17 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, conn->_base.state = OR_CONN_STATE_CONNECTING; control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0); + /* If we are using a proxy server, find it and use it. */ proxy_type = get_proxy_type(); r = get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, TO_CONN(conn)); if (r == 1) { /* proxy found. */ addr = proxy_addr; port = proxy_port; conn->_base.proxy_state = PROXY_INFANT; - } else if (r < 0) + } else if (r < 0) { + log_info(LD_PROTOCOL, "Failed on getting proxy addrport."); return NULL; + } switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr, port, &socket_error)) { -- cgit v1.2.3-54-g00ecf From 392e947df5db1d2cdd0cbd0d63226f734dfd7267 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 21 Jun 2011 18:46:50 +0200 Subject: Fixes on circuitbuild.[ch] based on nick's comments. * Renamed transport_info_t to transport_t. * Introduced transport_get_by_name(). * Killed match_bridges_with_transports(). We currently *don't* detect whether any bridges miss their transports, of if any transports miss their bridges. * Various code and aesthetic tweaks and English language changes. --- src/or/circuitbuild.c | 231 +++++++++++++++++++------------------------------- src/or/circuitbuild.h | 10 +-- 2 files changed, 91 insertions(+), 150 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 53a3063c59..d5989f34c0 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -79,6 +79,28 @@ typedef struct { * at which we last failed to connect to it. */ } entry_guard_t; +/** Information about a configured bridge. Currently this just matches the + * ones in the torrc file, but one day we may be able to learn about new + * bridges on our own, and remember them in the state file. */ +typedef struct { + /** Address of the bridge. */ + tor_addr_t addr; + /** TLS port for the bridge. */ + uint16_t port; + /** Boolean: We are re-parsing our bridge list, and we are going to remove + * this one if we don't find it in the list of configured bridges. */ + unsigned marked_for_removal : 1; + /** 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. */ + char *transport_name; + + /** When should we next try to fetch a descriptor for this bridge? */ + download_status_t fetch_status; +} bridge_info_t; + /** A list of our chosen entry guards. */ static smartlist_t *entry_guards = NULL; /** A value of 1 means that the entry_guards list has changed @@ -100,7 +122,10 @@ static int count_acceptable_nodes(smartlist_t *routers); static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice); static void entry_guards_changed(void); -static void transport_free(transport_info_t *transport); + +static transport_t *transport_get_by_name(const char *name); +static void transport_free(transport_t *transport); +static void bridge_free(bridge_info_t *bridge); /** * This function decides if CBT learning should be disabled. It returns @@ -4498,33 +4523,6 @@ getinfo_helper_entry_guards(control_connection_t *conn, return 0; } -/** Information about a configured bridge. Currently this just matches the - * ones in the torrc file, but one day we may be able to learn about new - * bridges on our own, and remember them in the state file. */ -typedef struct { - /** Address of the bridge. */ - tor_addr_t addr; - /** TLS port for the bridge. */ - uint16_t port; - /** Boolean: We are re-parsing our bridge list, and we are going to remove - * this one if we don't find it in the list of configured bridges. */ - unsigned marked_for_removal : 1; - /** 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; - /** A list of configured bridges. Whenever we actually get a descriptor * for one, we add it as an entry guard. Note that the order of bridges * in this list does not necessarily correspond to the order of bridges @@ -4552,7 +4550,7 @@ sweep_bridge_list(void) SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) { if (b->marked_for_removal) { SMARTLIST_DEL_CURRENT(bridge_list, b); - tor_free(b); + bridge_free(b); } } SMARTLIST_FOREACH_END(b); } @@ -4563,54 +4561,80 @@ clear_bridge_list(void) { if (!bridge_list) bridge_list = smartlist_create(); - SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, tor_free(b)); + SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, bridge_free(b)); smartlist_clear(bridge_list); } +/** Free the transport_t transport. */ +static void +bridge_free(bridge_info_t *bridge) +{ + if (!bridge) + return; + + tor_free(bridge->transport_name); + tor_free(bridge); +} + /** 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. */ + * 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_FOREACH(transport_list, transport_t *, t, transport_free(t)); smartlist_clear(transport_list); } -/** - Free the transport_info_t transport. -*/ +/** Free the transport_t transport. */ static void -transport_free(transport_info_t *transport) +transport_free(transport_t *transport) { + if (!transport) + return; + tor_free(transport->name); tor_free(transport); } -/** Remember a new pluggable transport proxy at addr:port. - name is set to the name of the protocol this proxy uses. - socks_ver is set to the SOCKS version of the proxy. +/** Returns the transport in our transport list that has the name name. + * Else returns NULL. */ +static transport_t * +transport_get_by_name(const char *name) +{ + tor_assert(name); + if (transport_list) { + SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) { + if (!strcmp(transport->name, name)) + return transport; + } SMARTLIST_FOREACH_END(transport); + } - Returns 1 on success, -1 on fail. -*/ + log_notice(LD_GENERAL, "We were asked to match '%s' to a pluggable " + "transport, and we failed. If you didn't expect this, please " + "check your configuration.", name); + return NULL; +} + +/** Remember a new pluggable transport proxy at addr:port. + * name is set to the name of the protocol this proxy uses. + * socks_ver is set to the SOCKS version of the proxy. + * + * Returns 0 on success, -1 on fail. */ int 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)); + transport_t *t = tor_malloc_zero(sizeof(transport_t)); - if (transport_list) { /*check out for duplicate transport names*/ - SMARTLIST_FOREACH_BEGIN(transport_list, transport_info_t *, transport) { - if (!strcmp(transport->name, name)) { - log_notice(LD_CONFIG, "More than one transports have '%s' as " - "their name.", transport->name); - goto err; - } - } SMARTLIST_FOREACH_END(transport); + if (transport_get_by_name(name)) { /* check for duplicate names */ + log_notice(LD_CONFIG, "More than one transports have '%s' as " + "their name.", name); + goto err; } tor_addr_copy(&t->addr, addr); @@ -4622,75 +4646,13 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, transport_list = smartlist_create(); smartlist_add(transport_list, t); - return 1; + return 0; err: tor_free(t); return -1; } -/** - 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; - log_warn(LD_CONFIG, "Matched transport '%s'", t->name); - break; - } - } 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 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 but we only " - "managed to match %d of them!\n", n_transports, n_matches); - return -1; - } - - /* clear the method names taken from the config, we no longer need them. */ - SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, - tor_free(b->transport_name_config)); - - 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). * Else return NULL. */ @@ -4771,11 +4733,8 @@ learned_router_identity(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. - * - * Returns 1 on success, -1 on fail. - */ -int + * 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) { @@ -4783,7 +4742,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, if ((b = get_configured_bridge_by_addr_port_digest(addr, port, digest))) { b->marked_for_removal = 0; - return 1; + return; } b = tor_malloc_zero(sizeof(bridge_info_t)); @@ -4791,28 +4750,13 @@ 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) { - if (bridge_list) { /*check out for duplicate transport names*/ - SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { - if (!strcmp(bridge->transport_name_config, transport_name)) { - log_notice(LD_CONFIG, "More than one bridges have '%s' as " - "their transport name.", transport_name); - goto err; - } - } SMARTLIST_FOREACH_END(bridge); - } - b->transport_name_config = strdup(transport_name); - } + if (transport_name) + b->transport_name = tor_strdup(transport_name); b->fetch_status.schedule = DL_SCHED_BRIDGE; if (!bridge_list) bridge_list = smartlist_create(); smartlist_add(bridge_list, b); - return 1; - - err: - tor_free(b); - return -1; } /** Return true iff routerset contains the bridge bridge. */ @@ -4846,23 +4790,22 @@ find_bridge_by_digest(const char *digest) } /** If addr and port match one of our known bridges, - * returns its transport protocol if it has one, else returns NULL. - */ -transport_info_t * + * returns its transport protocol if it has one, else returns NULL. */ +transport_t * find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port) { - assert(bridge_list); + tor_assert(bridge_list); SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { if (tor_addr_eq(&bridge->addr, addr) && (bridge->port == port)) { - if (bridge->transport) { - log_debug(LD_GENERAL, "Found matching bridge!\n"); - return bridge->transport; + if (bridge->transport_name) { + return transport_get_by_name(bridge->transport_name); } else /* bridge found, but it had no transport */ - return NULL; + break; } } SMARTLIST_FOREACH_END(bridge); + return NULL; } diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 9e05d6e142..83eb7ba2e7 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -12,8 +12,7 @@ #ifndef _TOR_CIRCUITBUILD_H #define _TOR_CIRCUITBUILD_H -/** - Represents a pluggable transport proxy used by a bridge. */ +/** Represents a pluggable transport proxy used by a bridge. */ typedef struct { /* SOCKS version */ int socks_version; @@ -23,7 +22,7 @@ typedef struct { tor_addr_t addr; /* Port of proxy */ uint16_t port; -} transport_info_t; +} transport_t; char *circuit_list_path(origin_circuit_t *circ, int verbose); char *circuit_list_path_for_controller(origin_circuit_t *circ); @@ -82,7 +81,7 @@ 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); -int bridge_add_from_config(const tor_addr_t *addr, uint16_t port, +void bridge_add_from_config(const tor_addr_t *addr, uint16_t port, const char *digest, const char *transport_name); void retry_bridge_descriptor_fetch_directly(const char *digest); @@ -141,10 +140,9 @@ 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); int transport_add_from_config(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver); -transport_info_t * +transport_t * find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port); #endif -- cgit v1.2.3-54-g00ecf From 298f1700367f4d17cf376ea09442b23e7f16229b Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 21 Jun 2011 18:48:43 +0200 Subject: Tweaked connection{.c,.h,_or.c} based on nick's comments. * Tweaked doxygen comments. * Changed returns of get_proxy_addrport(). * Ran make check-spaces. * Various small code tweaks. --- src/or/connection.c | 62 ++++++++++++++++++++++---------------------------- src/or/connection.h | 4 ++-- src/or/connection_or.c | 9 +++----- 3 files changed, 32 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/or/connection.c b/src/or/connection.c index 898f242f7b..fafea43297 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -68,7 +68,6 @@ static int connection_read_https_proxy_response(connection_t *conn); static void connection_send_socks5_connect(connection_t *conn); static const char *proxy_type_to_string(int proxy_type); - /** The last IPv4 address that our network interface seemed to have been * binding to, in host order. We use this to detect when our IP changes. */ static uint32_t last_interface_ip = 0; @@ -3938,7 +3937,7 @@ connection_dump_buffer_mem_stats(int severity) U64_PRINTF_ARG(used_by_type[i]), U64_PRINTF_ARG(alloc_by_type[i])); } } - + /** Verify that connection conn has all of its invariants * correct. Trigger an assert if anything is invalid. */ @@ -4101,22 +4100,19 @@ assert_connection_ok(connection_t *conn, time_t now) } } -/** - Fills addr and port with the details of the proxy - server of type 'proxy_type' we are using. - 'conn' contains the connection_t we are using the proxy for. - - Returns 1 if we were successfull, 0 if we are not using a proxy - server and -1 if something went wrong. -*/ +/** Fills addr and port with the details of the proxy + * server of type proxy_type we are using. + * conn contains the connection_t we are using the proxy for. + * Returns 0 if we were successfull or returns 1 if we are not using + * a proxy. */ int -get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, +get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, connection_t *conn) { or_options_t *options; if (proxy_type == PROXY_NONE) - return 0; + return 1; options = get_options(); @@ -4130,22 +4126,20 @@ get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, tor_addr_copy(addr, &options->Socks5ProxyAddr); *port = options->Socks5ProxyPort; } else if (proxy_type == PROXY_PLUGGABLE) { - transport_info_t *transport; + transport_t *transport; transport = find_transport_by_bridge_addrport(&conn->addr, conn->port); if (transport) { tor_addr_copy(addr, &transport->addr); *port = transport->port; - } else - return -1; - } else - return -1; + } else { /* no transport for this bridge. */ + return 1; + } + } - return 1; -} + return 0; +} -/** - Returns the proxy type used by tor. -*/ +/** Returns the proxy type used by tor. */ int get_proxy_type(void) { @@ -4162,10 +4156,9 @@ get_proxy_type(void) else return PROXY_NONE; } - -/** - Log a failed connection to a proxy server. -*/ + +/** Log a failed connection to a proxy server. + * conn is the connection we use the proxy server for. */ void log_failed_proxy_connection(connection_t *conn) { @@ -4174,19 +4167,17 @@ log_failed_proxy_connection(connection_t *conn) uint16_t proxy_port; proxy_type = get_proxy_type(); - if (get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, conn) <= 0) - return; - + if (get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, conn) != 0) + return; /* if we have no proxy set up leave this function. */ + log_warn(LD_NET, "The connection to the %s proxy server at %s:%u just failed. " "Make sure that the proxy server is up and running.", - proxy_type_to_string(proxy_type), fmt_addr(&proxy_addr), - proxy_port); + proxy_type_to_string(proxy_type), fmt_addr(&proxy_addr), + proxy_port); } -/** - Return string representation of proxy_type. -*/ +/** Return string representation of proxy_type. */ static const char * proxy_type_to_string(int proxy_type) { @@ -4196,6 +4187,7 @@ proxy_type_to_string(int proxy_type) case PROXY_SOCKS5: return "SOCKS5"; case PROXY_PLUGGABLE: return "pluggable transports SOCKS"; case PROXY_NONE: return "NULL"; /* probably a bug */ - default: tor_assert(0); + default: tor_assert(0); } } + diff --git a/src/or/connection.h b/src/or/connection.h index 544e9392d0..34be9cc215 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -58,10 +58,10 @@ int connection_connect(connection_t *conn, const char *address, int connection_proxy_connect(connection_t *conn, int type); int connection_read_proxy_handshake(connection_t *conn); void log_failed_proxy_connection(connection_t *conn); -int get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, connection_t *conn); +int get_proxy_addrport(int proxy_type, tor_addr_t *addr, + uint16_t *port, connection_t *conn); int get_proxy_type(void); - int retry_all_listeners(smartlist_t *replaced_conns, smartlist_t *new_conns); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 4ed4723fed..6ed6fe65b5 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -336,7 +336,7 @@ connection_or_finished_connecting(or_connection_t *or_conn) else if (get_options()->Socks5Proxy) proxy_type = PROXY_SOCKS5; else if (get_options()->ClientTransportPlugin) { - transport_info_t *transport; + transport_t *transport; transport = find_transport_by_bridge_addrport(&conn->addr,conn->port); if (transport) { /* this bridge supports transports. use proxy. */ log_debug(LD_GENERAL, "Found transport. Setting proxy type!\n"); @@ -863,13 +863,10 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, /* If we are using a proxy server, find it and use it. */ proxy_type = get_proxy_type(); r = get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, TO_CONN(conn)); - if (r == 1) { /* proxy found. */ - addr = proxy_addr; + if (r == 0) { /* proxy found. */ + tor_addr_copy(&addr, &proxy_addr); port = proxy_port; conn->_base.proxy_state = PROXY_INFANT; - } else if (r < 0) { - log_info(LD_PROTOCOL, "Failed on getting proxy addrport."); - return NULL; } switch (connection_connect(TO_CONN(conn), conn->_base.address, -- cgit v1.2.3-54-g00ecf From 5a05deb574a7178e752ce22d754d0d6fc1fa2141 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 21 Jun 2011 18:49:04 +0200 Subject: Various small tweaks around config.c and or.h --- src/or/config.c | 37 +++++++++++-------------------------- src/or/or.h | 2 +- 2 files changed, 12 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index a78252c6c5..c414981a92 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1208,8 +1208,8 @@ options_act(or_options_t *old_options) if (consider_adding_dir_authorities(options, old_options) < 0) return -1; + clear_transport_list(); if (options->ClientTransportPlugin) { - clear_transport_list(); for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { if (parse_client_transport_line(cl->value, 0)<0) { log_warn(LD_BUG, @@ -1232,14 +1232,6 @@ 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) { - assert(!server_mode(options)); - 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!"); @@ -3566,15 +3558,9 @@ options_validate(or_options_t *old_options, or_options_t *options, } } - /* Check if more than one proxy type has been enabled. This looks REALLY ugly! */ - if ((options->Socks4Proxy && (options->Socks5Proxy || options->HTTPSProxy - || options->ClientTransportPlugin)) || - (options->Socks5Proxy && (options->Socks4Proxy || options->HTTPSProxy - || options->ClientTransportPlugin)) || - (options->HTTPSProxy && (options->Socks4Proxy || options->Socks5Proxy - || options->ClientTransportPlugin)) || - (options->ClientTransportPlugin && (options->Socks4Proxy - || options->Socks5Proxy || options->HTTPSProxy))) + /* Check if more than one proxy type has been enabled. */ + if (!!options->Socks4Proxy + !!options->Socks5Proxy + + !!options->HTTPSProxy + !!options->ClientTransportPlugin > 1) REJECT("You have configured more than one proxy types. " "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)"); @@ -4593,7 +4579,7 @@ options_init_logs(or_options_t *options, int validate_only) * validate_only is 0, and the line is well-formed, then add * the bridge described in the line to our internal bridge list. */ static int -parse_bridge_line(const char *line, int validate_only, +parse_bridge_line(const char *line, int validate_only, or_options_t *options) { smartlist_t *items = NULL; @@ -4654,13 +4640,12 @@ parse_bridge_line(const char *line, int validate_only, } if (!validate_only) { - log_debug(LD_DIR, "Bridge at %s:%d with transport %s (%s)", - fmt_addr(&addr), (int)port, transport_name, - fingerprint ? fingerprint : "no key listed"); - - if (bridge_add_from_config(&addr, port, - fingerprint ? digest : NULL,transport_name) < 0) - goto err; + log_debug(LD_DIR, "Bridge at %s:%d (transport: %s) (%s)", + fmt_addr(&addr), (int)port, + transport_name ? transport_name : "no transport", + fingerprint ? fingerprint : "no key listed"); + bridge_add_from_config(&addr, port, + fingerprint ? digest : NULL,transport_name); } r = 0; diff --git a/src/or/or.h b/src/or/or.h index f713db7887..72d311b430 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -234,7 +234,7 @@ typedef enum { #define PROXY_PLUGGABLE 4 /* Proxy client handshake states */ -/* We use a proxy but we haven't even connected to it yet. */ +/* We use a proxy but we haven't even connected to it yet. */ #define PROXY_INFANT 1 /* We use an HTTP proxy and we've sent the CONNECT command. */ #define PROXY_HTTPS_WANT_CONNECT_OK 2 -- cgit v1.2.3-54-g00ecf From 1fe8bee6562956e1725f8c4feaac32c8e21b84b3 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 22 Jun 2011 23:28:11 +0200 Subject: Revised how we handle ClientTransportPlugin and Bridge lines. Multiple Bridge lines can point to the same one ClientTransportPlugin line, and we can have multiple ClientTransportPlugin lines in our configuration file that don't match with a bridge. We also issue a warning when we have a Bridge line with a pluggable transport but we can't match it to a ClientTransportPlugin line. --- src/or/circuitbuild.c | 77 +++++++++++++++++++++++++++++++++++++------------- src/or/circuitbuild.h | 5 ++-- src/or/config.c | 16 ++++------- src/or/connection.c | 48 ++++++++++++++++--------------- src/or/connection.h | 3 +- src/or/connection_or.c | 19 +++++++++---- 6 files changed, 105 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index d5989f34c0..b1f967b7be 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4607,16 +4607,15 @@ static transport_t * transport_get_by_name(const char *name) { tor_assert(name); - if (transport_list) { - SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) { - if (!strcmp(transport->name, name)) - return transport; - } SMARTLIST_FOREACH_END(transport); - } - log_notice(LD_GENERAL, "We were asked to match '%s' to a pluggable " - "transport, and we failed. If you didn't expect this, please " - "check your configuration.", name); + if (!transport_list) + return NULL; + + SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) { + if (!strcmp(transport->name, name)) + return transport; + } SMARTLIST_FOREACH_END(transport); + return NULL; } @@ -4653,6 +4652,27 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, return -1; } +/** Warns the user of possible pluggable transport misconfiguration. */ +void +validate_pluggable_transports_config(void) +{ + if (bridge_list) { + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) + { + /* Skip bridges without transports. */ + if (!b->transport_name) + continue; + /* See if the user has Bridges that specify nonexistent + pluggable transports. We should warn the user in such case, + since it's probably misconfiguration. */ + if (!transport_get_by_name(b->transport_name)) + log_warn(LD_CONFIG, "You have a Bridge line using the %s " + "pluggable transport, but there doesn't seem to be a " + "corresponding ClientTransportPlugin line.", b->transport_name); + } SMARTLIST_FOREACH_END(b); + } +} + /** Return a bridge pointer if ri is one of our known bridges * (either by comparing keys if possible, else by comparing addr/port). * Else return NULL. */ @@ -4789,24 +4809,41 @@ find_bridge_by_digest(const char *digest) return NULL; } -/** If addr and port match one of our known bridges, - * returns its transport protocol if it has one, else returns NULL. */ -transport_t * -find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port) +/** If addr and port match the address and port of a + * bridge of ours that uses pluggable transports, place it's transport + * in transport. + * + * Return: + * 0: if transport was found successfully. + * 1: if addr:port did not match a bridge, + * or if matched bridge was not using transports. + * -1: if we should be using a transport, but the transport could not be found. + */ +int +find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, + transport_t **transport) { - tor_assert(bridge_list); + if (!bridge_list) + return 1; + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { if (tor_addr_eq(&bridge->addr, addr) && - (bridge->port == port)) { - if (bridge->transport_name) { - return transport_get_by_name(bridge->transport_name); - } else /* bridge found, but it had no transport */ + (bridge->port == port)) { /* bridge matched */ + if (bridge->transport_name) { /* it also uses pluggable transports */ + *transport = transport_get_by_name(bridge->transport_name); + if (*transport == NULL) { /* it uses pluggable transports, but + the transport could not be found! */ + return -1; + } + return 0; + } else { /* bridge matched, but it doesn't use transports. */ break; + } } } SMARTLIST_FOREACH_END(bridge); - return NULL; + return 1; } /** We need to ask bridge for its server descriptor. */ @@ -5116,6 +5153,8 @@ entry_guards_free_all(void) clear_bridge_list(); clear_transport_list(); smartlist_free(bridge_list); + smartlist_free(transport_list); bridge_list = NULL; + transport_list = NULL; } diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 83eb7ba2e7..71ea6080e3 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -142,8 +142,9 @@ int circuit_build_times_get_bw_scale(networkstatus_t *ns); void clear_transport_list(void); int transport_add_from_config(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver); -transport_t * -find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port); +int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, + transport_t **transport); +void validate_pluggable_transports_config(void); #endif diff --git a/src/or/config.c b/src/or/config.c index c414981a92..41142b644e 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1232,6 +1232,11 @@ options_act(or_options_t *old_options) sweep_bridge_list(); } + /* If we have pluggable transport related options enabled, see if we + should warn the user about potential configuration problems. */ + if (options->Bridges || options->ClientTransportPlugin) + validate_pluggable_transports_config(); + if (running_tor && rend_config_services(options, 0)<0) { log_warn(LD_BUG, "Previously validated hidden services line could not be added!"); @@ -3683,11 +3688,6 @@ options_validate(or_options_t *old_options, or_options_t *options, REJECT("TunnelDirConns set to 0 only works with UseBridges set to 0"); 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_client_transport_line(cl->value, 1)<0) REJECT("Transport line did not parse. See logs for details."); @@ -4604,12 +4604,6 @@ parse_bridge_line(const char *line, int validate_only, smartlist_del_keeporder(items, 0); if (!strstr(field1, ".")) { /* new-style bridge line */ - if (!options->ClientTransportPlugin) { - log_warn(LD_CONFIG, "Pluggable transports protocol found " - "in bridge line, but no ClientTransportPlugin lines found."); - goto err; - } - transport_name = field1; addrport = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); diff --git a/src/or/connection.c b/src/or/connection.c index fafea43297..bfc901fa18 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -67,6 +67,7 @@ static const char *connection_proxy_state_to_string(int state); static int connection_read_https_proxy_response(connection_t *conn); static void connection_send_socks5_connect(connection_t *conn); static const char *proxy_type_to_string(int proxy_type); +static int get_proxy_type(void); /** The last IPv4 address that our network interface seemed to have been * binding to, in host order. We use this to detect when our IP changes. */ @@ -4103,44 +4104,47 @@ assert_connection_ok(connection_t *conn, time_t now) /** Fills addr and port with the details of the proxy * server of type proxy_type we are using. * conn contains the connection_t we are using the proxy for. - * Returns 0 if we were successfull or returns 1 if we are not using - * a proxy. */ + * Returns 0 if we were successfull, 1 if we are not using + * a proxy, -1 if we are using a proxy but his addrport could not be + * found. */ int -get_proxy_addrport(int proxy_type, tor_addr_t *addr, uint16_t *port, +get_proxy_addrport(tor_addr_t *addr, uint16_t *port, connection_t *conn) { - or_options_t *options; - - if (proxy_type == PROXY_NONE) - return 1; - - options = get_options(); + or_options_t *options = get_options(); - if (proxy_type == PROXY_CONNECT) { + if (options->HTTPSProxy) { tor_addr_copy(addr, &options->HTTPSProxyAddr); *port = options->HTTPSProxyPort; - } else if (proxy_type == PROXY_SOCKS4) { + goto done; + } else if (options->Socks4Proxy) { tor_addr_copy(addr, &options->Socks4ProxyAddr); *port = options->Socks4ProxyPort; - } else if (proxy_type == PROXY_SOCKS5) { + goto done; + } else if (options->Socks5Proxy) { tor_addr_copy(addr, &options->Socks5ProxyAddr); *port = options->Socks5ProxyPort; - } else if (proxy_type == PROXY_PLUGGABLE) { - transport_t *transport; - transport = find_transport_by_bridge_addrport(&conn->addr, conn->port); - if (transport) { + goto done; + } else if (options->ClientTransportPlugin || + options->Bridges) { + transport_t *transport=NULL; + int r; + r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport); + if (r == 0) { /* transport found */ tor_addr_copy(addr, &transport->addr); *port = transport->port; - } else { /* no transport for this bridge. */ - return 1; } + return r; } + return 1; + + done: return 0; } /** Returns the proxy type used by tor. */ -int +static int get_proxy_type(void) { or_options_t *options = get_options(); @@ -4162,18 +4166,16 @@ get_proxy_type(void) void log_failed_proxy_connection(connection_t *conn) { - int proxy_type; tor_addr_t proxy_addr; uint16_t proxy_port; - proxy_type = get_proxy_type(); - if (get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, conn) != 0) + if (get_proxy_addrport(&proxy_addr, &proxy_port, conn) != 0) return; /* if we have no proxy set up leave this function. */ log_warn(LD_NET, "The connection to the %s proxy server at %s:%u just failed. " "Make sure that the proxy server is up and running.", - proxy_type_to_string(proxy_type), fmt_addr(&proxy_addr), + proxy_type_to_string(get_proxy_type()), fmt_addr(&proxy_addr), proxy_port); } diff --git a/src/or/connection.h b/src/or/connection.h index 34be9cc215..bf439b9bbc 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -58,9 +58,8 @@ int connection_connect(connection_t *conn, const char *address, int connection_proxy_connect(connection_t *conn, int type); int connection_read_proxy_handshake(connection_t *conn); void log_failed_proxy_connection(connection_t *conn); -int get_proxy_addrport(int proxy_type, tor_addr_t *addr, +int get_proxy_addrport(tor_addr_t *addr, uint16_t *port, connection_t *conn); -int get_proxy_type(void); int retry_all_listeners(smartlist_t *replaced_conns, smartlist_t *new_conns); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 6ed6fe65b5..4cbd440a01 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -336,11 +336,15 @@ connection_or_finished_connecting(or_connection_t *or_conn) else if (get_options()->Socks5Proxy) proxy_type = PROXY_SOCKS5; else if (get_options()->ClientTransportPlugin) { - transport_t *transport; - transport = find_transport_by_bridge_addrport(&conn->addr,conn->port); - if (transport) { /* this bridge supports transports. use proxy. */ + transport_t *transport=NULL; + int r; + r = find_transport_by_bridge_addrport(&conn->addr,conn->port,&transport); + if (r == 0) { + tor_assert(transport); log_debug(LD_GENERAL, "Found transport. Setting proxy type!\n"); proxy_type = transport->socks_version; + } else if (r == -1) { + return -1; } } @@ -840,7 +844,6 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, tor_addr_t addr; int r; - int proxy_type; tor_addr_t proxy_addr; uint16_t proxy_port; @@ -861,12 +864,16 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0); /* If we are using a proxy server, find it and use it. */ - proxy_type = get_proxy_type(); - r = get_proxy_addrport(proxy_type, &proxy_addr, &proxy_port, TO_CONN(conn)); + r = get_proxy_addrport(&proxy_addr, &proxy_port, TO_CONN(conn)); if (r == 0) { /* proxy found. */ tor_addr_copy(&addr, &proxy_addr); port = proxy_port; conn->_base.proxy_state = PROXY_INFANT; + } else if (r == -1) { /* proxy could not be found. */ + log_warn(LD_GENERAL, "Tried to connect through proxy, but proxy address " + "could not be found."); + connection_free(TO_CONN(conn)); + return NULL; } switch (connection_connect(TO_CONN(conn), conn->_base.address, -- cgit v1.2.3-54-g00ecf From 36468ec44b6dc3443b0142de83a100e2a853acf8 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 28 Jun 2011 05:43:40 +0200 Subject: Trivial code tweaks and documentation updates. --- src/or/circuitbuild.c | 15 ++++++++------- src/or/config.c | 6 +++--- src/or/connection.c | 26 ++++++++++++++++---------- src/or/main.c | 2 +- 4 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index b1f967b7be..7857eda0b9 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4565,7 +4565,7 @@ clear_bridge_list(void) smartlist_clear(bridge_list); } -/** Free the transport_t transport. */ +/** Free the bridge bridge. */ static void bridge_free(bridge_info_t *bridge) { @@ -4590,7 +4590,7 @@ clear_transport_list(void) smartlist_clear(transport_list); } -/** Free the transport_t transport. */ +/** Free the pluggable transport struct transport. */ static void transport_free(transport_t *transport) { @@ -4639,8 +4639,8 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, tor_addr_copy(&t->addr, addr); t->port = port; t->name = tor_strdup(name); - t->socks_version = socks_ver; + if (!transport_list) transport_list = smartlist_create(); @@ -4662,13 +4662,14 @@ validate_pluggable_transports_config(void) /* Skip bridges without transports. */ if (!b->transport_name) continue; - /* See if the user has Bridges that specify nonexistent + /* See if the user has Bridges that specify nonexistent pluggable transports. We should warn the user in such case, since it's probably misconfiguration. */ if (!transport_get_by_name(b->transport_name)) log_warn(LD_CONFIG, "You have a Bridge line using the %s " "pluggable transport, but there doesn't seem to be a " - "corresponding ClientTransportPlugin line.", b->transport_name); + "corresponding ClientTransportPlugin line.", + b->transport_name); } SMARTLIST_FOREACH_END(b); } } @@ -4812,7 +4813,7 @@ find_bridge_by_digest(const char *digest) /** If addr and port match the address and port of a * bridge of ours that uses pluggable transports, place it's transport * in transport. - * + * * Return: * 0: if transport was found successfully. * 1: if addr:port did not match a bridge, @@ -4820,7 +4821,7 @@ find_bridge_by_digest(const char *digest) * -1: if we should be using a transport, but the transport could not be found. */ int -find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, +find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, transport_t **transport) { if (!bridge_list) diff --git a/src/or/config.c b/src/or/config.c index 41142b644e..12320e07f9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4680,8 +4680,7 @@ parse_client_transport_line(const char *line, int validate_only) SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1); if (smartlist_len(items) < 3) { - log_warn(LD_CONFIG, "parse_client_transport_line(): " - "Too few arguments on ClientTransportPlugin line."); + log_warn(LD_CONFIG, "Too few arguments on ClientTransportPlugin line."); goto err; } @@ -4696,7 +4695,8 @@ parse_client_transport_line(const char *line, int validate_only) else if (!strcmp(socks_ver_str,"socks5")) socks_ver = PROXY_SOCKS5; else { - log_warn(LD_CONFIG, "Strange transport proxy type."); + log_warn(LD_CONFIG, "Strange ClientTransportPlugin proxy type '%s'.", + socks_ver_str); goto err; } diff --git a/src/or/connection.c b/src/or/connection.c index bfc901fa18..e0865885f8 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4101,11 +4101,14 @@ assert_connection_ok(connection_t *conn, time_t now) } } -/** Fills addr and port with the details of the proxy - * server of type proxy_type we are using. - * conn contains the connection_t we are using the proxy for. - * Returns 0 if we were successfull, 1 if we are not using - * a proxy, -1 if we are using a proxy but his addrport could not be +/** Fills addr and port with the details of the global + * proxy server we are using. + * conn contains the connection we are using the proxy for. + * + * Returns: + * 0: if we were successfull + * 1: if we are not using a proxy + * -1: if we are using a proxy but its addrport could not be * found. */ int get_proxy_addrport(tor_addr_t *addr, uint16_t *port, @@ -4131,19 +4134,22 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int r; r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport); if (r == 0) { /* transport found */ + tor_assert(transport); tor_addr_copy(addr, &transport->addr); *port = transport->port; + goto done; + } else { + return r; } - return r; } return 1; - done: + done: /* proxy found */ return 0; } -/** Returns the proxy type used by tor. */ +/** Returns the global proxy type used by tor. */ static int get_proxy_type(void) { @@ -4170,7 +4176,7 @@ log_failed_proxy_connection(connection_t *conn) uint16_t proxy_port; if (get_proxy_addrport(&proxy_addr, &proxy_port, conn) != 0) - return; /* if we have no proxy set up leave this function. */ + return; /* if we have no proxy set up, leave this function. */ log_warn(LD_NET, "The connection to the %s proxy server at %s:%u just failed. " @@ -4188,7 +4194,7 @@ proxy_type_to_string(int proxy_type) case PROXY_SOCKS4: return "SOCKS4"; case PROXY_SOCKS5: return "SOCKS5"; case PROXY_PLUGGABLE: return "pluggable transports SOCKS"; - case PROXY_NONE: return "NULL"; /* probably a bug */ + case PROXY_NONE: return "NULL"; default: tor_assert(0); } } diff --git a/src/or/main.c b/src/or/main.c index f456b03d74..4d43267e45 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -760,7 +760,7 @@ conn_close_if_marked(int i) /* If the connection we are about to close was trying to connect to a proxy server and failed, the client won't be able to use that - proxy. We should warn him about this. */ + proxy. We should warn the user about this. */ if (conn->proxy_state == PROXY_INFANT) log_failed_proxy_connection(conn); -- cgit v1.2.3-54-g00ecf From c4b831e92d68e6c56246ae6e5b2002ef558525ac Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 2 Jul 2011 23:12:32 -0400 Subject: Small tweaks to 2841 code - const-ify some transport_t pointers - Remove a vestigial argument to parse_bridge_line - Make it compile without warnings on my laptop with --enable-gcc-warnings --- src/or/circuitbuild.c | 6 +++--- src/or/circuitbuild.h | 2 +- src/or/config.c | 10 ++++------ src/or/connection.c | 3 ++- src/or/connection_or.c | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 7857eda0b9..b00a35dcce 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -123,7 +123,7 @@ static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice); static void entry_guards_changed(void); -static transport_t *transport_get_by_name(const char *name); +static const transport_t *transport_get_by_name(const char *name); static void transport_free(transport_t *transport); static void bridge_free(bridge_info_t *bridge); @@ -4603,7 +4603,7 @@ transport_free(transport_t *transport) /** Returns the transport in our transport list that has the name name. * Else returns NULL. */ -static transport_t * +static const transport_t * transport_get_by_name(const char *name) { tor_assert(name); @@ -4822,7 +4822,7 @@ find_bridge_by_digest(const char *digest) */ int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, - transport_t **transport) + const transport_t **transport) { if (!bridge_list) return 1; diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 71ea6080e3..54f82500fc 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -143,7 +143,7 @@ void clear_transport_list(void); int transport_add_from_config(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver); int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, - transport_t **transport); + const transport_t **transport); void validate_pluggable_transports_config(void); #endif diff --git a/src/or/config.c b/src/or/config.c index 12320e07f9..9096839c15 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -570,8 +570,7 @@ static int options_transition_affects_descriptor(or_options_t *old_options, 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, - or_options_t *options); +static int parse_bridge_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, @@ -1223,7 +1222,7 @@ options_act(or_options_t *old_options) if (options->Bridges) { mark_bridge_list(); for (cl = options->Bridges; cl; cl = cl->next) { - if (parse_bridge_line(cl->value, 0, options)<0) { + if (parse_bridge_line(cl->value, 0)<0) { log_warn(LD_BUG, "Previously validated Bridge line could not be added!"); return -1; @@ -3696,7 +3695,7 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->Bridges) { for (cl = options->Bridges; cl; cl = cl->next) { - if (parse_bridge_line(cl->value, 1, options)<0) + if (parse_bridge_line(cl->value, 1)<0) REJECT("Bridge line did not parse. See logs for details."); } } @@ -4579,8 +4578,7 @@ options_init_logs(or_options_t *options, int validate_only) * validate_only is 0, and the line is well-formed, then add * the bridge described in the line to our internal bridge list. */ static int -parse_bridge_line(const char *line, int validate_only, - or_options_t *options) +parse_bridge_line(const char *line, int validate_only) { smartlist_t *items = NULL; int r; diff --git a/src/or/connection.c b/src/or/connection.c index e0865885f8..05937ac864 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4130,7 +4130,7 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, goto done; } else if (options->ClientTransportPlugin || options->Bridges) { - transport_t *transport=NULL; + const transport_t *transport=NULL; int r; r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport); if (r == 0) { /* transport found */ @@ -4197,5 +4197,6 @@ proxy_type_to_string(int proxy_type) case PROXY_NONE: return "NULL"; default: tor_assert(0); } + return NULL; /*Unreached*/ } diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 4cbd440a01..2de25f6807 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -336,7 +336,7 @@ connection_or_finished_connecting(or_connection_t *or_conn) else if (get_options()->Socks5Proxy) proxy_type = PROXY_SOCKS5; else if (get_options()->ClientTransportPlugin) { - transport_t *transport=NULL; + const transport_t *transport=NULL; int r; r = find_transport_by_bridge_addrport(&conn->addr,conn->port,&transport); if (r == 0) { -- cgit v1.2.3-54-g00ecf From ded6bbf70a3b63bb423b241c66684becefb1cff7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 2 Jul 2011 23:23:07 -0400 Subject: Style and grammar tweaks on 2841 branch --- src/or/circuitbuild.c | 71 ++++++++++++++++++++++++--------------------------- src/or/circuitbuild.h | 8 +++--- src/or/config.c | 39 +++++++++++++--------------- 3 files changed, 55 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index b00a35dcce..98d7ac32a0 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4611,7 +4611,7 @@ transport_get_by_name(const char *name) if (!transport_list) return NULL; - SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) { + SMARTLIST_FOREACH_BEGIN(transport_list, const transport_t *, transport) { if (!strcmp(transport->name, name)) return transport; } SMARTLIST_FOREACH_END(transport); @@ -4628,14 +4628,15 @@ int transport_add_from_config(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver) { - transport_t *t = tor_malloc_zero(sizeof(transport_t)); + transport_t *t; if (transport_get_by_name(name)) { /* check for duplicate names */ - log_notice(LD_CONFIG, "More than one transports have '%s' as " - "their name.", name); - goto err; + log_warn(LD_CONFIG, "More than one transport has '%s' as " + "its name.", name); + return -1; } + t = tor_malloc_zero(sizeof(transport_t)); tor_addr_copy(&t->addr, addr); t->port = port; t->name = tor_strdup(name); @@ -4646,10 +4647,6 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port, smartlist_add(transport_list, t); return 0; - - err: - tor_free(t); - return -1; } /** Warns the user of possible pluggable transport misconfiguration. */ @@ -4657,20 +4654,19 @@ void validate_pluggable_transports_config(void) { if (bridge_list) { - SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) - { - /* Skip bridges without transports. */ - if (!b->transport_name) - continue; - /* See if the user has Bridges that specify nonexistent - pluggable transports. We should warn the user in such case, - since it's probably misconfiguration. */ - if (!transport_get_by_name(b->transport_name)) - log_warn(LD_CONFIG, "You have a Bridge line using the %s " - "pluggable transport, but there doesn't seem to be a " - "corresponding ClientTransportPlugin line.", - b->transport_name); - } SMARTLIST_FOREACH_END(b); + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) { + /* Skip bridges without transports. */ + if (!b->transport_name) + continue; + /* See if the user has Bridges that specify nonexistent + pluggable transports. We should warn the user in such case, + since it's probably misconfiguration. */ + if (!transport_get_by_name(b->transport_name)) + log_warn(LD_CONFIG, "You have a Bridge line using the %s " + "pluggable transport, but there doesn't seem to be a " + "corresponding ClientTransportPlugin line.", + b->transport_name); + } SMARTLIST_FOREACH_END(b); } } @@ -4811,7 +4807,7 @@ find_bridge_by_digest(const char *digest) } /** If addr and port match the address and port of a - * bridge of ours that uses pluggable transports, place it's transport + * bridge of ours that uses pluggable transports, place its transport * in transport. * * Return: @@ -4827,22 +4823,21 @@ find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, if (!bridge_list) return 1; - SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) - { - if (tor_addr_eq(&bridge->addr, addr) && - (bridge->port == port)) { /* bridge matched */ - if (bridge->transport_name) { /* it also uses pluggable transports */ - *transport = transport_get_by_name(bridge->transport_name); - if (*transport == NULL) { /* it uses pluggable transports, but - the transport could not be found! */ - return -1; - } - return 0; - } else { /* bridge matched, but it doesn't use transports. */ - break; + SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) { + if (tor_addr_eq(&bridge->addr, addr) && + (bridge->port == port)) { /* bridge matched */ + if (bridge->transport_name) { /* it also uses pluggable transports */ + *transport = transport_get_by_name(bridge->transport_name); + if (*transport == NULL) { /* it uses pluggable transports, but + the transport could not be found! */ + return -1; } + return 0; + } else { /* bridge matched, but it doesn't use transports. */ + break; } - } SMARTLIST_FOREACH_END(bridge); + } + } SMARTLIST_FOREACH_END(bridge); return 1; } diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 54f82500fc..74715b7d06 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -14,13 +14,13 @@ /** Represents a pluggable transport proxy used by a bridge. */ typedef struct { - /* SOCKS version */ + /** SOCKS version: One of PROXY_SOCKS4, PROXY_SOCKS5. */ int socks_version; - /* Name of pluggable transport protocol */ + /** Name of pluggable transport protocol */ char *name; - /* Address of proxy */ + /** Address of proxy */ tor_addr_t addr; - /* Port of proxy */ + /** Port of proxy */ uint16_t port; } transport_t; diff --git a/src/or/config.c b/src/or/config.c index 9096839c15..e172f7310a 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), + V(ClientTransportPlugin, LINELIST, NULL), V(ConsensusParams, STRING, NULL), V(ConnLimit, UINT, "1000"), V(ConnDirectionStatistics, BOOL, "0"), @@ -3565,7 +3565,7 @@ options_validate(or_options_t *old_options, or_options_t *options, /* Check if more than one proxy type has been enabled. */ if (!!options->Socks4Proxy + !!options->Socks5Proxy + !!options->HTTPSProxy + !!options->ClientTransportPlugin > 1) - REJECT("You have configured more than one proxy types. " + REJECT("You have configured more than one proxy type. " "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)"); if (options->Socks5ProxyUsername) { @@ -3686,18 +3686,14 @@ options_validate(or_options_t *old_options, or_options_t *options, if (options->UseBridges && !options->TunnelDirConns) REJECT("TunnelDirConns set to 0 only works with UseBridges set to 0"); - if (options->ClientTransportPlugin) { - for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { - if (parse_client_transport_line(cl->value, 1)<0) - REJECT("Transport line did not parse. See logs for details."); - } + for (cl = options->ClientTransportPlugin; cl; cl = cl->next) { + if (parse_client_transport_line(cl->value, 1)<0) + REJECT("Transport line did not parse. See logs for details."); } - if (options->Bridges) { - for (cl = options->Bridges; cl; cl = cl->next) { - if (parse_bridge_line(cl->value, 1)<0) - REJECT("Bridge line did not parse. See logs for details."); - } + for (cl = options->Bridges; cl; cl = cl->next) { + if (parse_bridge_line(cl->value, 1)<0) + REJECT("Bridge line did not parse. See logs for details."); } if (options->ConstrainedSockets) { @@ -4605,8 +4601,9 @@ parse_bridge_line(const char *line, int validate_only) transport_name = field1; addrport = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); - } else + } else { addrport = field1; + } if (tor_addr_port_parse(addrport, &addr, &port)<0) { log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport); @@ -4632,21 +4629,21 @@ parse_bridge_line(const char *line, int validate_only) } if (!validate_only) { - log_debug(LD_DIR, "Bridge at %s:%d (transport: %s) (%s)", - fmt_addr(&addr), (int)port, - transport_name ? transport_name : "no transport", - fingerprint ? fingerprint : "no key listed"); - bridge_add_from_config(&addr, port, - fingerprint ? digest : NULL,transport_name); + log_debug(LD_DIR, "Bridge at %s:%d (transport: %s) (%s)", + fmt_addr(&addr), (int)port, + transport_name ? transport_name : "no transport", + fingerprint ? fingerprint : "no key listed"); + bridge_add_from_config(&addr, port, + fingerprint ? digest : NULL, transport_name); } r = 0; goto done; - err: + err: r = -1; - done: + done: SMARTLIST_FOREACH(items, char*, s, tor_free(s)); smartlist_free(items); tor_free(addrport); -- cgit v1.2.3-54-g00ecf From c0de533c56a02c5557236c5baac6b9d57133467f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 2 Jul 2011 23:32:17 -0400 Subject: Simplify parse_client_transport_line --- src/or/config.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index e172f7310a..a94abb0501 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4680,10 +4680,8 @@ parse_client_transport_line(const char *line, int validate_only) } name = smartlist_get(items, 0); - smartlist_del_keeporder(items, 0); - socks_ver_str = smartlist_get(items, 0); - smartlist_del_keeporder(items, 0); + socks_ver_str = smartlist_get(items, 1); if (!strcmp(socks_ver_str,"socks4")) socks_ver = PROXY_SOCKS4; @@ -4695,8 +4693,7 @@ parse_client_transport_line(const char *line, int validate_only) goto err; } - addrport = smartlist_get(items, 0); - smartlist_del_keeporder(items, 0); + addrport = smartlist_get(items, 2); if (tor_addr_port_parse(addrport, &addr, &port)<0) { log_warn(LD_CONFIG, "Error parsing transport " @@ -4714,8 +4711,7 @@ parse_client_transport_line(const char *line, int validate_only) log_debug(LD_DIR, "Transport %s found at %s:%d", name, fmt_addr(&addr), (int)port); - if (transport_add_from_config(&addr, port, name, - socks_ver) < 0) + if (transport_add_from_config(&addr, port, name, socks_ver) < 0) goto err; } @@ -4728,9 +4724,6 @@ parse_client_transport_line(const char *line, int validate_only) done: SMARTLIST_FOREACH(items, char*, s, tor_free(s)); smartlist_free(items); - tor_free(socks_ver_str); - tor_free(name); - tor_free(addrport); return r; } -- cgit v1.2.3-54-g00ecf From 72125389979af60b659dc469159ea9be397a2ffa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 2 Jul 2011 23:38:00 -0400 Subject: Future-proof and user-proof parse_bridge_line --- src/or/config.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index a94abb0501..0082ff9397 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4597,8 +4597,13 @@ parse_bridge_line(const char *line, int validate_only) field1 = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); - if (!strstr(field1, ".")) { /* new-style bridge line */ + if (!(strstr(field1, ".") || strstr(field1, ":"))) { + /* new-style bridge line */ transport_name = field1; + if (smartlist_len(items) < 1) { + log_warn(LD_CONFIG, "Too few items to Bridge line."); + goto err; + } addrport = smartlist_get(items, 0); smartlist_del_keeporder(items, 0); } else { -- cgit v1.2.3-54-g00ecf From 6053e11ee6540750a68a7c59a1b91727f7e10952 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 3 Jul 2011 00:13:41 -0400 Subject: Refactor the interfaces of transport/proxy lookup fns Returning a tristate is needless here; we can just use the yielded transport/proxy_type field to tell whether there's a proxy, and have the return indicate success/failure. Also, store the proxy_type in the or_connection_t rather than letting it get out of sync if a configuration reload happens between launching the or_connection and deciding what to say with it. --- src/or/circuitbuild.c | 14 +++++++------- src/or/connection.c | 39 +++++++++++++++++++-------------------- src/or/connection.h | 4 ++-- src/or/connection_or.c | 39 +++++++++++---------------------------- src/or/or.h | 3 +++ 5 files changed, 42 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 98d7ac32a0..aa0e996d17 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4810,18 +4810,17 @@ find_bridge_by_digest(const char *digest) * bridge of ours that uses pluggable transports, place its transport * in transport. * - * Return: - * 0: if transport was found successfully. - * 1: if addr:port did not match a bridge, - * or if matched bridge was not using transports. - * -1: if we should be using a transport, but the transport could not be found. + * Return 0 on success (found a transport, or found a bridge with no + * transport, or found no bridge); return -1 if we should be using a + * transport, but the transport could not be found. */ int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, const transport_t **transport) { + *transport = NULL; if (!bridge_list) - return 1; + return 0; SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) { if (tor_addr_eq(&bridge->addr, addr) && @@ -4839,7 +4838,8 @@ find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, } } SMARTLIST_FOREACH_END(bridge); - return 1; + *transport = NULL; + return 0; } /** We need to ask bridge for its server descriptor. */ diff --git a/src/or/connection.c b/src/or/connection.c index 05937ac864..00f25e6b52 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4105,47 +4105,45 @@ assert_connection_ok(connection_t *conn, time_t now) * proxy server we are using. * conn contains the connection we are using the proxy for. * - * Returns: - * 0: if we were successfull - * 1: if we are not using a proxy - * -1: if we are using a proxy but its addrport could not be - * found. */ + * Return 0 on success, -1 on failure. + */ int -get_proxy_addrport(tor_addr_t *addr, uint16_t *port, - connection_t *conn) +get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type, + const connection_t *conn) { or_options_t *options = get_options(); if (options->HTTPSProxy) { tor_addr_copy(addr, &options->HTTPSProxyAddr); *port = options->HTTPSProxyPort; - goto done; + *proxy_type = PROXY_CONNECT; + return 0; } else if (options->Socks4Proxy) { tor_addr_copy(addr, &options->Socks4ProxyAddr); *port = options->Socks4ProxyPort; - goto done; + *proxy_type = PROXY_SOCKS4; + return 0; } else if (options->Socks5Proxy) { tor_addr_copy(addr, &options->Socks5ProxyAddr); *port = options->Socks5ProxyPort; - goto done; + *proxy_type = PROXY_SOCKS5; + return 0; } else if (options->ClientTransportPlugin || options->Bridges) { - const transport_t *transport=NULL; + const transport_t *transport = NULL; int r; r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport); - if (r == 0) { /* transport found */ - tor_assert(transport); + if (r<0) + return -1; + if (transport) { /* transport found */ tor_addr_copy(addr, &transport->addr); *port = transport->port; - goto done; - } else { - return r; + *proxy_type = transport->socks_version; + return 0; } } - return 1; - - done: /* proxy found */ + *proxy_type = PROXY_NONE; return 0; } @@ -4174,8 +4172,9 @@ log_failed_proxy_connection(connection_t *conn) { tor_addr_t proxy_addr; uint16_t proxy_port; + int proxy_type; - if (get_proxy_addrport(&proxy_addr, &proxy_port, conn) != 0) + if (get_proxy_addrport(&proxy_addr, &proxy_port, &proxy_type, conn) != 0) return; /* if we have no proxy set up, leave this function. */ log_warn(LD_NET, diff --git a/src/or/connection.h b/src/or/connection.h index bf439b9bbc..be3de88aaa 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -58,8 +58,8 @@ int connection_connect(connection_t *conn, const char *address, int connection_proxy_connect(connection_t *conn, int type); int connection_read_proxy_handshake(connection_t *conn); void log_failed_proxy_connection(connection_t *conn); -int get_proxy_addrport(tor_addr_t *addr, - uint16_t *port, connection_t *conn); +int get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type, + const connection_t *conn); int retry_all_listeners(smartlist_t *replaced_conns, smartlist_t *new_conns); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 2de25f6807..a02ec1e268 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -317,7 +317,7 @@ connection_or_finished_flushing(or_connection_t *conn) int connection_or_finished_connecting(or_connection_t *or_conn) { - int proxy_type; + const int proxy_type = or_conn->proxy_type; connection_t *conn; tor_assert(or_conn); conn = TO_CONN(or_conn); @@ -327,27 +327,6 @@ connection_or_finished_connecting(or_connection_t *or_conn) conn->address,conn->port); control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0); - proxy_type = PROXY_NONE; - - if (get_options()->HTTPSProxy) - proxy_type = PROXY_CONNECT; - else if (get_options()->Socks4Proxy) - proxy_type = PROXY_SOCKS4; - else if (get_options()->Socks5Proxy) - proxy_type = PROXY_SOCKS5; - else if (get_options()->ClientTransportPlugin) { - const transport_t *transport=NULL; - int r; - r = find_transport_by_bridge_addrport(&conn->addr,conn->port,&transport); - if (r == 0) { - tor_assert(transport); - log_debug(LD_GENERAL, "Found transport. Setting proxy type!\n"); - proxy_type = transport->socks_version; - } else if (r == -1) { - return -1; - } - } - if (proxy_type != PROXY_NONE) { /* start proxy handshake */ if (connection_proxy_connect(conn, proxy_type) < 0) { @@ -846,6 +825,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, int r; tor_addr_t proxy_addr; uint16_t proxy_port; + int proxy_type; tor_assert(_addr); tor_assert(id_digest); @@ -864,12 +844,15 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port, control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0); /* If we are using a proxy server, find it and use it. */ - r = get_proxy_addrport(&proxy_addr, &proxy_port, TO_CONN(conn)); - if (r == 0) { /* proxy found. */ - tor_addr_copy(&addr, &proxy_addr); - port = proxy_port; - conn->_base.proxy_state = PROXY_INFANT; - } else if (r == -1) { /* proxy could not be found. */ + r = get_proxy_addrport(&proxy_addr, &proxy_port, &proxy_type, TO_CONN(conn)); + if (r == 0) { + conn->proxy_type = proxy_type; + if (proxy_type != PROXY_NONE) { + tor_addr_copy(&addr, &proxy_addr); + port = proxy_port; + conn->_base.proxy_state = PROXY_INFANT; + } + } else { log_warn(LD_GENERAL, "Tried to connect through proxy, but proxy address " "could not be found."); connection_free(TO_CONN(conn)); diff --git a/src/or/or.h b/src/or/or.h index 72d311b430..d1817d47f8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -230,6 +230,8 @@ typedef enum { #define PROXY_CONNECT 1 #define PROXY_SOCKS4 2 #define PROXY_SOCKS5 3 +/* !!!! If there is ever a PROXY_* type over 2, we must grow the proxy_type + * field in or_connection_t */ /* pluggable transports proxy type */ #define PROXY_PLUGGABLE 4 @@ -1097,6 +1099,7 @@ typedef struct or_connection_t { * router itself has a problem. */ unsigned int is_bad_for_new_circs:1; + unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */ uint8_t link_proto; /**< What protocol version are we using? 0 for * "none negotiated yet." */ circid_t next_circ_id; /**< Which circ_id do we try to use next on -- cgit v1.2.3-54-g00ecf