8319382: com/sun/jdi/JdwpAllowTest.java shows failures on AIX if prefixLen of mask is larger than 32 in IPv6 case

Backport-of: 22642ff0aa
This commit is contained in:
Joachim Kern
2024-01-31 13:06:43 +00:00
committed by Vitaly Provodin
parent 13a90975f4
commit 59b896f488

View File

@@ -395,18 +395,14 @@ parseAddress(const char *address, struct addrinfo **result) {
return getAddrInfo(address, hostnameLen, port, &hints, result);
}
/*
* Input is sockaddr just because all clients have it.
*/
static void convertIPv4ToIPv6(const struct sockaddr *addr4, struct in6_addr *addr6) {
static void convertIPv4ToIPv6(const struct in_addr *addr4, struct in6_addr *addr6) {
// Implement in a platform-independent way.
// Spec requires in_addr has s_addr member, in6_addr has s6_addr[16] member.
struct in_addr *a4 = &(((struct sockaddr_in*)addr4)->sin_addr);
memset(addr6, 0, sizeof(*addr6)); // for safety
// Mapped address contains 80 zero bits, then 16 "1" bits, then IPv4 address (4 bytes).
addr6->s6_addr[10] = addr6->s6_addr[11] = 0xFF;
memcpy(&(addr6->s6_addr[12]), &(a4->s_addr), 4);
memcpy(&(addr6->s6_addr[12]), &(addr4->s_addr), 4);
}
/*
@@ -415,37 +411,19 @@ static void convertIPv4ToIPv6(const struct sockaddr *addr4, struct in6_addr *add
*/
static jdwpTransportError
parseAllowedAddr(const char *buffer, struct in6_addr *result, int *isIPv4) {
struct addrinfo hints;
struct addrinfo *addrInfo = NULL;
jdwpTransportError err;
/*
* To parse both IPv4 and IPv6 need to specify AF_UNSPEC family
* (with AF_INET6 IPv4 addresses are not parsed even with AI_V4MAPPED and AI_ALL flags).
*/
memset (&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // IPv6 or mapped IPv4
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_NUMERICHOST; // only numeric addresses, no resolution
err = getAddrInfo(buffer, strlen(buffer), NULL, &hints, &addrInfo);
if (err != JDWPTRANSPORT_ERROR_NONE) {
return err;
}
if (addrInfo->ai_family == AF_INET6) {
memcpy(result, &(((struct sockaddr_in6 *)(addrInfo->ai_addr))->sin6_addr), sizeof(*result));
struct in_addr addr;
struct in6_addr addr6;
if (inet_pton(AF_INET6, buffer, &addr6) == 1) {
*isIPv4 = 0;
} else { // IPv4 address - convert to mapped IPv6
struct in6_addr addr6;
convertIPv4ToIPv6(addrInfo->ai_addr, &addr6);
memcpy(result, &addr6, sizeof(*result));
} else if (inet_pton(AF_INET, buffer, &addr) == 1) {
// IPv4 address - convert to mapped IPv6
convertIPv4ToIPv6(&addr, &addr6);
*isIPv4 = 1;
} else {
return JDWPTRANSPORT_ERROR_IO_ERROR;
}
dbgsysFreeAddrInfo(addrInfo);
memcpy(result, &addr6, sizeof(*result));
return JDWPTRANSPORT_ERROR_NONE;
}
@@ -603,7 +581,8 @@ isPeerAllowed(struct sockaddr_storage *peer) {
int i;
// _peers contains IPv6 subnet and mask (IPv4 is converted to mapped IPv6)
if (peer->ss_family == AF_INET) {
convertIPv4ToIPv6((struct sockaddr *)peer, &tmp);
struct in_addr *addr4 = &(((struct sockaddr_in*)peer)->sin_addr);
convertIPv4ToIPv6(addr4, &tmp);
addr6 = &tmp;
} else {
addr6 = &(((struct sockaddr_in6 *)peer)->sin6_addr);