diff options
Diffstat (limited to 'src/feature/nodelist/routerset.c')
-rw-r--r-- | src/feature/nodelist/routerset.c | 105 |
1 files changed, 71 insertions, 34 deletions
diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index 2e06ecbf04..0d123956d9 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -56,6 +56,7 @@ routerset_new(void) result->digests = digestmap_new(); result->policies = smartlist_new(); result->country_names = smartlist_new(); + result->fragile = 0; return result; } @@ -223,11 +224,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 +239,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 +253,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 *<b>setp</b> includes at least one country code, or if * <b>only_some_cc_set</b> is 0, add the ?? and A1 country codes to * *<b>setp</b>, creating it as needed. Return true iff *<b>setp</b> changed. @@ -292,12 +307,19 @@ routerset_add_unknown_ccs(routerset_t **setp, int only_if_some_cc_set) int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei) { - return routerset_contains(set, - &ei->addr, - ei->port, - ei->nickname, - ei->identity_digest, - -1 /*country*/); + const tor_addr_port_t *ap1 = NULL, *ap2 = NULL; + if (! tor_addr_is_null(&ei->orports[0].addr)) + ap1 = &ei->orports[0]; + if (! tor_addr_is_null(&ei->orports[1].addr)) + ap2 = &ei->orports[1]; + return routerset_contains2(set, + ap1 ? &ap1->addr : NULL, + ap1 ? ap1->port : 0, + ap2 ? &ap2->addr : NULL, + ap2 ? ap2->port : 0, + ei->nickname, + ei->identity_digest, + -1 /*country*/); } /** Return true iff <b>ri</b> is in <b>set</b>. If country is <b>-1</b>, we @@ -306,14 +328,9 @@ 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); + return routerset_contains2(set, &ri->ipv4_addr, ri->ipv4_orport, + &ri->ipv6_addr, ri->ipv6_orport, ri->nickname, + ri->cache_info.identity_digest, country); } /** Return true iff <b>rs</b> is in <b>set</b>. If country is <b>-1</b>, we @@ -323,11 +340,9 @@ routerset_contains_routerstatus(const routerset_t *set, const routerstatus_t *rs, country_t country) { - tor_addr_t addr; - tor_addr_from_ipv4h(&addr, rs->addr); return routerset_contains(set, - &addr, - rs->or_port, + &rs->ipv4_addr, + rs->ipv4_orport, rs->nickname, rs->identity_digest, country); @@ -485,21 +500,32 @@ routerset_kv_parse(void *target, const config_line_t *line, char **errmsg, const void *params) { (void)params; - routerset_t **p = (routerset_t**)target; - routerset_free(*p); // clear the old value, if any. + routerset_t **lines = target; + + if (*lines && (*lines)->fragile) { + if (line->command == CONFIG_LINE_APPEND) { + (*lines)->fragile = 0; + } else { + routerset_free(*lines); // Represent empty sets as NULL + } + } + + int ret; routerset_t *rs = routerset_new(); if (routerset_parse(rs, line->value, line->key) < 0) { - routerset_free(rs); *errmsg = tor_strdup("Invalid router list."); - return -1; + ret = -1; } else { - if (routerset_is_empty(rs)) { - /* Represent empty sets as NULL. */ - routerset_free(rs); + if (!routerset_is_empty(rs)) { + if (!*lines) { + *lines = routerset_new(); + } + routerset_union(*lines, rs); } - *p = rs; - return 0; + ret = 0; } + routerset_free(rs); + return ret; } /** @@ -550,6 +576,15 @@ routerset_copy(void *dest, const void *src, const void *params) return 0; } +static void +routerset_mark_fragile(void *target, const void *params) +{ + (void)params; + routerset_t **ptr = (routerset_t **)target; + if (*ptr) + (*ptr)->fragile = 1; +} + /** * Function table to implement a routerset_t-based configuration type. **/ @@ -557,7 +592,8 @@ static const var_type_fns_t routerset_type_fns = { .kv_parse = routerset_kv_parse, .encode = routerset_encode, .clear = routerset_clear, - .copy = routerset_copy + .copy = routerset_copy, + .mark_fragile = routerset_mark_fragile, }; /** @@ -571,5 +607,6 @@ static const var_type_fns_t routerset_type_fns = { **/ const var_type_def_t ROUTERSET_type_defn = { .name = "RouterList", - .fns = &routerset_type_fns + .fns = &routerset_type_fns, + .flags = CFLG_NOREPLACE }; |