r14812@Kushana: nickm | 2007-10-09 10:22:00 -0400

Merge extra fields in local_routerstatus_t back into routerstatus_t.  See changelog for rationale.


svn:r11799
This commit is contained in:
Nick Mathewson 2007-10-09 15:27:15 +00:00
parent ff19400cb0
commit bb9cc4fb29
7 changed files with 125 additions and 145 deletions

View File

@ -47,6 +47,15 @@ Changes in version 0.2.0.8-alpha - 2007-??-??
- Make a bunch of functions static. Remove some dead code. - Make a bunch of functions static. Remove some dead code.
- Pull out about a third of the really big routerlist.c; put it in a - Pull out about a third of the really big routerlist.c; put it in a
new module, networkstatus.c. new module, networkstatus.c.
- Merge the extra fields in local_routerstatus_t back into
routerstatus_t: we used to need one routerstatus_t for each
authority's opinion, plus a local_routerstatus_t for the locally
computed consensus opinion. To save space, we put the locally
modified fields into local_routerstatus_t, and only the common stuff
into routerstatus_t. But once v3 directories are in use, clients and
caches will no longer need to hold authority opinions; thus, the
rationale for keeping the types separate is now gone.
Changes in version 0.2.0.7-alpha - 2007-09-21 Changes in version 0.2.0.7-alpha - 2007-09-21
o New directory authorities: o New directory authorities:

View File

@ -78,19 +78,6 @@ Things we'd like to do in 0.2.0.x:
- When checking a consensus, make sure that its times are plausible. - When checking a consensus, make sure that its times are plausible.
o Add a function that will eventually tell us about our clock skew. o Add a function that will eventually tell us about our clock skew.
For now, just require that authorities not be skewed. For now, just require that authorities not be skewed.
. Start caching consensus documents once authorities make them;
start downloading consensus documents once caches serve
them
o Download code
o Code to schedule downloads
- Code to retry failed downloads
- Code to delay next download while fetching certificates
- Code to download routers listed in v3 networkstatus consensuses.
- Enable for non-caches
- Code to use v3 networkstatus documents once clients are
fetching them
- Implement
- Enable
. Start caching consensus documents once authorities make them; . Start caching consensus documents once authorities make them;
start downloading consensus documents once caches serve start downloading consensus documents once caches serve
them them

View File

