--- a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java Tue Oct 06 22:01:18 2009 -0400
+++ b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java Wed Oct 07 17:23:02 2009 +0100
@@ -27,7 +27,6 @@
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
*/
import java.net.*;
-import java.util.concurrent.*;
import java.util.*;
@@ -68,38 +67,61 @@
// We need 2 or more network interfaces to run the test
//
- List<NetworkInterface> nics = new ArrayList<NetworkInterface>();
+ List<NetIf> netIfs = new ArrayList<NetIf>();
+ int index = 1;
for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) {
// we should use only network interfaces with multicast support which are in "up" state
- if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp())
- nics.add(nic);
+ if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp()) {
+ NetIf netIf = NetIf.create(nic);
+
+ // now determine what (if any) type of addresses are assigned to this interface
+ for (InetAddress addr : Collections.list(nic.getInetAddresses())) {
+ if (addr instanceof Inet4Address) {
+ netIf.ipv4Address(true);
+ } else if (addr instanceof Inet6Address) {
+ netIf.ipv6Address(true);
+ }
+ }
+ if (netIf.ipv4Address() || netIf.ipv6Address()) {
+ netIf.index(index++);
+ netIfs.add(netIf);
+ debug("Using: " + nic);
+ }
+ }
}
- if (nics.size() <= 1) {
+ if (netIfs.size() <= 1) {
System.out.println("Need 2 or more network interfaces to run. Bye.");
return;
}
- // We will send packets to one ipv4, one ipv4-mapped, and one ipv6
+ // We will send packets to one ipv4, and one ipv6
// multicast group using each network interface :-
// 224.1.1.1 --|
- // ::ffff:224.1.1.2 -----> using network interface #1
- // ff02::1:1 --|
+ // ff02::1:1 --|--> using network interface #1
// 224.1.2.1 --|
- // ::ffff:224.1.2.2 -----> using network interface #2
- // ff02::1:2 --|
+ // ff02::1:2 --|--> using network interface #2
// and so on.
//
- List<InetAddress> groups = new ArrayList<InetAddress>();
- for (int i = 0; i < nics.size(); i++) {
- InetAddress groupv4 = InetAddress.getByName("224.1." + (i+1) + ".1");
- InetAddress groupv4mapped = InetAddress.getByName("::ffff:224.1." + (i+1) + ".2");
- InetAddress groupv6 = InetAddress.getByName("ff02::1:" + (i+1));
- groups.add(groupv4);
- groups.add(groupv4mapped);
- groups.add(groupv6);
+ for (NetIf netIf : netIfs) {
+ int NetIfIndex = netIf.index();
+ List<InetAddress> groups = new ArrayList<InetAddress>();
- // use a separated thread to send to those 3 groups
- Thread sender = new Thread(new Sender(nics.get(i), groupv4, groupv4mapped, groupv6, PORT));
+ if (netIf.ipv4Address()) {
+ InetAddress groupv4 = InetAddress.getByName("224.1." + NetIfIndex + ".1");
+ groups.add(groupv4);
+ }
+ if (netIf.ipv6Address()) {
+ InetAddress groupv6 = InetAddress.getByName("ff02::1:" + NetIfIndex);
+ groups.add(groupv6);
+ }
+
+ debug("Adding " + groups + " groups for " + netIf.nic().getName());
+ netIf.groups(groups);
+
+ // use a separated thread to send to those 2 groups
+ Thread sender = new Thread(new Sender(netIf,
+ groups,
+ PORT));
sender.setDaemon(true); // we want sender to stop when main thread exits
sender.start();
}
@@ -108,75 +130,135 @@
// from the expected network interface
//
byte[] buf = new byte[1024];
- for (InetAddress group : groups) {
- MulticastSocket mcastsock = new MulticastSocket(PORT);
- mcastsock.setSoTimeout(5000); // 5 second
- DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
-
- mcastsock.joinGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3));
+ for (NetIf netIf : netIfs) {
+ NetworkInterface nic = netIf.nic();
+ for (InetAddress group : netIf.groups()) {
+ MulticastSocket mcastsock = new MulticastSocket(PORT);
+ mcastsock.setSoTimeout(5000); // 5 second
+ DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
- try {
- mcastsock.receive(packet);
- } catch (Exception e) {
- // test failed if any exception
- throw new RuntimeException(e);
- }
+ // the interface supports the IP multicast group
+ debug("Joining " + group + " on " + nic.getName());
+ mcastsock.joinGroup(new InetSocketAddress(group, PORT), nic);
+
+ try {
+ mcastsock.receive(packet);
+ debug("received packet on " + packet.getAddress());
+ } catch (Exception e) {
+ // test failed if any exception
+ throw new RuntimeException(e);
+ }
- // now check which network interface this packet comes from
- NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress());
- NetworkInterface shouldbe = nics.get(groups.indexOf(group) / 3);
- if (!from.equals(shouldbe)) {
- System.out.println("Packets on group "
- + group + " should come from "
- + shouldbe.getName() + ", but came from "
- + from.getName());
- //throw new RuntimeException("Test failed.");
+ // now check which network interface this packet comes from
+ NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress());
+ NetworkInterface shouldbe = nic;
+ if (!from.equals(shouldbe)) {
+ System.out.println("Packets on group "
+ + group + " should come from "
+ + shouldbe.getName() + ", but came from "
+ + from.getName());
+ //throw new RuntimeException("Test failed.");
+ }
+
+ mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nic);
}
+ }
+ }
- mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3));
- }
+ private static boolean debug = true;
+
+ static void debug(String message) {
+ if (debug)
+ System.out.println(message);
}
}
class Sender implements Runnable {
- private NetworkInterface nic;
- private InetAddress group1;
- private InetAddress group2;
- private InetAddress group3;
+ private NetIf netIf;
+ private List<InetAddress> groups;
private int port;
- public Sender(NetworkInterface nic,
- InetAddress groupv4, InetAddress groupv4mapped, InetAddress groupv6,
- int port) {
- this.nic = nic;
- group1 = groupv4;
- group2 = groupv4mapped;
- group3 = groupv6;
+ public Sender(NetIf netIf,
+ List<InetAddress> groups,
+ int port) {
+ this.netIf = netIf;
+ this.groups = groups;
this.port = port;
}
public void run() {
try {
MulticastSocket mcastsock = new MulticastSocket();
- mcastsock.setNetworkInterface(nic);
+ mcastsock.setNetworkInterface(netIf.nic());
+ List<DatagramPacket> packets = new LinkedList<DatagramPacket>();
byte[] buf = "hello world".getBytes();
- DatagramPacket packet1 = new DatagramPacket(buf, buf.length,
- new InetSocketAddress(group1, port));
- DatagramPacket packet2 = new DatagramPacket(buf, buf.length,
- new InetSocketAddress(group2, port));
- DatagramPacket packet3 = new DatagramPacket(buf, buf.length,
- new InetSocketAddress(group3, port));
+ for (InetAddress group : groups) {
+ packets.add(new DatagramPacket(buf, buf.length, new InetSocketAddress(group, port)));
+ }
for (;;) {
- mcastsock.send(packet1);
- mcastsock.send(packet2);
- mcastsock.send(packet3);
+ for (DatagramPacket packet : packets)
+ mcastsock.send(packet);
- Thread.currentThread().sleep(1000); // sleep 1 second
+ Thread.sleep(1000); // sleep 1 second
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
+
+@SuppressWarnings("unchecked")
+class NetIf {
+ private boolean ipv4Address; //false
+ private boolean ipv6Address; //false
+ private int index;
+ List<InetAddress> groups = Collections.EMPTY_LIST;
+ private final NetworkInterface nic;
+
+ private NetIf(NetworkInterface nic) {
+ this.nic = nic;
+ }
+
+ static NetIf create(NetworkInterface nic) {
+ return new NetIf(nic);
+ }
+
+ NetworkInterface nic() {
+ return nic;
+ }
+
+ boolean ipv4Address() {
+ return ipv4Address;
+ }
+
+ void ipv4Address(boolean ipv4Address) {
+ this.ipv4Address = ipv4Address;
+ }
+
+ boolean ipv6Address() {
+ return ipv6Address;
+ }
+
+ void ipv6Address(boolean ipv6Address) {
+ this.ipv6Address = ipv6Address;
+ }
+
+ int index() {
+ return index;
+ }
+
+ void index(int index) {
+ this.index = index;
+ }
+
+ List<InetAddress> groups() {
+ return groups;
+ }
+
+ void groups(List<InetAddress> groups) {
+ this.groups = groups;
+ }
+}
+