mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
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:
parent
46434ecf5b
commit
6173d36340
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user