test/java/net/MulticastSocket/SetOutgoingIf.java

Print this page




  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  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4742177
  27  * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
  28  */
  29 import java.net.*;
  30 import java.util.concurrent.*;
  31 import java.util.*;
  32 
  33 
  34 public class SetOutgoingIf {
  35     private static int PORT = 9001;
  36     private static String osname;
  37 
  38     static boolean isWindows() {
  39         if (osname == null)
  40             osname = System.getProperty("os.name");
  41         return osname.contains("Windows");
  42     }
  43 
  44     private static boolean hasIPv6() throws Exception {
  45         List<NetworkInterface> nics = Collections.list(
  46                                         NetworkInterface.getNetworkInterfaces());
  47         for (NetworkInterface nic : nics) {
  48             List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
  49             for (InetAddress addr : addrs) {
  50                 if (addr instanceof Inet6Address)
  51                     return true;
  52             }
  53         }
  54 
  55         return false;
  56     }
  57 
  58     public static void main(String[] args) throws Exception {
  59         if (isWindows()) {
  60             System.out.println("The test only run on non-Windows OS. Bye.");
  61             return;
  62         }
  63 
  64         if (!hasIPv6()) {
  65             System.out.println("No IPv6 available. Bye.");
  66             return;
  67         }
  68 
  69         // We need 2 or more network interfaces to run the test
  70         //
  71         List<NetworkInterface> nics = new ArrayList<NetworkInterface>();

  72         for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) {
  73             // we should use only network interfaces with multicast support which are in "up" state
  74             if (!nic.isLoopback() && nic.supportsMulticast() && nic.isUp())
  75                 nics.add(nic);







  76         }
  77         if (nics.size() <= 1) {








  78             System.out.println("Need 2 or more network interfaces to run. Bye.");
  79             return;
  80         }
  81 
  82         // We will send packets to one ipv4, one ipv4-mapped, and one ipv6
  83         // multicast group using each network interface :-
  84         //      224.1.1.1        --|
  85         //      ::ffff:224.1.1.2 -----> using network interface #1
  86         //      ff02::1:1        --|
  87         //      224.1.2.1        --|
  88         //      ::ffff:224.1.2.2 -----> using network interface #2
  89         //      ff02::1:2        --|
  90         // and so on.
  91         //


  92         List<InetAddress> groups = new ArrayList<InetAddress>();
  93         for (int i = 0; i < nics.size(); i++) {
  94             InetAddress groupv4 = InetAddress.getByName("224.1." + (i+1) + ".1");
  95             InetAddress groupv4mapped = InetAddress.getByName("::ffff:224.1." + (i+1) + ".2");
  96             InetAddress groupv6 = InetAddress.getByName("ff02::1:" + (i+1));
  97             groups.add(groupv4);
  98             groups.add(groupv4mapped);


  99             groups.add(groupv6);

 100 
 101             // use a separated thread to send to those 3 groups
 102             Thread sender = new Thread(new Sender(nics.get(i), groupv4, groupv4mapped, groupv6, PORT));





 103             sender.setDaemon(true); // we want sender to stop when main thread exits
 104             sender.start();
 105         }
 106 
 107         // try to receive on each group, then check if the packet comes
 108         // from the expected network interface
 109         //
 110         byte[] buf = new byte[1024];
 111         for (InetAddress group : groups) {


 112         MulticastSocket mcastsock = new MulticastSocket(PORT);
 113         mcastsock.setSoTimeout(5000);   // 5 second
 114             DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
 115 
 116             mcastsock.joinGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3));


 117 
 118             try {
 119                 mcastsock.receive(packet);

 120             } catch (Exception e) {
 121                 // test failed if any exception
 122                 throw new RuntimeException(e);
 123             }
 124 
 125             // now check which network interface this packet comes from
 126             NetworkInterface from = NetworkInterface.getByInetAddress(packet.getAddress());
 127             NetworkInterface shouldbe = nics.get(groups.indexOf(group) / 3);
 128             if (!from.equals(shouldbe)) {
 129                 System.out.println("Packets on group "
 130                                     + group + " should come from "
 131                                     + shouldbe.getName() + ", but came from "
 132                                     + from.getName());
 133                 //throw new RuntimeException("Test failed.");
 134             }
 135 
 136             mcastsock.leaveGroup(new InetSocketAddress(group, PORT), nics.get(groups.indexOf(group) / 3));
 137         }
 138     }








 139 }
 140 
 141 class Sender implements Runnable {
 142     private NetworkInterface nic;
 143     private InetAddress group1;
 144     private InetAddress group2;
 145     private InetAddress group3;
 146     private int port;
 147 
 148     public Sender(NetworkInterface nic,
 149                     InetAddress groupv4, InetAddress groupv4mapped, InetAddress groupv6,
 150                     int port) {
 151         this.nic = nic;
 152         group1 = groupv4;
 153         group2 = groupv4mapped;
 154         group3 = groupv6;
 155         this.port = port;
 156     }
 157 
 158     public void run() {
 159         try {
 160             MulticastSocket mcastsock = new MulticastSocket();
 161             mcastsock.setNetworkInterface(nic);

 162 
 163             byte[] buf = "hello world".getBytes();
 164             DatagramPacket packet1 = new DatagramPacket(buf, buf.length,
 165                                         new InetSocketAddress(group1, port));
 166             DatagramPacket packet2 = new DatagramPacket(buf, buf.length,
 167                                         new InetSocketAddress(group2, port));
 168             DatagramPacket packet3 = new DatagramPacket(buf, buf.length,
 169                                         new InetSocketAddress(group3, port));
 170 
 171             for (;;) {
 172                 mcastsock.send(packet1);
 173                 mcastsock.send(packet2);
 174                 mcastsock.send(packet3);
 175 
 176                 Thread.currentThread().sleep(1000);   // sleep 1 second
 177             }
 178         } catch (Exception e) {
 179             throw new RuntimeException(e);
 180         }
 181     }
 182 }
























































  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  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4742177
  27  * @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
  28  */
  29 import java.net.*;

  30 import java.util.*;
  31 
  32 
  33 public 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         //
  70         List<NetIf> netIfs = new ArrayList<NetIf>();
  71         int index = 1;
  72         for (NetworkInterface nic : Collections.list(NetworkInterface.getNetworkInterfaces())) {
  73             // we should use only network interfaces with multicast support which are in "up" state
  74             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             }
  91         }
  92         if (netIfs.size() <= 1) {
  93             System.out.println("Need 2 or more network interfaces to run. Bye.");
  94             return;
  95         }
  96 
  97         // We will send packets to one ipv4, and one ipv6
  98         // multicast group using each network interface :-
  99         //      224.1.1.1        --|
 100         //      ff02::1:1        --|--> using network interface #1

 101         //      224.1.2.1        --|
 102         //      ff02::1:2        --|--> using network interface #2

 103         // and so on.
 104         //
 105         for (NetIf netIf : netIfs) {
 106             int NetIfIndex = netIf.index();
 107             List<InetAddress> groups = new ArrayList<InetAddress>();
 108 
 109             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));
 125             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];
 133         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);
 139 
 140                 // the interface supports the IP multicast group
 141                 debug("Joining " + group + " on " + nic.getName());
 142                 mcastsock.joinGroup(new InetSocketAddress(group, PORT), nic);
 143 
 144                 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);
 164             }
 165         }
 166     }
 167 
 168     private static boolean debug = true;
 169 
 170     static void debug(String message) {
 171         if (debug)
 172             System.out.println(message);
 173     }
 174 }
 175 
 176 class Sender implements Runnable {
 177     private NetIf netIf;
 178     private List<InetAddress> groups;


 179     private int port;
 180 
 181     public Sender(NetIf netIf,
 182                   List<InetAddress> groups,
 183                   int port) {
 184         this.netIf = netIf;
 185         this.groups = groups;


 186         this.port = port;
 187     }
 188 
 189     public void run() {
 190         try {
 191             MulticastSocket mcastsock = new MulticastSocket();
 192             mcastsock.setNetworkInterface(netIf.nic());
 193             List<DatagramPacket> packets = new LinkedList<DatagramPacket>();
 194 
 195             byte[] buf = "hello world".getBytes();
 196             for (InetAddress group : groups) {
 197                 packets.add(new DatagramPacket(buf, buf.length, new InetSocketAddress(group, port)));
 198             }



 199 
 200             for (;;) {
 201                 for (DatagramPacket packet : packets)
 202                     mcastsock.send(packet);

 203 
 204                 Thread.sleep(1000);   // sleep 1 second
 205             }
 206         } catch (Exception e) {
 207             throw new RuntimeException(e);
 208         }
 209     }
 210 }
 211 
 212 @SuppressWarnings("unchecked")
 213 class 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