mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8241336: Some java.net tests failed with NoRouteToHostException on MacOS with special network configuration
NetworkConfiguration updated to skip interfaces that have only IPv6 link local addresses. Reviewed-by: alanb, chegar
This commit is contained in:
parent
bb7a8f643f
commit
5ddbcb7a51
5 changed files with 114 additions and 52 deletions
|
@ -620,11 +620,6 @@ javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java 8042215
|
||||||
|
|
||||||
# jdk_net
|
# jdk_net
|
||||||
|
|
||||||
java/net/InetAddress/CheckJNI.java 8241336 macosx-all
|
|
||||||
java/net/Socket/LinkLocal.java 8241336 macosx-all
|
|
||||||
java/net/MulticastSocket/SetOutgoingIf.java 8241336 macosx-all
|
|
||||||
java/net/MulticastSocket/Promiscuous.java 8241336 macosx-all
|
|
||||||
|
|
||||||
java/net/MulticastSocket/NoLoopbackPackets.java 7122846 macosx-all
|
java/net/MulticastSocket/NoLoopbackPackets.java 7122846 macosx-all
|
||||||
java/net/MulticastSocket/SetLoopbackMode.java 7122846 macosx-all
|
java/net/MulticastSocket/SetLoopbackMode.java 7122846 macosx-all
|
||||||
|
|
||||||
|
@ -643,9 +638,6 @@ java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc6
|
||||||
|
|
||||||
java/nio/Buffer/EqualsCompareTest.java 8193917 solaris-all
|
java/nio/Buffer/EqualsCompareTest.java 8193917 solaris-all
|
||||||
|
|
||||||
java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java 8241336 macosx-all
|
|
||||||
java/nio/channels/DatagramChannel/AdaptorMulticasting.java 8241336 macosx-all
|
|
||||||
|
|
||||||
java/nio/channels/DatagramChannel/ChangingAddress.java 7141822 macosx-all
|
java/nio/channels/DatagramChannel/ChangingAddress.java 7141822 macosx-all
|
||||||
|
|
||||||
java/nio/channels/DatagramChannel/Unref.java 8233519 generic-all
|
java/nio/channels/DatagramChannel/Unref.java 8233519 generic-all
|
||||||
|
|
|
@ -32,7 +32,11 @@
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
|
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
|
||||||
|
import jdk.test.lib.NetworkConfiguration;
|
||||||
import jdk.test.lib.net.IPSupport;
|
import jdk.test.lib.net.IPSupport;
|
||||||
|
|
||||||
public class Promiscuous {
|
public class Promiscuous {
|
||||||
|
@ -69,8 +73,9 @@ public class Promiscuous {
|
||||||
}
|
}
|
||||||
} catch (SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
if (datagramExpected)
|
if (datagramExpected)
|
||||||
throw new RuntimeException("Expected message not received, "
|
throw new RuntimeException(mc.getLocalSocketAddress()
|
||||||
+ e.getMessage());
|
+ ": Expected message not received, "
|
||||||
|
+ e.getMessage());
|
||||||
else
|
else
|
||||||
out.printf("Message not received, as expected\n");
|
out.printf("Message not received, as expected\n");
|
||||||
}
|
}
|
||||||
|
@ -90,6 +95,10 @@ public class Promiscuous {
|
||||||
UUID = "<" + s1 + s2 + ">";
|
UUID = "<" + s1 + s2 + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SocketAddress toSocketAddress(InetAddress group) {
|
||||||
|
return new InetSocketAddress(group, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void test(InetAddress group1, InetAddress group2)
|
static void test(InetAddress group1, InetAddress group2)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
@ -107,10 +116,21 @@ public class Promiscuous {
|
||||||
p.setAddress(group1);
|
p.setAddress(group1);
|
||||||
p.setPort(port);
|
p.setPort(port);
|
||||||
|
|
||||||
mc1.joinGroup(group1);
|
// join groups on all network interfaces
|
||||||
out.printf("mc1 joined the MC group: %s\n", group1);
|
NetworkConfiguration.probe()
|
||||||
mc2.joinGroup(group2);
|
.multicastInterfaces(false)
|
||||||
out.printf("mc2 joined the MC group: %s\n", group2);
|
.forEach((nic) -> {
|
||||||
|
try {
|
||||||
|
mc1.joinGroup(toSocketAddress(group1), nic);
|
||||||
|
out.printf("mc1 joined the MC group on %s: %s\n",
|
||||||
|
nic.getDisplayName(), group1);
|
||||||
|
mc2.joinGroup(toSocketAddress(group2), nic);
|
||||||
|
out.printf("mc2 joined the MC group on %s: %s\n",
|
||||||
|
nic.getDisplayName(), group2);
|
||||||
|
} catch (IOException io) {
|
||||||
|
throw new UncheckedIOException(io);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
out.printf("Sending datagram to: %s/%d\n", group1, port);
|
out.printf("Sending datagram to: %s/%d\n", group1, port);
|
||||||
ds.send(p);
|
ds.send(p);
|
||||||
|
@ -132,8 +152,21 @@ public class Promiscuous {
|
||||||
receive(mc2, true, nextId);
|
receive(mc2, true, nextId);
|
||||||
receive(mc1, false, 0);
|
receive(mc1, false, 0);
|
||||||
|
|
||||||
mc1.leaveGroup(group1);
|
// leave groups on all network interfaces
|
||||||
mc2.leaveGroup(group2);
|
NetworkConfiguration.probe()
|
||||||
|
.multicastInterfaces(false)
|
||||||
|
.forEach((nic) -> {
|
||||||
|
try {
|
||||||
|
mc1.leaveGroup(toSocketAddress(group1), nic);
|
||||||
|
out.printf("mc1 left the MC group on %s: %s\n",
|
||||||
|
nic.getDisplayName(), group1);
|
||||||
|
mc2.leaveGroup(toSocketAddress(group2), nic);
|
||||||
|
out.printf("mc2 left the MC group on %s: %s\n",
|
||||||
|
nic.getDisplayName(), group2);
|
||||||
|
} catch (IOException io) {
|
||||||
|
throw new UncheckedIOException(io);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +188,8 @@ public class Promiscuous {
|
||||||
}
|
}
|
||||||
|
|
||||||
// multicast groups used for the test
|
// multicast groups used for the test
|
||||||
InetAddress ip4Group1 = InetAddress.getByName("224.0.0.120");
|
InetAddress ip4Group1 = InetAddress.getByName("224.1.1.120");
|
||||||
InetAddress ip4Group2 = InetAddress.getByName("224.0.0.121");
|
InetAddress ip4Group2 = InetAddress.getByName("224.1.1.121");
|
||||||
|
|
||||||
test(ip4Group1, ip4Group2);
|
test(ip4Group1, ip4Group2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,27 @@
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4742177
|
* @bug 4742177
|
||||||
|
* @library /test/lib
|
||||||
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
|
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
|
||||||
*/
|
*/
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import jdk.test.lib.NetworkConfiguration;
|
||||||
|
|
||||||
|
|
||||||
public class SetOutgoingIf {
|
public class SetOutgoingIf implements AutoCloseable {
|
||||||
private static int PORT = 9001;
|
|
||||||
private static String osname;
|
private static String osname;
|
||||||
|
private final MulticastSocket SOCKET;
|
||||||
|
private final int PORT;
|
||||||
|
private SetOutgoingIf() {
|
||||||
|
try {
|
||||||
|
SOCKET = new MulticastSocket();
|
||||||
|
PORT = SOCKET.getLocalPort();
|
||||||
|
} catch (IOException io) {
|
||||||
|
throw new ExceptionInInitializerError(io);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isWindows() {
|
static boolean isWindows() {
|
||||||
if (osname == null)
|
if (osname == null)
|
||||||
|
@ -45,20 +57,24 @@ public class SetOutgoingIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasIPv6() throws Exception {
|
private static boolean hasIPv6() throws Exception {
|
||||||
List<NetworkInterface> nics = Collections.list(
|
return NetworkConfiguration.probe()
|
||||||
NetworkInterface.getNetworkInterfaces());
|
.ip6Addresses()
|
||||||
for (NetworkInterface nic : nics) {
|
.findAny()
|
||||||
List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
|
.isPresent();
|
||||||
for (InetAddress addr : addrs) {
|
|
||||||
if (addr instanceof Inet6Address)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
try (var test = new SetOutgoingIf()) {
|
||||||
|
test.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
SOCKET.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() throws Exception {
|
||||||
if (isWindows()) {
|
if (isWindows()) {
|
||||||
System.out.println("The test only run on non-Windows OS. Bye.");
|
System.out.println("The test only run on non-Windows OS. Bye.");
|
||||||
return;
|
return;
|
||||||
|
@ -99,11 +115,14 @@ public class SetOutgoingIf {
|
||||||
System.out.println("Ignore NetworkInterface nic == " + nic);
|
System.out.println("Ignore NetworkInterface nic == " + nic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Collections.reverse(netIfs);
|
||||||
if (netIfs.size() <= 1) {
|
if (netIfs.size() <= 1) {
|
||||||
System.out.println("Need 2 or more network interfaces to run. Bye.");
|
System.out.println("Need 2 or more network interfaces to run. Bye.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("Using PORT: " + PORT);
|
||||||
|
|
||||||
// We will send packets to one ipv4, and one ipv6
|
// We will send packets to one ipv4, and one ipv6
|
||||||
// multicast group using each network interface :-
|
// multicast group using each network interface :-
|
||||||
// 224.1.1.1 --|
|
// 224.1.1.1 --|
|
||||||
|
@ -177,12 +196,8 @@ public class SetOutgoingIf {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isTestExcludedInterface(NetworkInterface nif) {
|
private static boolean isTestExcludedInterface(NetworkInterface nif) {
|
||||||
if (isMacOS() && nif.getName().contains("awdl"))
|
return !NetworkConfiguration.isTestable(nif)
|
||||||
return true;
|
|| isMacOS() && nif.getName().startsWith("utun");
|
||||||
String dName = nif.getDisplayName();
|
|
||||||
if (isWindows() && dName != null && dName.contains("Teredo"))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean debug = true;
|
private static boolean debug = true;
|
||||||
|
@ -281,4 +296,3 @@ class NetIf {
|
||||||
this.groups = groups;
|
this.groups = groups;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.SocketOption;
|
import java.net.SocketOption;
|
||||||
import java.nio.channels.DatagramChannel;
|
import java.nio.channels.DatagramChannel;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import static java.net.StandardSocketOptions.*;
|
import static java.net.StandardSocketOptions.*;
|
||||||
|
@ -427,7 +428,9 @@ public class AdaptorMulticasting {
|
||||||
assertTrue(s.getOption(IP_MULTICAST_IF) != null);
|
assertTrue(s.getOption(IP_MULTICAST_IF) != null);
|
||||||
|
|
||||||
SocketAddress target = new InetSocketAddress(group, s.getLocalPort());
|
SocketAddress target = new InetSocketAddress(group, s.getLocalPort());
|
||||||
byte[] message = "hello".getBytes("UTF-8");
|
long nano = System.nanoTime();
|
||||||
|
String text = nano + ": hello";
|
||||||
|
byte[] message = text.getBytes("UTF-8");
|
||||||
|
|
||||||
// send datagram to multicast group
|
// send datagram to multicast group
|
||||||
DatagramPacket p = new DatagramPacket(message, message.length);
|
DatagramPacket p = new DatagramPacket(message, message.length);
|
||||||
|
@ -437,10 +440,18 @@ public class AdaptorMulticasting {
|
||||||
// datagram should not be received
|
// datagram should not be received
|
||||||
s.setSoTimeout(500);
|
s.setSoTimeout(500);
|
||||||
p = new DatagramPacket(new byte[1024], 100);
|
p = new DatagramPacket(new byte[1024], 100);
|
||||||
try {
|
while (true) {
|
||||||
s.receive(p);
|
try {
|
||||||
assertTrue(false);
|
s.receive(p);
|
||||||
} catch (SocketTimeoutException expected) { }
|
if (Arrays.equals(p.getData(), p.getOffset(), p.getLength(), message, 0, message.length)) {
|
||||||
|
throw new RuntimeException("message shouldn't have been received");
|
||||||
|
} else {
|
||||||
|
System.out.println("Received unexpected message from " + p.getSocketAddress());
|
||||||
|
}
|
||||||
|
} catch (SocketTimeoutException expected) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,10 +31,11 @@ import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
|
@ -87,9 +88,20 @@ public class NetworkConfiguration {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNotExcludedInterface(NetworkInterface nif) {
|
private static boolean isIPv6LinkLocal(InetAddress a) {
|
||||||
if (Platform.isOSX() && nif.getName().contains("awdl")) {
|
return Inet6Address.class.isInstance(a) && a.isLinkLocalAddress();
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
public static boolean isTestable(NetworkInterface nif) {
|
||||||
|
if (Platform.isOSX()) {
|
||||||
|
if (nif.getName().contains("awdl")) {
|
||||||
|
return false; // exclude awdl
|
||||||
|
}
|
||||||
|
// filter out interfaces that only have link-local addresses
|
||||||
|
return nif.inetAddresses()
|
||||||
|
.filter(Predicate.not(NetworkConfiguration::isIPv6LinkLocal))
|
||||||
|
.findAny()
|
||||||
|
.isPresent();
|
||||||
}
|
}
|
||||||
if (Platform.isWindows()) {
|
if (Platform.isWindows()) {
|
||||||
String dName = nif.getDisplayName();
|
String dName = nif.getDisplayName();
|
||||||
|
@ -201,7 +213,7 @@ public class NetworkConfiguration {
|
||||||
public Stream<NetworkInterface> ip4Interfaces() {
|
public Stream<NetworkInterface> ip4Interfaces() {
|
||||||
return ip4Interfaces.keySet()
|
return ip4Interfaces.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(NetworkConfiguration::isNotExcludedInterface)
|
.filter(NetworkConfiguration::isTestable)
|
||||||
.filter(this::hasIp4Addresses);
|
.filter(this::hasIp4Addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +223,7 @@ public class NetworkConfiguration {
|
||||||
public Stream<NetworkInterface> ip6Interfaces() {
|
public Stream<NetworkInterface> ip6Interfaces() {
|
||||||
return ip6Interfaces.keySet()
|
return ip6Interfaces.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(NetworkConfiguration::isNotExcludedInterface)
|
.filter(NetworkConfiguration::isTestable)
|
||||||
.filter(this::hasIp6Addresses);
|
.filter(this::hasIp6Addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,8 +321,8 @@ public class NetworkConfiguration {
|
||||||
* Return a NetworkConfiguration instance.
|
* Return a NetworkConfiguration instance.
|
||||||
*/
|
*/
|
||||||
public static NetworkConfiguration probe() throws IOException {
|
public static NetworkConfiguration probe() throws IOException {
|
||||||
Map<NetworkInterface, List<Inet4Address>> ip4Interfaces = new HashMap<>();
|
Map<NetworkInterface, List<Inet4Address>> ip4Interfaces = new LinkedHashMap<>();
|
||||||
Map<NetworkInterface, List<Inet6Address>> ip6Interfaces = new HashMap<>();
|
Map<NetworkInterface, List<Inet6Address>> ip6Interfaces = new LinkedHashMap<>();
|
||||||
|
|
||||||
List<NetworkInterface> nifs = list(getNetworkInterfaces());
|
List<NetworkInterface> nifs = list(getNetworkInterfaces());
|
||||||
for (NetworkInterface nif : nifs) {
|
for (NetworkInterface nif : nifs) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue