diff options
Diffstat (limited to 'src/or/entrynodes.c')
-rw-r--r-- | src/or/entrynodes.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index ebf675166b..310a948b35 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2015, The Tor Project, Inc. */ + * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -87,7 +87,7 @@ get_entry_guards(void) /** Check whether the entry guard <b>e</b> is usable, given the directory * authorities' opinion about the router (stored in <b>ri</b>) and the user's - * configuration (in <b>options</b>). Set <b>e</b>->bad_since + * configuration (in <b>options</b>). Set <b>e</b>->bad_since * accordingly. Return true iff the entry guard's status changes. * * If it's not usable, set *<b>reason</b> to a static string explaining why. @@ -117,6 +117,9 @@ entry_guard_set_status(entry_guard_t *e, const node_t *node, *reason = "not recommended as a guard"; else if (routerset_contains_node(options->ExcludeNodes, node)) *reason = "excluded"; + /* We only care about OR connection connectivity for entry guards. */ + else if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, 0)) + *reason = "unreachable by config"; else if (e->path_bias_disabled) *reason = "path-biased"; @@ -268,7 +271,7 @@ entry_is_live(const entry_guard_t *e, entry_is_live_flags_t flags, *msg = "not fast/stable"; return NULL; } - if (!fascist_firewall_allows_node(node)) { + if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, 0)) { *msg = "unreachable by config"; return NULL; } @@ -918,7 +921,8 @@ entry_guards_set_from_config(const or_options_t *options) } else if (routerset_contains_node(options->ExcludeNodes, node)) { SMARTLIST_DEL_CURRENT(entry_nodes, node); continue; - } else if (!fascist_firewall_allows_node(node)) { + } else if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, + 0)) { SMARTLIST_DEL_CURRENT(entry_nodes, node); continue; } else if (! node->is_possible_guard) { @@ -1152,7 +1156,7 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory, } else { /* Try to have at least 2 choices available. This way we don't * get stuck with a single live-but-crummy entry and just keep - * using him. + * using it. * (We might get 2 live-but-crummy entry guards, but so be it.) */ preferred_min = 2; } @@ -1791,7 +1795,7 @@ get_configured_bridge_by_orports_digest(const char *digest, } /** If we have a bridge configured whose digest matches <b>digest</b>, or a - * bridge with no known digest whose address matches <b>addr</b>:<b>/port</b>, + * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>, * return that bridge. Else return NULL. If <b>digest</b> is NULL, check for * address/port matches only. */ static bridge_info_t * @@ -1814,6 +1818,30 @@ get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr, return NULL; } +/** If we have a bridge configured whose digest matches <b>digest</b>, or a + * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>, + * return 1. Else return 0. If <b>digest</b> is NULL, check for + * address/port matches only. */ +int +addr_is_a_configured_bridge(const tor_addr_t *addr, + uint16_t port, + const char *digest) +{ + tor_assert(addr); + return get_configured_bridge_by_addr_port_digest(addr, port, digest) ? 1 : 0; +} + +/** If we have a bridge configured whose digest matches + * <b>ei->identity_digest</b>, or a bridge with no known digest whose address + * matches <b>ei->addr</b>:<b>ei->port</b>, return 1. Else return 0. + * If <b>ei->onion_key</b> is NULL, check for address/port matches only. */ +int +extend_info_is_a_configured_bridge(const extend_info_t *ei) +{ + const char *digest = ei->onion_key ? ei->identity_digest : NULL; + return addr_is_a_configured_bridge(&ei->addr, ei->port, digest); +} + /** Wrapper around get_configured_bridge_by_addr_port_digest() to look * it up via router descriptor <b>ri</b>. */ static bridge_info_t * @@ -2116,8 +2144,18 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) return; } - directory_initiate_command(&bridge->addr, - bridge->port, 0/*no dirport*/, + /* Until we get a descriptor for the bridge, we only know one address for + * it. */ + if (!fascist_firewall_allows_address_addr(&bridge->addr, bridge->port, + FIREWALL_OR_CONNECTION, 0, 0)) { + log_notice(LD_CONFIG, "Tried to fetch a descriptor directly from a " + "bridge, but that bridge is not reachable through our " + "firewall."); + return; + } + + directory_initiate_command(&bridge->addr, bridge->port, + NULL, 0, /*no dirport*/ bridge->identity, DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE, @@ -2178,7 +2216,9 @@ fetch_bridge_descriptors(const or_options_t *options, time_t now) !options->UpdateBridgesFromAuthority, !num_bridge_auths); if (ask_bridge_directly && - !fascist_firewall_allows_address_or(&bridge->addr, bridge->port)) { + !fascist_firewall_allows_address_addr(&bridge->addr, bridge->port, + FIREWALL_OR_CONNECTION, 0, + 0)) { log_notice(LD_DIR, "Bridge at '%s' isn't reachable by our " "firewall policy. %s.", fmt_addrport(&bridge->addr, bridge->port), @@ -2205,7 +2245,7 @@ fetch_bridge_descriptors(const or_options_t *options, time_t now) log_info(LD_DIR, "Fetching bridge info '%s' from bridge authority.", resource); directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC, - ROUTER_PURPOSE_BRIDGE, resource, 0); + ROUTER_PURPOSE_BRIDGE, resource, 0, DL_WANT_AUTHORITY); } } SMARTLIST_FOREACH_END(bridge); @@ -2226,6 +2266,7 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node) * does so through an address from any source other than node_get_addr(). */ tor_addr_t addr; + const or_options_t *options = get_options(); if (node->ri) { routerinfo_t *ri = node->ri; @@ -2258,9 +2299,15 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node) } } - /* Mark which address to use based on which bridge_t we got. */ - node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 && - !tor_addr_is_null(&node->ri->ipv6_addr)); + if (options->ClientPreferIPv6ORPort == -1) { + /* Mark which address to use based on which bridge_t we got. */ + node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 && + !tor_addr_is_null(&node->ri->ipv6_addr)); + } else { + /* Mark which address to use based on user preference */ + node->ipv6_preferred = (fascist_firewall_prefer_ipv6_orport(options) && + !tor_addr_is_null(&node->ri->ipv6_addr)); + } /* XXXipv6 we lack support for falling back to another address for the same relay, warn the user */ @@ -2269,10 +2316,13 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node) node_get_pref_orport(node, &ap); log_notice(LD_CONFIG, "Bridge '%s' has both an IPv4 and an IPv6 address. " - "Will prefer using its %s address (%s).", + "Will prefer using its %s address (%s) based on %s.", ri->nickname, - tor_addr_family(&ap.addr) == AF_INET6 ? "IPv6" : "IPv4", - fmt_addrport(&ap.addr, ap.port)); + node->ipv6_preferred ? "IPv6" : "IPv4", + fmt_addrport(&ap.addr, ap.port), + options->ClientPreferIPv6ORPort == -1 ? + "the configured Bridge address" : + "ClientPreferIPv6ORPort"); } } if (node->rs) { |