From 0a3e6d81bba31ca19ce412d943901f43f54c4894 Mon Sep 17 00:00:00 2001 From: Neel Chauhan Date: Thu, 11 Jun 2020 12:27:40 -0700 Subject: [PATCH 1/3] Make routerset_contains_router() support IPv6 --- src/feature/nodelist/routerset.c | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index 2e06ecbf04..ebc08b7a51 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -223,11 +223,11 @@ routerset_len(const routerset_t *set) * * (If country is -1, then we take the country * from addr.) */ -STATIC int -routerset_contains(const routerset_t *set, const tor_addr_t *addr, - uint16_t orport, - const char *nickname, const char *id_digest, - country_t country) +static int +routerset_contains2(const routerset_t *set, const tor_addr_t *addr, + uint16_t orport, const tor_addr_t *addr2, + uint16_t orport2, const char *nickname, + const char *id_digest, country_t country) { if (!set || !set->list) return 0; @@ -238,6 +238,9 @@ routerset_contains(const routerset_t *set, const tor_addr_t *addr, if (addr && compare_tor_addr_to_addr_policy(addr, orport, set->policies) == ADDR_POLICY_REJECTED) return 3; + if (addr2 && compare_tor_addr_to_addr_policy(addr2, orport2, set->policies) + == ADDR_POLICY_REJECTED) + return 3; if (set->countries) { if (country < 0 && addr) country = geoip_get_country_by_addr(addr); @@ -249,6 +252,17 @@ routerset_contains(const routerset_t *set, const tor_addr_t *addr, return 0; } +/** Helper. Like routerset_contains2() but for a single IP/port combo. + */ +STATIC int +routerset_contains(const routerset_t *set, const tor_addr_t *addr, + uint16_t orport, const char *nickname, + const char *id_digest, country_t country) +{ + return routerset_contains2(set, addr, orport, NULL, 0, + nickname, id_digest, country); +} + /** If *setp includes at least one country code, or if * only_some_cc_set is 0, add the ?? and A1 country codes to * *setp, creating it as needed. Return true iff *setp changed. @@ -306,14 +320,11 @@ int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri, country_t country) { - tor_addr_t addr; - tor_addr_from_ipv4h(&addr, ri->addr); - return routerset_contains(set, - &addr, - ri->or_port, - ri->nickname, - ri->cache_info.identity_digest, - country); + tor_addr_t addr_v4; + tor_addr_from_ipv4h(&addr_v4, ri->addr); + return routerset_contains2(set, &addr_v4, ri->or_port, &ri->ipv6_addr, + ri->ipv6_orport, ri->nickname, + ri->cache_info.identity_digest, country); } /** Return true iff rs is in set. If country is -1, we From 6209939e864e5bfb951cb0406c24a85c27a7811a Mon Sep 17 00:00:00 2001 From: Neel Chauhan Date: Thu, 11 Jun 2020 13:13:13 -0700 Subject: [PATCH 2/3] Add changes file for ticket #34065 --- changes/bug34065 | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changes/bug34065 diff --git a/changes/bug34065 b/changes/bug34065 new file mode 100644 index 0000000000..f81cb77c21 --- /dev/null +++ b/changes/bug34065 @@ -0,0 +1,5 @@ + o Minor features (IPv6, ExcludeNodes): + - Make routerset_contains_router() capable of handling IPv6 + addresses. This makes ExcludeNodes capable of excluding an + IPv6 adddress. Previously, ExcludeNodes ignored IPv6 + addresses. Closes ticket 34065. Patch by Neel Chauhan. From c3c7ef5125fe1db59f6017390e6b068b1faaad27 Mon Sep 17 00:00:00 2001 From: Neel Chauhan Date: Mon, 22 Jun 2020 11:51:01 -0700 Subject: [PATCH 3/3] Add routerset_contains_router() test --- src/test/test_routerset.c | 56 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c index 892ac6e210..7601d5ba0f 100644 --- a/src/test/test_routerset.c +++ b/src/test/test_routerset.c @@ -1417,12 +1417,62 @@ test_rset_contains_router(void *arg) ri.nickname = (char *)nickname; r = routerset_contains_router(set, &ri, country); - tt_int_op(r, OP_EQ, 4); + done: routerset_free(set); } +static void +test_rset_contains_router_ipv4(void *arg) +{ + routerset_t *set; + routerinfo_t ri; + country_t country = 1; + int r; + const char *s; + (void) arg; + + /* IPv4 address test. */ + memset(&ri, 0, sizeof(ri)); + set = routerset_new(); + s = "10.0.0.1"; + r = routerset_parse(set, s, ""); + ri.addr = htonl(0x0a000001); /* 10.0.0.1 */ + ri.or_port = 1234; + + r = routerset_contains_router(set, &ri, country); + tt_int_op(r, OP_EQ, 3); + + done: + routerset_free(set); +} + +static void +test_rset_contains_router_ipv6(void *arg) +{ + routerset_t *set; + routerinfo_t ri; + country_t country = 1; + int r; + const char *s; + (void) arg; + + /* IPv6 address test. */ + memset(&ri, 0, sizeof(ri)); + set = routerset_new(); + s = "2600::1"; + r = routerset_parse(set, s, ""); + tor_addr_parse(&ri.ipv6_addr, "2600::1"); + ri.ipv6_orport = 12345; + + r = routerset_contains_router(set, &ri, country); + tt_int_op(r, OP_EQ, 3); + + done: + routerset_free(set); +} + /* * Functional test for routerset_contains_routerstatus. */ @@ -2144,6 +2194,10 @@ struct testcase_t routerset_tests[] = { { "contains_extendinfo", test_rset_contains_extendinfo, TT_FORK, NULL, NULL }, { "contains_router", test_rset_contains_router, TT_FORK, NULL, NULL }, + { "contains_router_ipv4", test_rset_contains_router_ipv4, + TT_FORK, NULL, NULL }, + { "contains_router_ipv6", test_rset_contains_router_ipv6, + TT_FORK, NULL, NULL }, { "contains_routerstatus", test_rset_contains_routerstatus, TT_FORK, NULL, NULL }, { "contains_none", test_rset_contains_none, TT_FORK, NULL, NULL },