mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-23 20:03:31 +01:00
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
This commit is contained in:
parent
4a03959b10
commit
d46b8a3eac
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 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_fetches_dir_info_like_mirror(or_options_t *options)
|
||||
{
|
||||
return directory_fetches_from_authorities(options);
|
||||
}
|
||||
|
||||
/* 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_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 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.
|
||||
* and we're willing to serve them to others. Else return 0.
|
||||
*/
|
||||
int
|
||||
directory_caches_dir_info(or_options_t *options)
|
||||
{
|
||||
return options->DirPort != 0;
|
||||
}
|
||||
|
||||
/** Return 1 if we fetch our directory material directly from the
|
||||
* authorities, rather than some other cache. */
|
||||
int
|
||||
directory_fetches_from_authorities(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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user