test/jdk/java/net/Inet6Address/Scoping.java
changeset 55375 96c7427456f9
equal deleted inserted replaced
55374:5c4f1b7c753b 55375:96c7427456f9
       
     1 /*
       
     2  * Copyright (c) 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 8216417
       
    27  * @summary cleanup of IPv6 scope-id handling
       
    28  * @library /test/lib
       
    29  * @build jdk.test.lib.NetworkConfiguration
       
    30  * @run main/othervm Scoping
       
    31  */
       
    32 
       
    33 import java.io.IOException;
       
    34 import java.net.*;
       
    35 import java.nio.ByteBuffer;
       
    36 import java.nio.channels.DatagramChannel;
       
    37 import java.nio.channels.ServerSocketChannel;
       
    38 import java.nio.channels.SocketChannel;
       
    39 import java.util.Enumeration;
       
    40 import java.util.LinkedList;
       
    41 import java.util.List;
       
    42 import java.util.stream.Collectors;
       
    43 
       
    44 import jdk.test.lib.NetworkConfiguration;
       
    45 
       
    46 public class Scoping {
       
    47 
       
    48     interface ThrowingConsumer<T> {
       
    49         public void accept(T t) throws Exception;
       
    50     }
       
    51 
       
    52     static List<ThrowingConsumer<InetSocketAddress>> targets = List.of(
       
    53         /* 0 */  (a) -> {Socket s = new Socket(); s.bind(a);s.close();},
       
    54         /* 1 */  (a) -> {ServerSocket s = new ServerSocket(); s.bind(a);s.close();},
       
    55         /* 2 */  (a) -> {DatagramSocket s = new DatagramSocket(null); s.bind(a); s.close();},
       
    56         /* 3 */  (a) -> {MulticastSocket s = new MulticastSocket(null); s.bind(a); s.close();},
       
    57         /* 4 */  (a) -> {SocketChannel s = SocketChannel.open(); s.bind(a);s.close();},
       
    58         /* 5 */  (a) -> {ServerSocketChannel s = ServerSocketChannel.open(); s.bind(a);s.close();},
       
    59         /* 6 */  (a) -> {DatagramChannel s = DatagramChannel.open(); s.bind(a); s.close();},
       
    60         /* 7 */  (a) -> {SocketChannel s = SocketChannel.open(); s.socket().bind(a);s.close();},
       
    61         /* 8 */  (a) -> {ServerSocketChannel s = ServerSocketChannel.open(); s.socket().bind(a);s.close();},
       
    62         /* 9 */  (a) -> {DatagramChannel s = DatagramChannel.open(); s.socket().bind(a); s.close();},
       
    63         /* 10 */ (a) -> {socketTest(a);},
       
    64         /* 11 */ (a) -> {dgSocketTest(a, false);},
       
    65         /* 12 */ (a) -> {dgSocketTest(a, true);},
       
    66         /* 13 */ (a) -> {dgChannelTest(a, false);},
       
    67         /* 14 */ (a) -> {dgChannelTest(a, true);}
       
    68     );
       
    69 
       
    70     static List<Inet6Address> getLinkLocalAddrs() throws IOException {
       
    71         return NetworkConfiguration.probe()
       
    72                    .ip6Addresses()
       
    73                    .filter(Inet6Address::isLinkLocalAddress)
       
    74                    .collect(Collectors.toList());
       
    75     }
       
    76 
       
    77     static void compare(InetSocketAddress a, InetSocketAddress b) {
       
    78         Inet6Address a1 = (Inet6Address)a.getAddress();
       
    79         Inet6Address b1 = (Inet6Address)b.getAddress();
       
    80         compare (a1, b1);
       
    81     }
       
    82 
       
    83     static void compare(InetAddress a, InetAddress b) {
       
    84         Inet6Address a1 = (Inet6Address)a;
       
    85         Inet6Address b1 = (Inet6Address)b;
       
    86         if (!a1.equals(b1)) {
       
    87             System.out.printf("%s != %s\n", a1, b1);
       
    88             throw new RuntimeException("Addresses not the same");
       
    89         }
       
    90 
       
    91         if (!a1.getHostAddress().equals(b1.getHostAddress())) {
       
    92             System.out.printf("%s != %s\n", a1, b1);
       
    93             if (a1.getScopeId() != b1.getScopeId())
       
    94                 throw new RuntimeException("Scope ids not the same");
       
    95         }
       
    96     }
       
    97 
       
    98     static void socketTest(InetSocketAddress a) throws Exception {
       
    99         System.out.printf("socketTest: address %s\n", a);
       
   100         try (ServerSocket server = new ServerSocket(0, 5, a.getAddress())) {
       
   101             InetAddress saddr = server.getInetAddress();
       
   102             int port = server.getLocalPort();
       
   103             Socket client = new Socket(saddr, port);
       
   104             compare(client.getInetAddress(), saddr);
       
   105             try {
       
   106                 client.close();
       
   107             } catch (IOException e) {}
       
   108         }
       
   109     }
       
   110 
       
   111     static void dgSocketTest(InetSocketAddress a, boolean connect) throws Exception {
       
   112         try (DatagramSocket s = new DatagramSocket(null)) {
       
   113             System.out.println("dgSocketTest: " + a);
       
   114             s.bind(a);
       
   115             String t = "Hello world";
       
   116             DatagramPacket rx = new DatagramPacket(new byte[128], 128);
       
   117             int port = s.getLocalPort();
       
   118             InetSocketAddress dest = new InetSocketAddress(a.getAddress(), port);
       
   119             DatagramPacket tx = new DatagramPacket(t.getBytes("ISO8859_1"), t.length(), dest);
       
   120             if (connect) {
       
   121                 s.connect(dest);
       
   122                 System.out.println("dgSocketTest: connect remote addr = " + s.getRemoteSocketAddress());
       
   123                 compare(a, (InetSocketAddress)s.getRemoteSocketAddress());
       
   124             }
       
   125             s.send(tx);
       
   126             s.receive(rx);
       
   127             String t1 = new String(rx.getData(), rx.getOffset(), rx.getLength(), "ISO8859_1");
       
   128             if (!t1.equals(t))
       
   129                 throw new RuntimeException("Packets not equal");
       
   130         }
       
   131     }
       
   132 
       
   133     static void dgChannelTest(InetSocketAddress a, boolean connect) throws Exception {
       
   134         try (DatagramChannel s = DatagramChannel.open()) {
       
   135             System.out.println("dgChannelTest: " + a);
       
   136             s.bind(a);
       
   137             String t = "Hello world";
       
   138             ByteBuffer rx = ByteBuffer.allocate(128);
       
   139             int port = ((InetSocketAddress)s.getLocalAddress()).getPort();
       
   140             InetSocketAddress dest = new InetSocketAddress(a.getAddress(), port);
       
   141             ByteBuffer tx = ByteBuffer.wrap(t.getBytes("ISO8859_1"));
       
   142             if (connect) {
       
   143                 s.connect(dest);
       
   144                 System.out.println("dgChannelTest: connect remote addr = " + s.getRemoteAddress());
       
   145                 compare(a, (InetSocketAddress)s.getRemoteAddress());
       
   146             }
       
   147             s.send(tx, dest);
       
   148             s.receive(rx);
       
   149             rx.flip();
       
   150             String t1 = new String(rx.array(), 0, rx.limit(), "ISO8859_1");
       
   151             System.out.printf("rx : %s, data: %s\n", rx, t1);
       
   152             if (!t1.equals(t))
       
   153                 throw new RuntimeException("Packets not equal");
       
   154         }
       
   155     }
       
   156 
       
   157     static Inet6Address stripScope(Inet6Address address) {
       
   158         byte[] bytes = address.getAddress();
       
   159         InetAddress result = null;
       
   160         try {
       
   161             result = InetAddress.getByAddress(bytes);
       
   162         } catch (UnknownHostException e) {
       
   163             assert false;
       
   164         }
       
   165         return (Inet6Address)result;
       
   166     }
       
   167 
       
   168     public static void main(String[] args) throws Exception {
       
   169         for (Inet6Address address : getLinkLocalAddrs()) {
       
   170             Inet6Address stripped = stripScope(address);
       
   171             InetSocketAddress s1 = new InetSocketAddress(address, 0);
       
   172             InetSocketAddress s2 = new InetSocketAddress(stripped, 0);
       
   173             System.out.println("Trying: " + address);
       
   174             int count = 0, success = 0;
       
   175             for (ThrowingConsumer<InetSocketAddress> target : targets) {
       
   176                 try {
       
   177                     target.accept(s1);
       
   178                     System.out.println("target " + count + " OK");
       
   179                     // if that succeeds try s2 (the actual test)
       
   180                     try {
       
   181                         target.accept(s2);
       
   182                         success++;
       
   183                     } catch (IOException ee) {
       
   184                         String msg = "Failed: " + s2.toString() + "count: " + Integer.toString(count);
       
   185                         throw new RuntimeException (msg);
       
   186                     }
       
   187                 } catch (IOException e) {
       
   188                     System.out.println(e.getMessage());
       
   189                     // OK
       
   190                 }
       
   191                 count++;
       
   192             }
       
   193             System.out.println("Succeeded with " + success + " binds");
       
   194         }
       
   195     }
       
   196 }