2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

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.
This commit is contained in:
Ondřej Surý
2023-09-12 16:33:19 +02:00
parent 17b08fa614
commit 9d326aaba3
2 changed files with 23 additions and 25 deletions

View File

@@ -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