test/jdk/java/net/MulticastSocket/PromiscuousIPv6.java
changeset 53073 11033c4ada54
parent 53047 b732de3068f4
parent 53072 82d3f0820d37
child 53074 1e213c37befa
equal deleted inserted replaced
53047:b732de3068f4 53073:11033c4ada54
     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  */
       
    33 import jdk.test.lib.NetworkConfiguration;
       
    34 import jtreg.SkippedException;
       
    35 
       
    36 import java.io.IOException;
       
    37 import java.net.DatagramPacket;
       
    38 import java.net.DatagramSocket;
       
    39 import java.net.InetAddress;
       
    40 import java.net.InetSocketAddress;
       
    41 import java.net.MulticastSocket;
       
    42 import java.net.SocketTimeoutException;
       
    43 
       
    44 import static java.lang.System.out;
       
    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 int TIMEOUT =  5 * 1000; // 5 secs
       
    53     static int id = 1000;
       
    54 
       
    55     static void receive(DatagramSocket mc, boolean datagramExpected, int id)
       
    56             throws IOException
       
    57     {
       
    58         byte[] ba = new byte[100];
       
    59         DatagramPacket p = new DatagramPacket(ba, ba.length);
       
    60         try {
       
    61             mc.receive(p);
       
    62             int recvId = Integer.parseInt(
       
    63                     new String(p.getData(), 0, p.getLength(), "UTF-8"));
       
    64             if (datagramExpected) {
       
    65                 if (recvId != id)
       
    66                     throw new RuntimeException("Unexpected id, got " + recvId
       
    67                                                        + ", expected: " + id);
       
    68                 out.printf("Received message as expected, %s\n", p.getAddress());
       
    69             } else {
       
    70                 throw new RuntimeException("Unexpected message received, "
       
    71                                                    + p.getAddress());
       
    72             }
       
    73         } catch (SocketTimeoutException e) {
       
    74             if (datagramExpected)
       
    75                 throw new RuntimeException("Expected message not received, "
       
    76                                                    + e.getMessage());
       
    77             else
       
    78                 out.printf("Message not received, as expected\n");
       
    79         }
       
    80     }
       
    81 
       
    82     static void test(InetAddress group1, InetAddress group2)
       
    83             throws IOException
       
    84     {
       
    85         try (MulticastSocket mc1 = new MulticastSocket(new InetSocketAddress(group1, 0));
       
    86              MulticastSocket mc2 = new MulticastSocket(new InetSocketAddress(group2, mc1.getLocalPort()));
       
    87              DatagramSocket ds = new DatagramSocket()) {
       
    88 
       
    89             final int port = mc1.getLocalPort();
       
    90             out.printf("Using port: %d\n", port);
       
    91 
       
    92             mc1.setSoTimeout(TIMEOUT);
       
    93             mc2.setSoTimeout(TIMEOUT);
       
    94             int nextId = id;
       
    95             byte[] msg = Integer.toString(nextId).getBytes("UTF-8");
       
    96             DatagramPacket p = new DatagramPacket(msg, msg.length);
       
    97             p.setAddress(group1);
       
    98             p.setPort(port);
       
    99 
       
   100             mc1.joinGroup(group1);
       
   101             out.printf("mc1 joined the MC group: %s\n", group1);
       
   102             mc2.joinGroup(group2);
       
   103             out.printf("mc2 joined the MC group: %s\n", group2);
       
   104 
       
   105             out.printf("Sending datagram to: %s/%d\n", group1, port);
       
   106             ds.send(p);
       
   107 
       
   108             // the packet should be received by mc1 only
       
   109             receive(mc1, true, nextId);
       
   110             receive(mc2, false, 0);
       
   111 
       
   112             nextId = ++id;
       
   113             msg = Integer.toString(nextId).getBytes("UTF-8");
       
   114             p = new DatagramPacket(msg, msg.length);
       
   115             p.setAddress(group2);
       
   116             p.setPort(port);
       
   117 
       
   118             out.printf("Sending datagram to: %s/%d\n", group2, port);
       
   119             ds.send(p);
       
   120 
       
   121             // the packet should be received by mc2 only
       
   122             receive(mc2, true, nextId);
       
   123             receive(mc1, false, 0);
       
   124 
       
   125             mc1.leaveGroup(group1);
       
   126             mc2.leaveGroup(group2);
       
   127         }
       
   128     }
       
   129 
       
   130     public static void main(String args[]) throws IOException {
       
   131         String os = System.getProperty("os.name");
       
   132 
       
   133         if (!os.equals("Linux")) {
       
   134             throw new SkippedException("This test should be run only on Linux");
       
   135         } else {
       
   136             String osVersion = System.getProperty("os.version");
       
   137             String prefix = "3.10.0";
       
   138             if (osVersion.startsWith(prefix)) {
       
   139                 throw new SkippedException(
       
   140                         String.format("The behavior under test is known NOT to work on '%s' kernels", prefix));
       
   141             }
       
   142         }
       
   143 
       
   144         NetworkConfiguration.printSystemConfiguration(System.out);
       
   145 
       
   146         if (NetworkConfiguration.probe()
       
   147                                 .ip6MulticastInterfaces()
       
   148                                 .findAny()
       
   149                                 .isEmpty()) {
       
   150             throw new SkippedException(
       
   151                     "No IPv6 interfaces that support multicast found");
       
   152         }
       
   153 
       
   154         InetAddress interfaceLocal1 = InetAddress.getByName("ff11::2.3.4.5");
       
   155         InetAddress interfaceLocal2 = InetAddress.getByName("ff11::6.7.8.9");
       
   156         test(interfaceLocal1, interfaceLocal2);
       
   157 
       
   158         InetAddress linkLocal1 = InetAddress.getByName("ff12::2.3.4.5");
       
   159         InetAddress linkLocal2 = InetAddress.getByName("ff12::6.7.8.9");
       
   160         test(linkLocal1, linkLocal2);
       
   161     }
       
   162 }