From 6173d36340096fc3e188e6cc886c345981e0f303 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 25 Jan 2012 18:51:38 +0200 Subject: Move transport-related functions from circuitbuild.c to transports.c. Move 'transport_t' to transports.h, and all transport-related functions that don't rely on 'bridge_list' to transports.c. --- src/or/circuitbuild.c | 196 ------------------------------------------------- src/or/circuitbuild.h | 30 +------- src/or/transports.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/or/transports.h | 27 +++++++ 4 files changed, 228 insertions(+), 225 deletions(-) (limited to 'src/or') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 6d1e4e764..0a04b1b11 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4970,199 +4970,6 @@ bridge_free(bridge_info_t *bridge) tor_free(bridge); } -/** A list of pluggable transports found in torrc. */ -static smartlist_t *transport_list = NULL; - -/** Mark every entry of the transport list to be removed on our next call to - * sweep_transport_list unless it has first been un-marked. */ -void -mark_transport_list(void) -{ - if (!transport_list) - transport_list = smartlist_new(); - SMARTLIST_FOREACH(transport_list, transport_t *, t, - t->marked_for_removal = 1); -} - -/** Remove every entry of the transport list that was marked with - * mark_transport_list if it has not subsequently been un-marked. */ -void -sweep_transport_list(void) -{ - if (!transport_list) - transport_list = smartlist_new(); - SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, t) { - if (t->marked_for_removal) { - SMARTLIST_DEL_CURRENT(transport_list, t); - transport_free(t); - } - } SMARTLIST_FOREACH_END(t); -} - -/** Initialize the pluggable transports list to empty, creating it if - * needed. */ -void -clear_transport_list(void) -{ - if (!transport_list) - transport_list = smartlist_new(); - SMARTLIST_FOREACH(transport_list, transport_t *, t, transport_free(t)); - smartlist_clear(transport_list); -} - -/** Free the pluggable transport struct transport. */ -void -transport_free(transport_t *transport) -{ - if (!transport) - return; - - tor_free(transport->name); - tor_free(transport); -} - -/** Returns the transport in our transport list that has the name name. - * Else returns NULL. */ -transport_t * -transport_get_by_name(const char *name) -{ - tor_assert(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; -} - -/** Returns a transport_t struct for a transport proxy supporting the - protocol name listening at addr:port using - SOCKS version socks_ver. */ -transport_t * -transport_new(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver) -{ - transport_t *t = tor_malloc_zero(sizeof(transport_t)); - - tor_addr_copy(&t->addr, addr); - t->port = port; - t->name = tor_strdup(name); - t->socks_version = socks_ver; - - return t; -} - -/** Resolve any conflicts that the insertion of transport t - * might cause. - * Return 0 if t is OK and should be registered, 1 if there is - * a transport identical to t already registered and -1 if - * t cannot be added due to conflicts. */ -static int -transport_resolve_conflicts(transport_t *t) -{ - /* This is how we resolve transport conflicts: - - If there is already a transport with the same name and addrport, - we either have duplicate torrc lines OR we are here post-HUP and - this transport was here pre-HUP as well. In any case, mark the - old transport so that it doesn't get removed and ignore the new - one. Our caller has to free the new transport so we return '1' to - signify this. - - If there is already a transport with the same name but different - addrport: - * if it's marked for removal, it means that it either has a lower - priority than 't' in torrc (otherwise the mark would have been - cleared by the paragraph above), or it doesn't exist at all in - the post-HUP torrc. We destroy the old transport and register 't'. - * if it's *not* marked for removal, it means that it was newly - added in the post-HUP torrc or that it's of higher priority, in - this case we ignore 't'. */ - transport_t *t_tmp = transport_get_by_name(t->name); - if (t_tmp) { /* same name */ - if (tor_addr_eq(&t->addr, &t_tmp->addr) && (t->port == t_tmp->port)) { - /* same name *and* addrport */ - t_tmp->marked_for_removal = 0; - return 1; - } else { /* same name but different addrport */ - if (t_tmp->marked_for_removal) { /* marked for removal */ - log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s:%u' " - "but there was already a transport marked for deletion at " - "'%s:%u'. We deleted the old transport and registered the " - "new one.", t->name, fmt_addr(&t->addr), t->port, - fmt_addr(&t_tmp->addr), t_tmp->port); - smartlist_remove(transport_list, t_tmp); - transport_free(t_tmp); - } else { /* *not* marked for removal */ - log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s:%u' " - "but the same transport already exists at '%s:%u'. " - "Skipping.", t->name, fmt_addr(&t->addr), t->port, - fmt_addr(&t_tmp->addr), t_tmp->port); - return -1; - } - } - } - - return 0; -} - -/** Add transport t to the internal list of pluggable - * transports. - * Returns 0 if the transport was added correctly, 1 if the same - * transport was already registered (in this case the caller must - * free the transport) and -1 if there was an error. */ -int -transport_add(transport_t *t) -{ - int r; - tor_assert(t); - - r = transport_resolve_conflicts(t); - - switch (r) { - case 0: /* should register transport */ - if (!transport_list) - transport_list = smartlist_new(); - smartlist_add(transport_list, t); - return 0; - default: /* let our caller know the return code */ - return r; - } -} - -/** 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. */ -int -transport_add_from_config(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver) -{ - transport_t *t = transport_new(addr, port, name, socks_ver); - - int r = transport_add(t); - - switch (r) { - case -1: - default: - log_notice(LD_GENERAL, "Could not add transport %s at %s:%u. Skipping.", - t->name, fmt_addr(&t->addr), t->port); - transport_free(t); - return -1; - case 1: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", - t->name, fmt_addr(&t->addr), t->port); - transport_free(t); /* falling */ - return 0; - case 0: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", - t->name, fmt_addr(&t->addr), t->port); - return 0; - } -} /** Return a bridge pointer if ri is one of our known bridges * (either by comparing keys if possible, else by comparing addr/port). @@ -5800,10 +5607,7 @@ entry_guards_free_all(void) entry_guards = NULL; } 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 984d04a99..e6783d832 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -12,20 +12,7 @@ #ifndef _TOR_CIRCUITBUILD_H #define _TOR_CIRCUITBUILD_H -/** Represents a pluggable transport proxy used by a bridge. */ -typedef struct { - /** SOCKS version: One of PROXY_SOCKS4, PROXY_SOCKS5. */ - int socks_version; - /** Name of pluggable transport protocol */ - char *name; - /** Address of proxy */ - tor_addr_t addr; - /** Port of proxy */ - uint16_t port; - /** Boolean: We are re-parsing our transport list, and we are going to remove - * this one if we don't find it in the list of configured transports. */ - unsigned marked_for_removal : 1; -} transport_t; +#include "transports.h" char *circuit_list_path(origin_circuit_t *circ, int verbose); char *circuit_list_path_for_controller(origin_circuit_t *circ); @@ -82,8 +69,6 @@ int getinfo_helper_entry_guards(control_connection_t *conn, void mark_bridge_list(void); void sweep_bridge_list(void); -void mark_transport_list(void); -void sweep_transport_list(void); int routerinfo_is_a_configured_bridge(const routerinfo_t *ri); int node_is_a_configured_bridge(const node_t *node); @@ -151,21 +136,8 @@ void circuit_build_times_network_circ_success(circuit_build_times_t *cbt); /* DOCDOC circuit_build_times_get_bw_scale */ 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); -int transport_add(transport_t *t); -void transport_free(transport_t *transport); -transport_t *transport_new(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver); - -/* DOCDOC find_transport_name_by_bridge_addrport */ -const char *find_transport_name_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, const transport_t **transport); -transport_t *transport_get_by_name(const char *name); #endif diff --git a/src/or/transports.c b/src/or/transports.c index 4ba239562..4f67a4633 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -127,6 +127,200 @@ static INLINE void free_execve_args(char **arg); protocol version. */ #define PROTO_VERSION_ONE 1 +/** A list of pluggable transports found in torrc. */ +static smartlist_t *transport_list = NULL; + +/** Mark every entry of the transport list to be removed on our next call to + * sweep_transport_list unless it has first been un-marked. */ +void +mark_transport_list(void) +{ + if (!transport_list) + transport_list = smartlist_new(); + SMARTLIST_FOREACH(transport_list, transport_t *, t, + t->marked_for_removal = 1); +} + +/** Remove every entry of the transport list that was marked with + * mark_transport_list if it has not subsequently been un-marked. */ +void +sweep_transport_list(void) +{ + if (!transport_list) + transport_list = smartlist_new(); + SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, t) { + if (t->marked_for_removal) { + SMARTLIST_DEL_CURRENT(transport_list, t); + transport_free(t); + } + } SMARTLIST_FOREACH_END(t); +} + +/** Initialize the pluggable transports list to empty, creating it if + * needed. */ +void +clear_transport_list(void) +{ + if (!transport_list) + transport_list = smartlist_new(); + SMARTLIST_FOREACH(transport_list, transport_t *, t, transport_free(t)); + smartlist_clear(transport_list); +} + +/** Returns a transport_t struct for a transport proxy supporting the + protocol name listening at addr:port using + SOCKS version socks_ver. */ +transport_t * +transport_new(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver) +{ + transport_t *t = tor_malloc_zero(sizeof(transport_t)); + + tor_addr_copy(&t->addr, addr); + t->port = port; + t->name = tor_strdup(name); + t->socks_version = socks_ver; + + return t; +} + +/** Free the pluggable transport struct transport. */ +void +transport_free(transport_t *transport) +{ + if (!transport) + return; + + tor_free(transport->name); + tor_free(transport); +} + +/** Returns the transport in our transport list that has the name name. + * Else returns NULL. */ +transport_t * +transport_get_by_name(const char *name) +{ + tor_assert(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; +} + +/** 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. */ +int +transport_add_from_config(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver) +{ + transport_t *t = transport_new(addr, port, name, socks_ver); + + int r = transport_add(t); + + switch (r) { + case -1: + default: + log_notice(LD_GENERAL, "Could not add transport %s at %s:%u. Skipping.", + t->name, fmt_addr(&t->addr), t->port); + transport_free(t); + return -1; + case 1: + log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", + t->name, fmt_addr(&t->addr), t->port); + transport_free(t); /* falling */ + return 0; + case 0: + log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", + t->name, fmt_addr(&t->addr), t->port); + return 0; + } +} + +/** Resolve any conflicts that the insertion of transport t + * might cause. + * Return 0 if t is OK and should be registered, 1 if there is + * a transport identical to t already registered and -1 if + * t cannot be added due to conflicts. */ +static int +transport_resolve_conflicts(transport_t *t) +{ + /* This is how we resolve transport conflicts: + + If there is already a transport with the same name and addrport, + we either have duplicate torrc lines OR we are here post-HUP and + this transport was here pre-HUP as well. In any case, mark the + old transport so that it doesn't get removed and ignore the new + one. Our caller has to free the new transport so we return '1' to + signify this. + + If there is already a transport with the same name but different + addrport: + * if it's marked for removal, it means that it either has a lower + priority than 't' in torrc (otherwise the mark would have been + cleared by the paragraph above), or it doesn't exist at all in + the post-HUP torrc. We destroy the old transport and register 't'. + * if it's *not* marked for removal, it means that it was newly + added in the post-HUP torrc or that it's of higher priority, in + this case we ignore 't'. */ + transport_t *t_tmp = transport_get_by_name(t->name); + if (t_tmp) { /* same name */ + if (tor_addr_eq(&t->addr, &t_tmp->addr) && (t->port == t_tmp->port)) { + /* same name *and* addrport */ + t_tmp->marked_for_removal = 0; + return 1; + } else { /* same name but different addrport */ + if (t_tmp->marked_for_removal) { /* marked for removal */ + log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s:%u' " + "but there was already a transport marked for deletion at " + "'%s:%u'. We deleted the old transport and registered the " + "new one.", t->name, fmt_addr(&t->addr), t->port, + fmt_addr(&t_tmp->addr), t_tmp->port); + smartlist_remove(transport_list, t_tmp); + transport_free(t_tmp); + } else { /* *not* marked for removal */ + log_notice(LD_GENERAL, "You tried to add transport '%s' at '%s:%u' " + "but the same transport already exists at '%s:%u'. " + "Skipping.", t->name, fmt_addr(&t->addr), t->port, + fmt_addr(&t_tmp->addr), t_tmp->port); + return -1; + } + } + } + + return 0; +} + +/** Add transport t to the internal list of pluggable + * transports. + * Returns 0 if the transport was added correctly, 1 if the same + * transport was already registered (in this case the caller must + * free the transport) and -1 if there was an error. */ +int +transport_add(transport_t *t) +{ + int r; + tor_assert(t); + + r = transport_resolve_conflicts(t); + + switch (r) { + case 0: /* should register transport */ + if (!transport_list) + transport_list = smartlist_new(); + smartlist_add(transport_list, t); + return 0; + default: /* let our caller know the return code */ + return r; + } +} + /** List of unconfigured managed proxies. */ static smartlist_t *managed_proxy_list = NULL; /** Number of still unconfigured proxies. */ @@ -1204,6 +1398,12 @@ sweep_proxy_list(void) void pt_free_all(void) { + if (transport_list) { + clear_transport_list(); + smartlist_free(transport_list); + transport_list = NULL; + } + if (managed_proxy_list) { /* If the proxy is in PT_PROTO_COMPLETED, it has registered its transports and it's the duty of the circuitbuild.c subsystem to diff --git a/src/or/transports.h b/src/or/transports.h index 02f159a5d..f00c7c093 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -11,6 +11,33 @@ #ifndef TOR_TRANSPORTS_H #define TOR_TRANSPORTS_H +/** Represents a pluggable transport used by a bridge. */ +typedef struct { + /** SOCKS version: One of PROXY_SOCKS4, PROXY_SOCKS5. */ + int socks_version; + /** Name of pluggable transport protocol */ + char *name; + /** Address of proxy */ + tor_addr_t addr; + /** Port of proxy */ + uint16_t port; + /** Boolean: We are re-parsing our transport list, and we are going to remove + * this one if we don't find it in the list of configured transports. */ + unsigned marked_for_removal : 1; +} transport_t; + +void mark_transport_list(void); +void sweep_transport_list(void); +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 transport_add(transport_t *t); +void transport_free(transport_t *transport); +transport_t *transport_new(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver); +transport_t *transport_get_by_name(const char *name); + + void pt_kickstart_proxy(const smartlist_t *transport_list, char **proxy_argv, int is_server); -- cgit v1.2.3 From d11b772a6c621d7011eed20cd58383c6f1ac0b54 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 25 Jan 2012 21:23:46 +0200 Subject: Introduce a transport_t deep copy function. --- src/or/transports.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index 4f67a4633..566cd9324 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -195,6 +195,25 @@ transport_free(transport_t *transport) tor_free(transport); } +/** Return a deep copy of transport. */ +static transport_t * +transport_copy(const transport_t *transport) +{ + transport_t *new_transport = NULL; + + tor_assert(transport); + + new_transport = tor_malloc_zero(sizeof(transport_t)); + + new_transport->socks_version = transport->socks_version; + new_transport->name = tor_strdup(transport->name); + tor_addr_copy(&new_transport->addr, &transport->addr); + new_transport->port = transport->port; + new_transport->marked_for_removal = transport->marked_for_removal; + + return new_transport; +} + /** Returns the transport in our transport list that has the name name. * Else returns NULL. */ transport_t * -- cgit v1.2.3 From aecc728a5adce225c8415ca90121f2dd23f4f695 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 26 Jan 2012 00:29:15 +0200 Subject: Refactor mp->transports to use transport_t. --- src/or/transports.c | 65 ++++++++++++++++++----------------------------------- src/or/transports.h | 23 +------------------ 2 files changed, 23 insertions(+), 65 deletions(-) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index 566cd9324..348b93179 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -430,11 +430,11 @@ proxy_needs_restart(const managed_proxy_t *mp) { /* mp->transport_to_launch is populated with the names of the transports that must be launched *after* the SIGHUP. - mp->transports is populated with the names of the transports that - were launched *before* the SIGHUP. + mp->transports is populated with the transports that were + launched *before* the SIGHUP. - If the two lists contain the same strings, we don't need to - restart the proxy, since it already does what we want. */ + Check if all the transports that need to be launched are already + launched: */ tor_assert(smartlist_len(mp->transports_to_launch) > 0); tor_assert(mp->conf_state == PT_PROTO_COMPLETED); @@ -442,11 +442,11 @@ proxy_needs_restart(const managed_proxy_t *mp) if (smartlist_len(mp->transports_to_launch) != smartlist_len(mp->transports)) goto needs_restart; - SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, char *, t_t_l) { - if (!smartlist_string_isin(mp->transports, t_t_l)) + SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) { + if (!smartlist_string_isin(mp->transports_to_launch, t->name)) goto needs_restart; - } SMARTLIST_FOREACH_END(t_t_l); + } SMARTLIST_FOREACH_END(t); return 0; @@ -458,6 +458,7 @@ proxy_needs_restart(const managed_proxy_t *mp) * preparations and then flag its state so that it will be relaunched * in the next tick. */ static void + proxy_prepare_for_restart(managed_proxy_t *mp) { transport_t *t_tmp = NULL; @@ -468,16 +469,17 @@ proxy_prepare_for_restart(managed_proxy_t *mp) tor_process_handle_destroy(mp->process_handle, 1); mp->process_handle = NULL; - /* destroy all its old transports. we no longer use them. */ - SMARTLIST_FOREACH_BEGIN(mp->transports, const char *, t_name) { - t_tmp = transport_get_by_name(t_name); + /* destroy all its registered transports, since we will no longer + use them. */ + SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) { + t_tmp = transport_get_by_name(t->name); if (t_tmp) t_tmp->marked_for_removal = 1; - } SMARTLIST_FOREACH_END(t_name); + } SMARTLIST_FOREACH_END(t); sweep_transport_list(); - /* free the transport names in mp->transports */ - SMARTLIST_FOREACH(mp->transports, char *, t_name, tor_free(t_name)); + /* free the transport in mp->transports */ + SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t)); smartlist_clear(mp->transports); /* flag it as an infant proxy so that it gets launched on next tick */ @@ -683,26 +685,13 @@ configure_proxy(managed_proxy_t *mp) static void register_server_proxy(managed_proxy_t *mp) { - /* After we register this proxy's transports, we switch its - mp->transports to a list containing strings of its transport - names. (See transports.h) */ - smartlist_t *sm_tmp = smartlist_new(); - tor_assert(mp->conf_state != PT_PROTO_COMPLETED); + SMARTLIST_FOREACH_BEGIN(mp->transports, transport_t *, t) { save_transport_to_state(t->name, &t->addr, t->port); log_notice(LD_GENERAL, "Registered server transport '%s' at '%s:%d'", t->name, fmt_addr(&t->addr), (int)t->port); - smartlist_add(sm_tmp, tor_strdup(t->name)); } SMARTLIST_FOREACH_END(t); - - /* Since server proxies don't register their transports in the - circuitbuild.c subsystem, it's our duty to free them when we - switch mp->transports to strings. */ - SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t)); - smartlist_free(mp->transports); - - mp->transports = sm_tmp; } /** Register all the transports supported by client managed proxy @@ -711,33 +700,26 @@ static void register_client_proxy(managed_proxy_t *mp) { int r; - /* After we register this proxy's transports, we switch its - mp->transports to a list containing strings of its transport - names. (See transports.h) */ - smartlist_t *sm_tmp = smartlist_new(); tor_assert(mp->conf_state != PT_PROTO_COMPLETED); + SMARTLIST_FOREACH_BEGIN(mp->transports, transport_t *, t) { - r = transport_add(t); + transport_t *transport_tmp = transport_copy(t); + r = transport_add(transport_tmp); switch (r) { case -1: log_notice(LD_GENERAL, "Could not add transport %s. Skipping.", t->name); - transport_free(t); + transport_free(transport_tmp); break; case 0: log_info(LD_GENERAL, "Succesfully registered transport %s", t->name); - smartlist_add(sm_tmp, tor_strdup(t->name)); break; case 1: log_info(LD_GENERAL, "Succesfully registered transport %s", t->name); - smartlist_add(sm_tmp, tor_strdup(t->name)); - transport_free(t); + transport_free(transport_tmp); break; } } SMARTLIST_FOREACH_END(t); - - smartlist_free(mp->transports); - mp->transports = sm_tmp; } /** Register the transports of managed proxy mp. */ @@ -755,10 +737,7 @@ static void managed_proxy_destroy(managed_proxy_t *mp, int also_terminate_process) { - if (mp->conf_state != PT_PROTO_COMPLETED) - SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t)); - else - SMARTLIST_FOREACH(mp->transports, char *, t_name, tor_free(t_name)); + SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t)); /* free the transports smartlist */ smartlist_free(mp->transports); diff --git a/src/or/transports.h b/src/or/transports.h index f00c7c093..aeca87312 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -95,28 +95,7 @@ typedef struct { smartlist_t *transports_to_launch; /* The 'transports' list contains all the transports this proxy has - launched. - - Before a managed_proxy_t reaches the PT_PROTO_COMPLETED phase, - this smartlist contains a 'transport_t' for every transport it - has launched. - - When the managed_proxy_t reaches the PT_PROTO_COMPLETED phase, it - registers all its transports to the circuitbuild.c subsystem. At - that point the 'transport_t's are owned by the circuitbuild.c - subsystem. - - To avoid carrying dangling 'transport_t's in this smartlist, - right before the managed_proxy_t reaches the PT_PROTO_COMPLETED - phase we replace all 'transport_t's with strings of their - transport names. - - So, tl;dr: - When (conf_state != PT_PROTO_COMPLETED) this list carries - (transport_t *). - When (conf_state == PT_PROTO_COMPLETED) this list carries - (char *). - */ + launched. */ smartlist_t *transports; } managed_proxy_t; -- cgit v1.2.3 From 17caec3676e857bf87f4b3c7d50114a9627b52a4 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 26 Jan 2012 00:42:30 +0200 Subject: Make some transports.c functions static. - Also reorder functions. --- src/or/transports.c | 120 ++++++++++++++++++++++++++-------------------------- src/or/transports.h | 6 +-- 2 files changed, 61 insertions(+), 65 deletions(-) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index 348b93179..6ba080e51 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -130,6 +130,34 @@ static INLINE void free_execve_args(char **arg); /** A list of pluggable transports found in torrc. */ static smartlist_t *transport_list = NULL; +/** Returns a transport_t struct for a transport proxy supporting the + protocol name listening at addr:port using + SOCKS version socks_ver. */ +static transport_t * +transport_new(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver) +{ + transport_t *t = tor_malloc_zero(sizeof(transport_t)); + + tor_addr_copy(&t->addr, addr); + t->port = port; + t->name = tor_strdup(name); + t->socks_version = socks_ver; + + return t; +} + +/** Free the pluggable transport struct transport. */ +void +transport_free(transport_t *transport) +{ + if (!transport) + return; + + tor_free(transport->name); + tor_free(transport); +} + /** Mark every entry of the transport list to be removed on our next call to * sweep_transport_list unless it has first been un-marked. */ void @@ -158,7 +186,7 @@ sweep_transport_list(void) /** Initialize the pluggable transports list to empty, creating it if * needed. */ -void +static void clear_transport_list(void) { if (!transport_list) @@ -167,34 +195,6 @@ clear_transport_list(void) smartlist_clear(transport_list); } -/** Returns a transport_t struct for a transport proxy supporting the - protocol name listening at addr:port using - SOCKS version socks_ver. */ -transport_t * -transport_new(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver) -{ - transport_t *t = tor_malloc_zero(sizeof(transport_t)); - - tor_addr_copy(&t->addr, addr); - t->port = port; - t->name = tor_strdup(name); - t->socks_version = socks_ver; - - return t; -} - -/** Free the pluggable transport struct transport. */ -void -transport_free(transport_t *transport) -{ - if (!transport) - return; - - tor_free(transport->name); - tor_free(transport); -} - /** Return a deep copy of transport. */ static transport_t * transport_copy(const transport_t *transport) @@ -232,36 +232,6 @@ transport_get_by_name(const char *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. */ -int -transport_add_from_config(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver) -{ - transport_t *t = transport_new(addr, port, name, socks_ver); - - int r = transport_add(t); - - switch (r) { - case -1: - default: - log_notice(LD_GENERAL, "Could not add transport %s at %s:%u. Skipping.", - t->name, fmt_addr(&t->addr), t->port); - transport_free(t); - return -1; - case 1: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", - t->name, fmt_addr(&t->addr), t->port); - transport_free(t); /* falling */ - return 0; - case 0: - log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", - t->name, fmt_addr(&t->addr), t->port); - return 0; - } -} - /** Resolve any conflicts that the insertion of transport t * might cause. * Return 0 if t is OK and should be registered, 1 if there is @@ -321,7 +291,7 @@ transport_resolve_conflicts(transport_t *t) * Returns 0 if the transport was added correctly, 1 if the same * transport was already registered (in this case the caller must * free the transport) and -1 if there was an error. */ -int +static int transport_add(transport_t *t) { int r; @@ -340,6 +310,36 @@ transport_add(transport_t *t) } } +/** 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. */ +int +transport_add_from_config(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver) +{ + transport_t *t = transport_new(addr, port, name, socks_ver); + + int r = transport_add(t); + + switch (r) { + case -1: + default: + log_notice(LD_GENERAL, "Could not add transport %s at %s:%u. Skipping.", + t->name, fmt_addr(&t->addr), t->port); + transport_free(t); + return -1; + case 1: + log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", + t->name, fmt_addr(&t->addr), t->port); + transport_free(t); /* falling */ + return 0; + case 0: + log_info(LD_GENERAL, "Succesfully registered transport %s at %s:%u.", + t->name, fmt_addr(&t->addr), t->port); + return 0; + } +} + /** List of unconfigured managed proxies. */ static smartlist_t *managed_proxy_list = NULL; /** Number of still unconfigured proxies. */ diff --git a/src/or/transports.h b/src/or/transports.h index aeca87312..39f7bf402 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -28,15 +28,11 @@ typedef struct { void mark_transport_list(void); void sweep_transport_list(void); -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 transport_add(transport_t *t); void transport_free(transport_t *transport); -transport_t *transport_new(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver); -transport_t *transport_get_by_name(const char *name); +transport_t *transport_get_by_name(const char *name); void pt_kickstart_proxy(const smartlist_t *transport_list, char **proxy_argv, int is_server); -- cgit v1.2.3 From 4bafe24400fa80d2bfc7c862924d8af04554e002 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 26 Jan 2012 01:09:53 +0200 Subject: Constify some functions. --- src/or/transports.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index 6ba080e51..e0492b8d6 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -135,7 +135,7 @@ static smartlist_t *transport_list = NULL; SOCKS version socks_ver. */ static transport_t * transport_new(const tor_addr_t *addr, uint16_t port, - const char *name, int socks_ver) + const char *name, int socks_ver) { transport_t *t = tor_malloc_zero(sizeof(transport_t)); @@ -238,7 +238,7 @@ transport_get_by_name(const char *name) * a transport identical to t already registered and -1 if * t cannot be added due to conflicts. */ static int -transport_resolve_conflicts(transport_t *t) +transport_resolve_conflicts(const transport_t *t) { /* This is how we resolve transport conflicts: @@ -683,7 +683,7 @@ configure_proxy(managed_proxy_t *mp) /** Register server managed proxy mp transports to state */ static void -register_server_proxy(managed_proxy_t *mp) +register_server_proxy(const managed_proxy_t *mp) { tor_assert(mp->conf_state != PT_PROTO_COMPLETED); @@ -697,7 +697,7 @@ register_server_proxy(managed_proxy_t *mp) /** Register all the transports supported by client managed proxy * mp to the bridge subsystem. */ static void -register_client_proxy(managed_proxy_t *mp) +register_client_proxy(const managed_proxy_t *mp) { int r; @@ -724,7 +724,7 @@ register_client_proxy(managed_proxy_t *mp) /** Register the transports of managed proxy mp. */ static INLINE void -register_proxy(managed_proxy_t *mp) +register_proxy(const managed_proxy_t *mp) { if (mp->is_server) register_server_proxy(mp); -- cgit v1.2.3 From 9dea3a03b925f8cd83f2a975c4d5899f7691252d Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 23 Feb 2012 17:51:48 -0800 Subject: Add pluggable transport info to extra-info descriptors. --- src/or/router.c | 7 +++++++ src/or/transports.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/or/transports.h | 2 ++ 3 files changed, 54 insertions(+) (limited to 'src/or') diff --git a/src/or/router.c b/src/or/router.c index 352c456f1..795afe2b3 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -2344,6 +2344,13 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, } } + /* Add information about the pluggable transports we support. */ + if (options->ServerTransportPlugin) { + char *pluggable_transports = pt_get_extra_info_descriptor_string(); + if (pluggable_transports) + smartlist_add(chunks, pluggable_transports); + } + if (should_record_bridge_info(options) && write_stats_to_extrainfo) { const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now); if (bridge_stats) { diff --git a/src/or/transports.c b/src/or/transports.c index e0492b8d6..e5a54463d 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1373,6 +1373,51 @@ pt_prepare_proxy_list_for_config_read(void) tor_assert(unconfigured_proxies_n == 0); } +/** Return the pluggable transport string that we should display in + * our extra-info descriptor. If we shouldn't display such a string, + * or we have nothing to display, return NULL. The string is + * allocated on the heap and it's the responsibility of the caller to + * free it. */ +char * +pt_get_extra_info_descriptor_string(void) +{ + char *the_string = NULL; + smartlist_t *string_chunks = NULL; + + if (!managed_proxy_list) + return NULL; + + string_chunks = smartlist_new(); + + /* For each managed proxy, add its transports to the chunks list. */ + SMARTLIST_FOREACH_BEGIN(managed_proxy_list, const managed_proxy_t *, mp) { + if ((!mp->is_server) || (mp->conf_state != PT_PROTO_COMPLETED)) + continue; + + tor_assert(mp->transports); + + SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) { + smartlist_add_asprintf(string_chunks, + "method %s %s:%u", + t->name, fmt_addr(&t->addr), t->port); + } SMARTLIST_FOREACH_END(t); + + } SMARTLIST_FOREACH_END(mp); + + if (smartlist_len(string_chunks) == 0) { + smartlist_free(string_chunks); + return NULL; + } + + /* Join all the chunks into the final string. */ + the_string = smartlist_join_strings(string_chunks, "\n", 1, NULL); + + SMARTLIST_FOREACH(string_chunks, char *, s, tor_free(s)); + smartlist_free(string_chunks); + + return the_string; +} + /** The tor config was read. * Destroy all managed proxies that were marked by a previous call to * prepare_proxy_list_for_config_read() and are not used by the new diff --git a/src/or/transports.h b/src/or/transports.h index 39f7bf402..17d99dd75 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -46,6 +46,8 @@ void pt_configure_remaining_proxies(void); int pt_proxies_configuration_pending(void); +char *pt_get_extra_info_descriptor_string(void); + void pt_free_all(void); void pt_prepare_proxy_list_for_config_read(void); -- cgit v1.2.3 From ca4e986c1d7fc806c8b9b6cb580ae8e6a51f8857 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 23 Feb 2012 17:51:54 -0800 Subject: Mark descriptor as dirty if all managed proxies are configured. --- src/or/transports.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index e5a54463d..26bb26037 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -572,6 +572,9 @@ pt_configure_remaining_proxies(void) smartlist_free(tmp); check_if_restarts_needed = 0; assert_unconfigured_count_ok(); + + if (!pt_proxies_configuration_pending()) + mark_my_descriptor_dirty("configured managed proxies"); } #ifdef _WIN32 -- cgit v1.2.3 From f8e49c57893f35b9b3c45865d00040bd05e53f0c Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 15 Mar 2012 14:36:00 -0700 Subject: Change extra-info "method" to "transport". --- src/or/transports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/or') diff --git a/src/or/transports.c b/src/or/transports.c index 26bb26037..251884601 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1401,7 +1401,7 @@ pt_get_extra_info_descriptor_string(void) SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) { smartlist_add_asprintf(string_chunks, - "method %s %s:%u", + "transport %s %s:%u", t->name, fmt_addr(&t->addr), t->port); } SMARTLIST_FOREACH_END(t); -- cgit v1.2.3 From 8b9f4d75f27728ca5f07c1eb00d4144cb3b33eac Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 12 Jul 2012 15:28:43 +0200 Subject: Address Nick's comments. - Add a changes/ file. - Make it compile under --enable-gcc-warnings. - Update the file-level documentation of src/or/transports.c. - Only update descriptor if at least a managed proxy was configured. - Add our external IP address to the extra-info descriptor instead of 0.0.0.0. --- changes/bug3589 | 3 +++ src/or/circuitbuild.h | 6 ++++-- src/or/connection.c | 1 + src/or/router.c | 1 + src/or/transports.c | 39 ++++++++++++++++++++++++++++++--------- src/or/transports.h | 5 +++-- 6 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 changes/bug3589 (limited to 'src/or') diff --git a/changes/bug3589 b/changes/bug3589 new file mode 100644 index 000000000..eff2650ff --- /dev/null +++ b/changes/bug3589 @@ -0,0 +1,3 @@ + o Major features: + - Bridges now report the pluggable transports they support to the + bridge authority. Implements ticket 3589. diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index e6783d832..a7beccebb 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -12,8 +12,6 @@ #ifndef _TOR_CIRCUITBUILD_H #define _TOR_CIRCUITBUILD_H -#include "transports.h" - 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, @@ -136,6 +134,10 @@ void circuit_build_times_network_circ_success(circuit_build_times_t *cbt); /* DOCDOC circuit_build_times_get_bw_scale */ int circuit_build_times_get_bw_scale(networkstatus_t *ns); +/* DOCDOC find_transport_name_by_bridge_addrport */ +const char *find_transport_name_by_bridge_addrport(const tor_addr_t *addr, + uint16_t port); +typedef struct transport_t transport_t; int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port, const transport_t **transport); diff --git a/src/or/connection.c b/src/or/connection.c index af5c01181..c9b16d7ae 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -34,6 +34,7 @@ #include "rendcommon.h" #include "rephist.h" #include "router.h" +#include "transports.h" #include "routerparse.h" #ifdef USE_BUFFEREVENTS diff --git a/src/or/router.c b/src/or/router.c index 795afe2b3..df44a76d8 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -27,6 +27,7 @@ #include "router.h" #include "routerlist.h" #include "routerparse.h" +#include "transports.h" /** * \file router.c diff --git a/src/or/transports.c b/src/or/transports.c index 251884601..dd07a917e 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -39,13 +39,17 @@ * transport_t structs. * * When the managed proxy stops spitting METHOD lines (signified by a - * '{S,C}METHODS DONE' message) we register all the transports - * collected to the circuitbuild.c subsystem. At this point, the - * pointers to transport_t can be transformed into dangling pointers - * at any point by the circuitbuild.c subsystem, and so we replace all - * transport_t pointers with strings describing the transport names. - * We can still go from a transport name to a transport_t using the - * fact that each transport name uniquely identifies a transport_t. + * '{S,C}METHODS DONE' message) we pass copies of its transports to + * the bridge subsystem. We keep copies of the 'transport_t's on the + * managed proxy to be able to associate the proxy with its + * transports, and we pass copies to the bridge subsystem so that + * transports can be associated with bridges. + * [ XXX We should try see whether the two copies are really needed + * and maybe cut it into a single copy of the 'transport_t' shared + * between the managed proxy and the bridge subsystem. Preliminary + * analysis shows that both copies are needed with the current code + * logic, because of race conditions that can cause dangling + * pointers. ] * * In even more detail, this is what happens when a SIGHUP * occurs: @@ -530,6 +534,7 @@ launch_managed_proxy(managed_proxy_t *mp) void pt_configure_remaining_proxies(void) { + int at_least_a_proxy_config_finished = 0; smartlist_t *tmp = smartlist_new(); log_debug(LD_CONFIG, "Configuring remaining managed proxies (%d)!", @@ -567,13 +572,16 @@ pt_configure_remaining_proxies(void) if (!proxy_configuration_finished(mp)) configure_proxy(mp); + if (proxy_configuration_finished(mp)) + at_least_a_proxy_config_finished = 1; + } SMARTLIST_FOREACH_END(mp); smartlist_free(tmp); check_if_restarts_needed = 0; assert_unconfigured_count_ok(); - if (!pt_proxies_configuration_pending()) + if (at_least_a_proxy_config_finished) mark_my_descriptor_dirty("configured managed proxies"); } @@ -1400,9 +1408,22 @@ pt_get_extra_info_descriptor_string(void) tor_assert(mp->transports); SMARTLIST_FOREACH_BEGIN(mp->transports, const transport_t *, t) { + /* If the transport proxy returned "0.0.0.0" as its address, and + * we know our external IP address, use it. Otherwise, use the + * returned address. */ + const char *addr_str = fmt_addr(&t->addr); + uint32_t external_ip_address = 0; + if (tor_addr_is_null(&t->addr) && + router_pick_published_address(get_options(), + &external_ip_address) >= 0) { + /* returned addr was 0.0.0.0 and we found our external IP + address: use it. */ + addr_str = fmt_addr32(external_ip_address); + } + smartlist_add_asprintf(string_chunks, "transport %s %s:%u", - t->name, fmt_addr(&t->addr), t->port); + t->name, addr_str, t->port); } SMARTLIST_FOREACH_END(t); } SMARTLIST_FOREACH_END(mp); diff --git a/src/or/transports.h b/src/or/transports.h index 17d99dd75..3fd97f8c2 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -12,12 +12,13 @@ #define TOR_TRANSPORTS_H /** Represents a pluggable transport used by a bridge. */ -typedef struct { +typedef struct transport_t { /** SOCKS version: One of PROXY_SOCKS4, PROXY_SOCKS5. */ int socks_version; /** Name of pluggable transport protocol */ char *name; - /** Address of proxy */ + /** The IP address where the transport bound and is waiting for + * connections. */ tor_addr_t addr; /** Port of proxy */ uint16_t port; -- cgit v1.2.3