|
@@ -22,7 +22,7 @@ static routerstatus_t *router_pick_directory_server_impl(int requireother,
|
|
|
int fascistfirewall,
|
|
|
int for_v2_directory);
|
|
|
static routerstatus_t *router_pick_trusteddirserver_impl(
|
|
|
- int need_v1_authority, int requireother, int fascistfirewall);
|
|
|
+ authority_type_t type, int requireother, int fascistfirewall);
|
|
|
static void mark_all_trusteddirservers_up(void);
|
|
|
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
|
|
|
static void routerstatus_list_update_from_networkstatus(time_t now);
|
|
@@ -97,6 +97,19 @@ static int have_warned_about_old_version = 0;
|
|
|
* listed by the authorities */
|
|
|
static int have_warned_about_new_version = 0;
|
|
|
|
|
|
+/** Return the number of v2 directory authorities */
|
|
|
+static INLINE int
|
|
|
+get_n_v2_authorities(void)
|
|
|
+{
|
|
|
+ int n = 0;
|
|
|
+ if (!trusted_dir_servers)
|
|
|
+ return 0;
|
|
|
+ SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
|
|
|
+ if (ds->is_v2_authority)
|
|
|
+ ++n);
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
/** Repopulate our list of network_status_t objects from the list cached on
|
|
|
* disk. Return 0 on success, -1 on failure. */
|
|
|
int
|
|
@@ -465,14 +478,14 @@ router_get_trusteddirserver_by_digest(const char *digest)
|
|
|
* Other args are as in router_pick_trusteddirserver_impl().
|
|
|
*/
|
|
|
routerstatus_t *
|
|
|
-router_pick_trusteddirserver(int need_v1_authority,
|
|
|
+router_pick_trusteddirserver(authority_type_t type,
|
|
|
int requireother,
|
|
|
int fascistfirewall,
|
|
|
int retry_if_no_servers)
|
|
|
{
|
|
|
routerstatus_t *choice;
|
|
|
|
|
|
- choice = router_pick_trusteddirserver_impl(need_v1_authority,
|
|
|
+ choice = router_pick_trusteddirserver_impl(type,
|
|
|
requireother, fascistfirewall);
|
|
|
if (choice || !retry_if_no_servers)
|
|
|
return choice;
|
|
@@ -480,7 +493,7 @@ router_pick_trusteddirserver(int need_v1_authority,
|
|
|
log_info(LD_DIR,
|
|
|
"No trusted dirservers are reachable. Trying them all again.");
|
|
|
mark_all_trusteddirservers_up();
|
|
|
- return router_pick_trusteddirserver_impl(need_v1_authority,
|
|
|
+ return router_pick_trusteddirserver_impl(type,
|
|
|
requireother, fascistfirewall);
|
|
|
}
|
|
|
|
|
@@ -540,7 +553,7 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
|
|
* system.
|
|
|
*/
|
|
|
static routerstatus_t *
|
|
|
-router_pick_trusteddirserver_impl(int need_v1_authority,
|
|
|
+router_pick_trusteddirserver_impl(authority_type_t type,
|
|
|
int requireother, int fascistfirewall)
|
|
|
{
|
|
|
smartlist_t *sl;
|
|
@@ -555,7 +568,11 @@ router_pick_trusteddirserver_impl(int need_v1_authority,
|
|
|
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
|
|
|
{
|
|
|
if (!d->is_running) continue;
|
|
|
- if (need_v1_authority && !d->is_v1_authority)
|
|
|
+ if (type == V1_AUTHORITY && !d->is_v1_authority)
|
|
|
+ continue;
|
|
|
+ if (type == V2_AUTHORITY && !d->is_v2_authority)
|
|
|
+ continue;
|
|
|
+ if (type == HIDSERV_AUTHORITY && !d->is_hidserv_authority)
|
|
|
continue;
|
|
|
if (requireother && me && router_digest_is_me(d->digest))
|
|
|
continue;
|
|
@@ -1310,9 +1327,7 @@ dump_routerlist_mem_usage(int severity)
|
|
|
static int
|
|
|
max_descriptors_per_router(void)
|
|
|
{
|
|
|
- int n_authorities = 0;
|
|
|
- if (trusted_dir_servers)
|
|
|
- n_authorities = smartlist_len(trusted_dir_servers);
|
|
|
+ int n_authorities = get_n_v2_authorities();
|
|
|
return (n_authorities < 5) ? 5 : n_authorities;
|
|
|
}
|
|
|
|
|
@@ -2219,7 +2234,8 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|
|
}
|
|
|
base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
|
|
|
if (!(trusted_dir =
|
|
|
- router_get_trusteddirserver_by_digest(ns->identity_digest))) {
|
|
|
+ router_get_trusteddirserver_by_digest(ns->identity_digest))
|
|
|
+ || !trusted_dir->is_v2_authority) {
|
|
|
log_info(LD_DIR, "Network status was signed, but not by an authoritative "
|
|
|
"directory we recognize.");
|
|
|
if (!get_options()->DirPort) {
|
|
@@ -2536,6 +2552,8 @@ update_networkstatus_cache_downloads(time_t now)
|
|
|
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
|
|
|
{
|
|
|
char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
|
|
|
+ if (!ds->is_v2_authority)
|
|
|
+ continue;
|
|
|
if (router_digest_is_me(ds->digest))
|
|
|
continue;
|
|
|
if (connection_get_by_type_addr_port_purpose(
|
|
@@ -2594,17 +2612,19 @@ update_networkstatus_client_downloads(time_t now)
|
|
|
* *one* if the most recent one's publication time is under
|
|
|
* NETWORKSTATUS_CLIENT_DL_INTERVAL.
|
|
|
*/
|
|
|
- if (!trusted_dir_servers || !smartlist_len(trusted_dir_servers))
|
|
|
+ if (!get_n_v2_authorities())
|
|
|
return;
|
|
|
- n_dirservers = n_running_dirservers = smartlist_len(trusted_dir_servers);
|
|
|
+ n_dirservers = n_running_dirservers = 0;
|
|
|
missing = smartlist_create();
|
|
|
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
|
|
|
{
|
|
|
networkstatus_t *ns = networkstatus_get_by_digest(ds->digest);
|
|
|
- if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
|
|
|
- --n_running_dirservers;
|
|
|
+ if (!ds->is_v2_authority)
|
|
|
continue;
|
|
|
- }
|
|
|
+ ++n_dirservers;
|
|
|
+ if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES)
|
|
|
+ continue;
|
|
|
+ ++n_running_dirservers;
|
|
|
if (ns && ns->published_on > now-NETWORKSTATUS_MAX_AGE)
|
|
|
++n_live;
|
|
|
else
|
|
@@ -2649,6 +2669,8 @@ update_networkstatus_client_downloads(time_t now)
|
|
|
if (i >= n_dirservers)
|
|
|
i = 0;
|
|
|
ds = smartlist_get(trusted_dir_servers, i);
|
|
|
+ if (! ds->is_v2_authority)
|
|
|
+ continue;
|
|
|
if (n_failed < n_dirservers &&
|
|
|
ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
|
|
|
++n_failed;
|
|
@@ -2726,7 +2748,8 @@ router_exit_policy_rejects_all(routerinfo_t *router)
|
|
|
* <b>address</b> is NULL, add ourself. */
|
|
|
void
|
|
|
add_trusted_dir_server(const char *nickname, const char *address,
|
|
|
- uint16_t port, const char *digest, int is_v1_authority)
|
|
|
+ uint16_t port, const char *digest, int is_v1_authority,
|
|
|
+ int is_v2_authority, int is_hidserv_authority)
|
|
|
{
|
|
|
trusted_dir_server_t *ent;
|
|
|
uint32_t a;
|
|
@@ -2760,6 +2783,8 @@ add_trusted_dir_server(const char *nickname, const char *address,
|
|
|
ent->dir_port = port;
|
|
|
ent->is_running = 1;
|
|
|
ent->is_v1_authority = is_v1_authority;
|
|
|
+ ent->is_v2_authority = is_v2_authority;
|
|
|
+ ent->is_hidserv_authority = is_hidserv_authority;
|
|
|
memcpy(ent->digest, digest, DIGEST_LEN);
|
|
|
|
|
|
dlen = 64 + strlen(hostname) + (nickname?strlen(nickname):0);
|
|
@@ -3115,8 +3140,8 @@ routerstatus_list_update_from_networkstatus(time_t now)
|
|
|
if (!warned_conflicts)
|
|
|
warned_conflicts = smartlist_create();
|
|
|
|
|
|
- n_trusted = smartlist_len(trusted_dir_servers);
|
|
|
n_statuses = smartlist_len(networkstatus_list);
|
|
|
+ n_trusted = get_n_v2_authorities();
|
|
|
|
|
|
if (n_statuses <= n_trusted/2) {
|
|
|
/* Not enough statuses to adjust status. */
|
|
@@ -3620,8 +3645,8 @@ update_router_descriptor_client_downloads(time_t now)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (networkstatus_list && smartlist_len(networkstatus_list) <=
|
|
|
- smartlist_len(trusted_dir_servers)/2) {
|
|
|
+ if (networkstatus_list &&
|
|
|
+ smartlist_len(networkstatus_list) <= get_n_v2_authorities()/2) {
|
|
|
log_info(LD_DIR,
|
|
|
"Not enough networkstatus documents to launch requests.");
|
|
|
}
|
|
@@ -3859,7 +3884,7 @@ update_router_have_minimum_dir_info(void)
|
|
|
res = 0;
|
|
|
goto done;
|
|
|
}
|
|
|
- n_authorities = smartlist_len(trusted_dir_servers);
|
|
|
+ n_authorities = get_n_v2_authorities();
|
|
|
n_ns = smartlist_len(networkstatus_list);
|
|
|
if (n_ns<=n_authorities/2) {
|
|
|
log_info(LD_DIR,
|
|
@@ -3904,6 +3929,8 @@ have_tried_downloading_all_statuses(int n_failures)
|
|
|
|
|
|
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
|
|
|
{
|
|
|
+ if (!ds->is_v2_authority)
|
|
|
+ continue;
|
|
|
/* If we don't have the status, and we haven't failed to get the status,
|
|
|
* we haven't tried to get the status. */
|
|
|
if (!networkstatus_get_by_digest(ds->digest) &&
|