diff options
-rw-r--r-- | changes/bug2328 | 3 | ||||
-rw-r--r-- | src/or/connection_edge.c | 23 |
2 files changed, 18 insertions, 8 deletions
diff --git a/changes/bug2328 b/changes/bug2328 index f1a4fa89c5..fee80a1585 100644 --- a/changes/bug2328 +++ b/changes/bug2328 @@ -5,4 +5,5 @@ - Correctly handle the case where AutomapHostsOnResolve is set but no virtual addresses are available. Fixes bug2328, bugfix on 0.1.2.1-alpha. Bug found by doorss. - + - Correctly handle wrapping around to when we run out of virtual address + space. Found by cypherpunks, bugfix on 0.2.0.5-alpha. diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4ae0ccf36a..73ed9fb5c3 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1177,6 +1177,18 @@ address_is_in_virtual_range(const char *address) return 0; } +/** Increment the value of next_virtual_addr; reset it to the start of the + * virtual address range if it wraps around. + */ +static INLINE void +increment_virtual_addr(void) +{ + ++next_virtual_addr; + if (addr_mask_cmp_bits(next_virtual_addr, virtual_addr_network, + virtual_addr_netmask_bits)) + next_virtual_addr = virtual_addr_network; +} + /** Return a newly allocated string holding an address of <b>type</b> * (one of RESOLVED_TYPE_{IPV4|HOSTNAME}) that has not yet been mapped, * and that is very unlikely to be the address of any real host. @@ -1206,7 +1218,7 @@ addressmap_get_virtual_address(int type) /* Don't hand out any .0 or .255 address. */ while ((next_virtual_addr & 0xff) == 0 || (next_virtual_addr & 0xff) == 0xff) { - ++next_virtual_addr; + increment_virtual_addr(); if (! --available) { log_warn(LD_CONFIG, "Ran out of virtual addresses!"); return NULL; @@ -1215,20 +1227,17 @@ addressmap_get_virtual_address(int type) in.s_addr = htonl(next_virtual_addr); tor_inet_ntoa(&in, buf, sizeof(buf)); if (!strmap_get(addressmap, buf)) { - ++next_virtual_addr; + increment_virtual_addr(); break; } - ++next_virtual_addr; + increment_virtual_addr(); --available; - log_info(LD_CONFIG, "%d addrs available", (int)available); + // log_info(LD_CONFIG, "%d addrs available", (int)available); if (! available) { log_warn(LD_CONFIG, "Ran out of virtual addresses!"); return NULL; } - if (addr_mask_cmp_bits(next_virtual_addr, virtual_addr_network, - virtual_addr_netmask_bits)) - next_virtual_addr = virtual_addr_network; } return tor_strdup(buf); } else { |