Commit c54091c8 authored by Mark Andrews's avatar Mark Andrews
Browse files

IPv6 addresses containing mapped IPv4 addresses generate the same hash

value as the equivalent IPv4 address.  This is now true regardless of
the value of address_only.  Document.
parent e1fdebdc
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sockaddr.h,v 1.35 2001/01/09 21:57:33 bwelling Exp $ */
/* $Id: sockaddr.h,v 1.36 2001/10/02 06:06:13 marka Exp $ */
#ifndef ISC_SOCKADDR_H
#define ISC_SOCKADDR_H 1
......@@ -64,6 +64,9 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only);
/*
* Return a hash value for the socket address 'sockaddr'. If 'address_only'
* is ISC_TRUE, the hash value will not depend on the port.
*
* IPv6 addresses containing mapped IPv4 addresses generate the same hash
* value as the equivalent IPv4 address.
*/
void
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sockaddr.c,v 1.49 2001/09/17 06:58:18 marka Exp $ */
/* $Id: sockaddr.c,v 1.50 2001/10/02 06:06:15 marka Exp $ */
#include <config.h>
......@@ -175,47 +175,45 @@ isc_sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size) {
unsigned int
isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
unsigned int length;
const unsigned char *s;
unsigned int length = 0;
const unsigned char *s = NULL;
unsigned int h = 0;
unsigned int g;
unsigned int p = 0;
const struct in6_addr *in6;
REQUIRE(sockaddr != NULL);
if (address_only) {
switch (sockaddr->type.sa.sa_family) {
case AF_INET:
return (ntohl(sockaddr->type.sin.sin_addr.s_addr));
case AF_INET6:
in6 = &sockaddr->type.sin6.sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(in6)) {
g = (in6->s6_addr[12] << 24) |
(in6->s6_addr[13] << 16) |
(in6->s6_addr[14] << 8) |
in6->s6_addr[15];
return (g);
}
switch (sockaddr->type.sa.sa_family) {
case AF_INET:
h = ntohl(sockaddr->type.sin.sin_addr.s_addr);
p = ntohs(sockaddr->type.sin.sin_port);
break;
case AF_INET6:
in6 = &sockaddr->type.sin6.sin6_addr;
if (IN6_IS_ADDR_V4MAPPED(in6)) {
h = (in6->s6_addr[12] << 24) |
(in6->s6_addr[13] << 16) |
(in6->s6_addr[14] << 8) |
in6->s6_addr[15];
} else {
s = (const unsigned char *)&sockaddr->
type.sin6.sin6_addr;
type.sin6.sin6_addr;
length = sizeof sockaddr->type.sin6.sin6_addr;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_SOCKADDR,
ISC_MSG_UNKNOWNFAMILY,
"unknown "
"address family: %d"),
(int)sockaddr->type.sa.sa_family);
s = (const unsigned char *)&sockaddr->type;
length = sockaddr->length;
}
} else {
p = ntohs(sockaddr->type.sin6.sin6_port);
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
isc_msgcat_get(isc_msgcat,
ISC_MSGSET_SOCKADDR,
ISC_MSG_UNKNOWNFAMILY,
"unknown address family: %d"),
(int)sockaddr->type.sa.sa_family);
s = (const unsigned char *)&sockaddr->type;
length = sockaddr->length;
p = 0;
}
while (length > 0) {
h = ( h << 4 ) + *s;
if ((g = ( h & 0xf0000000 )) != 0) {
......@@ -225,6 +223,13 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
s++;
length--;
}
if (!address_only) {
h = h ^ (p << 4);
if ((g = ( h & 0xf0000000 )) != 0) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
return (h);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment