diff options
author | Sebastian Hahn <sebastian@torproject.org> | 2010-02-05 16:58:24 +0100 |
---|---|---|
committer | Sebastian Hahn <sebastian@torproject.org> | 2010-02-09 09:10:07 +0100 |
commit | 1e49c908f724842a9adf383553689cf2a0aa7a0b (patch) | |
tree | d249927810a483bc6b72861a6bd0aba111038136 /src/or/policies.c | |
parent | 01030a4db2c9aae4479ee9df431a75f41e75025c (diff) | |
download | tor-1e49c908f724842a9adf383553689cf2a0aa7a0b.tar.gz tor-1e49c908f724842a9adf383553689cf2a0aa7a0b.zip |
Speed up the execution of exit_policy_is_general_exit_helper()
It isn't necessary to walk through all possible subnets when the policy
we're looking at doesn't touch that subnet.
Diffstat (limited to 'src/or/policies.c')
-rw-r--r-- | src/or/policies.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/src/or/policies.c b/src/or/policies.c index 3c060aeb73..a49de01e18 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -870,7 +870,7 @@ policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r) static int exit_policy_is_general_exit_helper(smartlist_t *policy, int port) { - uint32_t j; + uint32_t mask, ip, i; /* Is this /8 rejected (1), or undecided (0)? */ char subnet_status[256]; @@ -878,24 +878,30 @@ exit_policy_is_general_exit_helper(smartlist_t *policy, int port) SMARTLIST_FOREACH(policy, addr_policy_t *, p, { if (p->prt_min > port || p->prt_max < port) continue; /* Doesn't cover our port. */ - for (j = 0; j < 256; ++j) { + mask = 0; + tor_assert(p->maskbits <= 32); + + if (p->maskbits) + mask = UINT32_MAX<<(32-p->maskbits); + ip = tor_addr_to_ipv4h(&p->addr); + + /* Calculate the first and last subnet that this exit policy touches + * and set it as loop boundaries. */ + for (i = ((mask & ip)>>24); i <= (~((mask & ip) ^ mask)>>24); ++i) { tor_addr_t addr; - if (subnet_status[j] != 0) + if (subnet_status[i] != 0) continue; /* We already reject some part of this /8 */ - tor_addr_from_ipv4h(&addr, j<<24); + tor_addr_from_ipv4h(&addr, i<<24); if (tor_addr_is_internal(&addr, 0)) continue; /* Local or non-routable addresses */ - if (tor_addr_compare_masked(&addr, &p->addr, p->maskbits, - CMP_EXACT) == 0) { - if (p->policy_type == ADDR_POLICY_ACCEPT) { - if (p->maskbits > 8) - continue; /* Narrower than a /8. */ - /* We found an allowed subnet of at least size /8. Done - * for this port! */ - return 1; - } else if (p->policy_type == ADDR_POLICY_REJECT) { - subnet_status[j] = 1; - } + if (p->policy_type == ADDR_POLICY_ACCEPT) { + if (p->maskbits > 8) + continue; /* Narrower than a /8. */ + /* We found an allowed subnet of at least size /8. Done + * for this port! */ + return 1; + } else if (p->policy_type == ADDR_POLICY_REJECT) { + subnet_status[i] = 1; } } }); |