Skip to content

Commit c816276

Browse files
committed
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: shade Backport-of: 5ddbcb7
1 parent 910e24b commit c816276

File tree

3 files changed

+98
-38
lines changed

3 files changed

+98
-38
lines changed

test/jdk/java/net/MulticastSocket/Promiscuous.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
2424
/* @test
2525
* @bug 8014499 8219804
26+
* @library /test/lib
2627
* @summary Test for interference when two sockets are bound to the same
2728
* port but joined to different multicast groups
2829
* @run main Promiscuous
@@ -31,8 +32,12 @@
3132

3233
import java.io.IOException;
3334
import static java.lang.System.out;
35+
36+
import java.io.UncheckedIOException;
3437
import java.net.*;
3538

39+
import jdk.test.lib.NetworkConfiguration;
40+
3641
public class Promiscuous {
3742

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

97+
static SocketAddress toSocketAddress(InetAddress group) {
98+
return new InetSocketAddress(group, 0);
99+
}
100+
91101
static void test(InetAddress group1, InetAddress group2)
92102
throws IOException
93103
{
@@ -105,10 +115,21 @@ static void test(InetAddress group1, InetAddress group2)
105115
p.setAddress(group1);
106116
p.setPort(port);
107117

108-
mc1.joinGroup(group1);
109-
out.printf("mc1 joined the MC group: %s\n", group1);
110-
mc2.joinGroup(group2);
111-
out.printf("mc2 joined the MC group: %s\n", group2);
118+
// join groups on all network interfaces
119+
NetworkConfiguration.probe()
120+
.multicastInterfaces(false)
121+
.forEach((nic) -> {
122+
try {
123+
mc1.joinGroup(toSocketAddress(group1), nic);
124+
out.printf("mc1 joined the MC group on %s: %s\n",
125+
nic.getDisplayName(), group1);
126+
mc2.joinGroup(toSocketAddress(group2), nic);
127+
out.printf("mc2 joined the MC group on %s: %s\n",
128+
nic.getDisplayName(), group2);
129+
} catch (IOException io) {
130+
throw new UncheckedIOException(io);
131+
}
132+
});
112133

113134
out.printf("Sending datagram to: %s/%d\n", group1, port);
114135
ds.send(p);
@@ -130,8 +151,21 @@ static void test(InetAddress group1, InetAddress group2)
130151
receive(mc2, true, nextId);
131152
receive(mc1, false, 0);
132153

133-
mc1.leaveGroup(group1);
134-
mc2.leaveGroup(group2);
154+
// leave groups on all network interfaces
155+
NetworkConfiguration.probe()
156+
.multicastInterfaces(false)
157+
.forEach((nic) -> {
158+
try {
159+
mc1.leaveGroup(toSocketAddress(group1), nic);
160+
out.printf("mc1 left the MC group on %s: %s\n",
161+
nic.getDisplayName(), group1);
162+
mc2.leaveGroup(toSocketAddress(group2), nic);
163+
out.printf("mc2 left the MC group on %s: %s\n",
164+
nic.getDisplayName(), group2);
165+
} catch (IOException io) {
166+
throw new UncheckedIOException(io);
167+
}
168+
});
135169
}
136170
}
137171

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

154188
// multicast groups used for the test
155-
InetAddress ip4Group1 = InetAddress.getByName("224.0.0.120");
156-
InetAddress ip4Group2 = InetAddress.getByName("224.0.0.121");
189+
InetAddress ip4Group1 = InetAddress.getByName("224.1.1.120");
190+
InetAddress ip4Group2 = InetAddress.getByName("224.1.1.121");
157191

158192
test(ip4Group1, ip4Group2);
159193
}

test/jdk/java/net/MulticastSocket/SetOutgoingIf.java

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,27 @@
2424
/*
2525
* @test
2626
* @bug 4742177
27+
* @library /test/lib
2728
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
2829
*/
30+
import java.io.IOException;
2931
import java.net.*;
3032
import java.util.*;
33+
import jdk.test.lib.NetworkConfiguration;
3134

3235

