Implement Tor2webRendezvousPoints functionality.

This commit is contained in:
George Kadianakis 2014-09-15 15:28:11 +03:00
parent 3e7c5e9f44
commit 24a7726955
4 changed files with 87 additions and 4 deletions

View File

@ -1735,6 +1735,79 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
return NULL;
}
/* The config option Tor2webRendezvousPoints has been set and we need
* to pick an RP out of that set. Make sure that the RP we choose is
* alive, and return it. Return NULL if no usable RP could be found in
* Tor2webRendezvousPoints. */
STATIC const node_t *
pick_tor2web_rendezvous_node(router_crn_flags_t flags,
const or_options_t *options)
{
const node_t *rp_node = NULL;
const int allow_invalid = (flags & CRN_ALLOW_INVALID) != 0;
const int need_desc = (flags & CRN_NEED_DESC) != 0;
smartlist_t *whitelisted_live_rps = smartlist_new();
smartlist_t *all_live_nodes = smartlist_new();
tor_assert(options->Tor2webRendezvousPoints);
/* Add all running nodes to all_live_nodes */
router_add_running_nodes_to_smartlist(all_live_nodes,
allow_invalid,
0, 0, 0,
need_desc);
/* Filter all_live_nodes to only add live *and* whitelisted RPs to
* the list whitelisted_live_rps. */
SMARTLIST_FOREACH_BEGIN(all_live_nodes, node_t *, live_node) {
if (routerset_contains_node(options->Tor2webRendezvousPoints, live_node)) {
smartlist_add(whitelisted_live_rps, live_node);
}
} SMARTLIST_FOREACH_END(live_node);
/* Honor ExcludeNodes */
if (options->ExcludeNodes) {
routerset_subtract_nodes(whitelisted_live_rps, options->ExcludeNodes);
}
/* Now pick randomly amongst the whitelisted RPs. No need to waste time
doing bandwidth load balancing, for most use cases
'whitelisted_live_rps' contains a single OR anyway. */
rp_node = smartlist_choose(whitelisted_live_rps);
if (!rp_node) {
log_warn(LD_REND, "Could not find a Rendezvous Point that suits "
"the purposes of Tor2webRendezvousPoints. Choosing random one.");
}
smartlist_free(whitelisted_live_rps);
smartlist_free(all_live_nodes);
return rp_node;
}
/* Pick a Rendezvous Point for our HS circuits according to <b>flags</b>. */
static const node_t *
pick_rendezvous_node(router_crn_flags_t flags)
{
const or_options_t *options = get_options();
if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
flags |= CRN_ALLOW_INVALID;
/* The user wants us to pick specific RPs. */
if (options->Tor2webRendezvousPoints) {
const node_t *tor2web_rp = pick_tor2web_rendezvous_node(flags, options);
if (tor2web_rp) {
return tor2web_rp;
}
/* Else, if no tor2web RP was found, fall back to choosing a random node */
}
return router_choose_random_node(NULL, options->ExcludeNodes, flags);
}
/** Return a pointer to a suitable router to be the exit node for the
* circuit of purpose <b>purpose</b> that we're about to build (or NULL
* if no router is suitable).
@ -1765,9 +1838,12 @@ choose_good_exit_server(uint8_t purpose,
else
return choose_good_exit_server_general(need_uptime,need_capacity);
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
flags |= CRN_ALLOW_INVALID;
return router_choose_random_node(NULL, options->ExcludeNodes, flags);
{
/* Pick a new RP */
const node_t *rendezvous_node = pick_rendezvous_node(flags);
log_info(LD_REND, "Picked new RP: %s", node_describe(rendezvous_node));
return rendezvous_node;
}
}
log_warn(LD_BUG,"Unhandled purpose %d", purpose);
tor_fragile_assert();

View File

@ -60,6 +60,9 @@ const node_t *choose_good_entry_server(uint8_t purpose,
#ifdef CIRCUITBUILD_PRIVATE
STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan);
STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags,
const or_options_t *options);
#endif
#endif

View File

@ -1732,7 +1732,7 @@ routerlist_add_node_and_family(smartlist_t *sl, const routerinfo_t *router)
/** Add every suitable node from our nodelist to <b>sl</b>, so that
* we can pick a node for a circuit.
*/
static void
void
router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
int need_uptime, int need_capacity,
int need_guard, int need_desc)

View File

@ -58,6 +58,10 @@ const routerstatus_t *router_pick_fallback_dirserver(dirinfo_type_t type,
int router_get_my_share_of_directory_requests(double *v3_share_out);
void router_reset_status_download_failures(void);
int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
void router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
int need_uptime, int need_capacity,
int need_guard, int need_desc);
const routerinfo_t *routerlist_find_my_routerinfo(void);
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);