blob: dd2e3d62706a03a61692232b8a4720e6131eb14e [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
ohair2283b9d2010-05-25 15:58:33 -07002 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
duke6e45e102007-12-01 00:00:00 +00003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
ohair2283b9d2010-05-25 15:58:33 -070019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
duke6e45e102007-12-01 00:00:00 +000022 */
23
24/*
25 * @test
26 * @bug 4742177
27 * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
28 */
29import java.net.*;
duke6e45e102007-12-01 00:00:00 +000030import java.util.*;
31
32
33public class SetOutgoingIf {
34 private static int PORT = 9001;
35 private static String osname;
36
37 static boolean isWindows() {
38 if (osname == null)
39 osname = System.getProperty("os.name");
40 return osname.contains("Windows");
41 }
42
43 private static boolean hasIPv6() throws Exception {
44 List<NetworkInterface> nics = Collections.list(
45 NetworkInterface.getNetworkInterfaces());
46 for (NetworkInterface nic : nics) {
47 List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
48 for (InetAddress addr : addrs) {
49 if (addr instanceof Inet6Address)
50 return true;
51 }
52 }
53
54 return false;
55 }
56
57 public static void main(String[] args) throws Exception {
58 if (isWindows()) {
59 System.out.println("The test only run on non-Windows OS. Bye.");
60 return;
61 }
62
63 if (!hasIPv6()) {
64 System.out.println("No IPv6 available. Bye.");
65 return;
66 }
67
68 // We need 2 or more network interfaces to run the test
69 //
chegar387ebef2009-10-07 17:23:02 +010070 List<NetIf> netIfs = new ArrayList<NetIf>();
71 int index = 1;
duke6e45e102007-12-01 00:00:00 +000072 for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) {
ptisnovs535d6aa2009-09-30 11:49:10 +020073 // we should use only network interfaces with multicast support which are in "up" state
chegar387ebef2009-10-07 17:23:02 +010074 if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp()) {
75 NetIf netIf = NetIf.create(nic);
76
77 // now determine what (if any) type of addresses are assigned to this interface
78 for (InetAddress addr : Collections.list(nic.getInetAddresses())) {
79 if (addr instanceof Inet4Address) {
80 netIf.ipv4Address(true);
81 } else if (addr instanceof Inet6Address) {
82 netIf.ipv6Address(true);
83 }
84 }
85 if (netIf.ipv4Address() || netIf.ipv6Address()) {
86 netIf.index(index++);
87 netIfs.add(netIf);
88 debug("Using: " + nic);
89 }
90 }
duke6e45e102007-12-01 00:00:00 +000091 }
chegar387ebef2009-10-07 17:23:02 +010092 if (netIfs.size() <= 1) {
duke6e45e102007-12-01 00:00:00 +000093 System.out.println("Need 2 or more network interfaces to run. Bye.");
94 return;
95 }
96
chegar387ebef2009-10-07 17:23:02 +010097 // We will send packets to one ipv4, and one ipv6
duke6e45e102007-12-01 00:00:00 +000098 // multicast group using each network interface :-
99 // 224.1.1.1 --|
chegar387ebef2009-10-07 17:23:02 +0100100 // ff02::1:1 --|--> using network interface #1
duke6e45e102007-12-01 00:00:00 +0000101 // 224.1.2.1 --|
chegar387ebef2009-10-07 17:23:02 +0100102 // ff02::1:2 --|--> using network interface #2
duke6e45e102007-12-01 00:00:00 +0000103 // and so on.
104 //
chegar387ebef2009-10-07 17:23:02 +0100105 for (NetIf netIf : netIfs) {
106 int NetIfIndex = netIf.index();
107 List<InetAddress> groups = new ArrayList<InetAddress>();
duke6e45e102007-12-01 00:00:00 +0000108
chegar387ebef2009-10-07 17:23:02 +0100109 if (netIf.ipv4Address()) {
110 InetAddress groupv4 = InetAddress.getByName("224.1." + NetIfIndex + ".1");
111 groups.add(groupv4);
112 }
113 if (netIf.ipv6Address()) {
114 InetAddress groupv6 = InetAddress.getByName("ff02::1:" + NetIfIndex);
115 groups.add(groupv6);
116 }
117
118 debug("Adding " + groups + " groups for " + netIf.nic().getName());
119 netIf.groups(groups);
120
121 // use a separated thread to send to those 2 groups
122 Thread sender = new Thread(new Sender(netIf,
123 groups,
124 PORT));
duke6e45e102007-12-01 00:00:00 +0000125 sender.setDaemon(true); // we want sender to stop when main thread exits
126 sender.start();
127 }
128
129 // try to receive on each group, then check if the packet comes
130 // from the expected network interface
131 //
132 byte[] buf = new byte[1024];
chegar387ebef2009-10-07 17:23:02 +0100133 for (NetIf netIf : netIfs) {
134 NetworkInterface nic = netIf.nic();
135 for (InetAddress group : netIf.groups()) {
136 MulticastSocket mcastsock = new MulticastSocket(PORT);
137 mcastsock.setSoTimeout(5000); // 5 second
138 DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
duke6e45e102007-12-01 00:00:00 +0000139
chegar387ebef2009-10-07 17:23:02 +0100140 // the interface supports the IP multicast group
141 debug("Joining " + group + " on " + nic.getName());
142 mcastsock.joinGroup(new InetSocketAddress(group, PORT), nic);
duke6e45e102007-12-01 00:00:00 +0000143
chegar387ebef2009-10-07 17:23:02 +0100144 try {
145 mcastsock.receive(packet);
146 debug("received packet on " + packet.getAddress());
147 } catch (Exception e) {
148 // test failed if any exception
149 throw new RuntimeException(e);
150 }
151
152 // now check which network interface this packet comes from
153 NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress());
154 NetworkInterface shouldbe = nic;
155 if (!from.equals(shouldbe)) {
156 System.out.println("Packets on group "
157 + group + " should come from "
158 + shouldbe.getName() + ", but came from "
159 + from.getName());
160 //throw new RuntimeException("Test failed.");
161 }
162
163 mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nic);
duke6e45e102007-12-01 00:00:00 +0000164 }
duke6e45e102007-12-01 00:00:00 +0000165 }
166 }
chegar387ebef2009-10-07 17:23:02 +0100167
168 private static boolean debug = true;
169
170 static void debug(String message) {
171 if (debug)
172 System.out.println(message);
173 }
duke6e45e102007-12-01 00:00:00 +0000174}
175
176class Sender implements Runnable {
chegar387ebef2009-10-07 17:23:02 +0100177 private NetIf netIf;
178 private List<InetAddress> groups;
duke6e45e102007-12-01 00:00:00 +0000179 private int port;
180
chegar387ebef2009-10-07 17:23:02 +0100181 public Sender(NetIf netIf,
182 List<InetAddress> groups,
183 int port) {
184 this.netIf = netIf;
185 this.groups = groups;
duke6e45e102007-12-01 00:00:00 +0000186 this.port = port;
187 }
188
189 public void run() {
190 try {
191 MulticastSocket mcastsock = new MulticastSocket();
chegar387ebef2009-10-07 17:23:02 +0100192 mcastsock.setNetworkInterface(netIf.nic());
193 List<DatagramPacket> packets = new LinkedList<DatagramPacket>();
duke6e45e102007-12-01 00:00:00 +0000194
195 byte[] buf = "hello world".getBytes();
chegar387ebef2009-10-07 17:23:02 +0100196 for (InetAddress group : groups) {
197 packets.add(new DatagramPacket(buf, buf.length, new InetSocketAddress(group, port)));
198 }
duke6e45e102007-12-01 00:00:00 +0000199
200 for (;;) {
chegar387ebef2009-10-07 17:23:02 +0100201 for (DatagramPacket packet : packets)
202 mcastsock.send(packet);
duke6e45e102007-12-01 00:00:00 +0000203
chegar387ebef2009-10-07 17:23:02 +0100204 Thread.sleep(1000); // sleep 1 second
duke6e45e102007-12-01 00:00:00 +0000205 }
206 } catch (Exception e) {
207 throw new RuntimeException(e);
208 }
209 }
210}
chegar387ebef2009-10-07 17:23:02 +0100211
212@SuppressWarnings("unchecked")
213class NetIf {
214 private boolean ipv4Address; //false
215 private boolean ipv6Address; //false
216 private int index;
217 List<InetAddress> groups = Collections.EMPTY_LIST;
218 private final NetworkInterface nic;
219
220 private NetIf(NetworkInterface nic) {
221 this.nic = nic;
222 }
223
224 static NetIf create(NetworkInterface nic) {
225 return new NetIf(nic);
226 }
227
228 NetworkInterface nic() {
229 return nic;
230 }
231
232 boolean ipv4Address() {
233 return ipv4Address;
234 }
235
236 void ipv4Address(boolean ipv4Address) {
237 this.ipv4Address = ipv4Address;
238 }
239
240 boolean ipv6Address() {
241 return ipv6Address;
242 }
243
244 void ipv6Address(boolean ipv6Address) {
245 this.ipv6Address = ipv6Address;
246 }
247
248 int index() {
249 return index;
250 }
251
252 void index(int index) {
253 this.index = index;
254 }
255
256 List<InetAddress> groups() {
257 return groups;
258 }
259
260 void groups(List<InetAddress> groups) {
261 this.groups = groups;
262 }
263}
264