diff options
author | George Kadianakis <desnacked@gmail.com> | 2011-06-11 23:20:39 +0200 |
---|---|---|
committer | George Kadianakis <desnacked@gmail.com> | 2011-06-11 23:20:39 +0200 |
commit | e09f302589dc3e46edccf366595392f2dd9b43e3 (patch) | |
tree | 6acf339455c1f0f7bca35237ea029f149ff28940 /src/or/circuitbuild.c | |
parent | 20c31c80fb7265e8987747b3cdba04f16c352b15 (diff) | |
download | tor-e09f302589dc3e46edccf366595392f2dd9b43e3.tar.gz tor-e09f302589dc3e46edccf366595392f2dd9b43e3.zip |
We can now match our transports with our bridges.
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 117 |
1 files changed, 116 insertions, 1 deletions
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 <b>transport</b>. +*/ +static void +transport_free(transport_info_t *transport) +{ + tor_free(transport->name); + tor_free(transport); +} + +/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>. + <b>name</b> is set to the name of the protocol this proxy uses. + <b>socks_ver</b> is set to the SOCKS version of the proxy. +*/ +void +transport_add_from_config(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver) +{ + transport_info_t *t = tor_malloc_zero(sizeof(transport_info_t)); + + tor_addr_copy(&t->addr, addr); + t->port = port; + /** check strdup return */ + t->name = strdup(name); + t->socks_version = socks_ver; + if (!transport_list) + transport_list = smartlist_create(); + + smartlist_add(transport_list, t); +} + +/** + Attempts to map every transport found on torrc to it's + corresponding bridge. + Returns 1 on a succesfull bijective map, otherwise it returns -1. +*/ +int +match_bridges_with_transports(void) +{ + /* Used to check if a transport was finally found for a bridge */ + int found_match=0; + /* Number of matches. */ + int n_matches=0; + /* Number of transports. */ + int n_transports=0; + + tor_assert(transport_list); + tor_assert(bridge_list); + + /* Iterate bridges */ + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) + { + /* Skip bridges without transports. */ + if (!b->transport_name_config) + continue; + found_match=0; + /* Iterate transports */ + SMARTLIST_FOREACH_BEGIN(transport_list, transport_info_t *, t) + { + /* If the transport name of the transport is the same as the + transport name of the bridge, we have a match. */ + if (!strcmp(b->transport_name_config, t->name)) { + found_match=1; + n_matches++; + b->transport = t; + tor_free(b->transport_name_config); + log_warn(LD_CONFIG, "Matched transport '%s'", t->name); + continue; + } + } SMARTLIST_FOREACH_END(t); + if (!found_match) { + log_warn(LD_CONFIG, "Couldn't find transport " + "match for %s!\n", b->transport_name_config); + return -1; + } + } SMARTLIST_FOREACH_END(b); + + /* count number of transports to see if there were transports + that didn't get matched to a bridge. */ + SMARTLIST_FOREACH(transport_list, transport_info_t *, t, n_transports++); + if (n_transports != n_matches) { + log_warn(LD_CONFIG, "You have %d transports and we only " + "managed to match %d of them!\n", n_transports, n_matches); + return -1; + } + + return 1; +} + /** Return a bridge pointer if <b>ri</b> is one of our known bridges * (either by comparing keys if possible, else by comparing addr/port). * Else return NULL. */ @@ -4638,7 +4750,7 @@ learned_router_identity(const tor_addr_t *addr, uint16_t port, * bridge in our list, unmark it, and don't actually add anything new. */ void bridge_add_from_config(const tor_addr_t *addr, uint16_t port, - const char *digest) + const char *digest, const char *transport_name) { bridge_info_t *b; @@ -4652,6 +4764,8 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, b->port = port; if (digest) memcpy(b->identity, digest, DIGEST_LEN); + if (transport_name) + b->transport_name_config = strdup(transport_name); b->fetch_status.schedule = DL_SCHED_BRIDGE; if (!bridge_list) bridge_list = smartlist_create(); @@ -4994,6 +5108,7 @@ entry_guards_free_all(void) entry_guards = NULL; } clear_bridge_list(); + clear_transport_list(); smartlist_free(bridge_list); bridge_list = NULL; } |