From: Ondřej Surý Date: Tue, 12 Sep 2023 14:33:19 +0000 (+0200) Subject: Use incremental hashing in the isc_sockaddr_hash() function X-Git-Tag: v9.19.18~75^2~4 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=9d326aaba32d28674b20c426537c0014dd044318;p=thirdparty%2Fbind9.git Use incremental hashing in the isc_sockaddr_hash() function Instead of copying address back and forth when hashing addr+port, we can use incremental hashing. Additionally, switch from 64-bit isc_hash_function to 32-bit isc_hash32() as the resulting value is 32-bit. --- diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 9523865c5ae..b9dda2b0c23 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -85,7 +85,7 @@ isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b, * If 'b''s scope is zero then 'a''s scope will be ignored. */ -unsigned int +uint32_t isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only); /*%< * Return a hash value for the socket address 'sockaddr'. If 'address_only' diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index 765e73e5660..020cc58ae99 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -187,51 +187,49 @@ isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) { } } -unsigned int +uint32_t isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, bool address_only) { - unsigned int length = 0; - const unsigned char *s = NULL; - unsigned int h = 0; + REQUIRE(sockaddr != NULL); + + size_t len = 0; + const uint8_t *s = NULL; unsigned int p = 0; const struct in6_addr *in6; + isc_hash32_t hash; - REQUIRE(sockaddr != NULL); + isc_hash32_init(&hash); switch (sockaddr->type.sa.sa_family) { case AF_INET: - s = (const unsigned char *)&sockaddr->type.sin.sin_addr; - p = ntohs(sockaddr->type.sin.sin_port); - length = sizeof(sockaddr->type.sin.sin_addr.s_addr); + s = (const uint8_t *)&sockaddr->type.sin.sin_addr; + len = sizeof(sockaddr->type.sin.sin_addr.s_addr); + if (!address_only) { + p = ntohs(sockaddr->type.sin.sin_port); + } break; case AF_INET6: in6 = &sockaddr->type.sin6.sin6_addr; - s = (const unsigned char *)in6; + s = (const uint8_t *)in6; if (IN6_IS_ADDR_V4MAPPED(in6)) { s += 12; - length = sizeof(sockaddr->type.sin.sin_addr.s_addr); + len = sizeof(sockaddr->type.sin.sin_addr.s_addr); } else { - length = sizeof(sockaddr->type.sin6.sin6_addr); + len = sizeof(sockaddr->type.sin6.sin6_addr); + } + if (!address_only) { + p = ntohs(sockaddr->type.sin6.sin6_port); } - p = ntohs(sockaddr->type.sin6.sin6_port); break; default: - UNEXPECTED_ERROR("unknown address family: %d", - (int)sockaddr->type.sa.sa_family); - s = (const unsigned char *)&sockaddr->type; - length = sockaddr->length; - p = 0; + UNREACHABLE(); } - uint8_t buf[sizeof(struct sockaddr_storage) + sizeof(p)]; - memmove(buf, s, length); + isc_hash32_hash(&hash, s, len, true); if (!address_only) { - memmove(buf + length, &p, sizeof(p)); - h = isc_hash_function(buf, length + sizeof(p), true); - } else { - h = isc_hash_function(buf, length, true); + isc_hash32_hash(&hash, &p, sizeof(p), true); } - return (h); + return (isc_hash32_finalize(&hash)); } void