Skip to content
Permalink
Browse files
8241336: Some java.net tests failed with NoRouteToHostException on Ma…
…cOS with special network configuration

NetworkConfiguration updated to skip interfaces that have only IPv6 link local addresses.

Reviewed-by: shade
Backport-of: 5ddbcb7
  • Loading branch information
RealCLanger committed Aug 27, 2021
1 parent 910e24b commit c816276ee6834332bece428e77583b6e1d80b20b
Showing with 98 additions and 38 deletions.
  1. +44 −10 test/jdk/java/net/MulticastSocket/Promiscuous.java
  2. +33 −19 test/jdk/java/net/MulticastSocket/SetOutgoingIf.java
  3. +21 −9 test/lib/jdk/test/lib/NetworkConfiguration.java
@@ -23,6 +23,7 @@
/* @test
* @bug 8014499 8219804
* @library /test/lib
* @summary Test for interference when two sockets are bound to the same
* port but joined to different multicast groups
* @run main Promiscuous
@@ -31,8 +32,12 @@

import java.io.IOException;
import static java.lang.System.out;

import java.io.UncheckedIOException;
import java.net.*;

import jdk.test.lib.NetworkConfiguration;

public class Promiscuous {

static final int TIMEOUT = 5 * 1000; // 5 secs
@@ -67,8 +72,9 @@ static void receive(MulticastSocket mc, boolean datagramExpected, int id)
}
} catch (SocketTimeoutException e) {
if (datagramExpected)
throw new RuntimeException("Expected message not received, "
+ e.getMessage());
throw new RuntimeException(mc.getLocalSocketAddress()
+ ": Expected message not received, "
+ e.getMessage());
else
out.printf("Message not received, as expected\n");
}
@@ -88,6 +94,10 @@ static void logUnexpected(DatagramPacket p) {
UUID = "<" + s1 + s2 + ">";
}

static SocketAddress toSocketAddress(InetAddress group) {
return new InetSocketAddress(group, 0);
}

static void test(InetAddress group1, InetAddress group2)
throws IOException
{
@@ -105,10 +115,21 @@ static void test(InetAddress group1, InetAddress group2)
p.setAddress(group1);
p.setPort(port);

mc1.joinGroup(group1);
out.printf("mc1 joined the MC group: %s\n", group1);
mc2.joinGroup(group2);
out.printf("mc2 joined the MC group: %s\n", group2);
// join groups on all network interfaces
NetworkConfiguration.probe()
.multicastInterfaces(false)
.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);
ds.send(p);
@@ -130,8 +151,21 @@ static void test(InetAddress group1, InetAddress group2)
receive(mc2, true, nextId);
receive(mc1, false, 0);

mc1.leaveGroup(group1);
mc2.leaveGroup(group2);
// leave groups on all network interfaces
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);
}
});
}
}

@@ -152,8 +186,8 @@ public static void main(String args[]) throws IOException {
}

// multicast groups used for the test
InetAddress ip4Group1 = InetAddress.getByName("224.0.0.120");
InetAddress ip4Group2 = InetAddress.getByName("224.0.0.121");
InetAddress ip4Group1 = InetAddress.getByName("224.1.1.120");
InetAddress ip4Group2 = InetAddress.getByName("224.1.1.121");

test(ip4Group1, ip4Group2);
}
@@ -24,15 +24,27 @@
/*
* @test
* @bug 4742177
* @library /test/lib
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
*/
import java.io.IOException;
import java.net.*;
import java.util.*;
import jdk.test.lib.NetworkConfiguration;


public class SetOutgoingIf {
private static int PORT = 9001;
public class SetOutgoingIf implements AutoCloseable {
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() {
if (osname == null)
@@ -45,20 +57,24 @@ static boolean isMacOS() {
}

private static boolean hasIPv6() throws Exception {
List<NetworkInterface> nics = Collections.list(
NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nic : nics) {
List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
for (InetAddress addr : addrs) {
if (addr instanceof Inet6Address)
return true;
}
return NetworkConfiguration.probe()
.ip6Addresses()
.findAny()
.isPresent();
}

public static void main(String[] args) throws Exception {
try (var test = new SetOutgoingIf()) {
test.run();
}
}

return false;
@Override
public void close() {
SOCKET.close();
}

public static void main(String[] args) throws Exception {
public void run() throws Exception {
if (isWindows()) {
System.out.println("The test only run on non-Windows OS. Bye.");
return;
@@ -99,11 +115,14 @@ public static void main(String[] args) throws Exception {
System.out.println("Ignore NetworkInterface nic == " + nic);
}
}
Collections.reverse(netIfs);
if (netIfs.size() <= 1) {
System.out.println("Need 2 or more network interfaces to run. Bye.");
return;
}

System.out.println("Using PORT: " + PORT);

// We will send packets to one ipv4, and one ipv6
// multicast group using each network interface :-
// 224.1.1.1 --|
@@ -177,12 +196,8 @@ public static void main(String[] args) throws Exception {
}

private static boolean isTestExcludedInterface(NetworkInterface nif) {
if (isMacOS() && nif.getName().contains("awdl"))
return true;
String dName = nif.getDisplayName();
if (isWindows() && dName != null && dName.contains("Teredo"))
return true;
return false;
return !NetworkConfiguration.isTestable(nif)
|| isMacOS() && nif.getName().startsWith("utun");
}

private static boolean debug = true;
@@ -281,4 +296,3 @@ void groups(List<InetAddress> groups) {
this.groups = groups;
}
}

@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,11 @@
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@@ -85,9 +86,20 @@ private NetworkConfiguration(
});
}

private static boolean isNotExcludedInterface(NetworkInterface nif) {
if (Platform.isOSX() && nif.getName().contains("awdl")) {
return false;
private static boolean isIPv6LinkLocal(InetAddress a) {
return Inet6Address.class.isInstance(a) && a.isLinkLocalAddress();
}

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()) {
String dName = nif.getDisplayName();
@@ -199,7 +211,7 @@ public boolean has_globaladdress() {
public Stream<NetworkInterface> ip4Interfaces() {
return ip4Interfaces.keySet()
.stream()
.filter(NetworkConfiguration::isNotExcludedInterface)
.filter(NetworkConfiguration::isTestable)
.filter(this::hasIp4Addresses);
}

@@ -209,7 +221,7 @@ public boolean has_globaladdress() {
public Stream<NetworkInterface> ip6Interfaces() {
return ip6Interfaces.keySet()
.stream()
.filter(NetworkConfiguration::isNotExcludedInterface)
.filter(NetworkConfiguration::isTestable)
.filter(this::hasIp6Addresses);
}

@@ -307,8 +319,8 @@ public String toString() {
* Return a NetworkConfiguration instance.
*/
public static NetworkConfiguration probe() throws IOException {
Map<NetworkInterface, List<Inet4Address>> ip4Interfaces = new HashMap<>();
Map<NetworkInterface, List<Inet6Address>> ip6Interfaces = new HashMap<>();
Map<NetworkInterface, List<Inet4Address>> ip4Interfaces = new LinkedHashMap<>();
Map<NetworkInterface, List<Inet6Address>> ip6Interfaces = new LinkedHashMap<>();

List<NetworkInterface> nifs = list(getNetworkInterfaces());
for (NetworkInterface nif : nifs) {

1 comment on commit c816276

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on c816276 Aug 27, 2021

Please sign in to comment.