Commit 1be9e84b authored by Nick Mathewson's avatar Nick Mathewson 🌉
Browse files

Refactor address comparison in get_sybil_list_by_ip_version

parent 2dba6679
...@@ -4208,6 +4208,20 @@ MOCK_IMPL(uint32_t,dirserv_get_bandwidth_for_router_kb, ...@@ -4208,6 +4208,20 @@ MOCK_IMPL(uint32_t,dirserv_get_bandwidth_for_router_kb,
return bw_kb; return bw_kb;
} }
/**
* Helper: compare the address of family `family` in `a` with the address in
* `b`. The family must be one of `AF_INET` and `AF_INET6`.
**/
static int
compare_routerinfo_addrs_by_family(const routerinfo_t *a,
const routerinfo_t *b,
int family)
{
const tor_addr_t *addr1 = (family==AF_INET) ? &a->ipv4_addr : &a->ipv6_addr;
const tor_addr_t *addr2 = (family==AF_INET) ? &b->ipv4_addr : &b->ipv6_addr;
return tor_addr_compare(addr1, addr2, CMP_EXACT);
}
/** Helper for sorting: compares two ipv4 routerinfos first by ipv4 address, /** Helper for sorting: compares two ipv4 routerinfos first by ipv4 address,
* and then by descending order of "usefulness" * and then by descending order of "usefulness"
* (see compare_routerinfo_usefulness) * (see compare_routerinfo_usefulness)
...@@ -4217,9 +4231,7 @@ compare_routerinfo_by_ipv4(const void **a, const void **b) ...@@ -4217,9 +4231,7 @@ compare_routerinfo_by_ipv4(const void **a, const void **b)
{ {
const routerinfo_t *first = *(const routerinfo_t **)a; const routerinfo_t *first = *(const routerinfo_t **)a;
const routerinfo_t *second = *(const routerinfo_t **)b; const routerinfo_t *second = *(const routerinfo_t **)b;
const tor_addr_t *first_ipv4 = &first->ipv4_addr; int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET);
const tor_addr_t *second_ipv4 = &first->ipv4_addr;
int comparison = tor_addr_compare(first_ipv4, second_ipv4, CMP_EXACT);
if (comparison == 0) { if (comparison == 0) {
// If addresses are equal, use other comparison criteria // If addresses are equal, use other comparison criteria
return compare_routerinfo_usefulness(first, second); return compare_routerinfo_usefulness(first, second);
...@@ -4237,9 +4249,7 @@ compare_routerinfo_by_ipv6(const void **a, const void **b) ...@@ -4237,9 +4249,7 @@ compare_routerinfo_by_ipv6(const void **a, const void **b)
{ {
const routerinfo_t *first = *(const routerinfo_t **)a; const routerinfo_t *first = *(const routerinfo_t **)a;
const routerinfo_t *second = *(const routerinfo_t **)b; const routerinfo_t *second = *(const routerinfo_t **)b;
const tor_addr_t *first_ipv6 = &(first->ipv6_addr); int comparison = compare_routerinfo_addrs_by_family(first, second, AF_INET6);
const tor_addr_t *second_ipv6 = &(second->ipv6_addr);
int comparison = tor_addr_compare(first_ipv6, second_ipv6, CMP_EXACT);
// If addresses are equal, use other comparison criteria // If addresses are equal, use other comparison criteria
if (comparison == 0) if (comparison == 0)
return compare_routerinfo_usefulness(first, second); return compare_routerinfo_usefulness(first, second);
...@@ -4309,10 +4319,8 @@ get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family) ...@@ -4309,10 +4319,8 @@ get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family)
const dirauth_options_t *options = dirauth_get_options(); const dirauth_options_t *options = dirauth_get_options();
digestmap_t *omit_as_sybil = digestmap_new(); digestmap_t *omit_as_sybil = digestmap_new();
smartlist_t *routers_by_ip = smartlist_new(); smartlist_t *routers_by_ip = smartlist_new();
int ipv4_addr_count = 0; int addr_count = 0;
int ipv6_addr_count = 0; routerinfo_t *last_ri = NULL;
tor_addr_t last_ipv6_addr, last_ipv4_addr;
int addr_comparison = 0;
/* Allow at most this number of Tor servers on a single IP address, ... */ /* Allow at most this number of Tor servers on a single IP address, ... */
int max_with_same_addr = options->AuthDirMaxServersPerAddr; int max_with_same_addr = options->AuthDirMaxServersPerAddr;
if (max_with_same_addr <= 0) if (max_with_same_addr <= 0)
...@@ -4325,25 +4333,18 @@ get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family) ...@@ -4325,25 +4333,18 @@ get_sybil_list_by_ip_version(const smartlist_t *routers, sa_family_t family)
smartlist_sort(routers_by_ip, compare_routerinfo_by_ipv4); smartlist_sort(routers_by_ip, compare_routerinfo_by_ipv4);
SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) { SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) {
if (family == AF_INET6) { bool addrs_equal;
addr_comparison = tor_addr_compare(&last_ipv6_addr, &(ri->ipv6_addr), if (last_ri)
CMP_EXACT); addrs_equal = !compare_routerinfo_addrs_by_family(last_ri, ri, family);
if (addr_comparison != 0) { else
tor_addr_copy(&last_ipv6_addr, &(ri->ipv6_addr)); addrs_equal = false;
ipv6_addr_count = 1;
} else if (++ipv6_addr_count > max_with_same_addr) { if (! addrs_equal) {
digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri); last_ri = ri;
} addr_count = 1;
} else { } else if (++addr_count > max_with_same_addr) {
addr_comparison = tor_addr_compare(&last_ipv4_addr, &(ri->ipv4_addr),
CMP_EXACT);
if (addr_comparison != 0) {
tor_addr_copy(&last_ipv4_addr, &(ri->ipv4_addr));
ipv4_addr_count = 1;
} else if (++ipv4_addr_count > max_with_same_addr) {
digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri); digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
} }
}
} SMARTLIST_FOREACH_END(ri); } SMARTLIST_FOREACH_END(ri);
smartlist_free(routers_by_ip); smartlist_free(routers_by_ip);
return omit_as_sybil; return omit_as_sybil;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment