8233847: (sctp) Flx link-local IPv6 scope handling and test cleanup
authorchegar
Thu, 21 Nov 2019 12:14:29 +0000
changeset 59205 afcc8af048e6
parent 59204 7b10581e9632
child 59206 61091a42f19d
8233847: (sctp) Flx link-local IPv6 scope handling and test cleanup Reviewed-by: alanb
src/java.base/share/classes/module-info.java
src/jdk.sctp/share/classes/com/sun/nio/sctp/HandlerResult.java
src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java
src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java
src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java
test/jdk/com/sun/nio/sctp/SctpChannel/Bind.java
test/jdk/com/sun/nio/sctp/SctpChannel/CommUp.java
test/jdk/com/sun/nio/sctp/SctpChannel/Connect.java
test/jdk/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java
test/jdk/com/sun/nio/sctp/SctpMultiChannel/Branch.java
test/jdk/com/sun/nio/sctp/SctpMultiChannel/Send.java
test/jdk/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java
test/jdk/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java
--- a/src/java.base/share/classes/module-info.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/src/java.base/share/classes/module-info.java	Thu Nov 21 12:14:29 2019 +0000
@@ -240,8 +240,9 @@
         jdk.naming.dns;
     exports sun.net.util to
         java.desktop,
+        java.net.http,
         jdk.jconsole,
-        java.net.http;
+        jdk.sctp;
     exports sun.net.www to
         java.net.http,
         jdk.jartool;
--- a/src/jdk.sctp/share/classes/com/sun/nio/sctp/HandlerResult.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/src/jdk.sctp/share/classes/com/sun/nio/sctp/HandlerResult.java	Thu Nov 21 12:14:29 2019 +0000
@@ -29,7 +29,7 @@
  *
  * <P> The {@code HandlerResult} is used to determine the behavior of the
  * channel after it handles a notification from the SCTP stack. Essentially its
- * value determines if the channel should try to receive another notificaiton or
+ * value determines if the channel should try to receive another notification or
  * a message before returning.
  *
  * @since 1.7
--- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Thu Nov 21 12:14:29 2019 +0000
@@ -53,6 +53,7 @@
 import com.sun.nio.sctp.NotificationHandler;
 import com.sun.nio.sctp.SctpChannel;
 import com.sun.nio.sctp.SctpSocketOption;
+import sun.net.util.IPAddressUtil;
 import sun.nio.ch.DirectBuffer;
 import sun.nio.ch.IOStatus;
 import sun.nio.ch.IOUtil;
@@ -1012,6 +1013,9 @@
         if (target != null) {
             InetSocketAddress isa = Net.checkAddress(target);
             addr = isa.getAddress();
+            if (addr.isLinkLocalAddress()) {
+                addr = IPAddressUtil.toScopedAddress(addr);
+            }
             port = isa.getPort();
         }
 
--- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Thu Nov 21 12:14:29 2019 +0000
@@ -53,6 +53,7 @@
 import com.sun.nio.sctp.SctpChannel;
 import com.sun.nio.sctp.SctpMultiChannel;
 import com.sun.nio.sctp.SctpSocketOption;
+import sun.net.util.IPAddressUtil;
 import sun.nio.ch.DirectBuffer;
 import sun.nio.ch.NativeThread;
 import sun.nio.ch.IOStatus;
@@ -892,6 +893,9 @@
         if (target != null) {
             InetSocketAddress isa = Net.checkAddress(target);
             addr = isa.getAddress();
+            if (addr.isLinkLocalAddress()) {
+                addr = IPAddressUtil.toScopedAddress(addr);
+            }
             port = isa.getPort();
         }
         int pos = bb.position();
--- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java	Thu Nov 21 12:14:29 2019 +0000
@@ -34,6 +34,7 @@
 import java.util.HashSet;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import sun.net.util.IPAddressUtil;
 import sun.nio.ch.IOUtil;
 import sun.nio.ch.Net;
 import com.sun.nio.sctp.SctpSocketOption;
@@ -169,9 +170,13 @@
             InetSocketAddress netAddr = (InetSocketAddress)addr;
 
             if (name.equals(SCTP_PRIMARY_ADDR)) {
+                InetAddress inetAddress = netAddr.getAddress();
+                if (inetAddress.isLinkLocalAddress()) {
+                    inetAddress = IPAddressUtil.toScopedAddress(inetAddress);
+                }
                 setPrimAddrOption0(fd,
                                    assocId,
-                                   netAddr.getAddress(),
+                                   inetAddress,
                                    netAddr.getPort());
             } else {
                 setPeerPrimAddrOption0(fd,
--- a/test/jdk/com/sun/nio/sctp/SctpChannel/Bind.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpChannel/Bind.java	Thu Nov 21 12:14:29 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -110,9 +110,10 @@
             try {
                 channel.close();  /* open a new unbound channel for test */
                 channel = SctpChannel.open();
-                connectChannel(channel);
-                channel.bind(null);
-                fail("AlreadyConnectedException expected");
+                try (var peer = connectChannel(channel)) {
+                    channel.bind(null);
+                    fail("AlreadyConnectedException expected");
+                }
             } catch (AlreadyConnectedException unused) { pass();
             } catch (IOException ioe) { unexpected(ioe); }
 
@@ -264,7 +265,9 @@
         } finally {
             try { if (channel != null) channel.close(); }
             catch (IOException ioe) { unexpected(ioe); }
-        }
+            try { if (peerChannel != null) peerChannel.close(); }
+            catch (IOException ioe) { unexpected(ioe); }
+         }
     }
 
     boolean boundAddress(SctpChannel channel, InetAddress addr)
--- a/test/jdk/com/sun/nio/sctp/SctpChannel/CommUp.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpChannel/CommUp.java	Thu Nov 21 12:14:29 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -191,6 +191,9 @@
                 }
             } //for
 
+            try { sc.close(); }
+            catch (IOException ioe) { unexpected(ioe); }
+
         } catch (IOException ioe) {
             unexpected(ioe);
         } catch (InterruptedException ie) {
--- a/test/jdk/com/sun/nio/sctp/SctpChannel/Connect.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpChannel/Connect.java	Thu Nov 21 12:14:29 2019 +0000
@@ -61,11 +61,10 @@
 
     void doTest() {
         SctpChannel channel = null;
-        SctpServerChannel ssc = null;
 
-        try {
+        try (SctpServerChannel ssc = SctpServerChannel.open()) {
             /* Create a server channel to connect to */
-            ssc = SctpServerChannel.open().bind(null);
+            ssc.bind(null);
             Set<SocketAddress> addrs = ssc.getAllLocalAddresses();
             if (addrs.isEmpty())
                 debug("addrs should not be empty");
@@ -209,8 +208,6 @@
         } finally {
             try { if (channel != null) channel.close(); }
             catch (IOException unused) {}
-            try { if (ssc != null) ssc.close(); }
-            catch (IOException unused) {}
         }
     }
 
--- a/test/jdk/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java	Thu Nov 21 12:14:29 2019 +0000
@@ -72,8 +72,7 @@
             return;
         }
 
-        try {
-            SctpChannel sc = SctpChannel.open();
+        try (SctpChannel sc = SctpChannel.open()) {
 
             /* check supported options */
             Set<SctpSocketOption<?>> options = sc.supportedOptions();
@@ -143,8 +142,6 @@
 
     /* SCTP_PRIMARY_ADDR */
     void sctpPrimaryAddr() throws IOException {
-        SocketAddress addrToSet = null;;
-
         System.out.println("TESTING SCTP_PRIMARY_ADDR");
         SctpChannel sc = SctpChannel.open();
         SctpServerChannel ssc = SctpServerChannel.open().bind(null);
@@ -158,12 +155,11 @@
         sc.connect(serverAddr);
         SctpChannel peerChannel = ssc.accept();
         ssc.close();
-        Set<SocketAddress> peerAddrs = peerChannel.getAllLocalAddresses();
-        debug("Peer local Addresses: ");
-        for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
+        Set<SocketAddress> remoteAddresses = sc.getRemoteAddresses();
+        debug("Remote Addresses: ");
+        for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
             InetSocketAddress addr = (InetSocketAddress)it.next();
             debug("\t" + addr);
-            addrToSet = addr;   // any of the peer addresses will do!
         }
 
         /* retrieval of SCTP_PRIMARY_ADDR is not supported on Solaris */
@@ -176,25 +172,21 @@
         } else { /* Linux */
             SocketAddress primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
             System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
-            /* Verify that this is one of the peer addresses */
-            boolean found = false;
-            addrToSet = primaryAddr; // may not have more than one addr
-            for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
-                InetSocketAddress addr = (InetSocketAddress)it.next();
-                if (addr.equals(primaryAddr)) {
-                    found = true;
-                }
-                addrToSet = addr;
+            /* Verify that this is one of the remote addresses */
+            check(remoteAddresses.contains(primaryAddr), "SCTP_PRIMARY_ADDR returned bogus address!");
+
+            for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
+                InetSocketAddress addrToSet = (InetSocketAddress) it.next();
+                System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
+                sc.setOption(SCTP_PRIMARY_ADDR, addrToSet);
+                System.out.println("SCTP_PRIMARY_ADDR set to    : " + addrToSet);
+                primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
+                System.out.println("SCTP_PRIMARY_ADDR returned  : " + primaryAddr);
+                check(addrToSet.equals(primaryAddr), "SCTP_PRIMARY_ADDR not set correctly");
             }
-            check(found, "SCTP_PRIMARY_ADDR returned bogus address!");
-
-            System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
-            sc.setOption(SCTP_PRIMARY_ADDR, addrToSet);
-            System.out.println("SCTP_PRIMARY_ADDR set to: " + addrToSet);
-            primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
-            System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
-            check(addrToSet.equals(primaryAddr),"SCTP_PRIMARY_ADDR not set correctly");
         }
+        sc.close();
+        peerChannel.close();
     }
             //--------------------- Infrastructure ---------------------------
     boolean debug = true;
--- a/test/jdk/com/sun/nio/sctp/SctpMultiChannel/Branch.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpMultiChannel/Branch.java	Thu Nov 21 12:14:29 2019 +0000
@@ -210,7 +210,8 @@
                 /* echo the message */
                 debug("Server: echoing first message");
                 buffer.flip();
-                int bytes = serverChannel.send(buffer, info);
+                MessageInfo sendInfo = MessageInfo.createOutgoing(info.association(), null, 0);
+                int bytes = serverChannel.send(buffer, sendInfo);
                 debug("Server: sent " + bytes + "bytes");
 
                 clientFinishedLatch.await(10L, TimeUnit.SECONDS);
--- a/test/jdk/com/sun/nio/sctp/SctpMultiChannel/Send.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpMultiChannel/Send.java	Thu Nov 21 12:14:29 2019 +0000
@@ -276,7 +276,8 @@
                 /* echo the message */
                 debug("Server: echoing first message");
                 buffer.flip();
-                int bytes = serverChannel.send(buffer, info);
+                MessageInfo sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());
+                int bytes = serverChannel.send(buffer, sendInfo);
                 debug("Server: sent " + bytes + "bytes");
 
                 /* receive a large message */
@@ -302,7 +303,8 @@
                 /* echo the message */
                 debug("Server: echoing second message");
                 buffer.flip();
-                bytes = serverChannel.send(buffer, info);
+                sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());
+                bytes = serverChannel.send(buffer, sendInfo);
                 debug("Server: sent " + bytes + "bytes");
 
                 /* TEST 6 */
--- a/test/jdk/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpMultiChannel/SendFailed.java	Thu Nov 21 12:14:29 2019 +0000
@@ -98,14 +98,19 @@
                     new SendFailedNotificationHandler();
             ByteBuffer recvBuffer = direct ? allocateDirect(recvBufferSize)
                                            : allocate((recvBufferSize));
-            channel.receive(recvBuffer, null, handler);
+            MessageInfo info = channel.receive(recvBuffer, null, handler);
+            debug("receive returned info:" + info);
 
