< prev index next >

test/jdk/java/nio/channels/DatagramChannel/PromiscuousIPv6.java

Print this page
rev 54822 : [mq]: updated_promiscuousV6_tests
rev 54821 : [mq]: orig_promiscuousV6_tests
rev 54553 : Merge
rev 53335 : Merge
rev 53189 : Merge
rev 53073 : Merge
rev 53053 : 8215292: Back out changes for node- and link- local ipv6 multicast address
Reviewed-by: chegar, alanb
rev 52491 : 8210493: Bind to node- or linklocal ipv6 multicast address fails
Reviewed-by: alanb, chegar
   1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * 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  *
  19  * 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.
  22  *
  23 
  24 /*
  25  * @test
  26  * @bug 8210493
  27  * @requires os.family == "linux"
  28  * @library /test/lib
  29  * @build jdk.test.lib.NetworkConfiguration
  30  *        PromiscuousIPv6
  31  * @run main PromiscuousIPv6
  32  * @key randomness
  33  */
  34 
  35 import java.nio.ByteBuffer;
  36 import java.nio.channels.*;
  37 import java.net.*;
  38 import static java.net.StandardProtocolFamily.*;
  39 import java.util.*;
  40 import java.io.IOException;
  41 import java.util.stream.Collectors;
  42 
  43 import jdk.test.lib.NetworkConfiguration;
  44 import jtreg.SkippedException;



  45 
  46 /*
  47  * This test was created as a copy of the Promiscuous test and adapted for
  48  * IPv6 node-local and link-local multicast addresses on Linux.
  49  */
  50 public class PromiscuousIPv6 {
  51 
  52     static final Random rand = new Random();
  53 
  54     static final ProtocolFamily UNSPEC = () -> "UNSPEC";
  55 
  56     /**
  57      * Sends a datagram to the given multicast group
  58      */
  59     static int sendDatagram(NetworkInterface nif,
  60                             InetAddress group,
  61                             int port)
  62             throws IOException
  63     {
  64         ProtocolFamily family = (group instanceof Inet6Address) ?
  65                 StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
  66         DatagramChannel dc = DatagramChannel.open(family)
  67                 .setOption(StandardSocketOptions.IP_MULTICAST_IF, nif);
  68         int id = rand.nextInt();
  69         byte[] msg = Integer.toString(id).getBytes("UTF-8");
  70         ByteBuffer buf = ByteBuffer.wrap(msg);
  71         System.out.format("Send message -> group %s (id=0x%x)\n",
  72                           group.getHostAddress(), id);
  73         dc.send(buf, new InetSocketAddress(group, port));
  74         dc.close();
  75         return id;
  76     }
  77 
  78     /**
  79      * Wait (with timeout) for datagram. The {@code datagramExpected}
  80      * parameter indicates whether a datagram is expected, and if
  81      * {@code true} then {@code id} is the identifier in the payload.
  82      */
  83     static void receiveDatagram(DatagramChannel dc,
  84                                 String name,
  85                                 boolean datagramExpected,
  86                                 int id)
  87             throws IOException
  88     {
  89         System.out.println("Checking if received by " + name);
  90 
  91         Selector sel = Selector.open();
  92         dc.configureBlocking(false);
  93         dc.register(sel, SelectionKey.OP_READ);
  94         ByteBuffer buf = ByteBuffer.allocateDirect(100);
  95 
  96         try {
  97             for (;;) {
  98                 System.out.println("Waiting to receive message");
  99                 sel.select(5*1000);


 136                     System.out.println("Message ignored (wrong sender)");
 137                 }
 138 
 139                 sel.selectedKeys().clear();
 140                 buf.rewind();
 141             }
 142         } finally {
 143             sel.close();
 144         }
 145     }
 146 
 147     static void test(ProtocolFamily family,
 148                      NetworkInterface nif,
 149                      InetAddress group1,
 150                      InetAddress group2)
 151             throws IOException
 152     {
 153 
 154         System.out.format("%nTest family=%s%n", family.name());
 155 





 156         DatagramChannel dc1 = (family == UNSPEC) ?
 157                 DatagramChannel.open() : DatagramChannel.open(family);
 158         DatagramChannel dc2 = (family == UNSPEC) ?
 159                 DatagramChannel.open() : DatagramChannel.open(family);
 160 
 161         try {
 162             dc1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
 163             dc2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
 164 
 165             dc1.bind(new InetSocketAddress(group1, 0));
 166             int port = dc1.socket().getLocalPort();
 167             dc2.bind(new InetSocketAddress(group2, port));
 168 
 169             System.out.format("dc1 joining [%s]:%d @ %s\n",
 170                               group1.getHostAddress(), port, nif.getName());
 171             System.out.format("dc2 joining [%s]:%d @ %s\n",
 172                               group2.getHostAddress(), port, nif.getName());
 173 
 174             dc1.join(group1, nif);
 175             dc2.join(group2, nif);
 176 
 177             int id = sendDatagram(nif, group1, port);
 178 
 179             receiveDatagram(dc1, "dc1", true, id);
 180             receiveDatagram(dc2, "dc2", false, id);
 181 
 182             id = sendDatagram(nif, group2, port);
 183 
 184             receiveDatagram(dc1, "dc1", false, id);
 185             receiveDatagram(dc2, "dc2", true, id);
 186 
 187         } finally {


 189             dc2.close();
 190         }
 191     }
 192 
 193     public static void main(String[] args) throws IOException {
 194 
 195         String os = System.getProperty("os.name");
 196 
 197         if (!os.equals("Linux")) {
 198             throw new SkippedException("This test should be run only on Linux");
 199         } else {
 200             String osVersion = System.getProperty("os.version");
 201             String prefix = "3.10.0";
 202             if (osVersion.startsWith(prefix)) {
 203                 throw new SkippedException(
 204                         String.format("The behavior under test is known NOT to work on '%s' kernels", prefix));
 205             }
 206         }
 207 
 208         NetworkConfiguration.printSystemConfiguration(System.out);








 209 
 210         InetAddress interfaceLocal1 = InetAddress.getByName("ff11::2.3.4.5");
 211         InetAddress interfaceLocal2 = InetAddress.getByName("ff11::6.7.8.9");
 212 
 213         InetAddress linkLocal1 = InetAddress.getByName("ff12::2.3.4.5");
 214         InetAddress linkLocal2 = InetAddress.getByName("ff12::6.7.8.9");
 215 
 216         // get local network configuration to use
 217         NetworkConfiguration config = NetworkConfiguration.probe();
 218         boolean foundAtLeastOne = false;
 219         for (NetworkInterface nif: config.ip6MulticastInterfaces()
 220                 .collect(Collectors.toList())) {
 221             foundAtLeastOne = true;
 222             test(INET6, nif, interfaceLocal1, interfaceLocal2);
 223             test(INET6, nif, linkLocal1, linkLocal2);
 224         }
 225         if (!foundAtLeastOne) {
 226             throw new SkippedException(
 227                     "No IPv6 interfaces that support multicast found");
 228         }
 229     }
 230 }
   1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * 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  *
  19  * 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.
  22  *
  23 
  24 /*
  25  * @test
  26  * @bug 8215294
  27  * @requires os.family == "linux"
  28  * @library /test/lib
  29  * @build jdk.test.lib.NetworkConfiguration
  30  *        PromiscuousIPv6
  31  * @run main PromiscuousIPv6
  32  * @key randomness
  33  */
  34 
  35 import java.nio.ByteBuffer;
  36 import java.nio.channels.*;
  37 import java.net.*;

  38 import java.util.*;
  39 import java.io.IOException;


  40 import jdk.test.lib.NetworkConfiguration;
  41 import jtreg.SkippedException;
  42 import static java.net.StandardProtocolFamily.*;
  43 import static java.nio.charset.StandardCharsets.UTF_8;
  44 import static java.util.stream.Collectors.toList;
  45 
  46 /*
  47  * This test was created as a copy of the Promiscuous test and adapted for
  48  * IPv6 node-local and link-local multicast addresses on Linux.
  49  */
  50 public class PromiscuousIPv6 {
  51 
  52     static final Random rand = new Random();
  53 
  54     static final ProtocolFamily UNSPEC = () -> "UNSPEC";
  55 
  56     /**
  57      * Sends a datagram to the given multicast group
  58      */
  59     static int sendDatagram(NetworkInterface nif,
  60                             InetAddress group,
  61                             int port)
  62             throws IOException
  63     {
  64         ProtocolFamily family = (group instanceof Inet6Address) ? INET6 : INET;

  65         DatagramChannel dc = DatagramChannel.open(family)
  66                 .setOption(StandardSocketOptions.IP_MULTICAST_IF, nif);
  67         int id = rand.nextInt();
  68         byte[] msg = Integer.toString(id).getBytes(UTF_8);
  69         ByteBuffer buf = ByteBuffer.wrap(msg);
  70         System.out.format("Send message -> group %s (id=0x%x)\n",
  71                           group.getHostAddress(), id);
  72         dc.send(buf, new InetSocketAddress(group, port));
  73         dc.close();
  74         return id;
  75     }
  76 
  77     /**
  78      * Waits (with timeout) for datagram. The {@code datagramExpected}
  79      * parameter indicates whether a datagram is expected, and if
  80      * {@code true} then {@code id} is the identifier in the payload.
  81      */
  82     static void receiveDatagram(DatagramChannel dc,
  83                                 String name,
  84                                 boolean datagramExpected,
  85                                 int id)
  86         throws IOException
  87     {
  88         System.out.println("Checking if received by " + name);
  89 
  90         Selector sel = Selector.open();
  91         dc.configureBlocking(false);
  92         dc.register(sel, SelectionKey.OP_READ);
  93         ByteBuffer buf = ByteBuffer.allocateDirect(100);
  94 
  95         try {
  96             for (;;) {
  97                 System.out.println("Waiting to receive message");
  98                 sel.select(5*1000);


 135                     System.out.println("Message ignored (wrong sender)");
 136                 }
 137 
 138                 sel.selectedKeys().clear();
 139                 buf.rewind();
 140             }
 141         } finally {
 142             sel.close();
 143         }
 144     }
 145 
 146     static void test(ProtocolFamily family,
 147                      NetworkInterface nif,
 148                      InetAddress group1,
 149                      InetAddress group2)
 150             throws IOException
 151     {
 152 
 153         System.out.format("%nTest family=%s%n", family.name());
 154 
 155         // Bind addresses should include the same network interface / scope, so
 156         // as to not reply on the default route when there are multiple interfaces
 157         InetAddress bindAddr1 = Inet6Address.getByAddress(null, group1.getAddress(), nif);
 158         InetAddress bindAddr2 = Inet6Address.getByAddress(null, group2.getAddress(), nif);
 159 
 160         DatagramChannel dc1 = (family == UNSPEC) ?
 161                 DatagramChannel.open() : DatagramChannel.open(family);
 162         DatagramChannel dc2 = (family == UNSPEC) ?
 163                 DatagramChannel.open() : DatagramChannel.open(family);
 164 
 165         try {
 166             dc1.setOption(StandardSocketOptions.SO_REUSEADDR, true);
 167             dc2.setOption(StandardSocketOptions.SO_REUSEADDR, true);
 168 
 169             dc1.bind(new InetSocketAddress(bindAddr1, 0));
 170             int port = dc1.socket().getLocalPort();
 171             dc2.bind(new InetSocketAddress(bindAddr2, port));
 172 
 173             System.out.format("dc1 joining [%s]:%d @ %s\n",
 174                               group1.getHostAddress(), port, nif.getName());
 175             System.out.format("dc2 joining [%s]:%d @ %s\n",
 176                               group2.getHostAddress(), port, nif.getName());
 177 
 178             dc1.join(group1, nif);
 179             dc2.join(group2, nif);
 180 
 181             int id = sendDatagram(nif, group1, port);
 182 
 183             receiveDatagram(dc1, "dc1", true, id);
 184             receiveDatagram(dc2, "dc2", false, id);
 185 
 186             id = sendDatagram(nif, group2, port);
 187 
 188             receiveDatagram(dc1, "dc1", false, id);
 189             receiveDatagram(dc2, "dc2", true, id);
 190 
 191         } finally {


 193             dc2.close();
 194         }
 195     }
 196 
 197     public static void main(String[] args) throws IOException {
 198 
 199         String os = System.getProperty("os.name");
 200 
 201         if (!os.equals("Linux")) {
 202             throw new SkippedException("This test should be run only on Linux");
 203         } else {
 204             String osVersion = System.getProperty("os.version");
 205             String prefix = "3.10.0";
 206             if (osVersion.startsWith(prefix)) {
 207                 throw new SkippedException(
 208                         String.format("The behavior under test is known NOT to work on '%s' kernels", prefix));
 209             }
 210         }
 211 
 212         NetworkConfiguration.printSystemConfiguration(System.out);
 213         List<NetworkInterface> nifs = NetworkConfiguration.probe()
 214                 .ip6MulticastInterfaces()
 215                 .collect(toList());
 216 
 217         if (nifs.size() == 0) {
 218             throw new SkippedException(
 219                     "No IPv6 interfaces that support multicast found");
 220         }
 221 
 222         InetAddress interfaceLocal1 = InetAddress.getByName("ff11::2.3.4.5");
 223         InetAddress interfaceLocal2 = InetAddress.getByName("ff11::6.7.8.9");
 224 
 225         InetAddress linkLocal1 = InetAddress.getByName("ff12::2.3.4.5");
 226         InetAddress linkLocal2 = InetAddress.getByName("ff12::6.7.8.9");
 227 
 228         for (NetworkInterface nif : nifs) {





 229             test(INET6, nif, interfaceLocal1, interfaceLocal2);
 230             test(INET6, nif, linkLocal1, linkLocal2);




 231         }
 232     }
 233 }
< prev index next >