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.
This commit is contained in:
George Kadianakis 2012-01-25 18:51:38 +02:00
parent 46434ecf5b
commit 6173d36340
4 changed files with 228 additions and 225 deletions

View File

@ -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 <b>transport</b>. */
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 <b>name</b>.
* 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 <b>name</b> listening at <b>addr</b>:<b>port</b> using
SOCKS version <b>socks_ver</b>. */
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 <b>t</b>
* might cause.
* Return 0 if <b>t</b> is OK and should be registered, 1 if there is
* a transport identical to <b>t</b> already registered and -1 if
* <b>t</b> 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 <b>t</b> 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 <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. */
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 <b>ri</b> 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;
}

View File

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

View File

@ -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 <b>name</b> listening at <b>addr</b>:<b>port</b> using
SOCKS version <b>socks_ver</b>. */
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 <b>transport</b>. */
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 <b>name</b>.
* 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 <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. */
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 <b>t</b>
* might cause.
* Return 0 if <b>t</b> is OK and should be registered, 1 if there is
* a transport identical to <b>t</b> already registered and -1 if
* <b>t</b> 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 <b>t</b> 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

View File

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