-            // verify sent buffer received by send failed notification
-            ByteBuffer buffer = handler.getSendFailedByteBuffer();
-            check(buffer.remaining() == sent);
-            check(buffer.position() == 0);
-            check(buffer.limit() == sent);
-            assertSameContent(sendBuffer, handler.getSendFailedByteBuffer());
+            if (handler.receivedSendFailed) {
+                // verify sent buffer received by send failed notification
+                ByteBuffer buffer = handler.getSendFailedByteBuffer();
+                check(buffer.remaining() == sent);
+                check(buffer.position() == 0);
+                check(buffer.limit() == sent);
+                assertSameContent(sendBuffer, handler.getSendFailedByteBuffer());
+            } else {
+                debug("Unexpected event or received data. Check output.");
+            }
         }
     }
 
@@ -113,6 +118,7 @@
     {
         /** Reference to the buffer captured in send failed notification */
         private ByteBuffer sentBuffer;
+        boolean receivedSendFailed;
 
         @Override
         public HandlerResult handleNotification(
@@ -135,6 +141,7 @@
         public HandlerResult handleNotification(
                 SendFailedNotification notification, Object attachment) {
             debug("%nSendFailedNotification: %s. ", notification);
+            receivedSendFailed = true;
             sentBuffer = notification.buffer();
             return HandlerResult.RETURN;
         }
--- a/test/jdk/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java	Thu Nov 21 12:14:28 2019 +0000
+++ b/test/jdk/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java	Thu Nov 21 12:14:29 2019 +0000
@@ -154,7 +154,6 @@
 
     /* SCTP_PRIMARY_ADDR */
     void sctpPrimaryAddr() throws IOException {
-        SocketAddress addrToSet = null;
         ByteBuffer buffer = ByteBuffer.allocate(Util.SMALL_BUFFER);
 
         System.out.println("TESTING SCTP_PRIMARY_ADDR");
@@ -189,12 +188,11 @@
 
         SctpChannel peerChannel = ssc.accept();
         ssc.close();
-        Set<SocketAddress> peerAddrs = peerChannel.getAllLocalAddresses();
-        debug("Peer local Addresses: ");
-        for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
+        Set<SocketAddress> remoteAddresses = smc.getRemoteAddresses(assoc);
+        debug("Remote Addresses: ");
+        for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
             InetSocketAddress addr = (InetSocketAddress)it.next();
             debug("\t" + addr);
-            addrToSet = addr;   // any of the peer addresses will do!
         }
 
         /* retrieval of SCTP_PRIMARY_ADDR is not supported on Solaris */
@@ -207,25 +205,21 @@
         } else { /* Linux */
             SocketAddress primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
             System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
-            /* Verify that this is one of the peer addresses */
-            boolean found = false;
-            addrToSet = primaryAddr; // may not have more than one addr
-            for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
-                InetSocketAddress addr = (InetSocketAddress)it.next();
-                if (addr.equals(primaryAddr)) {
-                    found = true;
-                }
-                addrToSet = addr;
+            /* Verify that this is one of the remote addresses */
+            check(remoteAddresses.contains(primaryAddr), "SCTP_PRIMARY_ADDR returned bogus address!");
+
+            for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
+                InetSocketAddress addrToSet = (InetSocketAddress) it.next();
+                System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
+                smc.setOption(SCTP_PRIMARY_ADDR, addrToSet, assoc);
+                System.out.println("SCTP_PRIMARY_ADDR set to    : " + addrToSet);
+                primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
+                System.out.println("SCTP_PRIMARY_ADDR returned  : " + primaryAddr);
+                check(addrToSet.equals(primaryAddr), "SCTP_PRIMARY_ADDR not set correctly");
             }
-            check(found, "SCTP_PRIMARY_ADDR returned bogus address!");
-
-            System.out.println("Try SCTP_PRIMARY_ADDR set to: " + addrToSet);
-            smc.setOption(SCTP_PRIMARY_ADDR, addrToSet, assoc);
-            System.out.println("SCTP_PRIMARY_ADDR set to: " + addrToSet);
-            primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
-            System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
-            check(addrToSet.equals(primaryAddr),"SCTP_PRIMARY_ADDR not set correctly");
         }
+        smc.close();
+        peerChannel.close();
     }
 
     class SOTNotificationHandler extends AbstractNotificationHandler<Object>