diff options
-rw-r--r-- | src/or/circuitbuild.c | 30 | ||||
-rw-r--r-- | src/or/directory.c | 77 | ||||
-rw-r--r-- | src/or/main.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 7 | ||||
-rw-r--r-- | src/or/rendclient.c | 3 | ||||
-rw-r--r-- | src/or/rendservice.c | 1 | ||||
-rw-r--r-- | src/or/router.c | 7 | ||||
-rw-r--r-- | src/or/routerlist.c | 10 |
8 files changed, 84 insertions, 57 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 72c839b23..5cf90bd58 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1583,8 +1583,7 @@ choose_good_middle_server(uint8_t purpose, options->ExcludeNodes, excluded, state->need_uptime, state->need_capacity, 0, options->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0, 0); - if (preferred) - tor_free(preferred); + tor_free(preferred); smartlist_free(excluded); return choice; } @@ -1885,8 +1884,8 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri, return changed; } -/** Return true iff enough time has passed since we last tried connect to the - * unreachable guard <b>e</b> that we're willing to try again. */ +/** Return true iff enough time has passed since we last tried to connect + * to the unreachable guard <b>e</b> that we're willing to try again. */ static int entry_is_time_to_retry(entry_guard_t *e, time_t now) { @@ -1913,7 +1912,7 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now) * if demanded by <b>need_uptime</b> or <b>need_capacity</b>; * (This check is currently redundant with the Guard flag, but in * the future that might change. Best to leave it in for now.) - * - Allowed by our current ReachableAddresses config option; and + * - Allowed by our current ReachableORAddresses config option; and * - Currently thought to be reachable by us (unless assume_reachable * is true). */ @@ -1937,8 +1936,7 @@ entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity, return NULL; if (router_is_unreliable(r, need_uptime, need_capacity, 0)) return NULL; - if (firewall_is_fascist_or() && - !fascist_firewall_allows_address_or(r->addr,r->or_port)) + if (!fascist_firewall_allows_address_or(r->addr,r->or_port)) return NULL; return r; } @@ -2778,10 +2776,10 @@ fetch_bridge_descriptors(time_t now) SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge, { - if (bridge->fetch_status.next_attempt_at >= now) + if (bridge->fetch_status.next_attempt_at > now) continue; /* don't bother, no need to retry yet */ - /* schedule another fetch as if this one failed, in case it does */ + /* schedule another fetch as if this one will fail, in case it does */ bridge_fetch_status_increment(bridge, now); in.s_addr = htonl(bridge->addr); @@ -2813,8 +2811,18 @@ fetch_bridge_descriptors(time_t now) 0, "authority.z", NULL, 0); } } else { - /* we have a digest and we want to ask an authority. */ - // XXX + /* We have a digest and we want to ask an authority. We could + * combine all the requests into one, but that may give more + * hints to the bridge authority than we want to give. */ + char resource[10 + HEX_DIGEST_LEN]; + memcpy(resource, "fp/", 3); + base16_encode(resource+3, HEX_DIGEST_LEN+1, + bridge->identity, DIGEST_LEN); + memcpy(resource+3+HEX_DIGEST_LEN, ".z", 3); + log_info(LD_DIR, "Fetching bridge info '%s' from bridge authority.", + resource); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC, + ROUTER_PURPOSE_BRIDGE, resource, 1); } }); } diff --git a/src/or/directory.c b/src/or/directory.c index 7084c163e..2bbd4deab 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -36,7 +36,7 @@ directory_send_command(dir_connection_t *conn, const char *payload, size_t payload_len); static int directory_handle_command(dir_connection_t *conn); static int body_is_plausible(const char *body, size_t body_len, int purpose); -static int purpose_needs_anonymity(uint8_t purpose); +static int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose); static char *http_get_header(const char *headers, const char *which); static void http_set_address_origin(const char *headers, connection_t *conn); static void connection_dir_download_networkstatus_failed( @@ -71,16 +71,18 @@ static void note_request(const char *key, size_t bytes); /** Return true iff the directory purpose 'purpose' must use an * anonymous connection to a directory. */ static int -purpose_needs_anonymity(uint8_t purpose) +purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose) { if (get_options()->AllDirActionsPrivate) return 1; - if (purpose == DIR_PURPOSE_FETCH_DIR || - purpose == DIR_PURPOSE_UPLOAD_DIR || - purpose == DIR_PURPOSE_FETCH_RUNNING_LIST || - purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS || - purpose == DIR_PURPOSE_FETCH_SERVERDESC || - purpose == DIR_PURPOSE_FETCH_EXTRAINFO) + if (router_purpose == ROUTER_PURPOSE_BRIDGE) + return 1; /* if we have to ask, better make it anonymous */ + if (dir_purpose == DIR_PURPOSE_FETCH_DIR || + dir_purpose == DIR_PURPOSE_UPLOAD_DIR || + dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST || + dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS || + dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC || + dir_purpose == DIR_PURPOSE_FETCH_EXTRAINFO) return 0; return 1; } @@ -147,7 +149,8 @@ router_supports_extrainfo(const char *identity_digest, int is_authority) * support it. */ void -directory_post_to_dirservers(uint8_t purpose, authority_type_t type, +directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, + authority_type_t type, const char *payload, size_t payload_len, size_t extrainfo_len) { @@ -167,7 +170,7 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type, continue; found = 1; /* at least one authority of this type was listed */ - if (purpose == DIR_PURPOSE_UPLOAD_DIR) + if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR) ds->has_accepted_serverdesc = 0; if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) { @@ -175,10 +178,10 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type, log_info(LD_DIR, "Uploading an extrainfo (length %d)", (int) extrainfo_len); } - post_via_tor = purpose_needs_anonymity(purpose) || + post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) || !fascist_firewall_allows_address_dir(ds->addr, ds->dir_port); - directory_initiate_command_routerstatus(rs, purpose, - ROUTER_PURPOSE_GENERAL, + directory_initiate_command_routerstatus(rs, dir_purpose, + router_purpose, post_via_tor, NULL, payload, upload_len); }); @@ -191,29 +194,33 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type, } /** Start a connection to a random running directory server, using - * connection purpose 'purpose' and requesting 'resource'. + * connection purpose <b>dir_purpose</b>, intending to fetch descriptors + * of purpose <b>router_purpose</b>, and requesting <b>resource</b>. * If <b>retry_if_no_servers</b>, then if all the possible servers seem * down, mark them up and try again. */ void -directory_get_from_dirserver(uint8_t dir_purpose, const char *resource, - int retry_if_no_servers) +directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, + const char *resource, int retry_if_no_servers) { routerstatus_t *rs = NULL; or_options_t *options = get_options(); int prefer_authority = server_mode(options) && options->DirPort != 0; - int directconn = !purpose_needs_anonymity(dir_purpose); + int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose); authority_type_t type; /* FFFF we could break this switch into its own function, and call * it elsewhere in directory.c. -RD */ switch (dir_purpose) { case DIR_PURPOSE_FETCH_EXTRAINFO: - type = EXTRAINFO_CACHE | V2_AUTHORITY; + type = EXTRAINFO_CACHE | + (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY : + V2_AUTHORITY); break; case DIR_PURPOSE_FETCH_NETWORKSTATUS: case DIR_PURPOSE_FETCH_SERVERDESC: - type = V2_AUTHORITY; + type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY : + V2_AUTHORITY); break; case DIR_PURPOSE_FETCH_DIR: case DIR_PURPOSE_FETCH_RUNNING_LIST: @@ -230,21 +237,21 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource, if (!options->FetchServerDescriptors && type != HIDSERV_AUTHORITY) return; - if (directconn && options->UseBridges) { - /* want to pick a bridge for which we have a descriptor. */ + if (!get_via_tor && options->UseBridges) { + /* want to ask a running bridge for which we have a descriptor. */ routerinfo_t *ri = choose_random_entry(NULL); if (ri) { directory_initiate_command(ri->address, ri->addr, ri->or_port, 0, 1, ri->cache_info.identity_digest, dir_purpose, - ROUTER_PURPOSE_GENERAL, + router_purpose, 0, resource, NULL, 0); } else log_notice(LD_DIR, "Ignoring directory request, since no bridge " "nodes are available yet."); return; - } else if (directconn) { + } else if (!get_via_tor) { if (prefer_authority) { /* only ask authdirservers, and don't ask myself */ rs = router_pick_trusteddirserver(type, 1, 1, @@ -270,10 +277,10 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource, rs = router_pick_trusteddirserver(type, 1, 1, retry_if_no_servers); if (!rs) - directconn = 0; /* last resort: try routing it via Tor */ + get_via_tor = 1; /* last resort: try routing it via Tor */ } } - } else { /* !directconn */ + } else { /* get_via_tor */ /* Never use fascistfirewall; we're going via Tor. */ if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) { /* only ask hidserv authorities, any of them will do */ @@ -291,15 +298,15 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource, if (rs) directory_initiate_command_routerstatus(rs, dir_purpose, - ROUTER_PURPOSE_GENERAL, - !directconn, + router_purpose, + get_via_tor, resource, NULL, 0); else { log_notice(LD_DIR, "While fetching directory info, " "no running dirservers known. Will try again later. " "(purpose %d)", dir_purpose); - if (!purpose_needs_anonymity(dir_purpose)) { + if (!purpose_needs_anonymity(dir_purpose, router_purpose)) { /* remember we tried them all and failed. */ directory_all_unreachable(time(NULL)); } @@ -387,8 +394,8 @@ connection_dir_request_failed(dir_connection_t *conn) conn->_base.purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) { log_info(LD_DIR, "Giving up on directory server at '%s:%d'; retrying", conn->_base.address, conn->_base.port); - directory_get_from_dirserver(conn->_base.purpose, NULL, - 0 /* don't retry_if_no_servers */); + directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose, + NULL, 0 /* don't retry_if_no_servers */); } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) { log_info(LD_DIR, "Giving up on directory server at '%s'; retrying", conn->_base.address); @@ -422,8 +429,8 @@ connection_dir_download_networkstatus_failed(dir_connection_t *conn, smartlist_t *trusted_dirs = router_get_trusted_dir_servers(); SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds, ++ds->n_networkstatus_failures); - directory_get_from_dirserver(conn->_base.purpose, "all.z", - 0 /* don't retry_if_no_servers */); + directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose, + "all.z", 0 /* don't retry_if_no_servers */); } else if (!strcmpstart(conn->requested_resource, "fp/")) { /* We were trying to download by fingerprint; mark them all as having * failed, and possibly retry them later.*/ @@ -1699,7 +1706,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, /* try to get a new one now */ if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR) && !should_delay_dir_fetches(options)) - directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, + ROUTER_PURPOSE_GENERAL, NULL, 1); tor_free(url); return 0; } @@ -1750,7 +1758,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, /* try to get a new one now */ if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST) && !should_delay_dir_fetches(options)) - directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, + ROUTER_PURPOSE_GENERAL, NULL, 1); tor_free(url); return 0; } diff --git a/src/or/main.c b/src/or/main.c index 0d0adf700..d4dd8b324 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -939,7 +939,8 @@ run_scheduled_events(time_t now) * our dirport. not simply if we configured one. -RD */ if (any_trusted_dir_is_v1_authority() && !should_delay_dir_fetches(options)) - directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, + ROUTER_PURPOSE_GENERAL, NULL, 1); } /** How often do we (as a cache) fetch a new V1 directory? */ #define V1_DIR_FETCH_PERIOD (6*60*60) @@ -949,7 +950,8 @@ run_scheduled_events(time_t now) /* Caches need to fetch running_routers; directory clients don't. */ if (options->DirPort && time_to_fetch_running_routers < now) { if (!authdir_mode_v1(options) && !should_delay_dir_fetches(options)) { - directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, + ROUTER_PURPOSE_GENERAL, NULL, 1); } /** How often do we (as a cache) fetch a new V1 runningrouters document? */ #define V1_RUNNINGROUTERS_FETCH_PERIOD (30*60) diff --git a/src/or/or.h b/src/or/or.h index 8df54314e..7a1ac3117 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2670,10 +2670,11 @@ int assign_to_cpuworker(connection_t *cpuworker, uint8_t question_type, /********************************* directory.c ***************************/ char *authority_type_to_string(authority_type_t auth); -void directory_post_to_dirservers(uint8_t purpose, authority_type_t type, - const char *payload, +void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, + authority_type_t type, const char *payload, size_t payload_len, size_t extrainfo_len); -void directory_get_from_dirserver(uint8_t dir_purpose, const char *resource, +void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, + const char *resource, int retry_if_no_servers); void directory_initiate_command_routerstatus(routerstatus_t *status, uint8_t dir_purpose, diff --git a/src/or/rendclient.c b/src/or/rendclient.c index c65aa9513..fef95d1c8 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -261,7 +261,8 @@ rend_client_refetch_renddesc(const char *query) "already in progress.", escaped_safe_str(query)); } else { /* not one already; initiate a dir rend desc lookup */ - directory_get_from_dirserver(DIR_PURPOSE_FETCH_RENDDESC, query, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_RENDDESC, + ROUTER_PURPOSE_GENERAL, query, 1); } } diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 937d40b5c..8ec388809 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -948,6 +948,7 @@ upload_service_descriptor(rend_service_t *service, int version) /* Post it to the dirservers */ directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, + ROUTER_PURPOSE_GENERAL, HIDSERV_AUTHORITY, desc, desc_len, 0); tor_free(desc); diff --git a/src/or/router.c b/src/or/router.c index 1137881e6..77bcf19b7 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -909,8 +909,11 @@ router_upload_dir_desc_to_dirservers(int force) } msg[desc_len+extra_len] = 0; - directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, auth, - msg, desc_len, extra_len); + directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, + (auth & BRIDGE_AUTHORITY) ? + ROUTER_PURPOSE_BRIDGE : + ROUTER_PURPOSE_GENERAL, + auth, msg, desc_len, extra_len); tor_free(msg); } diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 92338fa3e..9bb456c3a 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -3416,7 +3416,8 @@ update_networkstatus_cache_downloads(time_t now) /* (Check whether we're currently fetching network-status objects.) */ if (!connection_get_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_NETWORKSTATUS)) - directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,"all.z",1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, + ROUTER_PURPOSE_GENERAL, "all.z",1); } } @@ -3541,7 +3542,8 @@ update_networkstatus_client_downloads(time_t now) *cp++ = '+'; }); memcpy(cp, ".z", 3); - directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, resource, 1); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, + ROUTER_PURPOSE_GENERAL, resource, 1); tor_free(resource); smartlist_free(missing); } @@ -4469,13 +4471,13 @@ initiate_descriptor_downloads(routerstatus_t *source, 0, /* not private */ resource, NULL, 0); } else { - directory_get_from_dirserver(purpose, resource, 1); + directory_get_from_dirserver(purpose, ROUTER_PURPOSE_GENERAL, resource, 1); } tor_free(resource); } /** Clients don't download any descriptor this recent, since it will probably - * not have propageted to enough caches. */ + * not have propagated to enough caches. */ #define ESTIMATED_PROPAGATION_TIME (10*60) /** Return 0 if this routerstatus is obsolete, too new, isn't |