mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
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
This commit is contained in:
parent
016adc9a08
commit
056d97da0c
@ -649,11 +649,13 @@ tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
|
|||||||
* preceeds addr2, and greater than 0 otherwise.
|
* preceeds addr2, and greater than 0 otherwise.
|
||||||
*
|
*
|
||||||
* Different address families (IPv4 vs IPv6) are always considered unequal.
|
* Different address families (IPv4 vs IPv6) are always considered unequal.
|
||||||
|
* NOT QUITE XXXX DOCDOC.
|
||||||
*/
|
*/
|
||||||
int
|
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
|
/** 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
|
int
|
||||||
tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
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;
|
uint32_t ip4a=0, ip4b=0;
|
||||||
sa_family_t v_family[2];
|
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);
|
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
|
/* 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
|
* 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.
|
* same in the first 16 bits, it will say "yes." That's not so intuitive.
|
||||||
|
@ -81,11 +81,19 @@ tor_addr_to_in(const tor_addr_t *a)
|
|||||||
|
|
||||||
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
|
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
|
||||||
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
|
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
|
||||||
|
|
||||||
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
|
int get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr);
|
||||||
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2);
|
|
||||||
|
/** DOCDOC */
|
||||||
|
typedef enum {
|
||||||
|
CMP_EXACT,
|
||||||
|
CMP_SEMANTIC,
|
||||||
|
} tor_addr_comparison_t;
|
||||||
|
|
||||||
|
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||||
|
tor_addr_comparison_t how);
|
||||||
int tor_addr_compare_masked(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 mask);
|
maskbits_t mask, tor_addr_comparison_t how);
|
||||||
|
|
||||||
unsigned int tor_addr_hash(const tor_addr_t *addr);
|
unsigned int tor_addr_hash(const tor_addr_t *addr);
|
||||||
int tor_addr_is_v4(const tor_addr_t *addr);
|
int tor_addr_is_v4(const tor_addr_t *addr);
|
||||||
int tor_addr_is_internal(const tor_addr_t *ip, int for_listening) ATTR_PURE;
|
int tor_addr_is_internal(const tor_addr_t *ip, int for_listening) ATTR_PURE;
|
||||||
|
@ -409,7 +409,7 @@ cmp_single_addr_policy(addr_policy_t *a, addr_policy_t *b)
|
|||||||
return r;
|
return r;
|
||||||
if ((r=((int)a->is_private - (int)b->is_private)))
|
if ((r=((int)a->is_private - (int)b->is_private)))
|
||||||
return r;
|
return r;
|
||||||
if ((r=tor_addr_compare(&a->addr, &b->addr)))
|
if ((r=tor_addr_compare(&a->addr, &b->addr, CMP_EXACT)))
|
||||||
return r;
|
return r;
|
||||||
if ((r=((int)a->maskbits - (int)b->maskbits)))
|
if ((r=((int)a->maskbits - (int)b->maskbits)))
|
||||||
return r;
|
return r;
|
||||||
@ -558,7 +558,8 @@ compare_addr_to_addr_policy(uint32_t _addr, uint16_t port,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Address is known */
|
/* Address is known */
|
||||||
if (!tor_addr_compare_masked(&addr, &tmpe->addr, tmpe->maskbits)) {
|
if (!tor_addr_compare_masked(&addr, &tmpe->addr, tmpe->maskbits,
|
||||||
|
CMP_SEMANTIC)) {
|
||||||
if (port >= tmpe->prt_min && port <= tmpe->prt_max) {
|
if (port >= tmpe->prt_min && port <= tmpe->prt_max) {
|
||||||
/* Exact match for the policy */
|
/* Exact match for the policy */
|
||||||
match = 1;
|
match = 1;
|
||||||
@ -601,7 +602,7 @@ addr_policy_covers(addr_policy_t *a, addr_policy_t *b)
|
|||||||
/* a has more fixed bits than b; it can't possibly cover b. */
|
/* a has more fixed bits than b; it can't possibly cover b. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tor_addr_compare_masked(&a->addr, &b->addr, a->maskbits)) {
|
if (tor_addr_compare_masked(&a->addr, &b->addr, a->maskbits, CMP_SEMANTIC)) {
|
||||||
/* There's a fixed bit in a that's set differently in b. */
|
/* There's a fixed bit in a that's set differently in b. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -624,7 +625,7 @@ addr_policy_intersects(addr_policy_t *a, addr_policy_t *b)
|
|||||||
minbits = a->maskbits;
|
minbits = a->maskbits;
|
||||||
else
|
else
|
||||||
minbits = b->maskbits;
|
minbits = b->maskbits;
|
||||||
if (tor_addr_compare_masked(&a->addr, &b->addr, minbits))
|
if (tor_addr_compare_masked(&a->addr, &b->addr, minbits, CMP_SEMANTIC))
|
||||||
return 0;
|
return 0;
|
||||||
if (a->prt_max < b->prt_min || b->prt_max < a->prt_min)
|
if (a->prt_max < b->prt_min || b->prt_max < a->prt_min)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1272,7 +1272,7 @@ _test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1,
|
|||||||
test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
|
test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
|
||||||
test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
|
test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
|
||||||
t1.family = t2.family = AF_INET6; \
|
t1.family = t2.family = AF_INET6; \
|
||||||
r = tor_addr_compare(&t1,&t2); \
|
r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \
|
||||||
if (!(r op 0)) \
|
if (!(r op 0)) \
|
||||||
test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \
|
test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \
|
||||||
STMT_END
|
STMT_END
|
||||||
@ -1284,7 +1284,7 @@ _test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1,
|
|||||||
test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
|
test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
|
||||||
test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
|
test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
|
||||||
t1.family = t2.family = AF_INET6; \
|
t1.family = t2.family = AF_INET6; \
|
||||||
r = tor_addr_compare_masked(&t1,&t2,m); \
|
r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \
|
||||||
if (!(r op 0)) \
|
if (!(r op 0)) \
|
||||||
test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \
|
test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \
|
||||||
STMT_END
|
STMT_END
|
||||||
@ -1445,10 +1445,10 @@ test_util_ip6_helpers(void)
|
|||||||
test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
|
test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
|
||||||
tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL);
|
tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL);
|
||||||
tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
|
tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
|
||||||
test_assert(tor_addr_compare(&t1, &t2) == 0);
|
test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
|
||||||
tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL);
|
tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL);
|
||||||
tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
|
tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL);
|
||||||
test_assert(tor_addr_compare(&t1, &t2) < 0);
|
test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
|
||||||
|
|
||||||
/* test compare_masked */
|
/* test compare_masked */
|
||||||
test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
|
test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
|
||||||
@ -3282,7 +3282,7 @@ test_policies(void)
|
|||||||
test_assert(p != NULL);
|
test_assert(p != NULL);
|
||||||
test_eq(ADDR_POLICY_REJECT, p->policy_type);
|
test_eq(ADDR_POLICY_REJECT, p->policy_type);
|
||||||
tor_addr_from_ipv4h(&tar, 0xc0a80000u);
|
tor_addr_from_ipv4h(&tar, 0xc0a80000u);
|
||||||
test_eq(0, tor_addr_compare(&p->addr, &tar));
|
test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
|
||||||
test_eq(16, p->maskbits);
|
test_eq(16, p->maskbits);
|
||||||
test_eq(1, p->prt_min);
|
test_eq(1, p->prt_min);
|
||||||
test_eq(65535, p->prt_max);
|
test_eq(65535, p->prt_max);
|
||||||
|
Loading…
Reference in New Issue
Block a user