mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
r15806@catbus: nickm | 2007-10-15 19:14:57 -0400
Implement v3 networkstatus client code. Remove v2 networkstatus client code, except as needed for caches to fetch and serve v2 networkstatues and the routers they list. svn:r11957
This commit is contained in:
parent
95f6265a79
commit
3ad6dc0e2e
@ -1,4 +1,9 @@
|
|||||||
Changes in version 0.2.0.9-alpha - 2007-10-??
|
Changes in version 0.2.0.9-alpha - 2007-10-??
|
||||||
|
o Major features (v3 directory system):
|
||||||
|
- Clients now download v3 consensus networkstatus documents instead
|
||||||
|
of v2 networkstatus documents. Clients and caches now their opinions
|
||||||
|
about routers on these consensus documents. Clients only download
|
||||||
|
router descriptors listed in the consensus.
|
||||||
|
|
||||||
o Major bugfixes:
|
o Major bugfixes:
|
||||||
- Stop publishing a new server descriptor just because we HUP or
|
- Stop publishing a new server descriptor just because we HUP or
|
||||||
|
25
doc/TODO
25
doc/TODO
@ -69,8 +69,29 @@ Things we'd like to do in 0.2.0.x:
|
|||||||
- Enable for non-caches
|
- Enable for non-caches
|
||||||
- Code to use v3 networkstatus documents once clients are
|
- Code to use v3 networkstatus documents once clients are
|
||||||
fetching them
|
fetching them
|
||||||
- Implement
|
o Make everybody download v3 networkstatus docs.
|
||||||
- Enable
|
o Make clients not download v2 networkstatus docs.
|
||||||
|
o Make everybody download routerdescs based on v3 networkstatus
|
||||||
|
docs.
|
||||||
|
o Change definition of "have enough information to build circuits"
|
||||||
|
o Base version sanity check on v3 ns.
|
||||||
|
o Change routerstatus_get_by_* to use v3 networkstatus docs.
|
||||||
|
o Make download_status_get_by_descriptor_digest() use v2
|
||||||
|
networkstatus docs too.
|
||||||
|
o Eliminate routerstatus_list.
|
||||||
|
o Make routers_update_all_from_networkstatus() [or equivalent]
|
||||||
|
get called at the right time.
|
||||||
|
o Make routersstatus_list_update_from_consensus_networkstatus()
|
||||||
|
get renamed and called.
|
||||||
|
o When setting a new consensus, copy the extra fields out of the
|
||||||
|
old consensus (if any).
|
||||||
|
o Update named-server-map as appropriate.
|
||||||
|
- Fix all XXXX020s.
|
||||||
|
- Sort out need_to_mirror
|
||||||
|
- Work hard to make sure clients never look at v2 networkstatus docs.
|
||||||
|
- Check in old_routers before fetching a router status. You never
|
||||||
|
know if we'll flap...
|
||||||
|
|
||||||
- Controller support
|
- Controller support
|
||||||
- GETINFO to get consensus
|
- GETINFO to get consensus
|
||||||
- Event when new consensus arrives
|
- Event when new consensus arrives
|
||||||
|
@ -1609,33 +1609,38 @@ getinfo_helper_events(control_connection_t *control_conn,
|
|||||||
check_whether_orport_reachable() ? 1 : 0,
|
check_whether_orport_reachable() ? 1 : 0,
|
||||||
check_whether_dirport_reachable() ? 1 : 0);
|
check_whether_dirport_reachable() ? 1 : 0);
|
||||||
} else if (!strcmpstart(question, "status/version/")) {
|
} else if (!strcmpstart(question, "status/version/")) {
|
||||||
combined_version_status_t st;
|
|
||||||
int is_server = server_mode(get_options());
|
int is_server = server_mode(get_options());
|
||||||
char *recommended;
|
networkstatus_vote_t *c = networkstatus_get_latest_consensus();
|
||||||
recommended = compute_recommended_versions(time(NULL),
|
version_status_t status;
|
||||||
!is_server, VERSION, &st);
|
const char *recommended;
|
||||||
|
if (c) {
|
||||||
|
recommended = is_server ? c->server_versions : c->client_versions;
|
||||||
|
status = tor_version_is_obsolete(VERSION, recommended);
|
||||||
|
} else {
|
||||||
|
recommended = "?";
|
||||||
|
status = VS_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(question, "status/version/recommended")) {
|
if (!strcmp(question, "status/version/recommended")) {
|
||||||
*answer = recommended;
|
*answer = tor_strdup(recommended);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tor_free(recommended);
|
|
||||||
if (!strcmp(question, "status/version/current")) {
|
if (!strcmp(question, "status/version/current")) {
|
||||||
switch (st.consensus)
|
switch (status)
|
||||||
{
|
{
|
||||||
case VS_RECOMMENDED: *answer = tor_strdup("recommended"); break;
|
case VS_RECOMMENDED: *answer = tor_strdup("recommended"); break;
|
||||||
case VS_OLD: *answer = tor_strdup("obsolete"); break;
|
case VS_OLD: *answer = tor_strdup("obsolete"); break;
|
||||||
case VS_NEW: *answer = tor_strdup("new"); break;
|
case VS_NEW: *answer = tor_strdup("new"); break;
|
||||||
case VS_NEW_IN_SERIES: *answer = tor_strdup("new in series"); break;
|
case VS_NEW_IN_SERIES: *answer = tor_strdup("new in series"); break;
|
||||||
case VS_UNRECOMMENDED: *answer = tor_strdup("unrecommended"); break;
|
case VS_UNRECOMMENDED: *answer = tor_strdup("unrecommended"); break;
|
||||||
|
case VS_UNKNOWN: *answer = tor_strdup("unknown"); break;
|
||||||
default: tor_fragile_assert();
|
default: tor_fragile_assert();
|
||||||
}
|
}
|
||||||
} else if (!strcmp(question, "status/version/num-versioning")) {
|
} else if (!strcmp(question, "status/version/num-versioning") ||
|
||||||
|
!strcmp(question, "status/version/num-concurring")) {
|
||||||
|
/*XXXX020 deprecate.*/
|
||||||
char s[33];
|
char s[33];
|
||||||
tor_snprintf(s, sizeof(s), "%d", st.n_versioning);
|
tor_snprintf(s, sizeof(s), "%d", get_n_authorities(V3_AUTHORITY));
|
||||||
*answer = tor_strdup(s);
|
|
||||||
} else if (!strcmp(question, "status/version/num-concurring")) {
|
|
||||||
char s[33];
|
|
||||||
tor_snprintf(s, sizeof(s), "%d", st.n_concurring);
|
|
||||||
*answer = tor_strdup(s);
|
*answer = tor_strdup(s);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,7 +178,7 @@ router_supports_extrainfo(const char *identity_digest, int is_authority)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (is_authority) {
|
if (is_authority) {
|
||||||
routerstatus_t *rs = router_get_combined_status_by_digest(identity_digest);
|
routerstatus_t *rs = router_get_consensus_status_by_id(identity_digest);
|
||||||
if (rs && rs->version_supports_extrainfo_upload)
|
if (rs && rs->version_supports_extrainfo_upload)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1232,7 +1232,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
"'%s:%d'. I'll try again soon.",
|
"'%s:%d'. I'll try again soon.",
|
||||||
status_code, escaped(reason), conn->_base.address,
|
status_code, escaped(reason), conn->_base.address,
|
||||||
conn->_base.port);
|
conn->_base.port);
|
||||||
if ((rs = router_get_combined_status_by_digest(conn->identity_digest)))
|
if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
|
||||||
rs->last_dir_503_at = now;
|
rs->last_dir_503_at = now;
|
||||||
if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
|
if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
|
||||||
ds->fake_status.last_dir_503_at = now;
|
ds->fake_status.last_dir_503_at = now;
|
||||||
@ -1387,7 +1387,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
if (next)
|
if (next)
|
||||||
next[1] = '\0';
|
next[1] = '\0';
|
||||||
/* learn from it, and then remove it from 'which' */
|
/* learn from it, and then remove it from 'which' */
|
||||||
if (router_set_networkstatus(cp, now, source, which)<0)
|
if (router_set_networkstatus_v2(cp, now, source, which)<0)
|
||||||
break;
|
break;
|
||||||
if (next) {
|
if (next) {
|
||||||
next[1] = 'n';
|
next[1] = 'n';
|
||||||
@ -1426,6 +1426,8 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
networkstatus_consensus_download_failed(0);
|
networkstatus_consensus_download_failed(0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
routers_update_all_from_networkstatus(now); /*launches router downloads*/
|
||||||
|
directory_info_has_arrived(now, 0);
|
||||||
log_info(LD_DIR, "Successfully loaded consensus.");
|
log_info(LD_DIR, "Successfully loaded consensus.");
|
||||||
}
|
}
|
||||||
if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
|
if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
|
||||||
@ -2790,10 +2792,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 {
|
||||||
routerstatus_t *rs =
|
dls = router_get_dl_status_by_descriptor_digest(digest);
|
||||||
router_get_combined_status_by_descriptor_digest(digest);
|
|
||||||
if (rs)
|
|
||||||
dls = &rs->dl_status;
|
|
||||||
}
|
}
|
||||||
if (!dls || dls->n_download_failures >= MAX_ROUTERDESC_DOWNLOAD_FAILURES)
|
if (!dls || dls->n_download_failures >= MAX_ROUTERDESC_DOWNLOAD_FAILURES)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2380,12 +2380,12 @@ generate_networkstatus_opinion(int v2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
networkstatus_t *ns;
|
networkstatus_v2_t *ns;
|
||||||
if (!(ns = networkstatus_parse_from_string(status))) {
|
if (!(ns = networkstatus_v2_parse_from_string(status))) {
|
||||||
log_err(LD_BUG,"Generated a networkstatus we couldn't parse.");
|
log_err(LD_BUG,"Generated a networkstatus we couldn't parse.");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
networkstatus_free(ns);
|
networkstatus_v2_free(ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -2395,7 +2395,7 @@ generate_networkstatus_opinion(int v2)
|
|||||||
*ns_ptr = new_cached_dir(status, now);
|
*ns_ptr = new_cached_dir(status, now);
|
||||||
status = NULL; /* So it doesn't get double-freed. */
|
status = NULL; /* So it doesn't get double-freed. */
|
||||||
the_v2_networkstatus_is_dirty = 0;
|
the_v2_networkstatus_is_dirty = 0;
|
||||||
router_set_networkstatus((*ns_ptr)->dir, now, NS_GENERATED, NULL);
|
router_set_networkstatus_v2((*ns_ptr)->dir, now, NS_GENERATED, NULL);
|
||||||
r = *ns_ptr;
|
r = *ns_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ networkstatus_vote_free(networkstatus_vote_t *ns)
|
|||||||
|
|
||||||
smartlist_free(ns->routerstatus_list);
|
smartlist_free(ns->routerstatus_list);
|
||||||
}
|
}
|
||||||
|
if (ns->desc_digest_map)
|
||||||
|
digestmap_free(ns->desc_digest_map, NULL);
|
||||||
|
|
||||||
memset(ns, 11, sizeof(*ns));
|
memset(ns, 11, sizeof(*ns));
|
||||||
tor_free(ns);
|
tor_free(ns);
|
||||||
|
@ -547,7 +547,6 @@ accounting_set_wakeup_time(void)
|
|||||||
|
|
||||||
/* This rounds 0 up to 1000, but that's actually a feature. */
|
/* This rounds 0 up to 1000, but that's actually a feature. */
|
||||||
#define ROUND_UP(x) (((x) + 0x3ff) & ~0x3ff)
|
#define ROUND_UP(x) (((x) + 0x3ff) & ~0x3ff)
|
||||||
#define BW_ACCOUNTING_VERSION 1
|
|
||||||
/** Save all our bandwidth tracking information to disk. Return 0 on
|
/** Save all our bandwidth tracking information to disk. Return 0 on
|
||||||
* success, -1 on failure. */
|
* success, -1 on failure. */
|
||||||
int
|
int
|
||||||
|
@ -995,9 +995,10 @@ run_scheduled_events(time_t now)
|
|||||||
* update all the descriptors' running status. */
|
* update all the descriptors' running status. */
|
||||||
/* purge obsolete entries */
|
/* purge obsolete entries */
|
||||||
routerlist_remove_old_routers();
|
routerlist_remove_old_routers();
|
||||||
networkstatus_list_clean(now);
|
networkstatus_v2_list_clean(now);
|
||||||
networkstatus_list_update_recent(now);
|
#if 0
|
||||||
routers_update_all_from_networkstatus(now);
|
networkstatus_v2_list_update_recent(now);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Also, once per minute, check whether we want to download any
|
/* Also, once per minute, check whether we want to download any
|
||||||
* networkstatus documents.
|
* networkstatus documents.
|
||||||
@ -1339,6 +1340,14 @@ do_main_loop(void)
|
|||||||
stats_prev_global_read_bucket = global_read_bucket;
|
stats_prev_global_read_bucket = global_read_bucket;
|
||||||
stats_prev_global_write_bucket = global_write_bucket;
|
stats_prev_global_write_bucket = global_write_bucket;
|
||||||
|
|
||||||
|
if (trusted_dirs_reload_certs())
|
||||||
|
return -1;
|
||||||
|
if (router_reload_v2_networkstatus()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (router_reload_consensus_networkstatus()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* load the routers file, or assign the defaults. */
|
/* load the routers file, or assign the defaults. */
|
||||||
if (router_reload_router_list()) {
|
if (router_reload_router_list()) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -1346,12 +1355,6 @@ do_main_loop(void)
|
|||||||
/* load the networkstatuses. (This launches a download for new routers as
|
/* load the networkstatuses. (This launches a download for new routers as
|
||||||
* appropriate.)
|
* appropriate.)
|
||||||
*/
|
*/
|
||||||
if (router_reload_networkstatus()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (router_reload_consensus_networkstatus()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
directory_info_has_arrived(now, 1);
|
directory_info_has_arrived(now, 1);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
81
src/or/or.h
81
src/or/or.h
@ -120,12 +120,6 @@
|
|||||||
#define cell_t tor_cell_t
|
#define cell_t tor_cell_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Undefine this when it's time to stop generating v1 directories. */
|
|
||||||
// #define FULL_V1_DIRECTORIES
|
|
||||||
/** Undefine this when it's time to stop includeing bandwidth info in router
|
|
||||||
* descriptors. */
|
|
||||||
#define INCLUDE_BW_INFO_IN_ROUTERDESCS
|
|
||||||
|
|
||||||
/** Length of longest allowable configured nickname. */
|
/** Length of longest allowable configured nickname. */
|
||||||
#define MAX_NICKNAME_LEN 19
|
#define MAX_NICKNAME_LEN 19
|
||||||
/** Length of a router identity encoded as a hexadecimal digest, plus
|
/** Length of a router identity encoded as a hexadecimal digest, plus
|
||||||
@ -172,8 +166,6 @@
|
|||||||
#define ROUTER_MAX_AGE_TO_PUBLISH (60*60*20)
|
#define ROUTER_MAX_AGE_TO_PUBLISH (60*60*20)
|
||||||
/** How old do we let a saved descriptor get before force-removing it? */
|
/** How old do we let a saved descriptor get before force-removing it? */
|
||||||
#define OLD_ROUTER_DESC_MAX_AGE (60*60*24*5)
|
#define OLD_ROUTER_DESC_MAX_AGE (60*60*24*5)
|
||||||
/** How old do we let a networkstatus get before ignoring it? */
|
|
||||||
#define NETWORKSTATUS_MAX_AGE (60*60*24)
|
|
||||||
|
|
||||||
/** Possible rules for generating circuit IDs on an OR connection. */
|
/** Possible rules for generating circuit IDs on an OR connection. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -342,26 +334,24 @@ typedef enum {
|
|||||||
#define DIR_PURPOSE_UPLOAD_RENDDESC 9
|
#define DIR_PURPOSE_UPLOAD_RENDDESC 9
|
||||||
/** A connection to a directory server: upload a v3 networkstatus vote. */
|
/** A connection to a directory server: upload a v3 networkstatus vote. */
|
||||||
#define DIR_PURPOSE_UPLOAD_VOTE 10
|
#define DIR_PURPOSE_UPLOAD_VOTE 10
|
||||||
/** A connection to a directory server: fetch a v3 networkstatus vote. */
|
|
||||||
#define DIR_PURPOSE_FETCH_VOTE 11
|
|
||||||
/** A connection to a directory server: upload a v3 consensus signature */
|
/** A connection to a directory server: upload a v3 consensus signature */
|
||||||
#define DIR_PURPOSE_UPLOAD_SIGNATURES 12
|
#define DIR_PURPOSE_UPLOAD_SIGNATURES 11
|
||||||
/** A connection to a directory server: download one or more network-status
|
/** A connection to a directory server: download one or more network-status
|
||||||
* objects */
|
* objects */
|
||||||
#define DIR_PURPOSE_FETCH_STATUS_VOTE 13
|
#define DIR_PURPOSE_FETCH_STATUS_VOTE 12
|
||||||
/** A connection to a directory server: download one or more network-status
|
/** A connection to a directory server: download one or more network-status
|
||||||
* objects */
|
* objects */
|
||||||
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 14
|
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 13
|
||||||
/** A connection to a directory server: download one or more network-status
|
/** A connection to a directory server: download one or more network-status
|
||||||
* objects */
|
* objects */
|
||||||
#define DIR_PURPOSE_FETCH_CONSENSUS 15
|
#define DIR_PURPOSE_FETCH_CONSENSUS 14
|
||||||
/** A connection to a directory server: download one or more network-status
|
/** A connection to a directory server: download one or more network-status
|
||||||
* objects */
|
* objects */
|
||||||
#define DIR_PURPOSE_FETCH_CERTIFICATE 16
|
#define DIR_PURPOSE_FETCH_CERTIFICATE 15
|
||||||
|
|
||||||
/** Purpose for connection at a directory server. */
|
/** Purpose for connection at a directory server. */
|
||||||
#define DIR_PURPOSE_SERVER 17
|
#define DIR_PURPOSE_SERVER 16
|
||||||
#define _DIR_PURPOSE_MAX 17
|
#define _DIR_PURPOSE_MAX 16
|
||||||
|
|
||||||
#define _EXIT_PURPOSE_MIN 1
|
#define _EXIT_PURPOSE_MIN 1
|
||||||
/** This exit stream wants to do an ordinary connect. */
|
/** This exit stream wants to do an ordinary connect. */
|
||||||
@ -1274,7 +1264,7 @@ typedef struct routerstatus_t {
|
|||||||
#define MAX_ROUTERDESC_DOWNLOAD_FAILURES 8
|
#define MAX_ROUTERDESC_DOWNLOAD_FAILURES 8
|
||||||
|
|
||||||
/** Contents of a v2 (non-consensus, non-vote) network status object. */
|
/** Contents of a v2 (non-consensus, non-vote) network status object. */
|
||||||
typedef struct networkstatus_t {
|
typedef struct networkstatus_v2_t {
|
||||||
/** When did we receive the network-status document? */
|
/** When did we receive the network-status document? */
|
||||||
time_t received_on;
|
time_t received_on;
|
||||||
|
|
||||||
@ -1312,7 +1302,7 @@ typedef struct networkstatus_t {
|
|||||||
|
|
||||||
smartlist_t *entries; /**< List of routerstatus_t*. This list is kept
|
smartlist_t *entries; /**< List of routerstatus_t*. This list is kept
|
||||||
* sorted by identity_digest. */
|
* sorted by identity_digest. */
|
||||||
} networkstatus_t;
|
} networkstatus_v2_t;
|
||||||
|
|
||||||
/** The claim about a single router, make in a vote. */
|
/** The claim about a single router, make in a vote. */
|
||||||
typedef struct vote_routerstatus_t {
|
typedef struct vote_routerstatus_t {
|
||||||
@ -1385,6 +1375,10 @@ typedef struct networkstatus_vote_t {
|
|||||||
* the elements are vote_routerstatus_t; for a consensus, the elements
|
* the elements are vote_routerstatus_t; for a consensus, the elements
|
||||||
* are routerstatus_t. */
|
* are routerstatus_t. */
|
||||||
smartlist_t *routerstatus_list;
|
smartlist_t *routerstatus_list;
|
||||||
|
|
||||||
|
/** If present, a map from descriptor digest to elements of
|
||||||
|
* routerstatus_list. */
|
||||||
|
digestmap_t *desc_digest_map;
|
||||||
} networkstatus_vote_t;
|
} networkstatus_vote_t;
|
||||||
|
|
||||||
/** A set of signatures for a networkstatus consensus. All fields are as for
|
/** A set of signatures for a networkstatus consensus. All fields are as for
|
||||||
@ -1466,7 +1460,6 @@ typedef struct extend_info_t {
|
|||||||
* display. */
|
* display. */
|
||||||
char identity_digest[DIGEST_LEN]; /**< Hash of this router's identity key. */
|
char identity_digest[DIGEST_LEN]; /**< Hash of this router's identity key. */
|
||||||
uint16_t port; /**< OR port. */
|
uint16_t port; /**< OR port. */
|
||||||
// uint8_t router_purpose; /**< General, controller, or bridge. */
|
|
||||||
uint32_t addr; /**< IP address in host order. */
|
uint32_t addr; /**< IP address in host order. */
|
||||||
crypto_pk_env_t *onion_key; /**< Current onionskin key. */
|
crypto_pk_env_t *onion_key; /**< Current onionskin key. */
|
||||||
} extend_info_t;
|
} extend_info_t;
|
||||||
@ -2310,7 +2303,6 @@ extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
|
|||||||
crypto_pk_env_t *onion_key,
|
crypto_pk_env_t *onion_key,
|
||||||
uint32_t addr, uint16_t port);
|
uint32_t addr, uint16_t port);
|
||||||
extend_info_t *extend_info_from_router(routerinfo_t *r);
|
extend_info_t *extend_info_from_router(routerinfo_t *r);
|
||||||
//extend_info_t *extend_info_from_routerstatus(routerstatus_t *s);
|
|
||||||
extend_info_t *extend_info_dup(extend_info_t *info);
|
extend_info_t *extend_info_dup(extend_info_t *info);
|
||||||
void extend_info_free(extend_info_t *info);
|
void extend_info_free(extend_info_t *info);
|
||||||
routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
|
routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
|
||||||
@ -3058,52 +3050,43 @@ typedef enum version_status_t {
|
|||||||
VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
|
VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
|
||||||
* in its series, but later recommended versions exist.
|
* in its series, but later recommended versions exist.
|
||||||
*/
|
*/
|
||||||
VS_UNRECOMMENDED=4 /**< This version is not recommended (general case). */
|
VS_UNRECOMMENDED=4, /**< This version is not recommended (general case). */
|
||||||
|
VS_UNKNOWN, /**< We have no idea. */
|
||||||
} version_status_t;
|
} version_status_t;
|
||||||
|
|
||||||
typedef struct combined_version_status_t {
|
|
||||||
/** How many networkstatuses claim to know about versions? */
|
|
||||||
int n_versioning;
|
|
||||||
/** What do the majority of networkstatuses believe about this version? */
|
|
||||||
enum version_status_t consensus;
|
|
||||||
/** How many networkstatuses constitute the majority? */
|
|
||||||
int n_concurring;
|
|
||||||
} combined_version_status_t;
|
|
||||||
|
|
||||||
void networkstatus_reset_warnings(void);
|
void networkstatus_reset_warnings(void);
|
||||||
int router_reload_networkstatus(void);
|
void networkstatus_reset_download_failures(void);
|
||||||
|
int router_reload_v2_networkstatus(void);
|
||||||
int router_reload_consensus_networkstatus(void);
|
int router_reload_consensus_networkstatus(void);
|
||||||
void routerstatus_free(routerstatus_t *rs);
|
void routerstatus_free(routerstatus_t *rs);
|
||||||
void networkstatus_free(networkstatus_t *ns);
|
void networkstatus_v2_free(networkstatus_v2_t *ns);
|
||||||
char *networkstatus_get_cache_filename(const char *identity_digest);
|
char *networkstatus_get_cache_filename(const char *identity_digest);
|
||||||
int router_set_networkstatus(const char *s, time_t arrived_at,
|
int router_set_networkstatus_v2(const char *s, time_t arrived_at,
|
||||||
networkstatus_source_t source,
|
networkstatus_source_t source,
|
||||||
smartlist_t *requested_fingerprints);
|
smartlist_t *requested_fingerprints);
|
||||||
void networkstatus_list_clean(time_t now);
|
void networkstatus_v2_list_clean(time_t now);
|
||||||
routerstatus_t *networkstatus_find_entry(networkstatus_t *ns,
|
routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
|
||||||
const char *digest);
|
const char *digest);
|
||||||
|
routerstatus_t *networkstatus_vote_find_entry(networkstatus_vote_t *ns,
|
||||||
|
const char *digest);
|
||||||
const smartlist_t *networkstatus_get_v2_list(void);
|
const smartlist_t *networkstatus_get_v2_list(void);
|
||||||
const smartlist_t *networkstatus_get_all_statuses(void);
|
download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
|
||||||
routerstatus_t *router_get_combined_status_by_digest(const char *digest);
|
routerstatus_t *router_get_consensus_status_by_id(const char *digest);
|
||||||
routerstatus_t *router_get_combined_status_by_descriptor_digest(const char *d);
|
routerstatus_t *router_get_consensus_status_by_descriptor_digest(
|
||||||
routerstatus_t *router_get_combined_status_by_nickname(const char *nickname,
|
const char *digest);
|
||||||
|
routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
|
||||||
int warn_if_unnamed);
|
int warn_if_unnamed);
|
||||||
const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
|
const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
|
||||||
routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest);
|
|
||||||
void networkstatus_consensus_download_failed(int status_code);
|
void networkstatus_consensus_download_failed(int status_code);
|
||||||
int should_delay_dir_fetches(or_options_t *options);
|
int should_delay_dir_fetches(or_options_t *options);
|
||||||
void update_networkstatus_downloads(time_t now);
|
void update_networkstatus_downloads(time_t now);
|
||||||
networkstatus_t *networkstatus_get_by_digest(const char *digest);
|
networkstatus_v2_t *networkstatus_v2_get_by_digest(const char *digest);
|
||||||
networkstatus_vote_t *networkstatus_get_latest_consensus(void);
|
networkstatus_vote_t *networkstatus_get_latest_consensus(void);
|
||||||
networkstatus_vote_t *networkstatus_get_live_consensus(time_t now);
|
networkstatus_vote_t *networkstatus_get_live_consensus(time_t now);
|
||||||
int networkstatus_set_current_consensus(const char *consensus, int from_cache,
|
int networkstatus_set_current_consensus(const char *consensus, int from_cache,
|
||||||
int was_waiting_for_certs);
|
int was_waiting_for_certs);
|
||||||
void networkstatus_note_certs_arrived(void);
|
void networkstatus_note_certs_arrived(void);
|
||||||
void routers_update_all_from_networkstatus(time_t now);
|
void routers_update_all_from_networkstatus(time_t now);
|
||||||
void networkstatus_list_update_recent(time_t now);
|
|
||||||
void routerstatus_list_update_from_networkstatus(time_t now);
|
|
||||||
void routers_update_status_from_networkstatus(smartlist_t *routers,
|
|
||||||
int reset_failures);
|
|
||||||
void routerstatus_list_update_from_consensus_networkstatus(time_t now);
|
void routerstatus_list_update_from_consensus_networkstatus(time_t now);
|
||||||
void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
|
void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
|
||||||
int reset_failures);
|
int reset_failures);
|
||||||
@ -3628,9 +3611,6 @@ void add_trusted_dir_server(const char *nickname, const char *address,
|
|||||||
authority_type_t type);
|
authority_type_t type);
|
||||||
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);
|
||||||
char *compute_recommended_versions(time_t now, int client,
|
|
||||||
const char *my_version,
|
|
||||||
combined_version_status_t *status_out);
|
|
||||||
void update_router_descriptor_downloads(time_t now);
|
void update_router_descriptor_downloads(time_t now);
|
||||||
void update_extrainfo_downloads(time_t now);
|
void update_extrainfo_downloads(time_t now);
|
||||||
int router_have_minimum_dir_info(void);
|
int router_have_minimum_dir_info(void);
|
||||||
@ -3695,7 +3675,6 @@ addr_policy_t *router_parse_addr_policy_from_string(const char *s,
|
|||||||
int assume_action);
|
int assume_action);
|
||||||
version_status_t tor_version_is_obsolete(const char *myversion,
|
version_status_t tor_version_is_obsolete(const char *myversion,
|
||||||
const char *versionlist);
|
const char *versionlist);
|
||||||
version_status_t version_status_join(version_status_t a, version_status_t b);
|
|
||||||
int tor_version_parse(const char *s, tor_version_t *out);
|
int tor_version_parse(const char *s, tor_version_t *out);
|
||||||
int tor_version_as_new_as(const char *platform, const char *cutoff);
|
int tor_version_as_new_as(const char *platform, const char *cutoff);
|
||||||
int tor_version_compare(tor_version_t *a, tor_version_t *b);
|
int tor_version_compare(tor_version_t *a, tor_version_t *b);
|
||||||
@ -3703,7 +3682,7 @@ void sort_version_list(smartlist_t *lst, int remove_duplicates);
|
|||||||
void assert_addr_policy_ok(addr_policy_t *t);
|
void assert_addr_policy_ok(addr_policy_t *t);
|
||||||
void dump_distinct_digest_count(int severity);
|
void dump_distinct_digest_count(int severity);
|
||||||
|
|
||||||
networkstatus_t *networkstatus_parse_from_string(const char *s);
|
networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
|
||||||
networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s,
|
networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s,
|
||||||
const char **eos_out,
|
const char **eos_out,
|
||||||
int is_vote);
|
int is_vote);
|
||||||
|
@ -468,6 +468,7 @@ router_rebuild_store(int force, desc_store_t *store)
|
|||||||
int r = -1;
|
int r = -1;
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
smartlist_t *signed_descriptors = NULL;
|
smartlist_t *signed_descriptors = NULL;
|
||||||
|
int nocache=0;
|
||||||
|
|
||||||
if (!force && !router_should_rebuild_store(store))
|
if (!force && !router_should_rebuild_store(store))
|
||||||
return 0;
|
return 0;
|
||||||
@ -506,11 +507,9 @@ router_rebuild_store(int force, desc_store_t *store)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SMARTLIST_FOREACH(routerlist->old_routers, signed_descriptor_t *, sd,
|
SMARTLIST_FOREACH(routerlist->old_routers, signed_descriptor_t *, sd,
|
||||||
if (desc_get_store(routerlist, sd) == store)
|
smartlist_add(signed_descriptors, sd));
|
||||||
smartlist_add(signed_descriptors, sd));
|
|
||||||
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
|
||||||
if (router_get_store(routerlist, ri) == store)
|
smartlist_add(signed_descriptors, &ri->cache_info));
|
||||||
smartlist_add(signed_descriptors, &ri->cache_info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smartlist_sort(signed_descriptors, _compare_signed_descriptors_by_age);
|
smartlist_sort(signed_descriptors, _compare_signed_descriptors_by_age);
|
||||||
@ -524,8 +523,10 @@ router_rebuild_store(int force, desc_store_t *store)
|
|||||||
log_warn(LD_BUG, "No descriptor available for router.");
|
log_warn(LD_BUG, "No descriptor available for router.");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (sd->do_not_cache)
|
if (sd->do_not_cache) {
|
||||||
|
++nocache;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
c = tor_malloc(sizeof(sized_chunk_t));
|
c = tor_malloc(sizeof(sized_chunk_t));
|
||||||
c->bytes = body;
|
c->bytes = body;
|
||||||
c->len = sd->signed_descriptor_len + sd->annotations_len;
|
c->len = sd->signed_descriptor_len + sd->annotations_len;
|
||||||
@ -549,8 +550,10 @@ router_rebuild_store(int force, desc_store_t *store)
|
|||||||
}
|
}
|
||||||
|
|
||||||
store->mmap = tor_mmap_file(fname);
|
store->mmap = tor_mmap_file(fname);
|
||||||
if (! store->mmap)
|
if (! store->mmap) {
|
||||||
log_warn(LD_FS, "Unable to mmap new descriptor file at '%s'.",fname);
|
log_warn(LD_FS, "Unable to mmap new descriptor file at '%s'.",fname);
|
||||||
|
//tor_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
log_info(LD_DIR, "Reconstructing pointers into cache");
|
log_info(LD_DIR, "Reconstructing pointers into cache");
|
||||||
|
|
||||||
@ -688,8 +691,6 @@ router_reload_router_list(void)
|
|||||||
return -1;
|
return -1;
|
||||||
if (router_reload_router_list_impl(&rl->extrainfo_store))
|
if (router_reload_router_list_impl(&rl->extrainfo_store))
|
||||||
return -1;
|
return -1;
|
||||||
if (trusted_dirs_reload_certs())
|
|
||||||
return -1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,7 +845,10 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
|||||||
smartlist_t *trusted_direct, *trusted_tunnel;
|
smartlist_t *trusted_direct, *trusted_tunnel;
|
||||||
smartlist_t *overloaded_direct, *overloaded_tunnel;
|
smartlist_t *overloaded_direct, *overloaded_tunnel;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
const smartlist_t *routerstatus_list = networkstatus_get_all_statuses();
|
const networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
|
||||||
|
|
||||||
|
if (!consensus)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
direct = smartlist_create();
|
direct = smartlist_create();
|
||||||
tunnel = smartlist_create();
|
tunnel = smartlist_create();
|
||||||
@ -854,7 +858,7 @@ 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, routerstatus_t *, status,
|
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, status,
|
||||||
{
|
{
|
||||||
int is_trusted;
|
int is_trusted;
|
||||||
int is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
|
int is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
|
||||||
@ -997,7 +1001,7 @@ mark_all_trusteddirservers_up(void)
|
|||||||
routerstatus_t *rs;
|
routerstatus_t *rs;
|
||||||
dir->is_running = 1;
|
dir->is_running = 1;
|
||||||
download_status_reset(&dir->v2_ns_dl_status);
|
download_status_reset(&dir->v2_ns_dl_status);
|
||||||
rs = router_get_combined_status_by_digest(dir->digest);
|
rs = router_get_consensus_status_by_id(dir->digest);
|
||||||
if (rs && !rs->is_running) {
|
if (rs && !rs->is_running) {
|
||||||
rs->is_running = 1;
|
rs->is_running = 1;
|
||||||
rs->last_dir_503_at = 0;
|
rs->last_dir_503_at = 0;
|
||||||
@ -1147,7 +1151,7 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
|
|||||||
if (!must_be_running || router->is_running) {
|
if (!must_be_running || router->is_running) {
|
||||||
smartlist_add(sl,router);
|
smartlist_add(sl,router);
|
||||||
}
|
}
|
||||||
} else if (!router_get_combined_status_by_nickname(nick,1)) {
|
} else if (!router_get_consensus_status_by_nickname(nick,1)) {
|
||||||
if (!warned) {
|
if (!warned) {
|
||||||
log_fn(have_dir_info ? LOG_WARN : LOG_INFO, LD_CONFIG,
|
log_fn(have_dir_info ? LOG_WARN : LOG_INFO, LD_CONFIG,
|
||||||
"Nickname list includes '%s' which isn't a known router.",nick);
|
"Nickname list includes '%s' which isn't a known router.",nick);
|
||||||
@ -1714,6 +1718,8 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
|
|||||||
return rimap_get(routerlist->identity_map, named_digest);
|
return rimap_get(routerlist->identity_map, named_digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we reach this point, there's no canonical value for the nickname. */
|
||||||
|
|
||||||
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
{
|
{
|
||||||
if (!strcasecmp(router->nickname, nickname)) {
|
if (!strcasecmp(router->nickname, nickname)) {
|
||||||
@ -1742,7 +1748,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
|
|||||||
char fp[HEX_DIGEST_LEN+1];
|
char fp[HEX_DIGEST_LEN+1];
|
||||||
if (strcasecmp(router->nickname, nickname))
|
if (strcasecmp(router->nickname, nickname))
|
||||||
continue;
|
continue;
|
||||||
rs = router_get_combined_status_by_digest(
|
rs = router_get_consensus_status_by_id(
|
||||||
router->cache_info.identity_digest);
|
router->cache_info.identity_digest);
|
||||||
if (rs && !rs->name_lookup_warned) {
|
if (rs && !rs->name_lookup_warned) {
|
||||||
rs->name_lookup_warned = 1;
|
rs->name_lookup_warned = 1;
|
||||||
@ -1768,7 +1774,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) {
|
||||||
routerstatus_t *rs = router_get_combined_status_by_digest(
|
routerstatus_t *rs = router_get_consensus_status_by_id(
|
||||||
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];
|
||||||
@ -2134,15 +2140,6 @@ dump_routerlist_mem_usage(int severity)
|
|||||||
smartlist_len(routerlist->old_routers), U64_PRINTF_ARG(olddescs));
|
smartlist_len(routerlist->old_routers), U64_PRINTF_ARG(olddescs));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the greatest number of routerdescs we'll hold for any given router.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
max_descriptors_per_router(void)
|
|
||||||
{
|
|
||||||
int n_authorities = get_n_v2_authorities();
|
|
||||||
return (n_authorities < 5) ? 5 : n_authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return non-zero if we have a lot of extra descriptors in our
|
/** Return non-zero if we have a lot of extra descriptors in our
|
||||||
* routerlist, and should get rid of some of them. Else return 0.
|
* routerlist, and should get rid of some of them. Else return 0.
|
||||||
*
|
*
|
||||||
@ -2154,8 +2151,12 @@ max_descriptors_per_router(void)
|
|||||||
static INLINE int
|
static INLINE int
|
||||||
routerlist_is_overfull(routerlist_t *rl)
|
routerlist_is_overfull(routerlist_t *rl)
|
||||||
{
|
{
|
||||||
return smartlist_len(rl->old_routers) >
|
/*XXXX020 no longer wholly logical.*/
|
||||||
smartlist_len(rl->routers)*(max_descriptors_per_router()+1);
|
if (dirserver_mode(get_options())) {
|
||||||
|
return smartlist_len(rl->old_routers) > smartlist_len(rl->routers)*5;
|
||||||
|
} else {
|
||||||
|
return smartlist_len(rl->old_routers) > smartlist_len(rl->routers)*2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE int
|
static INLINE int
|
||||||
@ -2541,7 +2542,7 @@ router_set_status(const char *digest, int up)
|
|||||||
"addresses reachable?");
|
"addresses reachable?");
|
||||||
router->is_running = up;
|
router->is_running = up;
|
||||||
}
|
}
|
||||||
status = router_get_combined_status_by_digest(digest);
|
status = router_get_consensus_status_by_id(digest);
|
||||||
if (status && status->is_running != up) {
|
if (status && status->is_running != up) {
|
||||||
status->is_running = up;
|
status->is_running = up;
|
||||||
control_event_networkstatus_changed_single(status);
|
control_event_networkstatus_changed_single(status);
|
||||||
@ -2574,8 +2575,8 @@ router_set_status(const char *digest, int up)
|
|||||||
* server or via the controller.)
|
* server or via the controller.)
|
||||||
*
|
*
|
||||||
* This function should be called *after*
|
* This function should be called *after*
|
||||||
* routers_update_status_from_networkstatus; subsequently, you should call
|
* routers_update_status_from_consensus_networkstatus; subsequently, you
|
||||||
* router_rebuild_store and routerlist_descriptors_added.
|
* should call router_rebuild_store and routerlist_descriptors_added.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||||
@ -2590,7 +2591,9 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
|||||||
int authdir_may_warn_about_unreachable_server =
|
int authdir_may_warn_about_unreachable_server =
|
||||||
authdir && !from_cache && !from_fetch &&
|
authdir && !from_cache && !from_fetch &&
|
||||||
router_have_minimum_dir_info();
|
router_have_minimum_dir_info();
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
|
||||||
|
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||||
|
int in_consensus = 0;
|
||||||
|
|
||||||
tor_assert(msg);
|
tor_assert(msg);
|
||||||
|
|
||||||
@ -2644,15 +2647,37 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We no longer need a router with this descriptor digest. */
|
/* We no longer need a router with this descriptor digest. */
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||||
{
|
{
|
||||||
routerstatus_t *rs =
|
routerstatus_t *rs =
|
||||||
networkstatus_find_entry(ns, router->cache_info.identity_digest);
|
networkstatus_v2_find_entry(ns, router->cache_info.identity_digest);
|
||||||
if (rs && !memcmp(rs->descriptor_digest,
|
if (rs && !memcmp(rs->descriptor_digest,
|
||||||
router->cache_info.signed_descriptor_digest,
|
router->cache_info.signed_descriptor_digest,
|
||||||
DIGEST_LEN))
|
DIGEST_LEN))
|
||||||
rs->need_to_mirror = 0;
|
rs->need_to_mirror = 0;
|
||||||
});
|
});
|
||||||
|
if (consensus) {
|
||||||
|
routerstatus_t *rs = networkstatus_vote_find_entry(consensus,
|
||||||
|
router->cache_info.identity_digest);
|
||||||
|
if (rs && !memcmp(rs->descriptor_digest,
|
||||||
|
router->cache_info.signed_descriptor_digest,
|
||||||
|
DIGEST_LEN)) {
|
||||||
|
in_consensus = 1;
|
||||||
|
rs->need_to_mirror = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*XXXX020 I had suspicions about whether this was correct, but now I
|
||||||
|
* can't remember why. :( -NM */
|
||||||
|
if (consensus && !in_consensus && !authdir_mode(get_options())) {
|
||||||
|
/* If it's not listed in the consensus, then don't consider replacing
|
||||||
|
* the latest router with it. */
|
||||||
|
if (!from_cache && should_cache_old_descriptors())
|
||||||
|
signed_desc_append_to_journal(&router->cache_info,
|
||||||
|
router_get_store(routerlist, router));
|
||||||
|
routerlist_insert_old(routerlist, router);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we have a router with the same identity key, choose the newer one. */
|
/* If we have a router with the same identity key, choose the newer one. */
|
||||||
old_router = rimap_get(routerlist->identity_map,
|
old_router = rimap_get(routerlist->identity_map,
|
||||||
@ -2802,7 +2827,7 @@ routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi,
|
|||||||
|
|
||||||
/* Check whether we need to do anything at all. */
|
/* Check whether we need to do anything at all. */
|
||||||
{
|
{
|
||||||
int mdpr = max_descriptors_per_router();
|
int mdpr = dirserver_mode(get_options()) ? 5 : 2;
|
||||||
if (n <= mdpr)
|
if (n <= mdpr)
|
||||||
return;
|
return;
|
||||||
n_extra = n - mdpr;
|
n_extra = n - mdpr;
|
||||||
@ -2874,11 +2899,13 @@ routerlist_remove_old_routers(void)
|
|||||||
routerinfo_t *router;
|
routerinfo_t *router;
|
||||||
signed_descriptor_t *sd;
|
signed_descriptor_t *sd;
|
||||||
digestmap_t *retain;
|
digestmap_t *retain;
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
int dirserv = dirserver_mode(get_options());
|
||||||
|
const networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
|
||||||
|
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||||
|
|
||||||
trusted_dirs_remove_old_certs();
|
trusted_dirs_remove_old_certs();
|
||||||
|
|
||||||
if (!routerlist || !networkstatus_list)
|
if (!routerlist || !consensus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
routerlist_assert_ok(routerlist);
|
routerlist_assert_ok(routerlist);
|
||||||
@ -2886,7 +2913,8 @@ routerlist_remove_old_routers(void)
|
|||||||
retain = digestmap_new();
|
retain = digestmap_new();
|
||||||
cutoff = now - OLD_ROUTER_DESC_MAX_AGE;
|
cutoff = now - OLD_ROUTER_DESC_MAX_AGE;
|
||||||
/* Build a list of all the descriptors that _anybody_ lists. */
|
/* Build a list of all the descriptors that _anybody_ lists. */
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
if (dirserv) {
|
||||||
|
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||||
{
|
{
|
||||||
/* XXXX The inner loop here gets pretty expensive, and actually shows up
|
/* XXXX The inner loop here gets pretty expensive, and actually shows up
|
||||||
* on some profiles. It may be the reason digestmap_set shows up in
|
* on some profiles. It may be the reason digestmap_set shows up in
|
||||||
@ -2900,22 +2928,21 @@ routerlist_remove_old_routers(void)
|
|||||||
if (rs->published_on >= cutoff)
|
if (rs->published_on >= cutoff)
|
||||||
digestmap_set(retain, rs->descriptor_digest, (void*)1));
|
digestmap_set(retain, rs->descriptor_digest, (void*)1));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
{
|
/* Retain anything listed in the consensus. */
|
||||||
/* Retain anything listed in the consensus. */
|
if (consensus) {
|
||||||
networkstatus_vote_t *ns = networkstatus_get_latest_consensus();
|
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
|
||||||
if (ns) {
|
|
||||||
SMARTLIST_FOREACH(ns->routerstatus_list, routerstatus_t *, rs,
|
|
||||||
if (rs->published_on >= cutoff)
|
if (rs->published_on >= cutoff)
|
||||||
digestmap_set(retain, rs->descriptor_digest, (void*)1));
|
digestmap_set(retain, rs->descriptor_digest, (void*)1));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a bunch of networkstatuses, we should consider pruning current
|
/* If we have a bunch of networkstatuses, we should consider pruning current
|
||||||
* routers that are too old and that nobody recommends. (If we don't have
|
* 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
|
* enough networkstatuses, then we should get more before we decide to kill
|
||||||
* routers.) */
|
* routers.) */
|
||||||
if (smartlist_len(networkstatus_list) > get_n_v2_authorities() / 2) {
|
if (!dirserv ||
|
||||||
|
smartlist_len(networkstatus_v2_list) > get_n_v2_authorities() / 2) {
|
||||||
cutoff = now - ROUTER_MAX_AGE;
|
cutoff = now - ROUTER_MAX_AGE;
|
||||||
/* Remove too-old unrecommended members of routerlist->routers. */
|
/* Remove too-old unrecommended members of routerlist->routers. */
|
||||||
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
|
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
|
||||||
@ -2955,7 +2982,7 @@ routerlist_remove_old_routers(void)
|
|||||||
* total number doesn't approach max_descriptors_per_router()*len(router).
|
* total number doesn't approach max_descriptors_per_router()*len(router).
|
||||||
*/
|
*/
|
||||||
if (smartlist_len(routerlist->old_routers) <
|
if (smartlist_len(routerlist->old_routers) <
|
||||||
smartlist_len(routerlist->routers) * (max_descriptors_per_router() - 1))
|
smartlist_len(routerlist->routers) * (dirserver_mode(get_options())?4:2))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
smartlist_sort(routerlist->old_routers, _compare_old_routers_by_identity);
|
smartlist_sort(routerlist->old_routers, _compare_old_routers_by_identity);
|
||||||
@ -3040,7 +3067,7 @@ router_load_single_router(const char *s, uint8_t purpose, int cache,
|
|||||||
|
|
||||||
lst = smartlist_create();
|
lst = smartlist_create();
|
||||||
smartlist_add(lst, ri);
|
smartlist_add(lst, ri);
|
||||||
routers_update_status_from_networkstatus(lst, 0);
|
routers_update_status_from_consensus_networkstatus(lst, 0);
|
||||||
|
|
||||||
if ((r=router_add_to_routerlist(ri, msg, 0, 0))<0) {
|
if ((r=router_add_to_routerlist(ri, msg, 0, 0))<0) {
|
||||||
/* we've already assigned to *msg now, and ri is already freed */
|
/* we've already assigned to *msg now, and ri is already freed */
|
||||||
@ -3086,7 +3113,7 @@ router_load_routers_from_string(const char *s, const char *eos,
|
|||||||
router_parse_list_from_string(&s, eos, routers, saved_location, 0,
|
router_parse_list_from_string(&s, eos, routers, saved_location, 0,
|
||||||
allow_annotations, prepend_annotations);
|
allow_annotations, prepend_annotations);
|
||||||
|
|
||||||
routers_update_status_from_networkstatus(routers, !from_cache);
|
routers_update_status_from_consensus_networkstatus(routers, !from_cache);
|
||||||
|
|
||||||
log_info(LD_DIR, "%d elements to add", smartlist_len(routers));
|
log_info(LD_DIR, "%d elements to add", smartlist_len(routers));
|
||||||
|
|
||||||
@ -3171,16 +3198,26 @@ static int
|
|||||||
signed_desc_digest_is_recognized(signed_descriptor_t *desc)
|
signed_desc_digest_is_recognized(signed_descriptor_t *desc)
|
||||||
{
|
{
|
||||||
routerstatus_t *rs;
|
routerstatus_t *rs;
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
|
||||||
|
int dirserv = dirserver_mode(get_options());
|
||||||
|
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||||
|
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
if (consensus) {
|
||||||
{
|
rs = networkstatus_vote_find_entry(consensus, desc->identity_digest);
|
||||||
if (!(rs = networkstatus_find_entry(ns, desc->identity_digest)))
|
if (rs && !memcmp(rs->descriptor_digest,
|
||||||
continue;
|
desc->signed_descriptor_digest, DIGEST_LEN))
|
||||||
if (!memcmp(rs->descriptor_digest,
|
|
||||||
desc->signed_descriptor_digest, DIGEST_LEN))
|
|
||||||
return 1;
|
return 1;
|
||||||
});
|
}
|
||||||
|
if (dirserv && networkstatus_v2_list) {
|
||||||
|
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||||
|
{
|
||||||
|
if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest)))
|
||||||
|
continue;
|
||||||
|
if (!memcmp(rs->descriptor_digest,
|
||||||
|
desc->signed_descriptor_digest, DIGEST_LEN))
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3336,103 +3373,6 @@ any_trusted_dir_is_v1_authority(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a newly allocated string naming the versions of Tor recommended by
|
|
||||||
* more than half the versioning networkstatuses. */
|
|
||||||
char *
|
|
||||||
compute_recommended_versions(time_t now, int client,
|
|
||||||
const char *my_version,
|
|
||||||
combined_version_status_t *status_out)
|
|
||||||
{
|
|
||||||
int n_seen;
|
|
||||||
char *current;
|
|
||||||
smartlist_t *combined, *recommended;
|
|
||||||
int n_versioning, n_recommending;
|
|
||||||
char *result;
|
|
||||||
/** holds the compromise status taken among all non-recommending
|
|
||||||
* authorities */
|
|
||||||
version_status_t consensus = VS_RECOMMENDED;
|
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
|
||||||
(void) now; /* right now, we consider *all* statuses, regardless of age. */
|
|
||||||
|
|
||||||
tor_assert(my_version);
|
|
||||||
tor_assert(status_out);
|
|
||||||
|
|
||||||
memset(status_out, 0, sizeof(combined_version_status_t));
|
|
||||||
|
|
||||||
if (!networkstatus_list)
|
|
||||||
return tor_strdup("<none>");
|
|
||||||
|
|
||||||
combined = smartlist_create();
|
|
||||||
n_versioning = n_recommending = 0;
|
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
|
||||||
{
|
|
||||||
const char *vers;
|
|
||||||
smartlist_t *versions;
|
|
||||||
version_status_t status;
|
|
||||||
if (! ns->recommends_versions)
|
|
||||||
continue;
|
|
||||||
n_versioning++;
|
|
||||||
vers = client ? ns->client_versions : ns->server_versions;
|
|
||||||
if (!vers)
|
|
||||||
continue;
|
|
||||||
versions = smartlist_create();
|
|
||||||
smartlist_split_string(versions, vers, ",",
|
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
|
||||||
sort_version_list(versions, 1);
|
|
||||||
smartlist_add_all(combined, versions);
|
|
||||||
smartlist_free(versions);
|
|
||||||
|
|
||||||
/* now, check _our_ version */
|
|
||||||
status = tor_version_is_obsolete(my_version, vers);
|
|
||||||
if (status == VS_RECOMMENDED)
|
|
||||||
n_recommending++;
|
|
||||||
consensus = version_status_join(status, consensus);
|
|
||||||
});
|
|
||||||
|
|
||||||
sort_version_list(combined, 0);
|
|
||||||
|
|
||||||
current = NULL;
|
|
||||||
n_seen = 0;
|
|
||||||
recommended = smartlist_create();
|
|
||||||
SMARTLIST_FOREACH(combined, char *, cp,
|
|
||||||
{
|
|
||||||
if (current && !strcmp(cp, current)) {
|
|
||||||
++n_seen;
|
|
||||||
} else {
|
|
||||||
if (current)
|
|
||||||
log_info(LD_DIR,"version %s is recommended by %d authorities",
|
|
||||||
current, n_seen);
|
|
||||||
if (n_seen > n_versioning/2 && current) {
|
|
||||||
smartlist_add(recommended, current);
|
|
||||||
}
|
|
||||||
n_seen = 1;
|
|
||||||
current = cp;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (current)
|
|
||||||
log_info(LD_DIR,"version %s is recommended by %d authorities",
|
|
||||||
current, n_seen);
|
|
||||||
if (n_seen > n_versioning/2 && current)
|
|
||||||
smartlist_add(recommended, current);
|
|
||||||
|
|
||||||
result = smartlist_join_strings(recommended, ", ", 0, NULL);
|
|
||||||
|
|
||||||
SMARTLIST_FOREACH(combined, char *, cp, tor_free(cp));
|
|
||||||
smartlist_free(combined);
|
|
||||||
smartlist_free(recommended);
|
|
||||||
|
|
||||||
status_out->n_versioning = n_versioning;
|
|
||||||
if (n_recommending > n_versioning/2) {
|
|
||||||
status_out->consensus = VS_RECOMMENDED;
|
|
||||||
status_out->n_concurring = n_recommending;
|
|
||||||
} else {
|
|
||||||
status_out->consensus = consensus;
|
|
||||||
status_out->n_concurring = n_versioning - n_recommending;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DOCDOC */
|
/** DOCDOC */
|
||||||
static void
|
static void
|
||||||
list_pending_downloads(digestmap_t *result,
|
list_pending_downloads(digestmap_t *result,
|
||||||
@ -3541,128 +3481,26 @@ client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return new list of ID fingerprints for routers that we (as a client) would
|
/** Max amount of hashes to download per request.
|
||||||
* like to download.
|
* Since squid does not like URLs >= 4096 bytes we limit it to 96.
|
||||||
|
* 4096 - strlen(http://255.255.255.255/tor/server/d/.z) == 4058
|
||||||
|
* 4058/41 (40 for the hash and 1 for the + that separates them) => 98
|
||||||
|
* So use 96 because it's a nice number.
|
||||||
*/
|
*/
|
||||||
static smartlist_t *
|
|
||||||
router_list_client_downloadable(void)
|
|
||||||
{
|
|
||||||
int n_downloadable = 0;
|
|
||||||
smartlist_t *downloadable = smartlist_create();
|
|
||||||
digestmap_t *downloading;
|
|
||||||
time_t now = time(NULL);
|
|
||||||
/* these are just used for logging */
|
|
||||||
int n_not_ready = 0, n_in_progress = 0, n_uptodate = 0, n_wouldnt_use = 0;
|
|
||||||
or_options_t *options = get_options();
|
|
||||||
const smartlist_t *routerstatus_list = networkstatus_get_all_statuses();
|
|
||||||
|
|
||||||
if (!smartlist_len(routerstatus_list))
|
|
||||||
return downloadable;
|
|
||||||
|
|
||||||
downloading = digestmap_new();
|
|
||||||
list_pending_descriptor_downloads(downloading, 0);
|
|
||||||
|
|
||||||
routerstatus_list_update_from_networkstatus(now);
|
|
||||||
SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
|
|
||||||
{
|
|
||||||
routerinfo_t *ri;
|
|
||||||
if (router_get_by_descriptor_digest(rs->descriptor_digest)) {
|
|
||||||
/* We have the 'best' descriptor for this router. */
|
|
||||||
++n_uptodate;
|
|
||||||
} else if (!client_would_use_router(rs, now, options)) {
|
|
||||||
/* We wouldn't want this descriptor even if we got it. */
|
|
||||||
++n_wouldnt_use;
|
|
||||||
} else if (digestmap_get(downloading, rs->descriptor_digest)) {
|
|
||||||
/* We're downloading this one now. */
|
|
||||||
++n_in_progress;
|
|
||||||
} else if ((ri = router_get_by_digest(rs->identity_digest)) &&
|
|
||||||
ri->cache_info.published_on > rs->published_on) {
|
|
||||||
/* Oddly, we have a descriptor more recent than the 'best' one, but it
|
|
||||||
was once best. So that's okay. */
|
|
||||||
++n_uptodate;
|
|
||||||
} else if (!download_status_is_ready(&rs->dl_status, now,
|
|
||||||
MAX_ROUTERDESC_DOWNLOAD_FAILURES)) {
|
|
||||||
/* We failed too recently to try again. */
|
|
||||||
++n_not_ready;
|
|
||||||
} else {
|
|
||||||
/* Okay, time to try it. */
|
|
||||||
smartlist_add(downloadable, rs->descriptor_digest);
|
|
||||||
++n_downloadable;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
log_info(LD_DIR,
|
|
||||||
"%d router descriptors are downloadable. "
|
|
||||||
"%d are in progress. %d are up-to-date. "
|
|
||||||
"%d are non-useful. %d failed too recently to retry.",
|
|
||||||
n_downloadable, n_in_progress, n_uptodate,
|
|
||||||
n_wouldnt_use, n_not_ready);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
digestmap_free(downloading, NULL);
|
|
||||||
return downloadable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initiate new router downloads as needed, using the strategy for
|
|
||||||
* non-directory-servers.
|
|
||||||
*
|
|
||||||
* We don't launch any downloads if there are fewer than MAX_DL_TO_DELAY
|
|
||||||
* descriptors to get and less than MAX_CLIENT_INTERVAL_WITHOUT_REQUEST
|
|
||||||
* seconds have passed.
|
|
||||||
*
|
|
||||||
* Otherwise, we ask for all descriptors that we think are different from what
|
|
||||||
* we have, and that we don't currently have an in-progress download attempt
|
|
||||||
* for. */
|
|
||||||
static void
|
|
||||||
update_router_descriptor_client_downloads(time_t now)
|
|
||||||
{
|
|
||||||
/** Max amount of hashes to download per request.
|
|
||||||
* Since squid does not like URLs >= 4096 bytes we limit it to 96.
|
|
||||||
* 4096 - strlen(http://255.255.255.255/tor/server/d/.z) == 4058
|
|
||||||
* 4058/41 (40 for the hash and 1 for the + that separates them) => 98
|
|
||||||
* So use 96 because it's a nice number.
|
|
||||||
*/
|
|
||||||
#define MAX_DL_PER_REQUEST 96
|
#define MAX_DL_PER_REQUEST 96
|
||||||
/** Don't split our requests so finely that we are requesting fewer than
|
/** Don't split our requests so finely that we are requesting fewer than
|
||||||
* this number per server. */
|
* this number per server. */
|
||||||
#define MIN_DL_PER_REQUEST 4
|
#define MIN_DL_PER_REQUEST 4
|
||||||
/** To prevent a single screwy cache from confusing us by selective reply,
|
/** To prevent a single screwy cache from confusing us by selective reply,
|
||||||
* try to split our requests into at least this this many requests. */
|
* try to split our requests into at least this this many requests. */
|
||||||
#define MIN_REQUESTS 3
|
#define MIN_REQUESTS 3
|
||||||
/** If we want fewer than this many descriptors, wait until we
|
/** If we want fewer than this many descriptors, wait until we
|
||||||
* want more, or until MAX_CLIENT_INTERVAL_WITHOUT_REQUEST has
|
* want more, or until MAX_CLIENT_INTERVAL_WITHOUT_REQUEST has
|
||||||
* passed. */
|
* passed. */
|
||||||
#define MAX_DL_TO_DELAY 16
|
#define MAX_DL_TO_DELAY 16
|
||||||
/** When directory clients have only a few servers to request, they batch
|
/** When directory clients have only a few servers to request, they batch
|
||||||
* them until they have more, or until this amount of time has passed. */
|
* them until they have more, or until this amount of time has passed. */
|
||||||
#define MAX_CLIENT_INTERVAL_WITHOUT_REQUEST (10*60)
|
#define MAX_CLIENT_INTERVAL_WITHOUT_REQUEST (10*60)
|
||||||
smartlist_t *downloadable = NULL;
|
|
||||||
or_options_t *options = get_options();
|
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
|
||||||
|
|
||||||
if (dirserver_mode(options)) {
|
|
||||||
log_warn(LD_BUG,
|
|
||||||
"Called router_descriptor_client_downloads() on a dir mirror?");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rep_hist_circbuilding_dormant(now)) {
|
|
||||||
// log_info(LD_CIRC, "Skipping descriptor downloads: we haven't needed "
|
|
||||||
// "any circuits lately.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (networkstatus_list &&
|
|
||||||
smartlist_len(networkstatus_list) <= get_n_v2_authorities()/2) {
|
|
||||||
log_info(LD_DIR,
|
|
||||||
"Not enough networkstatus documents to launch requests.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadable = router_list_client_downloadable();
|
|
||||||
launch_router_descriptor_downloads(downloadable, now);
|
|
||||||
smartlist_free(downloadable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DOCDOC */
|
/** DOCDOC */
|
||||||
static void
|
static void
|
||||||
@ -3734,18 +3572,18 @@ update_router_descriptor_cache_downloads(time_t now)
|
|||||||
int i, j, n;
|
int i, j, n;
|
||||||
int n_download;
|
int n_download;
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||||
|
|
||||||
if (! dirserver_mode(options)) {
|
if (! dirserver_mode(options)) {
|
||||||
log_warn(LD_BUG, "Called update_router_descriptor_cache_downloads() "
|
log_warn(LD_BUG, "Called update_router_descriptor_cache_downloads() "
|
||||||
"on a non-dir-mirror?");
|
"on a non-dir-mirror?");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!networkstatus_list || !smartlist_len(networkstatus_list))
|
if (!networkstatus_v2_list || !smartlist_len(networkstatus_v2_list))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
map = digestmap_new();
|
map = digestmap_new();
|
||||||
n = smartlist_len(networkstatus_list);
|
n = smartlist_len(networkstatus_v2_list);
|
||||||
|
|
||||||
downloadable = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
downloadable = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
||||||
download_from = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
download_from = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
||||||
@ -3760,7 +3598,7 @@ update_router_descriptor_cache_downloads(time_t now)
|
|||||||
* descriptor from the corresponding authority.
|
* descriptor from the corresponding authority.
|
||||||
*/
|
*/
|
||||||
n_download = 0;
|
n_download = 0;
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||||
{
|
{
|
||||||
trusted_dir_server_t *ds;
|
trusted_dir_server_t *ds;
|
||||||
smartlist_t *dl;
|
smartlist_t *dl;
|
||||||
@ -3837,7 +3675,7 @@ update_router_descriptor_cache_downloads(time_t now)
|
|||||||
|
|
||||||
/* Now, we can actually launch our requests. */
|
/* Now, we can actually launch our requests. */
|
||||||
for (i=0; i<n; ++i) {
|
for (i=0; i<n; ++i) {
|
||||||
networkstatus_t *ns = smartlist_get(networkstatus_list, i);
|
networkstatus_v2_t *ns = smartlist_get(networkstatus_v2_list, i);
|
||||||
trusted_dir_server_t *ds =
|
trusted_dir_server_t *ds =
|
||||||
router_get_trusteddirserver_by_digest(ns->identity_digest);
|
router_get_trusteddirserver_by_digest(ns->identity_digest);
|
||||||
smartlist_t *dl = download_from[i];
|
smartlist_t *dl = download_from[i];
|
||||||
@ -3874,7 +3712,7 @@ update_consensus_router_descriptor_downloads(time_t now)
|
|||||||
smartlist_t *downloadable = smartlist_create();
|
smartlist_t *downloadable = smartlist_create();
|
||||||
int authdir = authdir_mode(options);
|
int authdir = authdir_mode(options);
|
||||||
int dirserver = dirserver_mode(options);
|
int dirserver = dirserver_mode(options);
|
||||||
networkstatus_vote_t *consensus = networkstatus_get_latest_consensus();
|
networkstatus_vote_t *consensus = networkstatus_get_live_consensus(now);
|
||||||
|
|
||||||
if (!dirserver) {
|
if (!dirserver) {
|
||||||
if (rep_hist_circbuilding_dormant(now))
|
if (rep_hist_circbuilding_dormant(now))
|
||||||
@ -3887,17 +3725,9 @@ update_consensus_router_descriptor_downloads(time_t now)
|
|||||||
list_pending_descriptor_downloads(map, 0);
|
list_pending_descriptor_downloads(map, 0);
|
||||||
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
|
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
|
||||||
{
|
{
|
||||||
routerstatus_t *lrs;
|
|
||||||
if (router_get_by_descriptor_digest(rs->descriptor_digest))
|
if (router_get_by_descriptor_digest(rs->descriptor_digest))
|
||||||
continue; /* We have it already. */
|
continue; /* We have it already. */
|
||||||
|
if (!download_status_is_ready(&rs->dl_status, now,
|
||||||
/* XXXX020 change this once the real consensus is the canonical place
|
|
||||||
* to go for router information. */
|
|
||||||
lrs = router_get_combined_status_by_digest(rs->identity_digest);
|
|
||||||
if (!lrs ||
|
|
||||||
memcmp(lrs->descriptor_digest, rs->descriptor_digest, DIGEST_LEN))
|
|
||||||
lrs = rs;
|
|
||||||
if (!download_status_is_ready(&lrs->dl_status, now,
|
|
||||||
MAX_ROUTERDESC_DOWNLOAD_FAILURES))
|
MAX_ROUTERDESC_DOWNLOAD_FAILURES))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3925,10 +3755,8 @@ update_router_descriptor_downloads(time_t now)
|
|||||||
return;
|
return;
|
||||||
if (dirserver_mode(options)) {
|
if (dirserver_mode(options)) {
|
||||||
update_router_descriptor_cache_downloads(now);
|
update_router_descriptor_cache_downloads(now);
|
||||||
update_consensus_router_descriptor_downloads(now); /*XXXX020 clients too*/
|
|
||||||
} else {
|
|
||||||
update_router_descriptor_client_downloads(now);
|
|
||||||
}
|
}
|
||||||
|
update_consensus_router_descriptor_downloads(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true iff <b>sd</b> is the descriptor for a router descriptor that
|
/** Return true iff <b>sd</b> is the descriptor for a router descriptor that
|
||||||
@ -3990,19 +3818,6 @@ update_extrainfo_downloads(time_t now)
|
|||||||
smartlist_free(wanted);
|
smartlist_free(wanted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the number of routerstatus_t in <b>entries</b> that we'd actually
|
|
||||||
* use. */
|
|
||||||
static int
|
|
||||||
routerstatus_count_usable_entries(smartlist_t *entries)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
time_t now = time(NULL);
|
|
||||||
or_options_t *options = get_options();
|
|
||||||
SMARTLIST_FOREACH(entries, routerstatus_t *, rs,
|
|
||||||
if (client_would_use_router(rs, now, options)) count++);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** True iff, the last time we checked whether we had enough directory info
|
/** True iff, the last time we checked whether we had enough directory info
|
||||||
* to build circuits, the answer was "yes". */
|
* to build circuits, the answer was "yes". */
|
||||||
static int have_min_dir_info = 0;
|
static int have_min_dir_info = 0;
|
||||||
@ -4041,20 +3856,18 @@ router_dir_info_changed(void)
|
|||||||
static void
|
static void
|
||||||
update_router_have_minimum_dir_info(void)
|
update_router_have_minimum_dir_info(void)
|
||||||
{
|
{
|
||||||
int tot = 0, num_running = 0;
|
/*XXX020 call when dirserver_mode() changes. */
|
||||||
int n_ns, n_authorities, res, avg;
|
int num_present = 0, num_usable=0;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
const smartlist_t *routerstatus_list = networkstatus_get_all_statuses();
|
int res;
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
or_options_t *options = get_options();
|
||||||
|
const networkstatus_vote_t *consensus =
|
||||||
|
networkstatus_get_live_consensus(now);
|
||||||
|
|
||||||
if (!routerlist) {
|
if (!consensus) {
|
||||||
res = 0;
|
res = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/*XXXX020 remove this call. routerlist_remove_old_routers shows up in some
|
|
||||||
* profiles, and this is the biggest caller of that function. */
|
|
||||||
routerlist_remove_old_routers();
|
|
||||||
networkstatus_list_clean(now);
|
|
||||||
|
|
||||||
if (should_delay_dir_fetches(get_options())) {
|
if (should_delay_dir_fetches(get_options())) {
|
||||||
log_notice(LD_DIR, "no known bridge descriptors running yet; stalling");
|
log_notice(LD_DIR, "no known bridge descriptors running yet; stalling");
|
||||||
@ -4062,24 +3875,17 @@ update_router_have_minimum_dir_info(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_authorities = get_n_v2_authorities();
|
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
|
||||||
n_ns = smartlist_len(networkstatus_list);
|
|
||||||
if (n_ns<=n_authorities/2) {
|
|
||||||
log_info(LD_DIR,
|
|
||||||
"We have %d of %d network statuses, and we want "
|
|
||||||
"more than %d.", n_ns, n_authorities, n_authorities/2);
|
|
||||||
res = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
|
||||||
tot += routerstatus_count_usable_entries(ns->entries));
|
|
||||||
avg = tot / n_ns;
|
|
||||||
SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
|
|
||||||
{
|
{
|
||||||
if (rs->is_running)
|
if (client_would_use_router(rs, now, options)) {
|
||||||
num_running++;
|
++num_usable;
|
||||||
|
if (router_get_by_digest(rs->identity_digest)) {
|
||||||
|
++num_present;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
res = smartlist_len(routerlist->routers) >= (avg/4) && num_running > 2;
|
res = num_present >= num_usable/4 && num_usable > 2;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (res && !have_min_dir_info) {
|
if (res && !have_min_dir_info) {
|
||||||
log(LOG_NOTICE, LD_DIR,
|
log(LOG_NOTICE, LD_DIR,
|
||||||
@ -4089,7 +3895,7 @@ update_router_have_minimum_dir_info(void)
|
|||||||
if (!res && have_min_dir_info) {
|
if (!res && have_min_dir_info) {
|
||||||
log(LOG_NOTICE, LD_DIR,"Our directory information is no longer up-to-date "
|
log(LOG_NOTICE, LD_DIR,"Our directory information is no longer up-to-date "
|
||||||
"enough to build circuits.%s",
|
"enough to build circuits.%s",
|
||||||
num_running > 2 ? "" : " (Not enough servers seem reachable -- "
|
num_usable > 2 ? "" : " (Not enough servers seem reachable -- "
|
||||||
"is your network connection down?)");
|
"is your network connection down?)");
|
||||||
control_event_client_status(LOG_NOTICE, "NOT_ENOUGH_DIR_INFO");
|
control_event_client_status(LOG_NOTICE, "NOT_ENOUGH_DIR_INFO");
|
||||||
}
|
}
|
||||||
@ -4102,18 +3908,7 @@ update_router_have_minimum_dir_info(void)
|
|||||||
void
|
void
|
||||||
router_reset_descriptor_download_failures(void)
|
router_reset_descriptor_download_failures(void)
|
||||||
{
|
{
|
||||||
const smartlist_t *networkstatus_list = networkstatus_get_v2_list();
|
networkstatus_reset_download_failures();
|
||||||
const smartlist_t *routerstatus_list = networkstatus_get_all_statuses();
|
|
||||||
SMARTLIST_FOREACH(routerstatus_list, routerstatus_t *, rs,
|
|
||||||
{
|
|
||||||
download_status_reset(&rs->dl_status);
|
|
||||||
});
|
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
|
||||||
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
|
|
||||||
{
|
|
||||||
if (!router_get_by_descriptor_digest(rs->descriptor_digest))
|
|
||||||
rs->need_to_mirror = 1;
|
|
||||||
}));
|
|
||||||
last_routerdesc_download_attempted = 0;
|
last_routerdesc_download_attempted = 0;
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
return;
|
return;
|
||||||
|
@ -564,36 +564,6 @@ tor_version_is_obsolete(const char *myversion, const char *versionlist)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the combined status of the current version, given that we know of
|
|
||||||
* one set of networkstatuses that give us status <b>a</b>, and another that
|
|
||||||
* gives us status <b>b</b>.
|
|
||||||
*
|
|
||||||
* For example, if one authority thinks that we're NEW, and another thinks
|
|
||||||
* we're OLD, we're simply UNRECOMMENDED.
|
|
||||||
*
|
|
||||||
* This function does not handle calculating whether we're RECOMMENDED; that
|
|
||||||
* follows a simple majority rule. This function simply calculates *why*
|
|
||||||
* we're not recommended (if we're not).
|
|
||||||
*/
|
|
||||||
version_status_t
|
|
||||||
version_status_join(version_status_t a, version_status_t b)
|
|
||||||
{
|
|
||||||
if (a == b)
|
|
||||||
return a;
|
|
||||||
else if (a == VS_UNRECOMMENDED || b == VS_UNRECOMMENDED)
|
|
||||||
return VS_UNRECOMMENDED;
|
|
||||||
else if (a == VS_RECOMMENDED)
|
|
||||||
return b;
|
|
||||||
else if (b == VS_RECOMMENDED)
|
|
||||||
return a;
|
|
||||||
/* Okay. Neither is 'recommended' or 'unrecommended', and they differ. */
|
|
||||||
else if (a == VS_OLD || b == VS_OLD)
|
|
||||||
return VS_UNRECOMMENDED;
|
|
||||||
/* One is VS_NEW, the other is VS_NEW_IN_SERIES */
|
|
||||||
else
|
|
||||||
return VS_NEW_IN_SERIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read a signed directory from <b>str</b>. If it's well-formed, return 0.
|
/** Read a signed directory from <b>str</b>. If it's well-formed, return 0.
|
||||||
* Otherwise, return -1. If we're a directory cache, cache it.
|
* Otherwise, return -1. If we're a directory cache, cache it.
|
||||||
*/
|
*/
|
||||||
@ -1722,13 +1692,13 @@ _free_duplicate_routerstatus_entry(void *e)
|
|||||||
* signature of the network status, but do not (yet) check the signing key for
|
* signature of the network status, but do not (yet) check the signing key for
|
||||||
* authority.
|
* authority.
|
||||||
*/
|
*/
|
||||||
networkstatus_t *
|
networkstatus_v2_t *
|
||||||
networkstatus_parse_from_string(const char *s)
|
networkstatus_v2_parse_from_string(const char *s)
|
||||||
{
|
{
|
||||||
const char *eos;
|
const char *eos;
|
||||||
smartlist_t *tokens = smartlist_create();
|
smartlist_t *tokens = smartlist_create();
|
||||||
smartlist_t *footer_tokens = smartlist_create();
|
smartlist_t *footer_tokens = smartlist_create();
|
||||||
networkstatus_t *ns = NULL;
|
networkstatus_v2_t *ns = NULL;
|
||||||
char ns_digest[DIGEST_LEN];
|
char ns_digest[DIGEST_LEN];
|
||||||
char tmp_digest[DIGEST_LEN];
|
char tmp_digest[DIGEST_LEN];
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
@ -1745,7 +1715,7 @@ networkstatus_parse_from_string(const char *s)
|
|||||||
log_warn(LD_DIR, "Error tokenizing network-status header.");
|
log_warn(LD_DIR, "Error tokenizing network-status header.");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ns = tor_malloc_zero(sizeof(networkstatus_t));
|
ns = tor_malloc_zero(sizeof(networkstatus_v2_t));
|
||||||
memcpy(ns->networkstatus_digest, ns_digest, DIGEST_LEN);
|
memcpy(ns->networkstatus_digest, ns_digest, DIGEST_LEN);
|
||||||
|
|
||||||
tok = find_first_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
|
tok = find_first_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
|
||||||
@ -1876,7 +1846,7 @@ networkstatus_parse_from_string(const char *s)
|
|||||||
goto done;
|
goto done;
|
||||||
err:
|
err:
|
||||||
if (ns)
|
if (ns)
|
||||||
networkstatus_free(ns);
|
networkstatus_v2_free(ns);
|
||||||
ns = NULL;
|
ns = NULL;
|
||||||
done:
|
done:
|
||||||
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
|
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
|
||||||
|
Loading…
Reference in New Issue
Block a user