diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-10-11 21:40:35 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-10-11 21:40:35 +0000 |
commit | 3100712c340b9db7195989f1502a8ecbeefe85c9 (patch) | |
tree | dec1240abcf327cffb5ea47fe8fdf22080909d76 | |
parent | 3de8158b1600927068edf5a723c0e447187b203d (diff) | |
download | tor-3100712c340b9db7195989f1502a8ecbeefe85c9.tar tor-3100712c340b9db7195989f1502a8ecbeefe85c9.tar.gz |
r15703@catbus: nickm | 2007-10-11 17:30:34 -0400
Fix for the reported case of bug 438: check families as well as identities in circuit_find_to_cannibalize(). Code audit still pending. ;)
svn:r11886
-rw-r--r-- | src/or/circuitlist.c | 7 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/routerlist.c | 46 |
3 files changed, 50 insertions, 4 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index d46f763f4..84336c2b1 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -801,7 +801,6 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, { circuit_t *_circ; origin_circuit_t *best=NULL; -// or_options_t *options = get_options(); log_debug(LD_CIRC, "Hunting for a circ to cannibalize: purpose %d, uptime %d, " @@ -829,10 +828,16 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, if (info) { /* need to make sure we don't duplicate hops */ crypt_path_t *hop = circ->cpath; + routerinfo_t *ri1 = router_get_by_digest(info->identity_digest); do { + routerinfo_t *ri2; if (!memcmp(hop->extend_info->identity_digest, info->identity_digest, DIGEST_LEN)) goto next; + if (ri1 && + (ri2 = router_get_by_digest(hop->extend_info->identity_digest)) + && routers_in_same_family(ri1, ri2)) + goto next; hop=hop->next; } while (hop!=circ->cpath); } diff --git a/src/or/or.h b/src/or/or.h index 9cd56c3d0..cfa969a0a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3546,6 +3546,7 @@ routerstatus_t *router_pick_trusteddirserver(authority_type_t type, int retry_if_no_servers); void router_reset_status_download_failures(void); void routerlist_add_family(smartlist_t *sl, routerinfo_t *router); +int routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2); void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list, int must_be_running); int router_nickname_is_in_list(routerinfo_t *router, const char *list); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index ac779045b..501803310 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1009,6 +1009,13 @@ router_reset_status_download_failures(void) mark_all_trusteddirservers_up(); } +/** Return true iff router1 and router2 have the same /16 network. */ +static INLINE int +routers_in_same_network_family(routerinfo_t *r1, routerinfo_t *r2) +{ + return (r1->addr & 0xffff0000) == (r2->addr & 0xffff0000); +} + /** Look through the routerlist and identify routers that * advertise the same /16 network address as <b>router</b>. * Add each of them to <b>sl</b>. @@ -1018,8 +1025,7 @@ routerlist_add_network_family(smartlist_t *sl, routerinfo_t *router) { SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r, { - if (router != r && - (router->addr & 0xffff0000) == (r->addr & 0xffff0000)) + if (router != r && routers_in_same_network_family(router, r)) smartlist_add(sl, r); }); } @@ -1056,13 +1062,47 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router) } /* If the user declared any families locally, honor those too. */ - for (cl = get_options()->NodeFamilies; cl; cl = cl->next) { + for (cl = options->NodeFamilies; cl; cl = cl->next) { if (router_nickname_is_in_list(router, cl->value)) { add_nickname_list_to_smartlist(sl, cl->value, 0); } } } +/** Return true iff r is named by some nickname in <b>lst</b>. */ +static INLINE int +router_in_nickname_smartlist(smartlist_t *lst, routerinfo_t *r) +{ + if (!lst) return 0; + SMARTLIST_FOREACH(lst, const char *, name, + if (router_nickname_matches(r, name)) + return 1;); + return 0; +} + +/** Return true iff r1 and r2 are in the same family, but not the same + * router. */ +int +routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2) +{ + or_options_t *options = get_options(); + config_line_t *cl; + + if (options->EnforceDistinctSubnets && routers_in_same_network_family(r1,r2)) + return 1; + + if (router_in_nickname_smartlist(r1->declared_family, r2) && + router_in_nickname_smartlist(r2->declared_family, r1)) + return 1; + + for (cl = options->NodeFamilies; cl; cl = cl->next) { + if (router_nickname_is_in_list(r1, cl->value) && + router_nickname_is_in_list(r2, cl->value)) + return 1; + } + return 0; +} + /** Given a (possibly NULL) comma-and-whitespace separated list of nicknames, * see which nicknames in <b>list</b> name routers in our routerlist, and add * the routerinfos for those routers to <b>sl</b>. If <b>must_be_running</b>, |