We can now match our transports with our bridges.

This commit is contained in:
George Kadianakis 2011-06-11 23:20:39 +02:00
parent 20c31c80fb
commit e09f302589
3 changed files with 150 additions and 5 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;