diff options
Diffstat (limited to 'src/feature/hs/hs_service.c')
-rw-r--r-- | src/feature/hs/hs_service.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 8a4f1efb16..2835912742 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -2071,6 +2071,7 @@ build_all_descriptors(time_t now) static hs_service_intro_point_t * pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) { + const or_options_t *options = get_options(); const node_t *node; hs_service_intro_point_t *ip = NULL; /* Normal 3-hop introduction point flags. */ @@ -2078,11 +2079,19 @@ pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) /* Single onion flags. */ router_crn_flags_t direct_flags = flags | CRN_PREF_ADDR | CRN_DIRECT_CONN; - node = router_choose_random_node(exclude_nodes, get_options()->ExcludeNodes, + node = router_choose_random_node(exclude_nodes, options->ExcludeNodes, direct_conn ? direct_flags : flags); - /* Unable to find a node. When looking for a node for a direct connection, - * we could try a 3-hop path instead. We'll add support for this in a later - * release. */ + + /* If we are in single onion mode, retry node selection for a 3-hop + * path */ + if (direct_conn && !node) { + log_info(LD_REND, + "Unable to find an intro point that we can connect to " + "directly, falling back to a 3-hop path."); + node = router_choose_random_node(exclude_nodes, options->ExcludeNodes, + flags); + } + if (!node) { goto err; } @@ -2583,7 +2592,7 @@ launch_intro_point_circuits(hs_service_t *service) * circuits using the current map. */ FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { /* Keep a ref on if we need a direct connection. We use this often. */ - unsigned int direct_conn = service->config.is_single_onion; + bool direct_conn = service->config.is_single_onion; DIGEST256MAP_FOREACH_MODIFY(desc->intro_points.map, key, hs_service_intro_point_t *, ip) { @@ -2594,8 +2603,15 @@ launch_intro_point_circuits(hs_service_t *service) if (hs_circ_service_get_intro_circ(ip)) { continue; } - ei = get_extend_info_from_intro_point(ip, direct_conn); + + /* If we can't connect directly to the intro point, get an extend_info + * for a multi-hop path instead. */ + if (ei == NULL && direct_conn) { + direct_conn = false; + ei = get_extend_info_from_intro_point(ip, 0); + } + if (ei == NULL) { /* This is possible if we can get a node_t but not the extend info out * of it. In this case, we remove the intro point and a new one will @@ -2607,7 +2623,7 @@ launch_intro_point_circuits(hs_service_t *service) /* Launch a circuit to the intro point. */ ip->circuit_retries++; - if (hs_circ_launch_intro_point(service, ip, ei) < 0) { + if (hs_circ_launch_intro_point(service, ip, ei, direct_conn) < 0) { log_info(LD_REND, "Unable to launch intro circuit to node %s " "for service %s.", safe_str_client(extend_info_describe(ei)), |