diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-07-25 15:11:21 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-07-25 15:11:21 +0000 |
commit | 056d97da0c6c69aa2da9855675b6726f471b5f5a (patch) | |
tree | 7ea7884cc6b035e6d0985b750a1e3d29f067720f /src/common/address.c | |
parent | 016adc9a08bdccf395b41709b5b534edf2298f6e (diff) | |
download | tor-056d97da0c6c69aa2da9855675b6726f471b5f5a.tar.gz tor-056d97da0c6c69aa2da9855675b6726f471b5f5a.zip |
r17391@pc-10-8-1-079: nickm | 2008-07-25 17:11:17 +0200
Tor_addr_compare did a semantic comparison, such that ::1.2.3.4 and 1.2.3.4 were "equal". we sometimes need an exact comparison. Add a feature to do that.
svn:r16210
Diffstat (limited to 'src/common/address.c')
-rw-r--r-- | src/common/address.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/common/address.c b/src/common/address.c index 35ea683cdd..e52c789f31 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -649,11 +649,13 @@ tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src) * preceeds addr2, and greater than 0 otherwise. * * Different address families (IPv4 vs IPv6) are always considered unequal. + * NOT QUITE XXXX DOCDOC. */ int -tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2) +tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2, + tor_addr_comparison_t how) { - return tor_addr_compare_masked(addr1, addr2, 128); + return tor_addr_compare_masked(addr1, addr2, 128, how); } /** As tor_addr_compare(), but only looks at the first <b>mask</b> bits of @@ -663,7 +665,7 @@ tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2) */ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, - maskbits_t mbits) + maskbits_t mbits, tor_addr_comparison_t how) { uint32_t ip4a=0, ip4b=0; sa_family_t v_family[2]; @@ -672,6 +674,28 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, tor_assert(addr1 && addr2); + if (how == CMP_EXACT) { + int r = ((int)addr2->family) - ((int)addr1->family); + if (r) return r; + switch (addr1->family) { + case AF_UNSPEC: + return 0; /* All unspecified addresses are equal */ + case AF_INET: { + uint32_t a1 = ntohl(addr1->addr.in_addr.s_addr); + uint32_t a2 = ntohl(addr2->addr.in_addr.s_addr); + return (a1 < a2) ? -1 : (a1 == a2) ? 0 : 1; + } + case AF_INET6: { + uint32_t *a1 = S6_ADDR32(addr1->addr.in6_addr); + uint32_t *a2 = S6_ADDR32(addr2->addr.in6_addr); + return memcmp(a1, a2, 16); + } + default: + tor_fragile_assert(); + return 0; + } + } + /* XXXX021 this code doesn't handle mask bits right it's using v4-mapped v6 * addresses. If I ask whether ::ffff:1.2.3.4 and ::ffff:1.2.7.8 are the * same in the first 16 bits, it will say "yes." That's not so intuitive. |