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:
@@ -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
|
||||
|
Reference in New Issue
Block a user