mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +01:00
Prepare circuitbuild.[ch] and config.[ch] for SIGHUPs.
* Create mark/sweep functions for transports. * Create a transport_resolve_conflicts() function that tries to resolve conflicts when registering transports.
This commit is contained in:
parent
782810a8bf
commit
fa514fb207
@ -124,7 +124,6 @@ static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice);
|
|||||||
|
|
||||||
static void entry_guards_changed(void);
|
static void entry_guards_changed(void);
|
||||||
|
|
||||||
static const transport_t *transport_get_by_name(const char *name);
|
|
||||||
static void bridge_free(bridge_info_t *bridge);
|
static void bridge_free(bridge_info_t *bridge);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4579,6 +4578,32 @@ bridge_free(bridge_info_t *bridge)
|
|||||||
/** A list of pluggable transports found in torrc. */
|
/** A list of pluggable transports found in torrc. */
|
||||||
static smartlist_t *transport_list = NULL;
|
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_create();
|
||||||
|
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_create();
|
||||||
|
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
|
/** Initialize the pluggable transports list to empty, creating it if
|
||||||
* needed. */
|
* needed. */
|
||||||
void
|
void
|
||||||
@ -4603,7 +4628,7 @@ transport_free(transport_t *transport)
|
|||||||
|
|
||||||
/** Returns the transport in our transport list that has the name <b>name</b>.
|
/** Returns the transport in our transport list that has the name <b>name</b>.
|
||||||
* Else returns NULL. */
|
* Else returns NULL. */
|
||||||
static const transport_t *
|
transport_t *
|
||||||
transport_get_by_name(const char *name)
|
transport_get_by_name(const char *name)
|
||||||
{
|
{
|
||||||
tor_assert(name);
|
tor_assert(name);
|
||||||
@ -4611,7 +4636,7 @@ transport_get_by_name(const char *name)
|
|||||||
if (!transport_list)
|
if (!transport_list)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(transport_list, const transport_t *, transport) {
|
SMARTLIST_FOREACH_BEGIN(transport_list, transport_t *, transport) {
|
||||||
if (!strcmp(transport->name, name))
|
if (!strcmp(transport->name, name))
|
||||||
return transport;
|
return transport;
|
||||||
} SMARTLIST_FOREACH_END(transport);
|
} SMARTLIST_FOREACH_END(transport);
|
||||||
@ -4636,23 +4661,81 @@ transport_create(const tor_addr_t *addr, uint16_t port,
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds transport <b>t</b> to the internal list of pluggable transports. */
|
/** 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.
|
||||||
|
|
||||||
|
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_warn(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_warn(LD_GENERAL, "You tried to add transport '%s' at '%s:%u' which "
|
||||||
|
"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
|
int
|
||||||
transport_add(transport_t *t)
|
transport_add(transport_t *t)
|
||||||
{
|
{
|
||||||
tor_assert(t);
|
tor_assert(t);
|
||||||
|
|
||||||
if (transport_get_by_name(t->name)) { /* check for duplicate names */
|
int r = transport_resolve_conflicts(t);
|
||||||
log_notice(LD_CONFIG, "More than one transports have '%s' as "
|
|
||||||
"their name.", t->name);
|
switch (r) {
|
||||||
return -1;
|
case 0: /* should register transport */
|
||||||
|
if (!transport_list)
|
||||||
|
transport_list = smartlist_create();
|
||||||
|
|
||||||
|
smartlist_add(transport_list, t);
|
||||||
|
return 0;
|
||||||
|
default: /* should let the caller know the return code */
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transport_list)
|
|
||||||
transport_list = smartlist_create();
|
|
||||||
|
|
||||||
smartlist_add(transport_list, t);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
|
/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
|
||||||
@ -4664,10 +4747,23 @@ transport_add_from_config(const tor_addr_t *addr, uint16_t port,
|
|||||||
{
|
{
|
||||||
transport_t *t = transport_create(addr, port, name, socks_ver);
|
transport_t *t = transport_create(addr, port, name, socks_ver);
|
||||||
|
|
||||||
if (transport_add(t) < 0) {
|
int r = transport_add(t);
|
||||||
|
|
||||||
|
switch (r) {
|
||||||
|
case -1:
|
||||||
|
default:
|
||||||
|
log_warn(LD_GENERAL, "Could not add transport %s at %s:%u. Skipping.",
|
||||||
|
t->name, fmt_addr(&t->addr), t->port);
|
||||||
transport_free(t);
|
transport_free(t);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
case 1:
|
||||||
|
log_warn(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_warn(LD_GENERAL, "Succesfully registered transport %s at %s:%u.",
|
||||||
|
t->name, fmt_addr(&t->addr), t->port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,9 @@ typedef struct {
|
|||||||
tor_addr_t addr;
|
tor_addr_t addr;
|
||||||
/** Port of proxy */
|
/** Port of proxy */
|
||||||
uint16_t port;
|
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;
|
} transport_t;
|
||||||
|
|
||||||
char *circuit_list_path(origin_circuit_t *circ, int verbose);
|
char *circuit_list_path(origin_circuit_t *circ, int verbose);
|
||||||
@ -77,6 +80,9 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
|
|||||||
|
|
||||||
void mark_bridge_list(void);
|
void mark_bridge_list(void);
|
||||||
void sweep_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 routerinfo_is_a_configured_bridge(const routerinfo_t *ri);
|
||||||
int node_is_a_configured_bridge(const node_t *node);
|
int node_is_a_configured_bridge(const node_t *node);
|
||||||
void learned_router_identity(const tor_addr_t *addr, uint16_t port,
|
void learned_router_identity(const tor_addr_t *addr, uint16_t port,
|
||||||
@ -149,6 +155,8 @@ transport_t *transport_create(const tor_addr_t *addr, uint16_t port,
|
|||||||
|
|
||||||
int find_transport_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);
|
const transport_t **transport);
|
||||||
|
transport_t *transport_get_by_name(const char *name);
|
||||||
|
|
||||||
void validate_pluggable_transports_config(void);
|
void validate_pluggable_transports_config(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1251,7 +1251,8 @@ options_act(or_options_t *old_options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
clear_transport_list();
|
mark_transport_list();
|
||||||
|
pt_prepare_proxy_list_for_config_read();
|
||||||
if (options->ClientTransportPlugin) {
|
if (options->ClientTransportPlugin) {
|
||||||
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
||||||
if (parse_client_transport_line(cl->value, 0)<0) {
|
if (parse_client_transport_line(cl->value, 0)<0) {
|
||||||
@ -1273,6 +1274,8 @@ options_act(or_options_t *old_options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sweep_transport_list();
|
||||||
|
sweep_proxy_list();
|
||||||
|
|
||||||
/* Bail out at this point if we're not going to be a client or server:
|
/* Bail out at this point if we're not going to be a client or server:
|
||||||
* we want to not fork, and to log stuff to stderr. */
|
* we want to not fork, and to log stuff to stderr. */
|
||||||
@ -4769,10 +4772,7 @@ parse_client_transport_line(const char *line, int validate_only)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!validate_only) {
|
if (!validate_only) {
|
||||||
if (transport_add_from_config(&addr, port, name,
|
transport_add_from_config(&addr, port, name, socks_ver);
|
||||||
socks_ver) < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug(LD_DIR, "Transport '%s' found at %s:%d", name,
|
log_debug(LD_DIR, "Transport '%s' found at %s:%d", name,
|
||||||
fmt_addr(&addr), (int)port);
|
fmt_addr(&addr), (int)port);
|
||||||
|
Loading…
Reference in New Issue
Block a user