8217451: ExtendedSocketOptions should encapsulate support for SO_FLOW_SLA
authoralanb
Tue, 22 Jan 2019 12:32:19 +0000
changeset 53419 eac105e3ec13
parent 53418 bc2bb4eee477
child 53420 2190f45140b1
8217451: ExtendedSocketOptions should encapsulate support for SO_FLOW_SLA Reviewed-by: michaelm, chegar
src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java
src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java
src/java.base/unix/classes/java/net/PlainSocketImpl.java
test/jdk/java/nio/channels/SocketChannel/SocketOptionTests.java
--- a/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -54,21 +54,53 @@
     /** Return the, possibly empty, set of extended socket options available. */
     public final Set<SocketOption<?>> options() { return options; }
 
-    public static final Set<SocketOption<?>> options(short type) {
-        return getInstance().options0(type);
+    /**
+     * Returns the (possibly empty) set of extended socket options for
+     * stream-oriented listening sockets.
+     */
+    public static Set<SocketOption<?>> serverSocketOptions() {
+        return getInstance().options0(SOCK_STREAM, true);
+    }
+
+    /**
+     * Returns the (possibly empty) set of extended socket options for
+     * stream-oriented connecting sockets.
+     */
+    public static Set<SocketOption<?>> clientSocketOptions() {
+        return getInstance().options0(SOCK_STREAM, false);
     }
 
-    private Set<SocketOption<?>> options0(short type) {
-        Set<SocketOption<?>> extOptions = null;
+    /**
+     * Returns the (possibly empty) set of extended socket options for
+     * datagram-oriented sockets.
+     */
+    public static Set<SocketOption<?>> datagramSocketOptions() {
+        return getInstance().options0(SOCK_DGRAM, false);
+    }
+
+    private boolean isDatagramOption(SocketOption<?> option) {
+        return !option.name().startsWith("TCP_");
+    }
+
+    private boolean isStreamOption(SocketOption<?> option, boolean server) {
+        if (server && "SO_FLOW_SLA".equals(option.name())) {
+            return false;
+        } else {
+            return !option.name().startsWith("UDP_");
+        }
+    }
+
+    private Set<SocketOption<?>> options0(short type, boolean server) {
+        Set<SocketOption<?>> extOptions;
         switch (type) {
             case SOCK_DGRAM:
                 extOptions = options.stream()
-                        .filter((option) -> !option.name().startsWith("TCP_"))
+                        .filter(option -> isDatagramOption(option))
                         .collect(Collectors.toUnmodifiableSet());
                 break;
             case SOCK_STREAM:
                 extOptions = options.stream()
-                        .filter((option) -> !option.name().startsWith("UDP_"))
+                        .filter(option -> isStreamOption(option, server))
                         .collect(Collectors.toUnmodifiableSet());
                 break;
             default:
--- a/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -40,7 +40,6 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
 
 /**
  * Base implementation of AsynchronousServerSocketChannel.
@@ -236,7 +235,7 @@
             if (Net.isReusePortAvailable()) {
                 set.add(StandardSocketOptions.SO_REUSEPORT);
             }
-            set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
+            set.addAll(ExtendedSocketOptions.serverSocketOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -40,7 +40,6 @@
 import java.util.concurrent.locks.*;
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
 
 /**
  * Base implementation of AsynchronousSocketChannel
@@ -513,7 +512,7 @@
                 set.add(StandardSocketOptions.SO_REUSEPORT);
             }
             set.add(StandardSocketOptions.TCP_NODELAY);
-            set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
+            set.addAll(ExtendedSocketOptions.clientSocketOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -57,7 +57,6 @@
 
 import sun.net.ResourceManager;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_DGRAM;
 
 /**
  * An implementation of DatagramChannels.
@@ -335,7 +334,7 @@
             set.add(StandardSocketOptions.IP_MULTICAST_IF);
             set.add(StandardSocketOptions.IP_MULTICAST_TTL);
             set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
-            set.addAll(ExtendedSocketOptions.options(SOCK_DGRAM));
+            set.addAll(ExtendedSocketOptions.datagramSocketOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -28,11 +28,9 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.InetSocketAddress;
-import java.net.ProtocolFamily;
 import java.net.ServerSocket;
 import java.net.SocketAddress;
 import java.net.SocketOption;
-import java.net.StandardProtocolFamily;
 import java.net.StandardSocketOptions;
 import java.nio.channels.AlreadyBoundException;
 import java.nio.channels.AsynchronousCloseException;
@@ -50,7 +48,6 @@
 
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
 
 /**
  * An implementation of ServerSocketChannels
@@ -193,7 +190,7 @@
             if (Net.isReusePortAvailable()) {
                 set.add(StandardSocketOptions.SO_REUSEPORT);
             }
-            set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
+            set.addAll(ExtendedSocketOptions.serverSocketOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -55,7 +55,6 @@
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
 import sun.net.util.SocketExceptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
 
 /**
  * An implementation of SocketChannels
@@ -282,7 +281,7 @@
             // additional options required by socket adaptor
             set.add(StandardSocketOptions.IP_TOS);
             set.add(ExtendedSocketOption.SO_OOBINLINE);
-            set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
+            set.addAll(ExtendedSocketOptions.clientSocketOptions());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -28,7 +28,6 @@
 import java.util.Set;
 import java.util.HashSet;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_DGRAM;
 
 /*
  * On Unix systems we simply delegate to native methods.
@@ -78,7 +77,7 @@
 
     protected Set<SocketOption<?>> supportedOptions() {
         HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
-        options.addAll(ExtendedSocketOptions.options(SOCK_DGRAM));
+        options.addAll(ExtendedSocketOptions.datagramSocketOptions());
         return options;
     }
 
--- a/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -29,7 +29,6 @@
 import java.util.Set;
 import java.util.HashSet;
 import sun.net.ext.ExtendedSocketOptions;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
 
 /*
  * On Unix systems we simply delegate to native methods.
@@ -91,25 +90,14 @@
 
     protected Set<SocketOption<?>> supportedOptions() {
         HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
-        addExtSocketOptions(ExtendedSocketOptions.options(SOCK_STREAM), options);
+        if (getServerSocket() != null) {
+            options.addAll(ExtendedSocketOptions.serverSocketOptions());
+        } else {
+            options.addAll(ExtendedSocketOptions.clientSocketOptions());
+        }
         return options;
     }
 
-    private void addExtSocketOptions(Set<SocketOption<?>> extOptions,
-            Set<SocketOption<?>> options) {
-        extOptions.forEach((option) -> {
-            if (option.name().equals("SO_FLOW_SLA")) {
-                // SO_FLOW_SLA is Solaris specific option which is not applicable
-                // for ServerSockets.
-                // getSocket() will always return null for server socket
-                if (getSocket() != null) {
-                    options.add(option);
-                }
-            } else {
-                options.add(option);
-            }
-        });
-    }
     protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
         if (opt == SocketOptions.SO_REUSEPORT &&
             !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
--- a/test/jdk/java/nio/channels/SocketChannel/SocketOptionTests.java	Tue Jan 22 11:22:44 2019 +0100
+++ b/test/jdk/java/nio/channels/SocketChannel/SocketOptionTests.java	Tue Jan 22 12:32:19 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -32,14 +32,15 @@
  * @run main/othervm --limit-modules=java.base SocketOptionTests
  */
 
-import java.nio.channels.*;
-import java.net.*;
 import java.io.IOException;
-import java.util.*;
+import java.net.InetSocketAddress;
+import java.net.SocketOption;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SocketChannel;
+import java.util.Set;
+import sun.net.ext.ExtendedSocketOptions;
 import static java.net.StandardSocketOptions.*;
 import static jdk.net.ExtendedSocketOptions.*;
-import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
-import sun.net.ext.ExtendedSocketOptions;
 
 public class SocketOptionTests {
 
@@ -52,26 +53,26 @@
     }
 
     public static void main(String[] args) throws IOException {
-        SocketChannel sc = SocketChannel.open();
-
-        // check supported options
-        Set<SocketOption<?>> options = sc.supportedOptions();
+        try (var channel = SocketChannel.open()) {
+            test(channel);
+        }
+    }
 
-        List<? extends SocketOption> extOptions = List.of(TCP_KEEPCOUNT,
-                TCP_KEEPIDLE, TCP_KEEPINTERVAL);
-        List<? extends SocketOption> expected;
-        boolean keepAliveOptsupported;
-        if (keepAliveOptsupported=ExtendedSocketOptions.options(SOCK_STREAM)
-                .containsAll(extOptions)) {
-            expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
+    static void test(SocketChannel sc) throws IOException {
+        Set<SocketOption<?>> extendedOptions = ExtendedSocketOptions.clientSocketOptions();
+        Set<SocketOption<?>> keepAliveOptions = Set.of(TCP_KEEPCOUNT, TCP_KEEPIDLE, TCP_KEEPINTERVAL);
+        boolean keepAliveOptionsSupported = extendedOptions.containsAll(keepAliveOptions);
+        Set<SocketOption<?>> expected;
+        if (keepAliveOptionsSupported) {
+            expected = Set.of(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
                     SO_REUSEADDR, SO_LINGER, TCP_NODELAY, TCP_KEEPCOUNT,
                     TCP_KEEPIDLE, TCP_KEEPINTERVAL);
         } else {
-            expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
+            expected = Set.of(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
                     SO_REUSEADDR, SO_LINGER, TCP_NODELAY);
         }
         for (SocketOption opt: expected) {
-            if (!options.contains(opt))
+            if (!sc.supportedOptions().contains(opt))
                 throw new RuntimeException(opt.name() + " should be supported");
         }
 
@@ -133,7 +134,7 @@
             throw new RuntimeException("expected linger to be disabled");
         sc.setOption(TCP_NODELAY, true);        // can't check
         sc.setOption(TCP_NODELAY, false);       // can't check
-        if (keepAliveOptsupported) {
+        if (keepAliveOptionsSupported) {
             sc.setOption(TCP_KEEPIDLE, 1234);
             checkOption(sc, TCP_KEEPIDLE, 1234);
             sc.setOption(TCP_KEEPINTERVAL, 123);
@@ -161,4 +162,4 @@
         } catch (ClosedChannelException x) {
         }
     }
-}
+}
\ No newline at end of file