Merge branch 'ahf_bugs_17847_2_squashed'

This commit is contained in:
Nick Mathewson 2017-01-18 11:04:58 -05:00
commit fa00f2dce5

View File

@ -1826,43 +1826,24 @@ router_is_already_dir_fetching(const tor_addr_port_t *ap, int serverdesc,
return 0; return 0;
} }
/* Check if we already have a directory fetch from ds, for serverdesc /* Check if we already have a directory fetch from the ipv4 or ipv6
* (including extrainfo) or microdesc documents. * router, for serverdesc (including extrainfo) or microdesc documents.
* If so, return 1, if not, return 0. * If so, return 1, if not, return 0.
*/ */
static int static int
router_is_already_dir_fetching_ds(const dir_server_t *ds, router_is_already_dir_fetching_(uint32_t ipv4_addr,
const tor_addr_t *ipv6_addr,
uint16_t dir_port,
int serverdesc, int serverdesc,
int microdesc) int microdesc)
{ {
tor_addr_port_t ipv4_dir_ap, ipv6_dir_ap; tor_addr_port_t ipv4_dir_ap, ipv6_dir_ap;
/* Assume IPv6 DirPort is the same as IPv4 DirPort */ /* Assume IPv6 DirPort is the same as IPv4 DirPort */
tor_addr_from_ipv4h(&ipv4_dir_ap.addr, ds->addr); tor_addr_from_ipv4h(&ipv4_dir_ap.addr, ipv4_addr);
ipv4_dir_ap.port = ds->dir_port; ipv4_dir_ap.port = dir_port;
tor_addr_copy(&ipv6_dir_ap.addr, &ds->ipv6_addr); tor_addr_copy(&ipv6_dir_ap.addr, ipv6_addr);
ipv6_dir_ap.port = ds->dir_port; ipv6_dir_ap.port = dir_port;
return (router_is_already_dir_fetching(&ipv4_dir_ap, serverdesc, microdesc)
|| router_is_already_dir_fetching(&ipv6_dir_ap, serverdesc, microdesc));
}
/* Check if we already have a directory fetch from rs, for serverdesc
* (including extrainfo) or microdesc documents.
* If so, return 1, if not, return 0.
*/
static int
router_is_already_dir_fetching_rs(const routerstatus_t *rs,
int serverdesc,
int microdesc)
{
tor_addr_port_t ipv4_dir_ap, ipv6_dir_ap;
/* Assume IPv6 DirPort is the same as IPv4 DirPort */
tor_addr_from_ipv4h(&ipv4_dir_ap.addr, rs->addr);
ipv4_dir_ap.port = rs->dir_port;
tor_addr_copy(&ipv6_dir_ap.addr, &rs->ipv6_addr);
ipv6_dir_ap.port = rs->dir_port;
return (router_is_already_dir_fetching(&ipv4_dir_ap, serverdesc, microdesc) return (router_is_already_dir_fetching(&ipv4_dir_ap, serverdesc, microdesc)
|| router_is_already_dir_fetching(&ipv6_dir_ap, serverdesc, microdesc)); || router_is_already_dir_fetching(&ipv6_dir_ap, serverdesc, microdesc));
@ -1954,6 +1935,21 @@ router_picked_poor_directory_log(const routerstatus_t *rs)
} \ } \
STMT_END STMT_END
/* Common code used in the loop within router_pick_directory_server_impl and
* router_pick_trusteddirserver_impl.
*
* Check if the given <b>identity</b> supports extrainfo. If not, skip further
* checks.
*/
#define SKIP_MISSING_TRUSTED_EXTRAINFO(type, identity) \
STMT_BEGIN \
int is_trusted_extrainfo = router_digest_is_trusted_dir_type( \
(identity), EXTRAINFO_DIRINFO); \
if (((type) & EXTRAINFO_DIRINFO) && \
!router_supports_extrainfo((identity), is_trusted_extrainfo)) \
continue; \
STMT_END
/* When iterating through the routerlist, can OR address/port preference /* When iterating through the routerlist, can OR address/port preference
* and reachability checks be skipped? * and reachability checks be skipped?
*/ */
@ -2026,7 +2022,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
/* Find all the running dirservers we know about. */ /* Find all the running dirservers we know about. */
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) { SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
int is_trusted, is_trusted_extrainfo; int is_trusted;
int is_overloaded; int is_overloaded;
const routerstatus_t *status = node->rs; const routerstatus_t *status = node->rs;
const country_t country = node->country; const country_t country = node->country;
@ -2037,12 +2033,9 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
continue; continue;
if (requireother && router_digest_is_me(node->identity)) if (requireother && router_digest_is_me(node->identity))
continue; continue;
is_trusted = router_digest_is_trusted_dir(node->identity);
is_trusted_extrainfo = router_digest_is_trusted_dir_type( SKIP_MISSING_TRUSTED_EXTRAINFO(type, node->identity);
node->identity, EXTRAINFO_DIRINFO);
if ((type & EXTRAINFO_DIRINFO) &&
!router_supports_extrainfo(node->identity, is_trusted_extrainfo))
continue;
#ifdef ENABLE_LEGACY_GUARD_ALGORITHM #ifdef ENABLE_LEGACY_GUARD_ALGORITHM
/* Don't make the same node a guard twice */ /* Don't make the same node a guard twice */
if (for_guard && is_node_used_as_guard(node)) { if (for_guard && is_node_used_as_guard(node)) {
@ -2060,7 +2053,9 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
continue; continue;
} }
if (router_is_already_dir_fetching_rs(status, if (router_is_already_dir_fetching_(status->addr,
&status->ipv6_addr,
status->dir_port,
no_serverdesc_fetching, no_serverdesc_fetching,
no_microdesc_fetching)) { no_microdesc_fetching)) {
++n_busy; ++n_busy;
@ -2068,6 +2063,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
} }
is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now; is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
is_trusted = router_digest_is_trusted_dir(node->identity);
/* Clients use IPv6 addresses if the server has one and the client /* Clients use IPv6 addresses if the server has one and the client
* prefers IPv6. * prefers IPv6.
@ -2199,11 +2195,9 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
if (!d->is_running) continue; if (!d->is_running) continue;
if ((type & d->type) == 0) if ((type & d->type) == 0)
continue; continue;
int is_trusted_extrainfo = router_digest_is_trusted_dir_type(
d->digest, EXTRAINFO_DIRINFO); SKIP_MISSING_TRUSTED_EXTRAINFO(type, d->digest);
if ((type & EXTRAINFO_DIRINFO) &&
!router_supports_extrainfo(d->digest, is_trusted_extrainfo))
continue;
if (requireother && me && router_digest_is_me(d->digest)) if (requireother && me && router_digest_is_me(d->digest))
continue; continue;
if (try_excluding && if (try_excluding &&
@ -2213,7 +2207,10 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
continue; continue;
} }
if (router_is_already_dir_fetching_ds(d, no_serverdesc_fetching, if (router_is_already_dir_fetching_(d->addr,
&d->ipv6_addr,
d->dir_port,
no_serverdesc_fetching,
no_microdesc_fetching)) { no_microdesc_fetching)) {
++n_busy; ++n_busy;
continue; continue;