diff options
Diffstat (limited to 'src/or/router.c')
-rw-r--r-- | src/or/router.c | 168 |
1 files changed, 103 insertions, 65 deletions
diff --git a/src/or/router.c b/src/or/router.c index 38f1cdd49..1cac63a3a 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -27,6 +27,9 @@ #include "router.h" #include "routerlist.h" #include "routerparse.h" +#include "statefile.h" +#include "transports.h" +#include "routerset.h" /** * \file router.c @@ -84,7 +87,7 @@ static authority_cert_t *legacy_key_certificate = NULL; static void set_onion_key(crypto_pk_t *k) { - if (onionkey && !crypto_pk_cmp_keys(onionkey, k)) { + if (onionkey && crypto_pk_eq_keys(onionkey, k)) { /* k is already our onion key; free it and return */ crypto_pk_free(k); return; @@ -152,12 +155,11 @@ assert_identity_keys_ok(void) if (public_server_mode(get_options())) { /* assert that we have set the client and server keys to be equal */ tor_assert(server_identitykey); - tor_assert(0==crypto_pk_cmp_keys(client_identitykey, server_identitykey)); + tor_assert(crypto_pk_eq_keys(client_identitykey, server_identitykey)); } else { /* assert that we have set the client and server keys to be unequal */ if (server_identitykey) - tor_assert(0!=crypto_pk_cmp_keys(client_identitykey, - server_identitykey)); + tor_assert(!crypto_pk_eq_keys(client_identitykey, server_identitykey)); } } @@ -397,7 +399,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out, log_warn(LD_DIR, "Unable to parse certificate in %s", fname); goto done; } - if (crypto_pk_cmp_keys(signing_key, parsed->signing_key) != 0) { + if (!crypto_pk_eq_keys(signing_key, parsed->signing_key)) { log_warn(LD_DIR, "Stored signing key does not match signing key in " "certificate"); goto done; @@ -671,7 +673,7 @@ init_keys(void) * we don't really need new keys yet so the descriptor doesn't * change and the old one is still fresh. */ log_info(LD_GENERAL, "Couldn't add own descriptor to directory " - "after key init: %s. This is usually not a problem.", + "after key init: %s This is usually not a problem.", m?m:"<unknown error>"); } } @@ -879,6 +881,21 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port) return advertising ? dir_port : 0; } +/** Allocate and return a new extend_info_t that can be used to build + * a circuit to or through the router <b>r</b>. Use the primary + * address of the router unless <b>for_direct_connect</b> is true, in + * which case the preferred address is used instead. */ +static extend_info_t * +extend_info_from_router(const routerinfo_t *r) +{ + tor_addr_port_t ap; + tor_assert(r); + + router_get_prim_orport(r, &ap); + return extend_info_new(r->nickname, r->cache_info.identity_digest, + r->onion_pkey, &ap.addr, ap.port); +} + /** Some time has passed, or we just got new directory information. * See if we currently believe our ORPort or DirPort to be * unreachable. If so, launch a new test for it. @@ -920,12 +937,11 @@ consider_testing_reachability(int test_or, int test_dir) } if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) { - extend_info_t *ei; + extend_info_t *ei = extend_info_from_router(me); + /* XXX IPv6 self testing */ log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.", !orport_reachable ? "reachability" : "bandwidth", me->address, me->or_port); - /* XXX IPv6 self testing IPv6 orports will need pref_addr */ - ei = extend_info_from_router(me, 0); circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei, CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL); extend_info_free(ei); @@ -939,11 +955,10 @@ consider_testing_reachability(int test_or, int test_dir) /* ask myself, via tor, for my server descriptor. */ directory_initiate_command(me->address, &addr, me->or_port, me->dir_port, - 0, /* does not matter */ - 0, me->cache_info.identity_digest, + me->cache_info.identity_digest, DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_GENERAL, - 1, "authority.z", NULL, 0, 0); + DIRIND_ANON_DIRPORT, "authority.z", NULL, 0, 0); } } @@ -955,7 +970,7 @@ router_orport_found_reachable(void) if (!can_reach_or_port && me) { log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from " "the outside. Excellent.%s", - get_options()->_PublishServerDescriptor != NO_DIRINFO ? + get_options()->PublishServerDescriptor_ != NO_DIRINFO ? " Publishing server descriptor." : ""); can_reach_or_port = 1; mark_my_descriptor_dirty("ORPort found reachable"); @@ -998,9 +1013,9 @@ router_perform_bandwidth_test(int num_circs, time_t now) CIRCUIT_PURPOSE_TESTING))) { /* dump cells_per_circuit drop cells onto this circ */ int i = cells_per_circuit; - if (circ->_base.state != CIRCUIT_STATE_OPEN) + if (circ->base_.state != CIRCUIT_STATE_OPEN) continue; - circ->_base.timestamp_dirty = now; + circ->base_.timestamp_dirty = now; while (i-- > 0) { if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), RELAY_COMMAND_DROP, @@ -1194,7 +1209,7 @@ decide_if_publishable_server(void) if (options->ClientOnly) return 0; - if (options->_PublishServerDescriptor == NO_DIRINFO) + if (options->PublishServerDescriptor_ == NO_DIRINFO) return 0; if (!server_mode(options)) return 0; @@ -1315,7 +1330,7 @@ router_upload_dir_desc_to_dirservers(int force) extrainfo_t *ei; char *msg; size_t desc_len, extra_len = 0, total_len; - dirinfo_type_t auth = get_options()->_PublishServerDescriptor; + dirinfo_type_t auth = get_options()->PublishServerDescriptor_; ri = router_get_my_routerinfo(); if (!ri) { @@ -1362,14 +1377,14 @@ router_compare_to_my_exit_policy(edge_connection_t *conn) /* make sure it's resolved to something. this way we can't get a 'maybe' below. */ - if (tor_addr_is_null(&conn->_base.addr)) + if (tor_addr_is_null(&conn->base_.addr)) return -1; /* XXXX IPv6 */ - if (tor_addr_family(&conn->_base.addr) != AF_INET) + if (tor_addr_family(&conn->base_.addr) != AF_INET) return -1; - return compare_tor_addr_to_addr_policy(&conn->_base.addr, conn->_base.port, + return compare_tor_addr_to_addr_policy(&conn->base_.addr, conn->base_.port, desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED; } @@ -1539,8 +1554,9 @@ router_rebuild_descriptor(int force) ri->cache_info.published_on = time(NULL); ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from * main thread */ - if (options->BridgeRelay) { - /* For now, only bridges advertise an ipv6 or-address. And only one. */ + + /* For now, at most one IPv6 or-address is being advertised. */ + { const port_cfg_t *ipv6_orport = NULL; SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { if (p->type == CONN_TYPE_OR_LISTENER && @@ -1565,6 +1581,7 @@ router_rebuild_descriptor(int force) ri->ipv6_orport = ipv6_orport->port; } } + ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key()); if (crypto_pk_get_digest(ri->identity_pkey, ri->cache_info.identity_digest)<0) { @@ -1779,7 +1796,7 @@ void mark_my_descriptor_dirty(const char *reason) { const or_options_t *options = get_options(); - if (server_mode(options) && options->_PublishServerDescriptor) + if (server_mode(options) && options->PublishServerDescriptor_) log_info(LD_OR, "Decided to publish new relay descriptor: %s", reason); desc_clean_since = 0; if (!desc_dirty_reason) @@ -1911,7 +1928,7 @@ router_new_address_suggestion(const char *suggestion, /* Don't believe anybody who says our IP is, say, 127.0.0.1. */ return; } - if (tor_addr_eq(&d_conn->_base.addr, &addr)) { + if (tor_addr_eq(&d_conn->base_.addr, &addr)) { /* Don't believe anybody who says our IP is their IP. */ log_debug(LD_DIR, "A directory server told us our IP address is %s, " "but he's just reporting his own IP address. Ignoring.", @@ -1927,7 +1944,7 @@ router_new_address_suggestion(const char *suggestion, "EXTERNAL_ADDRESS ADDRESS=%s METHOD=DIRSERV", suggestion); log_addr_has_changed(LOG_NOTICE, &last_guessed_ip, &addr, - d_conn->_base.address); + d_conn->base_.address); ip_address_changed(0); tor_addr_copy(&last_guessed_ip, &addr); /* router_rebuild_descriptor() will fetch it */ @@ -1990,7 +2007,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, const or_options_t *options = get_options(); /* Make sure the identity key matches the one in the routerinfo. */ - if (crypto_pk_cmp_keys(ident_key, router->identity_pkey)) { + if (!crypto_pk_eq_keys(ident_key, router->identity_pkey)) { log_warn(LD_BUG,"Tried to sign a router with a private key that didn't " "match router's public key!"); return -1; @@ -2054,9 +2071,9 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, "router %s %s %d 0 %d\n" "%s" "platform %s\n" - "opt protocols Link 1 2 Circuit 1\n" + "protocols Link 1 2 Circuit 1\n" "published %s\n" - "opt fingerprint %s\n" + "fingerprint %s\n" "uptime %ld\n" "bandwidth %d %d %d\n" "%s%s%s%s" @@ -2075,15 +2092,15 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, (int) router->bandwidthrate, (int) router->bandwidthburst, (int) router->bandwidthcapacity, - has_extra_info_digest ? "opt extra-info-digest " : "", + has_extra_info_digest ? "extra-info-digest " : "", has_extra_info_digest ? extra_info_digest : "", has_extra_info_digest ? "\n" : "", - options->DownloadExtraInfo ? "opt caches-extra-info\n" : "", + options->DownloadExtraInfo ? "caches-extra-info\n" : "", onion_pkey, identity_pkey, family_line, - we_are_hibernating() ? "opt hibernating 1\n" : "", - options->HidServDirectoryV2 ? "opt hidden-service-dir\n" : "", - options->AllowSingleHopExits ? "opt allow-single-hop-exits\n" : ""); + we_are_hibernating() ? "hibernating 1\n" : "", + options->HidServDirectoryV2 ? "hidden-service-dir\n" : "", + options->AllowSingleHopExits ? "allow-single-hop-exits\n" : ""); tor_free(family_line); tor_free(onion_pkey); @@ -2194,40 +2211,24 @@ router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) ap_out->port = router->or_port; } -/** Return 1 if we prefer the IPv6 address and OR TCP port of - * <b>router</b>, else 0. - * - * We prefer the IPv6 address if the router has one and - * i) the routerinfo_t says so - * or - * ii) the router has no IPv4 address. */ +/** Return 1 if any of <b>router</b>'s addresses are <b>addr</b>. + * Otherwise return 0. */ int -router_ipv6_preferred(const routerinfo_t *router) +router_has_addr(const routerinfo_t *router, const tor_addr_t *addr) { - return (!tor_addr_is_null(&router->ipv6_addr) - && (router->ipv6_preferred || router->addr == 0)); + return + tor_addr_eq_ipv4h(addr, router->addr) || + tor_addr_eq(&router->ipv6_addr, addr); } -/** Copy the preferred OR port (IP address and TCP port) for - * <b>router</b> into *<b>addr_out</b>. */ -void -router_get_pref_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) -{ - if (router_ipv6_preferred(router)) - router_get_pref_ipv6_orport(router, ap_out); - else - router_get_prim_orport(router, ap_out); -} - -/** Copy the preferred IPv6 OR port (IP address and TCP port) for - * <b>router</b> into *<b>ap_out</b>. */ -void -router_get_pref_ipv6_orport(const routerinfo_t *router, - tor_addr_port_t *ap_out) +int +router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) { - tor_assert(ap_out != NULL); - tor_addr_copy(&ap_out->addr, &router->ipv6_addr); - ap_out->port = router->ipv6_orport; + return + (tor_addr_eq_ipv4h(&orport->addr, router->addr) && + orport->port == router->or_port) || + (tor_addr_eq(&orport->addr, &router->ipv6_addr) && + orport->port == router->ipv6_orport); } /** Load the contents of <b>filename</b>, find the last line starting with @@ -2312,9 +2313,12 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, tor_free(bandwidth_usage); smartlist_add(chunks, pre); - if (geoip_is_loaded()) { - smartlist_add_asprintf(chunks, "geoip-db-digest %s\n", geoip_db_digest()); - } + if (geoip_is_loaded(AF_INET)) + smartlist_add_asprintf(chunks, "geoip-db-digest %s\n", + geoip_db_digest(AF_INET)); + if (geoip_is_loaded(AF_INET6)) + smartlist_add_asprintf(chunks, "geoip6-db-digest %s\n", + geoip_db_digest(AF_INET6)); if (options->ExtraInfoStatistics && write_stats_to_extrainfo) { log_info(LD_GENERAL, "Adding stats to extra-info descriptor."); @@ -2345,6 +2349,13 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, } } + /* Add information about the pluggable transports we support. */ + if (options->ServerTransportPlugin) { + char *pluggable_transports = pt_get_extra_info_descriptor_string(); + if (pluggable_transports) + smartlist_add(chunks, pluggable_transports); + } + if (should_record_bridge_info(options) && write_stats_to_extrainfo) { const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now); if (bridge_stats) { @@ -2754,3 +2765,30 @@ router_free_all(void) } } +/** Return a smartlist of tor_addr_port_t's with all the OR ports of + <b>ri</b>. Note that freeing of the items in the list as well as + the smartlist itself is the callers responsibility. + + XXX duplicating code from node_get_all_orports(). */ +smartlist_t * +router_get_all_orports(const routerinfo_t *ri) +{ + smartlist_t *sl = smartlist_new(); + tor_assert(ri); + + if (ri->addr != 0) { + tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); + tor_addr_from_ipv4h(&ap->addr, ri->addr); + ap->port = ri->or_port; + smartlist_add(sl, ap); + } + if (!tor_addr_is_null(&ri->ipv6_addr)) { + tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); + tor_addr_copy(&ap->addr, &ri->ipv6_addr); + ap->port = ri->or_port; + smartlist_add(sl, ap); + } + + return sl; +} + |