X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fsubnet.c;h=17dd39e83b334d1f7774f54dafdb26dd3b7d4f8f;hb=1022812ed4b5c70162f2f0a9d9a96c716c936408;hp=8c766378f1ee84a7ca7880a32ca1f74d648fe008;hpb=9a018c2e371eb1cef9708ac71653f2f2868895fa;p=tinc diff --git a/src/subnet.c b/src/subnet.c index 8c766378..17dd39e8 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -40,6 +40,14 @@ splay_tree_t subnet_tree = { /* Subnet lookup cache */ +static uint32_t wrapping_add32(uint32_t a, uint32_t b) { + return (uint32_t)((uint64_t)a + b); +} + +static uint32_t wrapping_mul32(uint32_t a, uint32_t b) { + return (uint32_t)((uint64_t)a * b); +} + static uint32_t hash_function_ipv4_t(const ipv4_t *p) { /* This basic hash works because @@ -51,7 +59,7 @@ static uint32_t hash_function_ipv4_t(const ipv4_t *p) { #if __BYTE_ORDER == __LITTLE_ENDIAN // 10.0.x.x/16 part - hash += halfwidth[1] * 0x9e370001UL; + hash = wrapping_add32(hash, wrapping_mul32(halfwidth[1], 0x9e370001U)); // x.x.0.[0-255] part #if SUBNET_HASH_SIZE >= 0x10000 @@ -62,7 +70,7 @@ static uint32_t hash_function_ipv4_t(const ipv4_t *p) { #endif // _____LP64_____ #else // 10.0.x.x/16 part - hash += halfwidth[0] * 0x9e370001UL; + hash = wrapping_add32(hash, wrapping_mul32(halfwidth[0], 0x9e370001U)); // x.x.0.[0-255] part (ntohs is nop on big endian) return hash ^ halfwidth[1]; @@ -75,8 +83,8 @@ static uint32_t hash_function_ipv6_t(const ipv6_t *p) { uint32_t hash = hash_seed; for(int i = 0; i < 4; i++) { - hash += fullwidth[i]; - hash *= 0x9e370001UL; + hash = wrapping_add32(hash, fullwidth[i]); + hash = wrapping_mul32(hash, 0x9e370001U); } return hash; @@ -87,8 +95,8 @@ static uint32_t hash_function_mac_t(const mac_t *p) { uint32_t hash = hash_seed; for(int i = 0; i < 3; i++) { - hash += halfwidth[i]; - hash *= 0x9e370001UL; + hash = wrapping_add32(hash, halfwidth[i]); + hash = wrapping_mul32(hash, 0x9e370001U); } return hash; @@ -121,6 +129,9 @@ void subnet_cache_flush_table(subnet_type_t stype) { void init_subnets(void) { hash_seed = (uint32_t)rand(); + + // tables need to be cleared on startup + subnet_cache_flush_tables(); } void exit_subnets(void) {