@ -3378,7 +3378,7 @@ control_event_or_authdir_new_descriptor(const char *action,
return 0; return 0;
} }
/** Called when the local_routerstatus_ts <b>statuses</b> have changed: sends /** Called when the routerstatus_ts <b>statuses</b> have changed: sends
* an NS event to any controller that cares. */ * an NS event to any controller that cares. */
int int
control_event_networkstatus_changed(smartlist_t *statuses) control_event_networkstatus_changed(smartlist_t *statuses)
@ -3390,9 +3390,9 @@ control_event_networkstatus_changed(smartlist_t *statuses)
strs = smartlist_create(); strs = smartlist_create();
smartlist_add(strs, tor_strdup("650+NS\r\n")); smartlist_add(strs, tor_strdup("650+NS\r\n"));
SMARTLIST_FOREACH(statuses, local_routerstatus_t *, rs, SMARTLIST_FOREACH(statuses, routerstatus_t *, rs,
{ {
s = networkstatus_getinfo_helper_single(&rs->status); s = networkstatus_getinfo_helper_single(rs);
if (!s) continue; if (!s) continue;
smartlist_add(strs, s); smartlist_add(strs, s);
}); });
@ -3413,7 +3413,7 @@ control_event_networkstatus_changed(smartlist_t *statuses)
/** Called when a single local_routerstatus_t has changed: Sends an NS event /** Called when a single local_routerstatus_t has changed: Sends an NS event
* to any countroller that cares. */ * to any countroller that cares. */
int int
control_event_networkstatus_changed_single(local_routerstatus_t *rs) control_event_networkstatus_changed_single(routerstatus_t *rs)
{ {
smartlist_t *statuses; smartlist_t *statuses;
int r; int r;

View File

@ -167,7 +167,6 @@ int
router_supports_extrainfo(const char *identity_digest, int is_authority) router_supports_extrainfo(const char *identity_digest, int is_authority)
{ {
routerinfo_t *ri = router_get_by_digest(identity_digest); routerinfo_t *ri = router_get_by_digest(identity_digest);
local_routerstatus_t *lrs;
if (ri) { if (ri) {
if (ri->caches_extra_info) if (ri->caches_extra_info)
@ -177,8 +176,8 @@ router_supports_extrainfo(const char *identity_digest, int is_authority)
return 1; return 1;
} }
if (is_authority) { if (is_authority) {
lrs = router_get_combined_status_by_digest(identity_digest); routerstatus_t *rs = router_get_combined_status_by_digest(identity_digest);
if (lrs && lrs->status.version_supports_extrainfo_upload) if (rs && rs->version_supports_extrainfo_upload)
return 1; return 1;
} }
return 0; return 0;
@ -229,7 +228,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
*/ */
SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds, SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds,
{ {
routerstatus_t *rs = &(ds->fake_status.status); routerstatus_t *rs = &(ds->fake_status);
size_t upload_len = payload_len; size_t upload_len = payload_len;
if ((type & ds->type) == 0) if ((type & ds->type) == 0)
@ -398,7 +397,7 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
continue; continue;
if (!(ds->type & V3_AUTHORITY)) if (!(ds->type & V3_AUTHORITY))
continue; continue;
rs = &ds->fake_status.status; rs = &ds->fake_status;
/* XXXX020 should this ever tunnel via tor? */ /* XXXX020 should this ever tunnel via tor? */
directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose, directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose,
0, resource, NULL, 0); 0, resource, NULL, 0);
@ -1196,7 +1195,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
(void) skewed; /* skewed isn't used yet. */ (void) skewed; /* skewed isn't used yet. */
if (status_code == 503) { if (status_code == 503) {
local_routerstatus_t *rs; routerstatus_t *rs;
trusted_dir_server_t *ds; trusted_dir_server_t *ds;
log_info(LD_DIR,"Received http status code %d (%s) from server " log_info(LD_DIR,"Received http status code %d (%s) from server "
"'%s:%d'. I'll try again soon.", "'%s:%d'. I'll try again soon.",
@ -2689,7 +2688,7 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
if (sd) if (sd)
dls = &sd->ei_dl_status; dls = &sd->ei_dl_status;
} else { } else {
local_routerstatus_t *rs = routerstatus_t *rs =
router_get_combined_status_by_descriptor_digest(digest); router_get_combined_status_by_descriptor_digest(digest);
if (rs) if (rs)
dls = &rs->dl_status; dls = &rs->dl_status;

View File

@ -12,7 +12,7 @@ const char networkstatus_c_id[] =
#include "or.h" #include "or.h"
/** Global list of local_routerstatus_t for each router, known or unknown. /** Global list of routerstatus_t for each router, known or unknown.
* Kept sorted by digest. */ * Kept sorted by digest. */
static smartlist_t *routerstatus_list = NULL; static smartlist_t *routerstatus_list = NULL;
/** Map from descriptor digest to a member of routerstatus_list: used to /** Map from descriptor digest to a member of routerstatus_list: used to
@ -74,7 +74,7 @@ networkstatus_reset_warnings(void)
{ {
if (!routerstatus_list) if (!routerstatus_list)
routerstatus_list = smartlist_create(); routerstatus_list = smartlist_create();
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
rs->name_lookup_warned = 0); rs->name_lookup_warned = 0);
if (!warned_conflicts) if (!warned_conflicts)
@ -171,13 +171,6 @@ routerstatus_free(routerstatus_t *rs)
tor_free(rs); tor_free(rs);
} }
/** Free all storage held by the local_routerstatus object <b>rs</b>. */
static void
local_routerstatus_free(local_routerstatus_t *rs)
{
tor_free(rs);
}
/** Free all storage held by the networkstatus object <b>ns</b>. */ /** Free all storage held by the networkstatus object <b>ns</b>. */
void void
networkstatus_free(networkstatus_t *ns) networkstatus_free(networkstatus_t *ns)
@ -505,7 +498,7 @@ networkstatus_get_v2_list(void)
return networkstatus_list; return networkstatus_list;
} }
/** DOCDOC list of local_routerstatus_t */ /** DOCDOC list of routerstatus_t */
const smartlist_t * const smartlist_t *
networkstatus_get_all_statuses(void) networkstatus_get_all_statuses(void)
{ {
@ -516,7 +509,7 @@ networkstatus_get_all_statuses(void)
/** Return the consensus view of the status of the router whose identity /** Return the consensus view of the status of the router whose identity
* digest is <b>digest</b>, or NULL if we don't know about any such router. */ * digest is <b>digest</b>, or NULL if we don't know about any such router. */
local_routerstatus_t * routerstatus_t *
router_get_combined_status_by_digest(const char *digest) router_get_combined_status_by_digest(const char *digest)
{ {
if (!routerstatus_list) if (!routerstatus_list)
@ -528,7 +521,7 @@ router_get_combined_status_by_digest(const char *digest)
/** Return the consensus view of the status of the router whose current /** Return the consensus view of the status of the router whose current
* <i>descriptor</i> digest is <b>digest</b>, or NULL if no such router is * <i>descriptor</i> digest is <b>digest</b>, or NULL if no such router is
* known. */ * known. */
local_routerstatus_t * routerstatus_t *
router_get_combined_status_by_descriptor_digest(const char *digest) router_get_combined_status_by_descriptor_digest(const char *digest)
{ {
if (!routerstatus_by_desc_digest_map) if (!routerstatus_by_desc_digest_map)
@ -537,15 +530,15 @@ router_get_combined_status_by_descriptor_digest(const char *digest)
} }
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return /** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
* the corresponding local_routerstatus_t, or NULL if none exists. Warn the * the corresponding routerstatus_t, or NULL if none exists. Warn the
* user if <b>warn_if_unnamed</b> is set, and they have specified a router by * user if <b>warn_if_unnamed</b> is set, and they have specified a router by
* nickname, but the Named flag isn't set for that router. */ * nickname, but the Named flag isn't set for that router. */
local_routerstatus_t * routerstatus_t *
router_get_combined_status_by_nickname(const char *nickname, router_get_combined_status_by_nickname(const char *nickname,
int warn_if_unnamed) int warn_if_unnamed)
{ {
char digest[DIGEST_LEN]; char digest[DIGEST_LEN];
local_routerstatus_t *best=NULL; routerstatus_t *best=NULL;
smartlist_t *matches=NULL; smartlist_t *matches=NULL;
if (!routerstatus_list || !nickname) if (!routerstatus_list || !nickname)
@ -561,10 +554,10 @@ router_get_combined_status_by_nickname(const char *nickname,
} }
matches = smartlist_create(); matches = smartlist_create();
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, lrs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, lrs,
{ {
if (!strcasecmp(lrs->status.nickname, nickname)) { if (!strcasecmp(lrs->nickname, nickname)) {
if (lrs->status.is_named) { if (lrs->is_named) {
smartlist_free(matches); smartlist_free(matches);
return lrs; return lrs;
} else { } else {
@ -576,7 +569,7 @@ router_get_combined_status_by_nickname(const char *nickname,
if (smartlist_len(matches)>1 && warn_if_unnamed) { if (smartlist_len(matches)>1 && warn_if_unnamed) {
int any_unwarned=0; int any_unwarned=0;
SMARTLIST_FOREACH(matches, local_routerstatus_t *, lrs, SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
{ {
if (! lrs->name_lookup_warned) { if (! lrs->name_lookup_warned) {
lrs->name_lookup_warned=1; lrs->name_lookup_warned=1;
@ -591,7 +584,7 @@ router_get_combined_status_by_nickname(const char *nickname,
} else if (warn_if_unnamed && best && !best->name_lookup_warned) { } else if (warn_if_unnamed && best && !best->name_lookup_warned) {
char fp[HEX_DIGEST_LEN+1]; char fp[HEX_DIGEST_LEN+1];
base16_encode(fp, sizeof(fp), base16_encode(fp, sizeof(fp),
best->status.identity_digest, DIGEST_LEN); best->identity_digest, DIGEST_LEN);
log_warn(LD_CONFIG, log_warn(LD_CONFIG,
"When looking up a status, you specified a server \"%s\" by name, " "When looking up a status, you specified a server \"%s\" by name, "
"but the directory authorities do not have any key registered for " "but the directory authorities do not have any key registered for "
@ -621,16 +614,16 @@ routerstatus_t *
routerstatus_get_by_hexdigest(const char *hexdigest) routerstatus_get_by_hexdigest(const char *hexdigest)
{ {
char digest[DIGEST_LEN]; char digest[DIGEST_LEN];
local_routerstatus_t *rs; routerstatus_t *rs;
trusted_dir_server_t *ds; trusted_dir_server_t *ds;
if (strlen(hexdigest) < HEX_DIGEST_LEN || if (strlen(hexdigest) < HEX_DIGEST_LEN ||
base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0) base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
return NULL; return NULL;
if ((ds = router_get_trusteddirserver_by_digest(digest))) if ((ds = router_get_trusteddirserver_by_digest(digest)))
return &(ds->fake_status.status); return &ds->fake_status;
if ((rs = router_get_combined_status_by_digest(digest))) if ((rs = router_get_combined_status_by_digest(digest)))
return &(rs->status); return rs;
return NULL; return NULL;
} }
#endif #endif
@ -685,7 +678,7 @@ update_networkstatus_cache_downloads(time_t now)
base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN); base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN);
strlcat(resource, ".z", sizeof(resource)); strlcat(resource, ".z", sizeof(resource));
directory_initiate_command_routerstatus( directory_initiate_command_routerstatus(
&ds->fake_status.status, DIR_PURPOSE_FETCH_NETWORKSTATUS, &ds->fake_status, DIR_PURPOSE_FETCH_NETWORKSTATUS,
ROUTER_PURPOSE_GENERAL, ROUTER_PURPOSE_GENERAL,
0, /* Not private */ 0, /* Not private */
resource, resource,
@ -1371,7 +1364,7 @@ routerstatus_list_update_from_networkstatus(time_t now)
int n_supports_extrainfo_upload=0; int n_supports_extrainfo_upload=0;
int n_desc_digests=0, highest_count=0; int n_desc_digests=0, highest_count=0;
const char *the_name = NULL; const char *the_name = NULL;
local_routerstatus_t *rs_out, *rs_old; routerstatus_t *rs_out, *rs_old;
routerstatus_t *rs, *most_recent; routerstatus_t *rs, *most_recent;
networkstatus_t *ns; networkstatus_t *ns;
const char *lowest = NULL; const char *lowest = NULL;
@ -1476,11 +1469,11 @@ routerstatus_list_update_from_networkstatus(time_t now)
digest_counts[i].rs->published_on > most_recent->published_on) digest_counts[i].rs->published_on > most_recent->published_on)
most_recent = digest_counts[i].rs; most_recent = digest_counts[i].rs;
} }
rs_out = tor_malloc_zero(sizeof(local_routerstatus_t)); rs_out = tor_malloc_zero(sizeof(routerstatus_t));
memcpy(&rs_out->status, most_recent, sizeof(routerstatus_t)); memcpy(rs_out, most_recent, sizeof(routerstatus_t));
/* Copy status info about this router, if we had any before. */ /* Copy status info about this router, if we had any before. */
if ((rs_old = router_get_combined_status_by_digest(lowest))) { if ((rs_old = router_get_combined_status_by_digest(lowest))) {
if (!memcmp(rs_out->status.descriptor_digest, if (!memcmp(rs_out->descriptor_digest,
most_recent->descriptor_digest, DIGEST_LEN)) { most_recent->descriptor_digest, DIGEST_LEN)) {
rs_out->dl_status.n_download_failures = rs_out->dl_status.n_download_failures =
rs_old->dl_status.n_download_failures; rs_old->dl_status.n_download_failures;
@ -1493,40 +1486,40 @@ routerstatus_list_update_from_networkstatus(time_t now)
log_debug(LD_DIR, "Router '%s' is listed by %d/%d directories, " log_debug(LD_DIR, "Router '%s' is listed by %d/%d directories, "
"named by %d/%d, validated by %d/%d, and %d/%d recent " "named by %d/%d, validated by %d/%d, and %d/%d recent "
"directories think it's running.", "directories think it's running.",
rs_out->status.nickname, rs_out->nickname,
n_listing, n_statuses, n_named, n_naming, n_valid, n_statuses, n_listing, n_statuses, n_named, n_naming, n_valid, n_statuses,
n_running, n_recent); n_running, n_recent);
rs_out->status.is_named = 0; rs_out->is_named = 0;
if (the_name && strcmp(the_name, "**mismatch**") && n_named > 0) { if (the_name && strcmp(the_name, "**mismatch**") && n_named > 0) {
const char *d = strmap_get_lc(name_map, the_name); const char *d = strmap_get_lc(name_map, the_name);
if (d && d != conflict) if (d && d != conflict)
rs_out->status.is_named = 1; rs_out->is_named = 1;
if (smartlist_string_isin(warned_conflicts, rs_out->status.nickname)) if (smartlist_string_isin(warned_conflicts, rs_out->nickname))
smartlist_string_remove(warned_conflicts, rs_out->status.nickname); smartlist_string_remove(warned_conflicts, rs_out->nickname);
} }
if (rs_out->status.is_named) if (rs_out->is_named)
strlcpy(rs_out->status.nickname, the_name, strlcpy(rs_out->nickname, the_name,
sizeof(rs_out->status.nickname)); sizeof(rs_out->nickname));
rs_out->status.is_valid = n_valid > n_statuses/2; rs_out->is_valid = n_valid > n_statuses/2;
rs_out->status.is_running = n_running > n_recent/2; rs_out->is_running = n_running > n_recent/2;
rs_out->status.is_exit = n_exit > n_statuses/2; rs_out->is_exit = n_exit > n_statuses/2;
rs_out->status.is_fast = n_fast > n_statuses/2; rs_out->is_fast = n_fast > n_statuses/2;
rs_out->status.is_possible_guard = n_guard > n_statuses/2; rs_out->is_possible_guard = n_guard > n_statuses/2;
rs_out->status.is_stable = n_stable > n_statuses/2; rs_out->is_stable = n_stable > n_statuses/2;
rs_out->status.is_v2_dir = n_v2_dir > n_statuses/2; rs_out->is_v2_dir = n_v2_dir > n_statuses/2;
rs_out->status.is_bad_exit = n_bad_exit > n_listing_bad_exits/2; rs_out->is_bad_exit = n_bad_exit > n_listing_bad_exits/2;
rs_out->status.is_bad_directory = rs_out->is_bad_directory =
n_bad_directory > n_listing_bad_directories/2; n_bad_directory > n_listing_bad_directories/2;
rs_out->status.version_known = n_version_known > 0; rs_out->version_known = n_version_known > 0;
rs_out->status.version_supports_begindir = rs_out->version_supports_begindir =
n_supports_begindir > n_version_known/2; n_supports_begindir > n_version_known/2;
rs_out->status.version_supports_extrainfo_upload = rs_out->version_supports_extrainfo_upload =
n_supports_extrainfo_upload > n_version_known/2; n_supports_extrainfo_upload > n_version_known/2;
if (!rs_old || memcmp(rs_old, rs_out, sizeof(local_routerstatus_t))) if (!rs_old || memcmp(rs_old, rs_out, sizeof(routerstatus_t)))
smartlist_add(changed_list, rs_out); smartlist_add(changed_list, rs_out);
} }
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
local_routerstatus_free(rs)); routerstatus_free(rs));
smartlist_free(routerstatus_list); smartlist_free(routerstatus_list);
routerstatus_list = result; routerstatus_list = result;
@ -1534,9 +1527,9 @@ routerstatus_list_update_from_networkstatus(time_t now)
if (routerstatus_by_desc_digest_map) if (routerstatus_by_desc_digest_map)
digestmap_free(routerstatus_by_desc_digest_map, NULL); digestmap_free(routerstatus_by_desc_digest_map, NULL);
routerstatus_by_desc_digest_map = digestmap_new(); routerstatus_by_desc_digest_map = digestmap_new();
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
digestmap_set(routerstatus_by_desc_digest_map, digestmap_set(routerstatus_by_desc_digest_map,
rs->status.descriptor_digest, rs->descriptor_digest,
rs)); rs));
tor_free(networkstatus); tor_free(networkstatus);
@ -1560,7 +1553,7 @@ routers_update_status_from_networkstatus(smartlist_t *routers,
int reset_failures) int reset_failures)
{ {
trusted_dir_server_t *ds; trusted_dir_server_t *ds;
local_routerstatus_t *rs; routerstatus_t *rs;
or_options_t *options = get_options(); or_options_t *options = get_options();
int authdir = authdir_mode_v2(options); int authdir = authdir_mode_v2(options);
int namingdir = authdir && options->NamingAuthoritativeDir; int namingdir = authdir && options->NamingAuthoritativeDir;
@ -1578,17 +1571,17 @@ routers_update_status_from_networkstatus(smartlist_t *routers,
continue; continue;
if (!namingdir) if (!namingdir)
router->is_named = rs->status.is_named; router->is_named = rs->is_named;
if (!authdir) { if (!authdir) {
/* If we're not an authdir, believe others. */ /* If we're not an authdir, believe others. */
router->is_valid = rs->status.is_valid; router->is_valid = rs->is_valid;
router->is_running = rs->status.is_running; router->is_running = rs->is_running;
router->is_fast = rs->status.is_fast; router->is_fast = rs->is_fast;
router->is_stable = rs->status.is_stable; router->is_stable = rs->is_stable;
router->is_possible_guard = rs->status.is_possible_guard; router->is_possible_guard = rs->is_possible_guard;
router->is_exit = rs->status.is_exit; router->is_exit = rs->is_exit;
router->is_bad_exit = rs->status.is_bad_exit; router->is_bad_exit = rs->is_bad_exit;
} }
if (router->is_running && ds) { if (router->is_running && ds) {
ds->n_networkstatus_failures = 0; ds->n_networkstatus_failures = 0;
@ -1641,7 +1634,7 @@ int
getinfo_helper_networkstatus(control_connection_t *conn, getinfo_helper_networkstatus(control_connection_t *conn,
const char *question, char **answer) const char *question, char **answer)
{ {
local_routerstatus_t *status; routerstatus_t *status;
(void) conn; (void) conn;
if (!routerstatus_list) { if (!routerstatus_list) {
@ -1651,9 +1644,8 @@ getinfo_helper_networkstatus(control_connection_t *conn,
if (!strcmp(question, "ns/all")) { if (!strcmp(question, "ns/all")) {
smartlist_t *statuses = smartlist_create(); smartlist_t *statuses = smartlist_create();
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, lrs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
{ {
routerstatus_t *rs = &(lrs->status);
smartlist_add(statuses, networkstatus_getinfo_helper_single(rs)); smartlist_add(statuses, networkstatus_getinfo_helper_single(rs));
}); });
*answer = smartlist_join_strings(statuses, "", 0, NULL); *answer = smartlist_join_strings(statuses, "", 0, NULL);
@ -1673,7 +1665,7 @@ getinfo_helper_networkstatus(control_connection_t *conn,
} }
if (status) { if (status) {
*answer = networkstatus_getinfo_helper_single(&status->status); *answer = networkstatus_getinfo_helper_single(status);
} }
return 0; return 0;
} }
@ -1690,8 +1682,8 @@ networkstatus_free_all(void)
networkstatus_list = NULL; networkstatus_list = NULL;
} }
if (routerstatus_list) { if (routerstatus_list) {
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
local_routerstatus_free(rs)); routerstatus_free(rs));
smartlist_free(routerstatus_list); smartlist_free(routerstatus_list);
routerstatus_list = NULL; routerstatus_list = NULL;
} }

View File

@ -1251,28 +1251,23 @@ typedef struct routerstatus_t {
* we can get v3 downloads from. */ * we can get v3 downloads from. */
unsigned int version_supports_v3_dir:1; unsigned int version_supports_v3_dir:1;
/* ---- The fields below aren't derived from the networkstatus; they
* hold local information only. */
/** True if we, as a directory mirror, want to download the corresponding /** True if we, as a directory mirror, want to download the corresponding
* routerinfo from the authority who gave us this routerstatus. (That is, * routerinfo from the authority who gave us this routerstatus. (That is,
* if we don't have the routerinfo, and if we haven't already tried to get it * if we don't have the routerinfo, and if we haven't already tried to get it
* from this authority.) * from this authority.)
*/ */
unsigned int need_to_mirror:1; unsigned int need_to_mirror:1;
} routerstatus_t;
/** Our "local" or combined view of the info from all networkstatus objects
* about a single router. */
typedef struct local_routerstatus_t {
/** What do we believe to be the case about this router? In this field,
* descriptor_digest represents the descriptor we would most like to use for
* this router. */
routerstatus_t status;
time_t last_dir_503_at; /**< When did this router last tell us that it
* was too busy to serve directory info? */
download_status_t dl_status;
unsigned int name_lookup_warned:1; /**< Have we warned the user for referring unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
* to this (unnamed) router by nickname? * to this (unnamed) router by nickname?
*/ */
} local_routerstatus_t; time_t last_dir_503_at; /**< When did this router last tell us that it
* was too busy to serve directory info? */
download_status_t dl_status;
} routerstatus_t;
/** How many times will we try to download a router's descriptor before giving /** How many times will we try to download a router's descriptor before giving
* up? */ * up? */
@ -2732,7 +2727,7 @@ int control_event_or_authdir_new_descriptor(const char *action,
const char *msg); const char *msg);
int control_event_my_descriptor_changed(void); int control_event_my_descriptor_changed(void);
int control_event_networkstatus_changed(smartlist_t *statuses); int control_event_networkstatus_changed(smartlist_t *statuses);
int control_event_networkstatus_changed_single(local_routerstatus_t *rs); int control_event_networkstatus_changed_single(routerstatus_t *rs);
int control_event_general_status(int severity, const char *format, ...) int control_event_general_status(int severity, const char *format, ...)
CHECK_PRINTF(2,3); CHECK_PRINTF(2,3);
int control_event_client_status(int severity, const char *format, ...) int control_event_client_status(int severity, const char *format, ...)
@ -3057,9 +3052,8 @@ const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
void routerstatus_list_update_from_networkstatus(time_t now); void routerstatus_list_update_from_networkstatus(time_t now);
void networkstatus_free_all(void); void networkstatus_free_all(void);
local_routerstatus_t *router_get_combined_status_by_nickname( routerstatus_t *router_get_combined_status_by_nickname(const char *nickname,
const char *nickname, int warn_if_unnamed);
int warn_if_unnamed);
void routerstatus_free(routerstatus_t *routerstatus); void routerstatus_free(routerstatus_t *routerstatus);
void networkstatus_free(networkstatus_t *networkstatus); void networkstatus_free(networkstatus_t *networkstatus);
@ -3467,7 +3461,7 @@ typedef struct trusted_dir_server_t {
int n_networkstatus_failures; /**< How many times have we asked for this int n_networkstatus_failures; /**< How many times have we asked for this
* server's network-status unsuccessfully? */ * server's network-status unsuccessfully? */
local_routerstatus_t fake_status; /**< Used when we need to pass this trusted routerstatus_t fake_status; /**< Used when we need to pass this trusted
* dir_server_t to directory_initiate_command_* * dir_server_t to directory_initiate_command_*
* as a routerstatus_t. Not updated by the * as a routerstatus_t. Not updated by the
* router-status management code! * router-status management code!
@ -3574,9 +3568,9 @@ void add_trusted_dir_server(const char *nickname, const char *address,
void clear_trusted_dir_servers(void); void clear_trusted_dir_servers(void);
int any_trusted_dir_is_v1_authority(void); int any_trusted_dir_is_v1_authority(void);
networkstatus_t *networkstatus_get_by_digest(const char *digest); networkstatus_t *networkstatus_get_by_digest(const char *digest);
local_routerstatus_t *router_get_combined_status_by_digest(const char *digest); routerstatus_t *router_get_combined_status_by_digest(const char *digest);
local_routerstatus_t *router_get_combined_status_by_descriptor_digest( routerstatus_t *router_get_combined_status_by_descriptor_digest(
const char *digest); const char *digest);
//routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest); //routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest);
int should_delay_dir_fetches(or_options_t *options); int should_delay_dir_fetches(or_options_t *options);

View File

@ -825,11 +825,10 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
overloaded_tunnel = smartlist_create(); overloaded_tunnel = smartlist_create();
/* Find all the running dirservers we know about. */ /* Find all the running dirservers we know about. */
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, _local_status, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, status,
{ {
routerstatus_t *status = &(_local_status->status);
int is_trusted; int is_trusted;
int is_overloaded = _local_status->last_dir_503_at + DIR_503_TIMEOUT > now; int is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
if (!status->is_running || !status->dir_port || !status->is_valid) if (!status->is_running || !status->dir_port || !status->is_valid)
continue; continue;
if (status->is_bad_directory) if (status->is_bad_directory)
@ -928,11 +927,11 @@ router_pick_trusteddirserver_impl(authority_type_t type,
(!fascistfirewall || (!fascistfirewall ||
fascist_firewall_allows_address_or(d->addr, d->or_port))) fascist_firewall_allows_address_or(d->addr, d->or_port)))
smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, smartlist_add(is_overloaded ? overloaded_tunnel : tunnel,
&d->fake_status.status); &d->fake_status);
else if (!fascistfirewall || else if (!fascistfirewall ||
fascist_firewall_allows_address_dir(d->addr, d->dir_port)) fascist_firewall_allows_address_dir(d->addr, d->dir_port))
smartlist_add(is_overloaded ? overloaded_direct : direct, smartlist_add(is_overloaded ? overloaded_direct : direct,
&d->fake_status.status); &d->fake_status);
}); });
if (smartlist_len(tunnel)) { if (smartlist_len(tunnel)) {
@ -966,13 +965,13 @@ mark_all_trusteddirservers_up(void)
if (trusted_dir_servers) { if (trusted_dir_servers) {
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, dir, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, dir,
{ {
local_routerstatus_t *rs; routerstatus_t *rs;
dir->is_running = 1; dir->is_running = 1;
dir->n_networkstatus_failures = 0; dir->n_networkstatus_failures = 0;
dir->fake_status.last_dir_503_at = 0; dir->fake_status.last_dir_503_at = 0;
rs = router_get_combined_status_by_digest(dir->digest); rs = router_get_combined_status_by_digest(dir->digest);
if (rs && !rs->status.is_running) { if (rs && !rs->is_running) {
rs->status.is_running = 1; rs->is_running = 1;
rs->last_dir_503_at = 0; rs->last_dir_503_at = 0;
control_event_networkstatus_changed_single(rs); control_event_networkstatus_changed_single(rs);
} }
@ -1670,7 +1669,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
int any_unwarned = 0; int any_unwarned = 0;
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router, SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
{ {
local_routerstatus_t *rs; routerstatus_t *rs;
char *desc; char *desc;
size_t dlen; size_t dlen;
char fp[HEX_DIGEST_LEN+1]; char fp[HEX_DIGEST_LEN+1];
@ -1702,7 +1701,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp)); SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp));
smartlist_free(fps); smartlist_free(fps);
} else if (warn_if_unnamed) { } else if (warn_if_unnamed) {
local_routerstatus_t *rs = router_get_combined_status_by_digest( routerstatus_t *rs = router_get_combined_status_by_digest(
best_match->cache_info.identity_digest); best_match->cache_info.identity_digest);
if (rs && !rs->name_lookup_warned) { if (rs && !rs->name_lookup_warned) {
char fp[HEX_DIGEST_LEN+1]; char fp[HEX_DIGEST_LEN+1];
@ -2443,7 +2442,7 @@ void
router_set_status(const char *digest, int up) router_set_status(const char *digest, int up)
{ {
routerinfo_t *router; routerinfo_t *router;
local_routerstatus_t *status; routerstatus_t *status;
tor_assert(digest); tor_assert(digest);
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d, SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
@ -2460,8 +2459,8 @@ router_set_status(const char *digest, int up)
router->is_running = up; router->is_running = up;
} }
status = router_get_combined_status_by_digest(digest); status = router_get_combined_status_by_digest(digest);
if (status && status->status.is_running != up) { if (status && status->is_running != up) {
status->status.is_running = up; status->is_running = up;
control_event_networkstatus_changed_single(status); control_event_networkstatus_changed_single(status);
} }
router_dir_info_changed(); router_dir_info_changed();
@ -3193,18 +3192,18 @@ add_trusted_dir_server(const char *nickname, const char *address,
tor_snprintf(ent->description, dlen, "directory server at %s:%d", tor_snprintf(ent->description, dlen, "directory server at %s:%d",
hostname, (int)dir_port); hostname, (int)dir_port);
ent->fake_status.status.addr = ent->addr; ent->fake_status.addr = ent->addr;
memcpy(ent->fake_status.status.identity_digest, digest, DIGEST_LEN); memcpy(ent->fake_status.identity_digest, digest, DIGEST_LEN);
if (nickname) if (nickname)
strlcpy(ent->fake_status.status.nickname, nickname, strlcpy(ent->fake_status.nickname, nickname,
sizeof(ent->fake_status.status.nickname)); sizeof(ent->fake_status.nickname));
else else
ent->fake_status.status.nickname[0] = '\0'; ent->fake_status.nickname[0] = '\0';
ent->fake_status.status.dir_port = ent->dir_port; ent->fake_status.dir_port = ent->dir_port;
ent->fake_status.status.or_port = ent->or_port; ent->fake_status.or_port = ent->or_port;
if (ent->or_port) if (ent->or_port)
ent->fake_status.status.version_supports_begindir = 1; ent->fake_status.version_supports_begindir = 1;
smartlist_add(trusted_dir_servers, ent); smartlist_add(trusted_dir_servers, ent);
router_dir_info_changed(); router_dir_info_changed();
@ -3470,20 +3469,20 @@ router_list_client_downloadable(void)
list_pending_descriptor_downloads(downloading, 0); list_pending_descriptor_downloads(downloading, 0);
routerstatus_list_update_from_networkstatus(now); routerstatus_list_update_from_networkstatus(now);
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
{ {
routerinfo_t *ri; routerinfo_t *ri;
if (router_get_by_descriptor_digest(rs->status.descriptor_digest)) { if (router_get_by_descriptor_digest(rs->descriptor_digest)) {
/* We have the 'best' descriptor for this router. */ /* We have the 'best' descriptor for this router. */
++n_uptodate; ++n_uptodate;
} else if (!client_would_use_router(&rs->status, now, options)) { } else if (!client_would_use_router(rs, now, options)) {
/* We wouldn't want this descriptor even if we got it. */ /* We wouldn't want this descriptor even if we got it. */
++n_wouldnt_use; ++n_wouldnt_use;
} else if (digestmap_get(downloading, rs->status.descriptor_digest)) { } else if (digestmap_get(downloading, rs->descriptor_digest)) {
/* We're downloading this one now. */ /* We're downloading this one now. */
++n_in_progress; ++n_in_progress;
} else if ((ri = router_get_by_digest(rs->status.identity_digest)) && } else if ((ri = router_get_by_digest(rs->identity_digest)) &&
ri->cache_info.published_on > rs->status.published_on) { ri->cache_info.published_on > rs->published_on) {
/* Oddly, we have a descriptor more recent than the 'best' one, but it /* Oddly, we have a descriptor more recent than the 'best' one, but it
was once best. So that's okay. */ was once best. So that's okay. */
++n_uptodate; ++n_uptodate;
@ -3492,7 +3491,7 @@ router_list_client_downloadable(void)
++n_not_ready; ++n_not_ready;
} else { } else {
/* Okay, time to try it. */ /* Okay, time to try it. */
smartlist_add(downloadable, rs->status.descriptor_digest); smartlist_add(downloadable, rs->descriptor_digest);
++n_downloadable; ++n_downloadable;
} }
}); });
@ -3756,7 +3755,7 @@ update_router_descriptor_cache_downloads(time_t now)
log_info(LD_DIR, "Requesting %d descriptors from authority \"%s\"", log_info(LD_DIR, "Requesting %d descriptors from authority \"%s\"",
smartlist_len(dl), ds->nickname); smartlist_len(dl), ds->nickname);
for (j=0; j < smartlist_len(dl); j += MAX_DL_PER_REQUEST) { for (j=0; j < smartlist_len(dl); j += MAX_DL_PER_REQUEST) {
initiate_descriptor_downloads(&(ds->fake_status.status), initiate_descriptor_downloads(&(ds->fake_status),
DIR_PURPOSE_FETCH_SERVERDESC, dl, j, DIR_PURPOSE_FETCH_SERVERDESC, dl, j,
j+MAX_DL_PER_REQUEST); j+MAX_DL_PER_REQUEST);
} }
@ -3966,9 +3965,9 @@ update_router_have_minimum_dir_info(void)
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns, SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
tot += routerstatus_count_usable_entries(ns->entries)); tot += routerstatus_count_usable_entries(ns->entries));
avg = tot / n_ns; avg = tot / n_ns;
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
{ {
if (rs->status.is_running) if (rs->is_running)
num_running++; num_running++;
}); });
res = smartlist_len(routerlist->routers) >= (avg/4) && num_running > 2; res = smartlist_len(routerlist->routers) >= (avg/4) && num_running > 2;
@ -3996,7 +3995,7 @@ router_reset_descriptor_download_failures(void)
{ {
const smartlist_t *networkstatus_list = networkstatus_get_v2_list(); const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
const smartlist_t *routerstatus_list = networkstatus_get_all_statuses(); const smartlist_t *routerstatus_list = networkstatus_get_all_statuses();
SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, rs, SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
{ {
rs->dl_status.n_download_failures = 0; rs->dl_status.n_download_failures = 0;
rs->dl_status.next_attempt_at = 0; rs->dl_status.next_attempt_at = 0;