From 3d641bde0e6d86f924252ae0f7cd427212ef937e Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Fri, 15 Jun 2007 02:12:15 +0000 Subject: [PATCH] Refine r10571: more work on bridge stuff. - Only listen to responses for "authority" fetches if we're configured to use Bridges. Otherwise it's safe (and maybe smarter) to silently discard them like we used to. - React faster to download networkstatuses after the first bridge descriptor arrives. - Don't do dir fetches before we have any bridges, even when our dirport is open. svn:r10604 --- src/or/circuitbuild.c | 9 ++++----- src/or/circuituse.c | 5 +---- src/or/directory.c | 21 +++++++++++++-------- src/or/main.c | 7 ++++--- src/or/or.h | 1 + src/or/routerlist.c | 11 +++++++++++ 6 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index a58c68d190..f505ae03fe 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1728,11 +1728,7 @@ extend_info_alloc(const char *nickname, const char *digest, { extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t)); memcpy(info->identity_digest, digest, DIGEST_LEN); - if (nickname) - strlcpy(info->nickname, nickname, sizeof(info->nickname)); - else { - /* make one up */ - } + strlcpy(info->nickname, nickname, sizeof(info->nickname)); if (onion_key) info->onion_key = crypto_pk_dup_key(onion_key); info->addr = addr; @@ -2751,9 +2747,12 @@ learned_bridge_descriptor(routerinfo_t *ri) tor_assert(ri); tor_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE); if (get_options()->UseBridges) { + int first = !any_bridge_descriptors_known(); ri->is_running = 1; add_an_entry_guard(ri); log_notice(LD_DIR, "new bridge descriptor '%s'", ri->nickname); + if (first) + routerlist_retry_directory_downloads(time(NULL)); } } diff --git a/src/or/circuituse.c b/src/or/circuituse.c index fef1471fdd..6ae4adac1d 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -969,10 +969,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, log_notice(LD_APP|LD_DIR, "Application request when we're believed to be " "offline. Optimistically trying directory fetches again."); - router_reset_status_download_failures(); - router_reset_descriptor_download_failures(); - update_networkstatus_downloads(time(NULL)); - update_router_descriptor_downloads(time(NULL)); + routerlist_retry_directory_downloads(time(NULL)); } /* the stream will be dealt with when router_have_minimum_dir_info becomes * 1, or when all directory attempts fail and directory_all_unreachable() diff --git a/src/or/directory.c b/src/or/directory.c index 8c483f5cae..83a7a7b0b2 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1269,14 +1269,17 @@ connection_dir_client_reached_eof(dir_connection_t *conn) return dir_okay ? 0 : -1; } /* Learn the routers, assuming we requested by fingerprint or "all" - * or "authority". (We use "authority" to fetch our own descriptor for - * testing, and to fetch bridge descriptors for bootstrapping.) - */ - /* XXX020 We now risk replacing ourself with a router running at - * the addr:port we think we have. Might want to check more carefully. */ + * or "authority". + * + * We use "authority" to fetch our own descriptor for + * testing, and to fetch bridge descriptors for bootstrapping. Ignore + * the output of "authority" requests unless we are using bridges, + * since otherwise they'll be the response from reachability tests, + * and we don't really want to add that to our routerlist. */ if (which || (conn->requested_resource && (!strcmpstart(conn->requested_resource, "all") || - !strcmpstart(conn->requested_resource, "authority")))) { + (!strcmpstart(conn->requested_resource, "authority") && + get_options()->UseBridges)))) { /* as we learn from them, we remove them from 'which' */ if (was_ei) { router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which); @@ -1694,7 +1697,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, "don't have a good one yet. Sending 503 Dir not available."); write_http_status_line(conn, 503, "Directory unavailable"); /* try to get a new one now */ - if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR)) + if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR) && + !should_delay_dir_fetches(options)) directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); tor_free(url); return 0; @@ -1744,7 +1748,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, if (!d) { write_http_status_line(conn, 503, "Directory unavailable"); /* try to get a new one now */ - if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST)) + 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); tor_free(url); return 0; diff --git a/src/or/main.c b/src/or/main.c index 14c242d20a..9d75f91381 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -937,7 +937,8 @@ run_scheduled_events(time_t now) if (options->DirPort && !authdir_mode_v1(options)) { /* XXX020 actually, we should only do this if we want to advertise * our dirport. not simply if we configured one. -RD */ - if (any_trusted_dir_is_v1_authority()) + if (any_trusted_dir_is_v1_authority() && + !should_delay_dir_fetches(options)) directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); } /** How often do we (as a cache) fetch a new V1 directory? */ @@ -947,7 +948,7 @@ 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)) { + if (!authdir_mode_v1(options) && !should_delay_dir_fetches(options)) { directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL, 1); } /** How often do we (as a cache) fetch a new V1 runningrouters document? */ @@ -959,7 +960,7 @@ run_scheduled_events(time_t now) rep_history_clean(now - options->RephistTrackTime); rend_cache_clean(); /* XXX020 we only clean this stuff if DirPort is set?! -RD */ - } + } /* 2b. Once per minute, regenerate and upload the descriptor if the old * one is inaccurate. */ diff --git a/src/or/or.h b/src/or/or.h index dd3106f7f9..ad25946e07 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3338,6 +3338,7 @@ local_routerstatus_t *router_get_combined_status_by_descriptor_digest( //routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest); int should_delay_dir_fetches(or_options_t *options); void update_networkstatus_downloads(time_t now); +void routerlist_retry_directory_downloads(time_t now); void update_router_descriptor_downloads(time_t now); void update_extrainfo_downloads(time_t now); void routers_update_all_from_networkstatus(time_t now); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 0df2f7f578..d7f56058fb 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -3545,6 +3545,17 @@ update_networkstatus_downloads(time_t now) update_networkstatus_client_downloads(now); } +/** Clear all our timeouts for fetching v2 directory stuff, and then + * give it all a try again. */ +void +routerlist_retry_directory_downloads(time_t now) +{ + router_reset_status_download_failures(); + router_reset_descriptor_download_failures(); + update_networkstatus_downloads(now); + update_router_descriptor_downloads(now); +} + /** Return 1 if all running sufficiently-stable routers will reject * addr:port, return 0 if any might accept it. */ int -- 2.11.4.GIT