Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8250630: test/jdk/com/sun/jdi/JdwpListenTest.java fails on Alpine Linux
Make sure that IN6ADDR_ANY is preferred over mapped INADDR_ANY

Reviewed-by: amenkov, sspitsyn
  • Loading branch information
Dmitry Samersoff committed Aug 30, 2020
1 parent 5eaef6d commit ffd78a95b20d6841f9d9d31534d0d48577ffb250
Showing with 39 additions and 10 deletions.
  1. +39 −10 src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -702,6 +702,15 @@ static jdwpTransportError startListening(struct addrinfo *ai, int *socket, char*
return JDWPTRANSPORT_ERROR_NONE;
}

static int isEqualIPv6Addr(const struct addrinfo *ai, const struct in6_addr in6Addr)
{
if (ai->ai_addr->sa_family == AF_INET6) {
const struct sockaddr_in6 sa = *((struct sockaddr_in6*) ai->ai_addr);
return (memcmp(&sa.sin6_addr, &in6Addr, sizeof(in6Addr)) == 0);
}
return 0;
}

static jdwpTransportError JNICALL
socketTransport_startListening(jdwpTransportEnv* env, const char* address,
char** actualAddress)
@@ -711,6 +720,7 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
struct addrinfo *addrInfo = NULL;
struct addrinfo *listenAddr = NULL;
struct addrinfo *ai = NULL;
struct in6_addr mappedAny = IN6ADDR_ANY_INIT;

/* no address provided */
if ((address == NULL) || (address[0] == '\0')) {
@@ -722,23 +732,42 @@ socketTransport_startListening(jdwpTransportEnv* env, const char* address,
return err;
}

/* 1st pass - preferredAddressFamily (by default IPv4), 2nd pass - the rest */
for (pass = 0; pass < 2 && listenAddr == NULL; pass++) {
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
if ((pass == 0 && ai->ai_family == preferredAddressFamily) ||
(pass == 1 && ai->ai_family != preferredAddressFamily))
{
listenAddr = ai;
break;
}
// Try to find bind address of preferred address family first.
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family == preferredAddressFamily) {
listenAddr = ai;
break;
}
}

if (listenAddr == NULL) {
// No address of preferred addres family found, grab the fist one.
listenAddr = &(addrInfo[0]);
}

if (listenAddr == NULL) {
dbgsysFreeAddrInfo(addrInfo);
RETURN_ERROR(JDWPTRANSPORT_ERROR_INTERNAL, "listen failed: wrong address");
}

// Binding to IN6ADDR_ANY allows to serve both IPv4 and IPv6 connections,
// but binding to mapped INADDR_ANY (::ffff:0.0.0.0) allows to serve IPv4
// connections only. Make sure that IN6ADDR_ANY is preferred over
// mapped INADDR_ANY if preferredAddressFamily is AF_INET6 or not set.

if (preferredAddressFamily != AF_INET) {
inet_pton(AF_INET6, "::ffff:0.0.0.0", &mappedAny);

if (isEqualIPv6Addr(listenAddr, mappedAny)) {
for (ai = addrInfo; ai != NULL; ai = ai->ai_next) {
if (isEqualIPv6Addr(listenAddr, in6addr_any)) {
listenAddr = ai;
break;
}
}
}
}

err = startListening(listenAddr, &serverSocketFD, actualAddress);

dbgsysFreeAddrInfo(addrInfo);

0 comments on commit ffd78a9

Please sign in to comment.