diff options
author | Roger Dingledine <arma@torproject.org> | 2007-12-04 18:35:03 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-12-04 18:35:03 +0000 |
commit | d46b8a3eac7983795756297cca2d69a5aa5e3ad3 (patch) | |
tree | ba91853b7e28c2bcd70d014373f98a3126923f93 | |
parent | 4a03959b10b9db3d47485e7ffb1848e1553cd601 (diff) | |
download | tor-d46b8a3eac7983795756297cca2d69a5aa5e3ad3.tar.gz tor-d46b8a3eac7983795756297cca2d69a5aa5e3ad3.zip |
Stop being so aggressive about fetching dir info if your DirPort is
on but your ORPort is off.
Add a new config option BridgeRelay that specifies you want to
be a bridge relay. Right now the only difference is that it makes
you answer begin_dir requests, and it makes you cache dir info,
even if your DirPort isn't on.
Refactor directory_caches_dir_info() into some more functions.
svn:r12668
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/or/command.c | 2 | ||||
-rw-r--r-- | src/or/config.c | 7 | ||||
-rw-r--r-- | src/or/connection_edge.c | 3 | ||||
-rw-r--r-- | src/or/dirserv.c | 60 | ||||
-rw-r--r-- | src/or/main.c | 7 | ||||
-rw-r--r-- | src/or/networkstatus.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 9 | ||||
-rw-r--r-- | src/or/routerlist.c | 38 |
9 files changed, 97 insertions, 43 deletions
@@ -14,6 +14,8 @@ Changes in version 0.2.0.13-alpha - 2007-12-?? - Stop thinking that 0.1.2.x directory servers can handle "begin_dir" requests. Should ease bugs 406 and 419 where 0.1.2.x relays are crashing or mis-answering these requests. + - Stop being so aggressive about fetching dir info if your DirPort is + on but your ORPort is off. o Minor bugfixes: - The fix in 0.2.0.12-alpha cleared the "hsdir" flag in v3 network @@ -37,9 +39,13 @@ Changes in version 0.2.0.13-alpha - 2007-12-?? consumers. (We already do this on HUP.) - Authorities and caches fetch the v2 networkstatus documents less often, now that v3 is encouraged. + - Add a new config option BridgeRelay that specifies you want to + be a bridge relay. Right now the only difference is that it makes + you answer begin_dir requests, and it makes you cache dir info, + even if your DirPort isn't on. o Code simplifications: - - + - ???? Changes in version 0.2.0.12-alpha - 2007-11-16 diff --git a/src/or/command.c b/src/or/command.c index 41c0c1112b..aa060faf3c 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -375,7 +375,7 @@ command_process_relay_cell(cell_t *cell, or_connection_t *conn) } if (CIRCUIT_IS_ORIGIN(circ)) { - /* if we're a server and treating connections with recent local + /* if we're a relay and treating connections with recent local * traffic better, then this is one of them. */ conn->client_used = time(NULL); } diff --git a/src/or/config.c b/src/or/config.c index a119644b98..a8060f2269 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -144,6 +144,7 @@ static config_var_t _option_vars[] = { V(BandwidthRate, MEMUNIT, "5 MB"), V(BridgeAuthoritativeDir, BOOL, "0"), VAR("Bridge", LINELIST, Bridges, NULL), + V(BridgeRelay, BOOL, "0"), V(CircuitBuildTimeout, INTERVAL, "1 minute"), V(CircuitIdleTimeout, INTERVAL, "1 hour"), V(ClientDNSRejectInternalAddresses, BOOL,"1"), @@ -1132,8 +1133,10 @@ options_act(or_options_t *old_options) if (old_options) { if (authdir_mode_v3(options) && !authdir_mode_v3(old_options)) dirvote_recalculate_timing(options, time(NULL)); - if (!bool_eq(directory_caches_dir_info(options), - directory_caches_dir_info(old_options))) { + if (!bool_eq(directory_fetches_dir_info_like_mirror(options), + directory_fetches_dir_info_like_mirror(old_options)) || + !bool_eq(directory_fetches_dir_info_like_bridge_user(options), + directory_fetches_dir_info_like_bridge_user(old_options))) { /* Make sure update_router_have_min_dir_info gets called. */ router_dir_info_changed(); /* We might need to download a new consensus status later or sooner than diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 8335a42a0d..f62984259e 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2292,8 +2292,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) return 0; } } else if (rh.command == RELAY_COMMAND_BEGIN_DIR) { - or_options_t *options = get_options(); - if (!directory_permits_begindir_requests(options) || + if (!directory_permits_begindir_requests(get_options()) || circ->purpose != CIRCUIT_PURPOSE_OR) { end_payload[0] = END_STREAM_REASON_NOTDIRECTORY; relay_send_command_from_edge(rh.stream_id, circ, RELAY_COMMAND_END, diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 03a0c2791b..f36ac55b67 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1089,25 +1089,50 @@ dirserv_dump_directory_to_string(char **dir_out, /********************************************************************/ /* A set of functions to answer questions about how we'd like to behave - * as a directory cache/client. */ + * as a directory mirror/client. */ -/** Return 1 if we want to keep descriptors, networkstatuses, etc around - * and serve them to others, or 0 otherwise. - * Also causes us to fetch new networkstatuses, descriptors, etc on the - * "mirror" schedule rather than the "client" schedule. +/** Return 1 if we fetch our directory material directly from the + * authorities, rather than from a mirror. */ +int +directory_fetches_from_authorities(or_options_t *options) +{ + if (options->DirPort == 0) + return 0; + /* XXX if dirport not advertised, return 0 too */ + if (!server_mode(options)) + return 0; + /* XXX if orport or dirport not reachable, return 0 too */ + return 1; +} + +/* Return 1 if we should fetch new networkstatuses, descriptors, etc + * on the "mirror" schedule rather than the "client" schedule. */ int -directory_caches_dir_info(or_options_t *options) +directory_fetches_dir_info_like_mirror(or_options_t *options) { - return options->DirPort != 0; + return directory_fetches_from_authorities(options); } -/** Return 1 if we fetch our directory material directly from the - * authorities, rather than some other cache. */ +/* Return 1 if we should fetch new networkstatuses, descriptors, etc + * on a very passive schedule -- waiting long enough for ordinary clients + * to probably have the info we want. These would include bridge users, + * and maybe others in the future e.g. if a Tor client uses another Tor + * client as a directory guard. + */ int -directory_fetches_from_authorities(or_options_t *options) +directory_fetches_dir_info_like_bridge_user(or_options_t *options) +{ + return options->UseBridges != 0; +} + +/** Return 1 if we want to keep descriptors, networkstatuses, etc around + * and we're willing to serve them to others. Else return 0. + */ +int +directory_caches_dir_info(or_options_t *options) { - return server_mode(options) && options->DirPort != 0; + return options->BridgeRelay != 0 || options->DirPort != 0; } /** Return 1 if we want to allow remote people to ask us directory @@ -1116,7 +1141,7 @@ directory_fetches_from_authorities(or_options_t *options) int directory_permits_begindir_requests(or_options_t *options) { - return options->DirPort != 0; + return options->BridgeRelay != 0 || options->DirPort != 0; } /** Return 1 if we want to allow controllers to ask us directory @@ -1128,6 +1153,17 @@ directory_permits_controller_requests(or_options_t *options) return options->DirPort != 0; } +/** Return 1 if we have no need to fetch new descriptors. This generally + * happens when we're not a dir cache and we haven't built any circuits + * lately. + */ +int +directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now) +{ + return !options->DirPort && !options->FetchUselessDescriptors && + rep_hist_circbuilding_dormant(now); +} + /********************************************************************/ /* Used only by non-v1-auth dirservers: The v1 directory and diff --git a/src/or/main.c b/src/or/main.c index acb7cac3f4..ccf1e1c637 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -952,9 +952,8 @@ run_scheduled_events(time_t now) * (if we've passed our internal checks). */ if (time_to_fetch_directory < now) { /* Only caches actually need to fetch directories now. */ - if (directory_caches_dir_info(options) && !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 (directory_fetches_dir_info_like_mirror(options) && + !authdir_mode_v1(options)) { if (any_trusted_dir_is_v1_authority() && !should_delay_dir_fetches(options)) directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, @@ -966,7 +965,7 @@ run_scheduled_events(time_t now) } /* Caches need to fetch running_routers; directory clients don't. */ - if (directory_caches_dir_info(options) && + if (directory_fetches_dir_info_like_mirror(options) && 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, diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 6472576f52..7051e82158 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1051,7 +1051,7 @@ update_consensus_networkstatus_fetch_time(time_t now) long dl_interval; long interval = c->fresh_until - c->valid_after; time_t start; - if (directory_caches_dir_info(options)) { + if (directory_fetches_dir_info_like_mirror(options)) { /* We want to cache the next one at some point after this one * is no longer fresh... */ start = c->fresh_until + CONSENSUS_MIN_SECONDS_BEFORE_CACHING; @@ -1062,6 +1062,8 @@ update_consensus_networkstatus_fetch_time(time_t now) start = c->fresh_until + (interval*3)/4; /* But download the next one before this one is expired. */ dl_interval = ((c->valid_until - start) * 7 )/ 8; + /* XXX020 do something different if + * directory_fetches_dir_info_like_bridge_user() */ } if (dl_interval < 1) dl_interval = 1; @@ -1110,7 +1112,7 @@ update_networkstatus_downloads(time_t now) or_options_t *options = get_options(); if (should_delay_dir_fetches(options)) return; - if (directory_caches_dir_info(options)) + if (directory_fetches_dir_info_like_mirror(options)) update_v2_networkstatus_cache_downloads(now); update_consensus_networkstatus_downloads(now); update_certificate_downloads(now); diff --git a/src/or/or.h b/src/or/or.h index d992d7cdc6..ddafcd3d20 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2084,6 +2084,10 @@ typedef struct { int UseBridges; /**< Boolean: should we start all circuits with a bridge? */ config_line_t *Bridges; /**< List of bootstrap bridge addresses. */ + int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make + * this explicit so we can change how we behave in the + * future. */ + /** Boolean: if we know the bridge's digest, should we get new * descriptors from the bridge authorities or from the bridge itself? */ int UpdateBridgesFromAuthority; @@ -3025,10 +3029,13 @@ int list_server_status(smartlist_t *routers, char **router_status_out, int dirserv_dump_directory_to_string(char **dir_out, crypto_pk_env_t *private_key); -int directory_caches_dir_info(or_options_t *options); int directory_fetches_from_authorities(or_options_t *options); +int directory_fetches_dir_info_like_mirror(or_options_t *options); +int directory_fetches_dir_info_like_bridge_user(or_options_t *options); +int directory_caches_dir_info(or_options_t *options); int directory_permits_begindir_requests(or_options_t *options); int directory_permits_controller_requests(or_options_t *options); +int directory_too_idle_to_fetch_descriptors(or_options_t *options, time_t now); void directory_set_dirty(void); cached_dir_t *dirserv_get_directory(void); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d7d33305bd..524113c4bf 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2909,7 +2909,7 @@ routerlist_remove_old_routers(void) routerinfo_t *router; signed_descriptor_t *sd; digestmap_t *retain; - int dirserv = directory_caches_dir_info(get_options()); + int caches = directory_caches_dir_info(get_options()); const networkstatus_vote_t *consensus = networkstatus_get_latest_consensus(); const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list(); @@ -2923,7 +2923,7 @@ routerlist_remove_old_routers(void) retain = digestmap_new(); cutoff = now - OLD_ROUTER_DESC_MAX_AGE; /* Build a list of all the descriptors that _anybody_ lists. */ - if (dirserv) { + if (caches) { SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, { /* XXXX The inner loop here gets pretty expensive, and actually shows up @@ -2951,7 +2951,7 @@ routerlist_remove_old_routers(void) * routers that are too old and that nobody recommends. (If we don't have * enough networkstatuses, then we should get more before we decide to kill * routers.) */ - if (!dirserv || + if (!caches || smartlist_len(networkstatus_v2_list) > get_n_v2_authorities() / 2) { cutoff = now - ROUTER_MAX_AGE; /* Remove too-old unrecommended members of routerlist->routers. */ @@ -3000,7 +3000,7 @@ routerlist_remove_old_routers(void) * total number doesn't approach max_descriptors_per_router()*len(router). */ if (smartlist_len(routerlist->old_routers) < - smartlist_len(routerlist->routers) * (dirserv?4:2)) + smartlist_len(routerlist->routers) * (caches?4:2)) goto done; smartlist_sort(routerlist->old_routers, _compare_old_routers_by_identity); @@ -3224,7 +3224,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc) { routerstatus_t *rs; networkstatus_vote_t *consensus = networkstatus_get_latest_consensus(); - int dirserv = directory_caches_dir_info(get_options()); + int caches = directory_caches_dir_info(get_options()); const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list(); if (consensus) { @@ -3233,7 +3233,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc) desc->signed_descriptor_digest, DIGEST_LEN)) return 1; } - if (dirserv && networkstatus_v2_list) { + if (caches && networkstatus_v2_list) { SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, { if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest))) @@ -3560,7 +3560,7 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now) or_options_t *options = get_options(); n_downloadable = smartlist_len(downloadable); - if (!directory_caches_dir_info(options)) { + if (!directory_fetches_dir_info_like_mirror(options)) { if (n_downloadable >= MAX_DL_TO_DELAY) { log_debug(LD_DIR, "There are enough downloadable routerdescs to launch requests."); @@ -3582,6 +3582,8 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now) } } } + /* XXX020 should we consider having even the dir mirrors delay + * a little bit, so we don't load the authorities as much? -RD */ if (! should_delay && n_downloadable) { int i, n_per_request; @@ -3611,10 +3613,11 @@ launch_router_descriptor_downloads(smartlist_t *downloadable, time_t now) } /** Launch downloads for router status as needed, using the strategy used by - * authorities and caches: download every descriptor we don't have but would - * serve, from a random authority that lists it. */ + * authorities and caches: based on the v2 networkstatuses we have, download + * every descriptor we don't have but would serve, from a random authority + * that lists it. */ static void -update_router_descriptor_cache_downloads(time_t now) +update_router_descriptor_cache_downloads_v2(time_t now) { smartlist_t **downloadable; /* For each authority, what can we dl from it? */ smartlist_t **download_from; /* ... and, what will we dl from it? */ @@ -3624,8 +3627,8 @@ update_router_descriptor_cache_downloads(time_t now) or_options_t *options = get_options(); const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list(); - if (! directory_caches_dir_info(options)) { - log_warn(LD_BUG, "Called update_router_descriptor_cache_downloads() " + if (! directory_fetches_dir_info_like_mirror(options)) { + log_warn(LD_BUG, "Called update_router_descriptor_cache_downloads_v2() " "on a non-dir-mirror?"); } @@ -3763,14 +3766,12 @@ update_consensus_router_descriptor_downloads(time_t now) smartlist_t *no_longer_old = smartlist_create(); smartlist_t *downloadable = smartlist_create(); int authdir = authdir_mode(options); - int dirserver = directory_caches_dir_info(options); networkstatus_vote_t *consensus = networkstatus_get_reasonably_live_consensus(now); int n_delayed=0, n_have=0, n_would_reject=0, n_wouldnt_use=0, n_inprogress=0, n_in_oldrouters=0; - if (!dirserver && !options->FetchUselessDescriptors && - rep_hist_circbuilding_dormant(now)) + if (directory_too_idle_to_fetch_descriptors(options, now)) goto done; if (!consensus) goto done; @@ -3804,7 +3805,8 @@ update_consensus_router_descriptor_downloads(time_t now) ++n_would_reject; continue; /* We would throw it out immediately. */ } - if (!dirserver && !client_would_use_router(rs, now, options)) { + if (!directory_caches_dir_info(options) && + !client_would_use_router(rs, now, options)) { ++n_wouldnt_use; continue; /* We would never use it ourself. */ } @@ -3859,8 +3861,8 @@ update_router_descriptor_downloads(time_t now) or_options_t *options = get_options(); if (should_delay_dir_fetches(options)) return; - if (directory_caches_dir_info(options)) { - update_router_descriptor_cache_downloads(now); + if (directory_fetches_dir_info_like_mirror(options)) { + update_router_descriptor_cache_downloads_v2(now); } update_consensus_router_descriptor_downloads(now); } |