diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-02-14 12:21:31 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-02-28 08:16:33 -0500 |
commit | 1582adabbb13871bcf6f91be4fa8523aeb36f79a (patch) | |
tree | 7d31fb0d465bc9dbd4149dcc096e79dcb87f3897 /src/or/bridges.c | |
parent | f5995692dadf9bc038455d7e701be84937f28d82 (diff) | |
download | tor-1582adabbb13871bcf6f91be4fa8523aeb36f79a.tar.gz tor-1582adabbb13871bcf6f91be4fa8523aeb36f79a.zip |
Change approach to preventing duplicate guards.
Previously I'd made a bad assumption in the implementation of
prop271 in 0.3.0.1-alpha: I'd assumed that there couldn't be two
guards with the same identity. That's true for non-bridges, but in
the bridge case, we allow two bridges to have the same ID if they
have different addr:port combinations -- in order to have the same
bridge ID running multiple PTs.
Fortunately, this assumption wasn't deeply ingrained: we stop
enforcing the "one guard per ID" rule in the bridge case, and
instead enforce "one guard per <id,addr,port>".
We also needed to tweak our implementation of
get_bridge_info_for_guard, since it made the same incorrect
assumption.
Fixes bug 21027; bugfix on 0.3.0.1-alpha.
Diffstat (limited to 'src/or/bridges.c')
-rw-r--r-- | src/or/bridges.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/or/bridges.c b/src/or/bridges.c index 8b37f412ea..f766931b46 100644 --- a/src/or/bridges.c +++ b/src/or/bridges.c @@ -199,6 +199,33 @@ get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr, return NULL; } +/** + * As get_configured_bridge_by_addr_port, but require that the + * address match <b>addr</b>:<b>port</b>, and that the ID digest match + * <b>digest</b>. (The other function will ignore the address if the + * digest matches.) + */ +bridge_info_t * +get_configured_bridge_by_exact_addr_port_digest(const tor_addr_t *addr, + uint16_t port, + const char *digest) +{ + if (!bridge_list) + return NULL; + SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { + if (!tor_addr_compare(&bridge->addr, addr, CMP_EXACT) && + bridge->port == port) { + + if (digest && tor_memeq(bridge->identity, digest, DIGEST_LEN)) + return bridge; + else if (!digest) + return bridge; + } + + } SMARTLIST_FOREACH_END(bridge); + return NULL; +} + /** If we have a bridge configured whose digest matches <b>digest</b>, or a * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>, * return 1. Else return 0. If <b>digest</b> is NULL, check for |