33-
public class SetOutgoingIf {
34-
private static int PORT = 9001;
36+
public class SetOutgoingIf implements AutoCloseable {
3537
private static String osname;
38+
private final MulticastSocket SOCKET;
39+
private final int PORT;
40+
private SetOutgoingIf() {
41+
try {
42+
SOCKET = new MulticastSocket();
43+
PORT = SOCKET.getLocalPort();
44+
} catch (IOException io) {
45+
throw new ExceptionInInitializerError(io);
46+
}
47+
}
3648

3749
static boolean isWindows() {
3850
if (osname == null)
@@ -45,20 +57,24 @@ static boolean isMacOS() {
4557
}
4658

4759
private static boolean hasIPv6() throws Exception {
48-
List<NetworkInterface> nics = Collections.list(
49-
NetworkInterface.getNetworkInterfaces());
50-
for (NetworkInterface nic : nics) {
51-
List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
52-
for (InetAddress addr : addrs) {
53-
if (addr instanceof Inet6Address)
54-
return true;
55-
}
60+
return NetworkConfiguration.probe()
61+
.ip6Addresses()
62+
.findAny()
63+
.isPresent();
64+
}
65+
66+
public static void main(String[] args) throws Exception {
67+
try (var test = new SetOutgoingIf()) {
68+
test.run();
5669
}
70+
}
5771

58-
return false;
72+
@Override
73+
public void close() {
74+
SOCKET.close();
5975
}
6076

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

124+
System.out.println("Using PORT: " + PORT);
125+
107126
// We will send packets to one ipv4, and one ipv6
108127
// multicast group using each network interface :-
109128
// 224.1.1.1 --|
@@ -177,12 +196,8 @@ public static void main(String[] args) throws Exception {
177196
}
178197

179198
private static boolean isTestExcludedInterface(NetworkInterface nif) {
180-
if (isMacOS() && nif.getName().contains("awdl"))
181-
return true;
182-
String dName = nif.getDisplayName();
183-
if (isWindows() && dName != null && dName.contains("Teredo"))
184-
return true;
185-
return false;
199+
return !NetworkConfiguration.isTestable(nif)
200+
|| isMacOS() && nif.getName().startsWith("utun");
186201
}
187202

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

test/lib/jdk/test/lib/NetworkConfiguration.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,11 @@
3131
import java.net.InetAddress;
3232
import java.net.NetworkInterface;
3333
import java.util.Arrays;
34-
import java.util.HashMap;
34+
import java.util.LinkedHashMap;
3535
import java.util.LinkedList;
3636
import java.util.List;
3737
import java.util.Map;
38+
import java.util.function.Predicate;
3839
import java.util.stream.Collectors;
3940
import java.util.stream.Stream;
4041

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

88-
private static boolean isNotExcludedInterface(NetworkInterface nif) {
89-
if (Platform.isOSX() && nif.getName().contains("awdl")) {
90-
return false;
89+
private static boolean isIPv6LinkLocal(InetAddress a) {
90+
return Inet6Address.class.isInstance(a) && a.isLinkLocalAddress();
91+
}
92+
93+
public static boolean isTestable(NetworkInterface nif) {
94+
if (Platform.isOSX()) {
95+
if (nif.getName().contains("awdl")) {
96+
return false; // exclude awdl
97+
}
98+
// filter out interfaces that only have link-local addresses
99+
return nif.inetAddresses()
100+
.filter(Predicate.not(NetworkConfiguration::isIPv6LinkLocal))
101+
.findAny()
102+
.isPresent();
91103
}
92104
if (Platform.isWindows()) {
93105
String dName = nif.getDisplayName();
@@ -199,7 +211,7 @@ public Stream<NetworkInterface> interfaces() {
199211
public Stream<NetworkInterface> ip4Interfaces() {
200212
return ip4Interfaces.keySet()
201213
.stream()
202-
.filter(NetworkConfiguration::isNotExcludedInterface)
214+
.filter(NetworkConfiguration::isTestable)
203215
.filter(this::hasIp4Addresses);
204216
}
205217

@@ -209,7 +221,7 @@ public Stream<NetworkInterface> ip4Interfaces() {
209221
public Stream<NetworkInterface> ip6Interfaces() {
210222
return ip6Interfaces.keySet()
211223
.stream()
212-
.filter(NetworkConfiguration::isNotExcludedInterface)
224+
.filter(NetworkConfiguration::isTestable)
213225
.filter(this::hasIp6Addresses);
214226
}
215227

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

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

0 commit comments

Comments
 (0)