8044773: Refactor jdk.net API so that it can be moved out of the base module
Reviewed-by: alanb, erikj, mchung
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.net.gmk Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2016, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+
+ $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
+ LIBRARY := extnet, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(JDK_TOPDIR)/src/jdk.net/solaris/native/libextnet, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := -lsocket -lc -ljava, \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
+ ))
+
+ $(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
+
+ TARGETS += $(BUILD_LIBEXTNET)
+endif
+
+
+################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libextnet/mapfile-vers Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2016, 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+SUNWprivate_1.1 {
+ global:
+ Java_jdk_net_SolarisSocketOptions_init;
+ Java_jdk_net_SolarisSocketOptions_setFlowOption;
+ Java_jdk_net_SolarisSocketOptions_getFlowOption;
+ Java_jdk_net_SolarisSocketOptions_flowSupported;
+ local:
+ *;
+};
--- a/jdk/make/mapfiles/libnet/mapfile-vers Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/make/mapfiles/libnet/mapfile-vers Wed Apr 27 20:36:02 2016 +0100
@@ -98,10 +98,6 @@
Java_sun_net_sdp_SdpSupport_create0;
Java_sun_net_spi_DefaultProxySelector_init;
Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
- Java_sun_net_ExtendedOptionsImpl_init;
- Java_sun_net_ExtendedOptionsImpl_setFlowOption;
- Java_sun_net_ExtendedOptionsImpl_getFlowOption;
- Java_sun_net_ExtendedOptionsImpl_flowSupported;
NET_AllocSockaddr;
NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress;
--- a/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java Wed Apr 27 20:36:02 2016 +0100
@@ -52,7 +52,7 @@
"Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
"Options are:\n" +
" -exports <package-name>\n" +
- " -exports <package-name>/<module-name>\n" +
+ " -exports <package-name>[/<module-name>]\n" +
" -uses <service>\n" +
" -provides <service>/<provider-impl-classname>\n";
--- a/jdk/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.net;
-
-import java.net.SocketOption;
-
-/**
- * Defines extended socket options, beyond those defined in
- * {@link java.net.StandardSocketOptions}. These options may be platform
- * specific.
- *
- * @since 1.8
- */
-public final class ExtendedSocketOptions {
-
- private static class ExtSocketOption<T> implements SocketOption<T> {
- private final String name;
- private final Class<T> type;
- ExtSocketOption(String name, Class<T> type) {
- this.name = name;
- this.type = type;
- }
- @Override public String name() { return name; }
- @Override public Class<T> type() { return type; }
- @Override public String toString() { return name; }
- }
-
- private ExtendedSocketOptions() {}
-
- /**
- * Service level properties. When a security manager is installed,
- * setting or getting this option requires a {@link NetworkPermission}
- * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
- * respectively.
- */
- public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
- ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
-}
--- a/jdk/src/java.base/share/classes/jdk/net/NetworkPermission.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.net;
-
-import java.security.BasicPermission;
-
-/**
- * Represents permission to access the extended networking capabilities
- * defined in the jdk.net package. These permissions contain a target
- * name, but no actions list. Callers either possess the permission or not.
- * <p>
- * The following targets are defined:
- *
- * <table border=1 cellpadding=5 summary="permission target name,
- * what the target allows,and associated risks">
- * <tr>
- * <th>Permission Target Name</th>
- * <th>What the Permission Allows</th>
- * <th>Risks of Allowing this Permission</th>
- * </tr>
- * <tr>
- * <td>setOption.SO_FLOW_SLA</td>
- * <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
- * on any socket that supports it</td>
- * <td>allows caller to set a higher priority or bandwidth allocation
- * to sockets it creates, than they might otherwise be allowed.</td>
- * </tr>
- * <tr>
- * <td>getOption.SO_FLOW_SLA</td>
- * <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
- * setting from any socket that supports the option</td>
- * <td>allows caller access to SLA information that it might not
- * otherwise have</td>
- * </tr></table>
- *
- * @see jdk.net.ExtendedSocketOptions
- *
- * @since 1.8
- */
-
-public final class NetworkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -2012939586906722291L;
-
- /**
- * Creates a NetworkPermission with the given target name.
- *
- * @param name the permission target name
- * @throws NullPointerException if {@code name} is {@code null}.
- * @throws IllegalArgumentException if {@code name} is empty.
- */
- public NetworkPermission(String name)
- {
- super(name);
- }
-
- /**
- * Creates a NetworkPermission with the given target name.
- *
- * @param name the permission target name
- * @param actions should be {@code null}. Is ignored if not.
- * @throws NullPointerException if {@code name} is {@code null}.
- * @throws IllegalArgumentException if {@code name} is empty.
- */
- public NetworkPermission(String name, String actions)
- {
- super(name, actions);
- }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/SocketFlow.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.net;
-
-import java.lang.annotation.Native;
-
-/**
- * Represents the service level properties for the platform specific socket
- * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
- * <p>
- * The priority and bandwidth parameters must be set before
- * setting the socket option.
- * <p>
- * When the {@code SO_FLOW_SLA} option is set then it may not take effect
- * immediately. If the value of the socket option is obtained with
- * {@code getOption()} then the status may be returned as {@code INPROGRESS}
- * until it takes effect. The priority and bandwidth values are only valid when
- * the status is returned as OK.
- * <p>
- * When a security manager is installed, a {@link NetworkPermission}
- * is required to set or get this option.
- *
- * @since 1.8
- */
-public class SocketFlow {
-
- private static final int UNSET = -1;
- @Native public static final int NORMAL_PRIORITY = 1;
- @Native public static final int HIGH_PRIORITY = 2;
-
- private int priority = NORMAL_PRIORITY;
-
- private long bandwidth = UNSET;
-
- private Status status = Status.NO_STATUS;
-
- private SocketFlow() {}
-
- /**
- * Enumeration of the return values from the SO_FLOW_SLA
- * socket option. Both setting and getting the option return
- * one of these statuses, which reflect the state of socket's
- * flow.
- *
- * @since 1.8
- */
- public enum Status {
- /**
- * Set or get socket option has not been called yet. Status
- * values can only be retrieved after calling set or get.
- */
- NO_STATUS,
- /**
- * Flow successfully created.
- */
- OK,
- /**
- * Caller has no permission to create flow.
- */
- NO_PERMISSION,
- /**
- * Flow can not be created because socket is not connected.
- */
- NOT_CONNECTED,
- /**
- * Flow creation not supported for this socket.
- */
- NOT_SUPPORTED,
- /**
- * A flow already exists with identical attributes.
- */
- ALREADY_CREATED,
- /**
- * A flow is being created.
- */
- IN_PROGRESS,
- /**
- * Some other unspecified error.
- */
- OTHER
- }
-
- /**
- * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
- * socket option and create a socket flow.
- */
- public static SocketFlow create() {
- return new SocketFlow();
- }
-
- /**
- * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
- * HIGH_PRIORITY. If not set, a flow's priority is normal.
- *
- * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
- * HIGH_PRIORITY.
- */
- public SocketFlow priority(int priority) {
- if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY) {
- throw new IllegalArgumentException("invalid priority");
- }
- this.priority = priority;
- return this;
- }
-
- /**
- * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
- * A value of zero drops all packets for the socket.
- *
- * @throws IllegalArgumentException if bandwidth is less than zero.
- */
- public SocketFlow bandwidth(long bandwidth) {
- if (bandwidth < 0) {
- throw new IllegalArgumentException("invalid bandwidth");
- } else {
- this.bandwidth = bandwidth;
- }
- return this;
- }
-
- /**
- * Returns this SocketFlow's priority.
- */
- public int priority() {
- return priority;
- }
-
- /**
- * Returns this SocketFlow's bandwidth.
- *
- * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
- */
- public long bandwidth() {
- return bandwidth;
- }
-
- /**
- * Returns the Status value of this SocketFlow. NO_STATUS is returned
- * if the object was not used in a call to set or get the option.
- */
- public Status status() {
- return status;
- }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/Sockets.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.net;
-
-import java.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-import sun.net.ExtendedOptionsImpl;
-
-/**
- * Defines static methods to set and get socket options defined by the
- * {@link java.net.SocketOption} interface. All of the standard options defined
- * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
- * {@link java.net.DatagramSocket} can be set this way, as well as additional
- * or platform specific options supported by each socket type.
- * <p>
- * The {@link #supportedOptions(Class)} method can be called to determine
- * the complete set of options available (per socket type) on the
- * current system.
- * <p>
- * When a security manager is installed, some non-standard socket options
- * may require a security permission before being set or get.
- * The details are specified in {@link ExtendedSocketOptions}. No permission
- * is required for {@link java.net.StandardSocketOptions}.
- *
- * @see java.nio.channels.NetworkChannel
- */
-public class Sockets {
-
- private static final HashMap<Class<?>,Set<SocketOption<?>>>
- options = new HashMap<>();
-
- static {
- initOptionSets();
- }
-
- private Sockets() {}
-
- /**
- * Sets the value of a socket option on a {@link java.net.Socket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option. May be null for some
- * options.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs, or socket is closed.
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @throws NullPointerException if name is null
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a {@link java.net.Socket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @throws NullPointerException if name is null
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Sets the value of a socket option on a {@link java.net.ServerSocket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a {@link java.net.ServerSocket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Sets the value of a socket option on a {@link java.net.DatagramSocket}
- * or {@link java.net.MulticastSocket}
- *
- * @param s the socket
- * @param name The socket option
- * @param value The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IllegalArgumentException if the value is not valid for
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
- {
- s.setOption(name, value);
- }
-
- /**
- * Returns the value of a socket option from a
- * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
- *
- * @param s the socket
- * @param name The socket option
- *
- * @return The value of the socket option.
- *
- * @throws UnsupportedOperationException if the socket does not support
- * the option.
- *
- * @throws IOException if an I/O error occurs
- *
- * @throws NullPointerException if name is null
- *
- * @throws SecurityException if a security manager is set and the
- * caller does not have any required permission.
- *
- * @see java.net.StandardSocketOptions
- */
- public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
- {
- return s.getOption(name);
- }
-
- /**
- * Returns a set of {@link java.net.SocketOption}s supported by the
- * given socket type. This set may include standard options and also
- * non standard extended options.
- *
- * @param socketType the type of java.net socket
- *
- * @throws IllegalArgumentException if socketType is not a valid
- * socket type from the java.net package.
- */
- public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
- Set<SocketOption<?>> set = options.get(socketType);
- if (set == null) {
- throw new IllegalArgumentException("unknown socket type");
- }
- return set;
- }
-
- private static void checkValueType(Object value, Class<?> type) {
- if (!type.isAssignableFrom(value.getClass())) {
- String s = "Found: " + value.getClass().toString() + " Expected: "
- + type.toString();
- throw new IllegalArgumentException(s);
- }
- }
-
- private static volatile boolean checkedReusePort;
- private static volatile boolean isReusePortAvailable;
-
- /**
- * Tells whether SO_REUSEPORT is supported.
- */
- static boolean isReusePortAvailable() {
- if (!checkedReusePort) {
- isReusePortAvailable = isReusePortAvailable0();
- checkedReusePort = true;
- }
- return isReusePortAvailable;
- }
-
- private static void initOptionSets() {
- boolean flowsupported = ExtendedOptionsImpl.flowSupported();
- boolean reuseportsupported = isReusePortAvailable();
- // Socket
-
- Set<SocketOption<?>> set = new HashSet<>();
- set.add(StandardSocketOptions.SO_KEEPALIVE);
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.SO_LINGER);
- set.add(StandardSocketOptions.IP_TOS);
- set.add(StandardSocketOptions.TCP_NODELAY);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(Socket.class, set);
-
- // ServerSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- set = Collections.unmodifiableSet(set);
- options.put(ServerSocket.class, set);
-
- // DatagramSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(DatagramSocket.class, set);
-
- // MulticastSocket
-
- set = new HashSet<>();
- set.add(StandardSocketOptions.SO_SNDBUF);
- set.add(StandardSocketOptions.SO_RCVBUF);
- set.add(StandardSocketOptions.SO_REUSEADDR);
- if (reuseportsupported) {
- set.add(StandardSocketOptions.SO_REUSEPORT);
- }
- set.add(StandardSocketOptions.IP_TOS);
- set.add(StandardSocketOptions.IP_MULTICAST_IF);
- set.add(StandardSocketOptions.IP_MULTICAST_TTL);
- set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- if (flowsupported) {
- set.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
- set = Collections.unmodifiableSet(set);
- options.put(MulticastSocket.class, set);
- }
-
- private static native boolean isReusePortAvailable0();
-}
--- a/jdk/src/java.base/share/classes/jdk/net/package-info.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
- * socket classes.
- *
- * @since 1.8
- */
-
-package jdk.net;
--- a/jdk/src/java.base/share/classes/module-info.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Apr 27 20:36:02 2016 +0100
@@ -83,8 +83,6 @@
// see JDK-8144062
exports jdk;
- // see JDK-8044773
- exports jdk.net;
// the service types defined by the APIs in this module
@@ -194,6 +192,8 @@
jdk.jvmstat;
exports sun.net to
java.httpclient;
+ exports sun.net.ext to
+ jdk.net;
exports sun.net.dns to
java.security.jgss,
jdk.naming.dns;
--- a/jdk/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net;
-
-import java.net.*;
-import jdk.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-
-/**
- * Contains the native implementation for extended socket options
- * together with some other static utilities
- */
-public class ExtendedOptionsImpl {
-
- static {
- AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
- System.loadLibrary("net");
- return null;
- });
- init();
- }
-
- private ExtendedOptionsImpl() {}
-
- public static void checkSetOptionPermission(SocketOption<?> option) {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- return;
- }
- String check = "setOption." + option.name();
- sm.checkPermission(new NetworkPermission(check));
- }
-
- public static void checkGetOptionPermission(SocketOption<?> option) {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null) {
- return;
- }
- String check = "getOption." + option.name();
- sm.checkPermission(new NetworkPermission(check));
- }
-
- public static void checkValueType(Object value, Class<?> type) {
- if (!type.isAssignableFrom(value.getClass())) {
- String s = "Found: " + value.getClass().toString() + " Expected: "
- + type.toString();
- throw new IllegalArgumentException(s);
- }
- }
-
- private static native void init();
-
- /*
- * Extension native implementations
- *
- * SO_FLOW_SLA
- */
- public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
- public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
- public static native boolean flowSupported();
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net.ext;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Defines the infrastructure to support extended socket options, beyond those
+ * defined in {@link java.net.StandardSocketOptions}.
+ *
+ * Extended socket options are accessed through the jdk.net API, which is in
+ * the jdk.net module.
+ */
+public abstract class ExtendedSocketOptions {
+
+ private final Set<SocketOption<?>> options;
+
+ /** Tells whether or not the option is supported. */
+ public final boolean isOptionSupported(SocketOption<?> option) {
+ return options().contains(option);
+ }
+
+ /** Return the, possibly empty, set of extended socket options available. */
+ public final Set<SocketOption<?>> options() { return options; }
+
+ /** Sets the value of a socket option, for the given socket. */
+ public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+ throws SocketException;
+
+ /** Returns the value of a socket option, for the given socket. */
+ public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
+ throws SocketException;
+
+ protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
+ this.options = options;
+ }
+
+ private static volatile ExtendedSocketOptions instance;
+
+ public static final ExtendedSocketOptions getInstance() { return instance; }
+
+ /** Registers support for extended socket options. Invoked by the jdk.net module. */
+ public static final void register(ExtendedSocketOptions extOptions) {
+ if (instance != null)
+ throw new InternalError("Attempting to reregister extended options");
+
+ instance = extOptions;
+ }
+
+ static {
+ try {
+ // If the class is present, it will be initialized which
+ // triggers registration of the extended socket options.
+ Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+ } catch (ClassNotFoundException e) {
+ // the jdk.net module is not present => no extended socket options
+ instance = new NoExtendedSocketOptions();
+ }
+ }
+
+ static final class NoExtendedSocketOptions extends ExtendedSocketOptions {
+
+ NoExtendedSocketOptions() {
+ super(Collections.<SocketOption<?>>emptySet());
+ }
+
+ @Override
+ public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException(
+ "no extended options: " + option.name());
+ }
+
+ @Override
+ public Object getOption(FileDescriptor fd, SocketOption<?> option)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException(
+ "no extended options: " + option.name());
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Wed Apr 27 20:36:02 2016 +0100
@@ -39,7 +39,7 @@
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
/**
* Base implementation of AsynchronousSocketChannel
@@ -512,9 +512,9 @@
set.add(StandardSocketOptions.SO_REUSEPORT);
}
set.add(StandardSocketOptions.TCP_NODELAY);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Apr 27 20:36:02 2016 +0100
@@ -33,7 +33,7 @@
import java.nio.channels.spi.*;
import java.util.*;
import sun.net.ResourceManager;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
/**
* An implementation of DatagramChannels.
@@ -306,9 +306,9 @@
set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java Wed Apr 27 20:36:02 2016 +0100
@@ -27,15 +27,13 @@
import java.io.*;
import java.net.*;
-import jdk.net.*;
import java.nio.channels.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
import sun.security.action.GetPropertyAction;
-
public class Net {
private Net() { }
@@ -281,6 +279,9 @@
// -- Socket options
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
SocketOption<?> name, Object value)
throws IOException
@@ -291,12 +292,8 @@
// only simple values supported by this method
Class<?> type = name.type();
- if (type == SocketFlow.class) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
- }
- ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
+ if (extendedOptions.isOptionSupported(name)) {
+ extendedOptions.setOption(fd, name, value);
return;
}
@@ -353,14 +350,8 @@
{
Class<?> type = name.type();
- if (type == SocketFlow.class) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
- }
- SocketFlow flow = SocketFlow.create();
- ExtendedOptionsImpl.getFlowOption(fd, flow);
- return flow;
+ if (extendedOptions.isOptionSupported(name)) {
+ return extendedOptions.getOption(fd, name);
}
// only simple values supported by this method
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Apr 27 20:36:02 2016 +0100
@@ -33,8 +33,7 @@
import java.nio.channels.spi.*;
import java.util.*;
import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
-
+import sun.net.ext.ExtendedSocketOptions;
/**
* An implementation of SocketChannels
@@ -242,9 +241,9 @@
// additional options required by socket adaptor
set.add(StandardSocketOptions.IP_TOS);
set.add(ExtendedSocketOption.SO_OOBINLINE);
- if (ExtendedOptionsImpl.flowSupported()) {
- set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+ set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set);
}
}
--- a/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Wed Apr 27 20:36:02 2016 +0100
@@ -27,9 +27,7 @@
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
@@ -43,8 +41,11 @@
init();
}
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value);
} else {
@@ -55,21 +56,16 @@
}
}
} else {
- if (!flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
- }
if (isClosed()) {
throw new SocketException("Socket closed");
}
- checkSetOptionPermission(name);
- checkValueType(value, SocketFlow.class);
- setFlowOption(getFileDescriptor(), (SocketFlow)value);
+ extendedOptions.setOption(fd, name, value);
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name);
} else {
@@ -79,31 +75,23 @@
throw new UnsupportedOperationException("unsupported option");
}
}
- }
- if (!flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
+ } else {
+ if (isClosed()) {
+ throw new SocketException("Socket closed");
+ }
+ return (T) extendedOptions.getOption(fd, name);
}
- if (isClosed()) {
- throw new SocketException("Socket closed");
- }
- checkGetOptionPermission(name);
- SocketFlow flow = SocketFlow.create();
- getFlowOption(getFileDescriptor(), flow);
- return (T)flow;
}
protected Set<SocketOption<?>> supportedOptions() {
- HashSet<SocketOption<?>> options = new HashSet<>(
- super.supportedOptions());
-
- if (flowSupported()) {
- options.add(ExtendedSocketOptions.SO_FLOW_SLA);
- }
+ HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+ options.addAll(extendedOptions.options());
return options;
}
protected void socketSetOption(int opt, Object val) throws SocketException {
- if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+ if (opt == SocketOptions.SO_REUSEPORT &&
+ !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
--- a/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Wed Apr 27 20:36:02 2016 +0100
@@ -28,10 +28,7 @@
import java.io.FileDescriptor;
import java.util.Set;
import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
@@ -57,8 +54,11 @@
this.fd = fd;
}
+ static final ExtendedSocketOptions extendedOptions =
+ ExtendedSocketOptions.getInstance();
+
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value);
} else {
@@ -69,21 +69,19 @@
}
}
} else {
- if (getSocket() == null || !flowSupported()) {
+ if (getSocket() == null) {
throw new UnsupportedOperationException("unsupported option");
}
if (isClosedOrPending()) {
throw new SocketException("Socket closed");
}
- checkSetOptionPermission(name);
- checkValueType(value, SocketFlow.class);
- setFlowOption(getFileDescriptor(), (SocketFlow)value);
+ extendedOptions.setOption(fd, name, value);
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name);
} else {
@@ -93,31 +91,28 @@
throw new UnsupportedOperationException("unsupported option");
}
}
- }
- if (getSocket() == null || !flowSupported()) {
- throw new UnsupportedOperationException("unsupported option");
+ } else {
+ if (getSocket() == null) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
+ if (isClosedOrPending()) {
+ throw new SocketException("Socket closed");
+ }
+ return (T) extendedOptions.getOption(fd, name);
}
- if (isClosedOrPending()) {
- throw new SocketException("Socket closed");
- }
- checkGetOptionPermission(name);
- SocketFlow flow = SocketFlow.create();
- getFlowOption(getFileDescriptor(), flow);
- return (T)flow;
}
protected Set<SocketOption<?>> supportedOptions() {
- HashSet<SocketOption<?>> options = new HashSet<>(
- super.supportedOptions());
-
- if (getSocket() != null && flowSupported()) {
- options.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+ if (getSocket() != null) {
+ options.addAll(extendedOptions.options());
}
return options;
}
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
- if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+ if (opt == SocketOptions.SO_REUSEPORT &&
+ !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
--- a/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-#include "jdk_net_SocketFlow.h"
-
-static jclass sf_status_class; /* Status enum type */
-
-static jfieldID sf_status;
-static jfieldID sf_priority;
-static jfieldID sf_bandwidth;
-
-static jfieldID sf_fd_fdID; /* FileDescriptor.fd */
-
-/* References to the literal enum values */
-
-static jobject sfs_NOSTATUS;
-static jobject sfs_OK;
-static jobject sfs_NOPERMISSION;
-static jobject sfs_NOTCONNECTED;
-static jobject sfs_NOTSUPPORTED;
-static jobject sfs_ALREADYCREATED;
-static jobject sfs_INPROGRESS;
-static jobject sfs_OTHER;
-
-static jobject getEnumField(JNIEnv *env, char *name);
-static void setStatus(JNIEnv *env, jobject obj, int errval);
-
-/* OS specific code is implemented in these three functions */
-
-static jboolean flowSupported0() ;
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
- (JNIEnv *env, jclass UNUSED)
-{
- static int initialized = 0;
- jclass c;
-
- /* Global class references */
-
- if (initialized) {
- return;
- }
-
- c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
- CHECK_NULL(c);
- sf_status_class = (*env)->NewGlobalRef(env, c);
- CHECK_NULL(sf_status_class);
-
- /* int "fd" field of java.io.FileDescriptor */
-
- c = (*env)->FindClass(env, "java/io/FileDescriptor");
- CHECK_NULL(c);
- sf_fd_fdID = (*env)->GetFieldID(env, c, "fd", "I");
- CHECK_NULL(sf_fd_fdID);
-
-
- /* SocketFlow fields */
-
- c = (*env)->FindClass(env, "jdk/net/SocketFlow");
- CHECK_NULL(c);
-
- /* status */
-
- sf_status = (*env)->GetFieldID(env, c, "status",
- "Ljdk/net/SocketFlow$Status;");
- CHECK_NULL(sf_status);
-
- /* priority */
-
- sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
- CHECK_NULL(sf_priority);
-
- /* bandwidth */
-
- sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
- CHECK_NULL(sf_bandwidth);
-
- /* Initialize the static enum values */
-
- sfs_NOSTATUS = getEnumField(env, "NO_STATUS");
- CHECK_NULL(sfs_NOSTATUS);
- sfs_OK = getEnumField(env, "OK");
- CHECK_NULL(sfs_OK);
- sfs_NOPERMISSION = getEnumField(env, "NO_PERMISSION");
- CHECK_NULL(sfs_NOPERMISSION);
- sfs_NOTCONNECTED = getEnumField(env, "NOT_CONNECTED");
- CHECK_NULL(sfs_NOTCONNECTED);
- sfs_NOTSUPPORTED = getEnumField(env, "NOT_SUPPORTED");
- CHECK_NULL(sfs_NOTSUPPORTED);
- sfs_ALREADYCREATED = getEnumField(env, "ALREADY_CREATED");
- CHECK_NULL(sfs_ALREADYCREATED);
- sfs_INPROGRESS = getEnumField(env, "IN_PROGRESS");
- CHECK_NULL(sfs_INPROGRESS);
- sfs_OTHER = getEnumField(env, "OTHER");
- CHECK_NULL(sfs_OTHER);
- initialized = JNI_TRUE;
-}
-
-static jobject getEnumField(JNIEnv *env, char *name)
-{
- jobject f;
- jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
- "Ljdk/net/SocketFlow$Status;");
- CHECK_NULL_RETURN(fID, NULL);
-
- f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
- CHECK_NULL_RETURN(f, NULL);
- f = (*env)->NewGlobalRef(env, f);
- CHECK_NULL_RETURN(f, NULL);
- return f;
-}
-
-/*
- * Retrieve the int file-descriptor from a public socket type object.
- * Gets impl, then the FileDescriptor from the impl, and then the fd
- * from that.
- */
-static int getFD(JNIEnv *env, jobject fileDesc) {
- return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
-}
-
-/**
- * Sets the status field of a SocketFlow to one of the
- * canned enum values
- */
-static void setStatus (JNIEnv *env, jobject obj, int errval)
-{
- switch (errval) {
- case 0: /* OK */
- (*env)->SetObjectField(env, obj, sf_status, sfs_OK);
- break;
- case EPERM:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);
- break;
- case ENOTCONN:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOTCONNECTED);
- break;
- case EOPNOTSUPP:
- (*env)->SetObjectField(env, obj, sf_status, sfs_NOTSUPPORTED);
- break;
- case EALREADY:
- (*env)->SetObjectField(env, obj, sf_status, sfs_ALREADYCREATED);
- break;
- case EINPROGRESS:
- (*env)->SetObjectField(env, obj, sf_status, sfs_INPROGRESS);
- break;
- default:
- (*env)->SetObjectField(env, obj, sf_status, sfs_OTHER);
- break;
- }
-}
-
-#ifdef __solaris__
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: setFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- int fd = getFD(env, fileDesc);
-
- if (fd < 0) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
- return;
- } else {
- sock_flow_props_t props;
- jlong bandwidth;
- int rv;
-
- jint priority = (*env)->GetIntField(env, flow, sf_priority);
- memset(&props, 0, sizeof(props));
- props.sfp_version = SOCK_FLOW_PROP_VERSION1;
-
- if (priority != jdk_net_SocketFlow_UNSET) {
- props.sfp_mask |= SFP_PRIORITY;
- props.sfp_priority = priority;
- }
- bandwidth = (*env)->GetLongField(env, flow, sf_bandwidth);
- if (bandwidth > -1) {
- props.sfp_mask |= SFP_MAXBW;
- props.sfp_maxbw = (uint64_t) bandwidth;
- }
- rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
- if (rv < 0) {
- if (errno == ENOPROTOOPT) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
- } else if (errno == EACCES || errno == EPERM) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "Permission denied");
- } else {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "set option SO_FLOW_SLA failed");
- }
- return;
- }
- setStatus(env, flow, props.sfp_status);
- }
-}
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: getFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- int fd = getFD(env, fileDesc);
-
- if (fd < 0) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
- return;
- } else {
- sock_flow_props_t props;
- int status;
- socklen_t sz = sizeof(props);
-
- int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
- if (rv < 0) {
- if (errno == ENOPROTOOPT) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
- } else if (errno == EACCES || errno == EPERM) {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "Permission denied");
- } else {
- NET_ERROR(env, JNU_JAVANETPKG "SocketException",
- "set option SO_FLOW_SLA failed");
- }
- return;
- }
- /* first check status to see if flow exists */
- status = props.sfp_status;
- setStatus(env, flow, status);
- if (status == 0) { /* OK */
- /* can set the other fields now */
- if (props.sfp_mask & SFP_PRIORITY) {
- (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
- }
- if (props.sfp_mask & SFP_MAXBW) {
- (*env)->SetLongField(env, flow, sf_bandwidth,
- (jlong)props.sfp_maxbw);
- }
- }
- }
-}
-
-static jboolean flowsupported;
-static jboolean flowsupported_set = JNI_FALSE;
-
-static jboolean flowSupported0()
-{
- /* Do a simple dummy call, and try to figure out from that */
- sock_flow_props_t props;
- int rv, s;
- if (flowsupported_set) {
- return flowsupported;
- }
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s < 0) {
- flowsupported = JNI_FALSE;
- flowsupported_set = JNI_TRUE;
- return JNI_FALSE;
- }
- memset(&props, 0, sizeof(props));
- props.sfp_version = SOCK_FLOW_PROP_VERSION1;
- props.sfp_mask |= SFP_PRIORITY;
- props.sfp_priority = SFP_PRIO_NORMAL;
- rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
- if (rv != 0 && errno == ENOPROTOOPT) {
- rv = JNI_FALSE;
- } else {
- rv = JNI_TRUE;
- }
- close(s);
- flowsupported = rv;
- flowsupported_set = JNI_TRUE;
- return flowsupported;
-}
-
-#else /* __solaris__ */
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-static jboolean flowSupported0() {
- return JNI_FALSE;
-}
-
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
- (JNIEnv *env, jclass UNUSED)
-{
- return flowSupported0();
-}
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h Wed Apr 27 20:36:02 2016 +0100
@@ -120,47 +120,6 @@
#ifdef __solaris__
int net_getParam(char *driver, char *param);
-
-#ifndef SO_FLOW_SLA
-#define SO_FLOW_SLA 0x1018
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
#endif
-/*
- * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
- * per socket service level properties.
- * When the application uses per-socket API, we will enforce the properties
- * on both outbound and inbound packets.
- *
- * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
- */
-typedef struct sock_flow_props_s {
- int sfp_version;
- uint32_t sfp_mask;
- int sfp_priority; /* flow priority */
- uint64_t sfp_maxbw; /* bandwidth limit in bps */
- int sfp_status; /* flow create status for getsockopt */
-} sock_flow_props_t;
-
-#define SOCK_FLOW_PROP_VERSION1 1
-
-/* bit mask values for sfp_mask */
-#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */
-#define SFP_PRIORITY 0x00000008 /* Flow priority */
-
-/* possible values for sfp_priority */
-#define SFP_PRIO_NORMAL 1
-#define SFP_PRIO_HIGH 2
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif /* _LONG_LONG_ALIGNMENT */
-
-#endif /* SO_FLOW_SLA */
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL NET_IsFlowSupported();
-
#endif /* NET_UTILS_MD_H */
--- a/jdk/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c Wed Apr 27 12:06:51 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-
-/*
- * Class: sun_net_ExtendedOptionsImpl
- * Method: init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
- (JNIEnv *env, jclass UNUSED)
-{
-}
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
- (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "unsupported socket option");
-}
-
-static jboolean flowSupported0() {
- return JNI_FALSE;
-}
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
- (JNIEnv *env, jclass UNUSED)
-{
- return JNI_FALSE;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Set;
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import jdk.internal.misc.SharedSecrets;
+
+/**
+ * Defines extended socket options, beyond those defined in
+ * {@link java.net.StandardSocketOptions}. These options may be platform
+ * specific.
+ *
+ * @since 1.8
+ */
+public final class ExtendedSocketOptions {
+
+ private static class ExtSocketOption<T> implements SocketOption<T> {
+ private final String name;
+ private final Class<T> type;
+ ExtSocketOption(String name, Class<T> type) {
+ this.name = name;
+ this.type = type;
+ }
+ @Override public String name() { return name; }
+ @Override public Class<T> type() { return type; }
+ @Override public String toString() { return name; }
+ }
+
+ private ExtendedSocketOptions() { }
+
+ /**
+ * Service level properties. When a security manager is installed,
+ * setting or getting this option requires a {@link NetworkPermission}
+ * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
+ * respectively.
+ */
+ public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
+ ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
+
+
+ private static final PlatformSocketOptions platformSocketOptions =
+ PlatformSocketOptions.get();
+
+ private static final boolean flowSupported =
+ platformSocketOptions.flowSupported();
+
+ private static final Set<SocketOption<?>> extendedOptions = options();
+
+ static Set<SocketOption<?>> options() {
+ if (flowSupported)
+ return Set.of(SO_FLOW_SLA);
+ else
+ return Collections.<SocketOption<?>>emptySet();
+ }
+
+ static {
+ // Registers the extended socket options with the base module.
+ sun.net.ext.ExtendedSocketOptions.register(
+ new sun.net.ext.ExtendedSocketOptions(extendedOptions) {
+
+ @Override
+ public void setOption(FileDescriptor fd,
+ SocketOption<?> option,
+ Object value)
+ throws SocketException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetworkPermission("setOption." + option.name()));
+
+ if (fd == null || !fd.valid())
+ throw new SocketException("socket closed");
+
+ if (option == SO_FLOW_SLA) {
+ assert flowSupported;
+ SocketFlow flow = checkValueType(value, option.type());
+ setFlowOption(fd, flow);
+ } else {
+ throw new InternalError("Unexpected option " + option);
+ }
+ }
+
+ @Override
+ public Object getOption(FileDescriptor fd,
+ SocketOption<?> option)
+ throws SocketException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetworkPermission("getOption." + option.name()));
+
+ if (fd == null || !fd.valid())
+ throw new SocketException("socket closed");
+
+ if (option == SO_FLOW_SLA) {
+ assert flowSupported;
+ SocketFlow flow = SocketFlow.create();
+ getFlowOption(fd, flow);
+ return flow;
+ } else {
+ throw new InternalError("Unexpected option " + option);
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T checkValueType(Object value, Class<?> type) {
+ if (!type.isAssignableFrom(value.getClass())) {
+ String s = "Found: " + value.getClass() + ", Expected: " + type;
+ throw new IllegalArgumentException(s);
+ }
+ return (T) value;
+ }
+
+ private static final JavaIOFileDescriptorAccess fdAccess =
+ SharedSecrets.getJavaIOFileDescriptorAccess();
+
+ private static void setFlowOption(FileDescriptor fd, SocketFlow f)
+ throws SocketException
+ {
+ int status = platformSocketOptions.setFlowOption(fdAccess.get(fd),
+ f.priority(),
+ f.bandwidth());
+ f.status(status); // augment the given flow with the status
+ }
+
+ private static void getFlowOption(FileDescriptor fd, SocketFlow f)
+ throws SocketException
+ {
+ int status = platformSocketOptions.getFlowOption(fdAccess.get(fd), f);
+ f.status(status); // augment the given flow with the status
+ }
+
+ static class PlatformSocketOptions {
+
+ protected PlatformSocketOptions() {}
+
+ @SuppressWarnings("unchecked")
+ private static PlatformSocketOptions newInstance(String cn) {
+ Class<PlatformSocketOptions> c;
+ try {
+ c = (Class<PlatformSocketOptions>)Class.forName(cn);
+ return c.getConstructor(new Class<?>[] { }).newInstance();
+ } catch (ReflectiveOperationException x) {
+ throw new AssertionError(x);
+ }
+ }
+
+ private static PlatformSocketOptions create() {
+ String osname = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("os.name");
+ }
+ });
+ if ("SunOS".equals(osname))
+ return newInstance("jdk.net.SolarisSocketOptions");
+ return new PlatformSocketOptions();
+ }
+
+ private static final PlatformSocketOptions instance = create();
+
+ static PlatformSocketOptions get() {
+ return instance;
+ }
+
+ int setFlowOption(int fd, int priority, long bandwidth)
+ throws SocketException
+ {
+ throw new UnsupportedOperationException("unsupported socket option");
+ }
+
+ int getFlowOption(int fd, SocketFlow f) throws SocketException {
+ throw new UnsupportedOperationException("unsupported socket option");
+ }
+
+ boolean flowSupported() {
+ return false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/NetworkPermission.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.security.BasicPermission;
+
+/**
+ * Represents permission to access the extended networking capabilities
+ * defined in the jdk.net package. These permissions contain a target
+ * name, but no actions list. Callers either possess the permission or not.
+ * <p>
+ * The following targets are defined:
+ *
+ * <table border=1 cellpadding=5 summary="permission target name,
+ * what the target allows,and associated risks">
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ * <td>setOption.SO_FLOW_SLA</td>
+ * <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
+ * on any socket that supports it</td>
+ * <td>allows caller to set a higher priority or bandwidth allocation
+ * to sockets it creates, than they might otherwise be allowed.</td>
+ * </tr>
+ * <tr>
+ * <td>getOption.SO_FLOW_SLA</td>
+ * <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
+ * setting from any socket that supports the option</td>
+ * <td>allows caller access to SLA information that it might not
+ * otherwise have</td>
+ * </tr></table>
+ *
+ * @see jdk.net.ExtendedSocketOptions
+ *
+ * @since 1.8
+ */
+
+public final class NetworkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -2012939586906722291L;
+
+ /**
+ * Creates a NetworkPermission with the given target name.
+ *
+ * @param name the permission target name
+ * @throws NullPointerException if {@code name} is {@code null}.
+ * @throws IllegalArgumentException if {@code name} is empty.
+ */
+ public NetworkPermission(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Creates a NetworkPermission with the given target name.
+ *
+ * @param name the permission target name
+ * @param actions should be {@code null}. Is ignored if not.
+ * @throws NullPointerException if {@code name} is {@code null}.
+ * @throws IllegalArgumentException if {@code name} is empty.
+ */
+ public NetworkPermission(String name, String actions)
+ {
+ super(name, actions);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/SocketFlow.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.lang.annotation.Native;
+
+/**
+ * Represents the service level properties for the platform specific socket
+ * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
+ * <p>
+ * The priority and bandwidth parameters must be set before
+ * setting the socket option.
+ * <p>
+ * When the {@code SO_FLOW_SLA} option is set then it may not take effect
+ * immediately. If the value of the socket option is obtained with
+ * {@code getOption()} then the status may be returned as {@code INPROGRESS}
+ * until it takes effect. The priority and bandwidth values are only valid when
+ * the status is returned as OK.
+ * <p>
+ * When a security manager is installed, a {@link NetworkPermission}
+ * is required to set or get this option.
+ *
+ * @since 1.8
+ */
+public class SocketFlow {
+
+ @Native public static final int UNSET = -1;
+ @Native public static final int NORMAL_PRIORITY = 1;
+ @Native public static final int HIGH_PRIORITY = 2;
+
+ @Native private static final int NO_STATUS_VALUE = 0;
+ @Native private static final int OK_VALUE = 1;
+ @Native private static final int NO_PERMISSION_VALUE = 2;
+ @Native private static final int NOT_CONNECTED_VALUE = 3;
+ @Native private static final int NOT_SUPPORTED_VALUE = 4;
+ @Native private static final int ALREADY_CREATED_VALUE = 5;
+ @Native private static final int IN_PROGRESS_VALUE = 6;
+ @Native private static final int OTHER_VALUE = 7;
+
+ /**
+ * Enumeration of the return values from the SO_FLOW_SLA
+ * socket option. Both setting and getting the option return
+ * one of these statuses, which reflect the state of socket's
+ * flow.
+ *
+ * @since 1.8
+ */
+ public enum Status {
+ /**
+ * Set or get socket option has not been called yet. Status
+ * values can only be retrieved after calling set or get.
+ */
+ NO_STATUS(NO_STATUS_VALUE),
+ /**
+ * Flow successfully created.
+ */
+ OK(OK_VALUE),
+ /**
+ * Caller has no permission to create flow.
+ */
+ NO_PERMISSION(NO_PERMISSION_VALUE),
+ /**
+ * Flow can not be created because socket is not connected.
+ */
+ NOT_CONNECTED(NOT_CONNECTED_VALUE),
+ /**
+ * Flow creation not supported for this socket.
+ */
+ NOT_SUPPORTED(NOT_SUPPORTED_VALUE),
+ /**
+ * A flow already exists with identical attributes.
+ */
+ ALREADY_CREATED(ALREADY_CREATED_VALUE),
+ /**
+ * A flow is being created.
+ */
+ IN_PROGRESS(IN_PROGRESS_VALUE),
+ /**
+ * Some other unspecified error.
+ */
+ OTHER(OTHER_VALUE);
+
+ private final int value;
+ Status(int value) { this.value = value; }
+
+ static Status from(int value) {
+ if (value == NO_STATUS.value) return NO_STATUS;
+ else if (value == OK.value) return OK;
+ else if (value == NO_PERMISSION.value) return NO_PERMISSION;
+ else if (value == NOT_CONNECTED.value) return NOT_CONNECTED;
+ else if (value == NOT_SUPPORTED.value) return NOT_SUPPORTED;
+ else if (value == ALREADY_CREATED.value) return ALREADY_CREATED;
+ else if (value == IN_PROGRESS.value) return IN_PROGRESS;
+ else if (value == OTHER.value) return OTHER;
+ else throw new InternalError("Unknown value: " + value);
+ }
+ }
+
+ private int priority = NORMAL_PRIORITY;
+ private long bandwidth = UNSET;
+ private Status status = Status.NO_STATUS;
+
+ /**
+ * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
+ * socket option and create a socket flow.
+ */
+ public static SocketFlow create() {
+ return new SocketFlow();
+ }
+
+ private SocketFlow() { }
+
+ /**
+ * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
+ * HIGH_PRIORITY. If not set, a flow's priority is normal.
+ *
+ * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
+ * HIGH_PRIORITY.
+ */
+ public SocketFlow priority(int priority) {
+ if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY)
+ throw new IllegalArgumentException("invalid priority :" + priority);
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
+ * A value of zero drops all packets for the socket.
+ *
+ * @throws IllegalArgumentException if bandwidth is less than zero.
+ */
+ public SocketFlow bandwidth(long bandwidth) {
+ if (bandwidth < 0)
+ throw new IllegalArgumentException("invalid bandwidth: " + bandwidth);
+ this.bandwidth = bandwidth;
+ return this;
+ }
+
+ /**
+ * Returns this SocketFlow's priority.
+ */
+ public int priority() {
+ return priority;
+ }
+
+ /**
+ * Returns this SocketFlow's bandwidth.
+ *
+ * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
+ */
+ public long bandwidth() {
+ return bandwidth;
+ }
+
+ /**
+ * Returns the Status value of this SocketFlow. NO_STATUS is returned
+ * if the object was not used in a call to set or get the option.
+ */
+ public Status status() {
+ return status;
+ }
+
+ void status(int status) {
+ this.status = Status.from(status);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append(" [ priority=").append(priority())
+ .append(", bandwidth=").append(bandwidth())
+ .append(", status=").append(status())
+ .append(" ]");
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/Sockets.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.net.*;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+/**
+ * Defines static methods to set and get socket options defined by the
+ * {@link java.net.SocketOption} interface. All of the standard options defined
+ * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
+ * {@link java.net.DatagramSocket} can be set this way, as well as additional
+ * or platform specific options supported by each socket type.
+ * <p>
+ * The {@link #supportedOptions(Class)} method can be called to determine
+ * the complete set of options available (per socket type) on the
+ * current system.
+ * <p>
+ * When a security manager is installed, some non-standard socket options
+ * may require a security permission before being set or get.
+ * The details are specified in {@link ExtendedSocketOptions}. No permission
+ * is required for {@link java.net.StandardSocketOptions}.
+ *
+ * @see java.nio.channels.NetworkChannel
+ */
+public class Sockets {
+
+ private static final Map<Class<?>,Set<SocketOption<?>>>
+ options = optionSets();
+
+ private Sockets() {}
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.Socket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option. May be null for some
+ * options.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs, or socket is closed.
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a {@link java.net.Socket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.ServerSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a {@link java.net.ServerSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Sets the value of a socket option on a {@link java.net.DatagramSocket}
+ * or {@link java.net.MulticastSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ * @param value The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IllegalArgumentException if the value is not valid for
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
+ {
+ s.setOption(name, value);
+ }
+
+ /**
+ * Returns the value of a socket option from a
+ * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
+ *
+ * @param s the socket
+ * @param name The socket option
+ *
+ * @return The value of the socket option.
+ *
+ * @throws UnsupportedOperationException if the socket does not support
+ * the option.
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @throws NullPointerException if name is null
+ *
+ * @throws SecurityException if a security manager is set and the
+ * caller does not have any required permission.
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
+ {
+ return s.getOption(name);
+ }
+
+ /**
+ * Returns a set of {@link java.net.SocketOption}s supported by the
+ * given socket type. This set may include standard options and also
+ * non standard extended options.
+ *
+ * @param socketType the type of java.net socket
+ *
+ * @throws IllegalArgumentException if socketType is not a valid
+ * socket type from the java.net package.
+ */
+ public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
+ Set<SocketOption<?>> set = options.get(socketType);
+ if (set == null) {
+ throw new IllegalArgumentException("unknown socket type");
+ }
+ return set;
+ }
+
+ private static void checkValueType(Object value, Class<?> type) {
+ if (!type.isAssignableFrom(value.getClass())) {
+ String s = "Found: " + value.getClass().toString() + " Expected: "
+ + type.toString();
+ throw new IllegalArgumentException(s);
+ }
+ }
+
+ private static volatile boolean checkedReusePort;
+ private static volatile boolean isReusePortAvailable;
+
+ /**
+ * Tells whether SO_REUSEPORT is supported.
+ */
+ static boolean isReusePortAvailable() {
+ if (!checkedReusePort) {
+ Set<SocketOption<?>> s = new Socket().supportedOptions();
+ isReusePortAvailable = s.contains(StandardSocketOptions.SO_REUSEPORT);
+ checkedReusePort = true;
+ }
+ return isReusePortAvailable;
+ }
+
+ private static Map<Class<?>,Set<SocketOption<?>>> optionSets() {
+ Map<Class<?>,Set<SocketOption<?>>> options = new HashMap<>();
+ boolean flowsupported = PlatformSocketOptions.get().flowSupported();
+ boolean reuseportsupported = isReusePortAvailable();
+ // Socket
+
+ Set<SocketOption<?>> set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_KEEPALIVE);
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.SO_LINGER);
+ set.add(StandardSocketOptions.IP_TOS);
+ set.add(StandardSocketOptions.TCP_NODELAY);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(Socket.class, set);
+
+ // ServerSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ set = Collections.unmodifiableSet(set);
+ options.put(ServerSocket.class, set);
+
+ // DatagramSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(DatagramSocket.class, set);
+
+ // MulticastSocket
+
+ set = new HashSet<>();
+ set.add(StandardSocketOptions.SO_SNDBUF);
+ set.add(StandardSocketOptions.SO_RCVBUF);
+ set.add(StandardSocketOptions.SO_REUSEADDR);
+ if (reuseportsupported) {
+ set.add(StandardSocketOptions.SO_REUSEPORT);
+ }
+ set.add(StandardSocketOptions.IP_TOS);
+ set.add(StandardSocketOptions.IP_MULTICAST_IF);
+ set.add(StandardSocketOptions.IP_MULTICAST_TTL);
+ set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+ if (flowsupported) {
+ set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+ }
+ set = Collections.unmodifiableSet(set);
+ options.put(MulticastSocket.class, set);
+
+ return Collections.unmodifiableMap(options);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/package-info.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
+ * socket classes.
+ *
+ * @since 1.8
+ */
+
+package jdk.net;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/module-info.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module jdk.net {
+ exports jdk.net;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/classes/jdk/net/SolarisSocketOptions.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.net.SocketException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+class SolarisSocketOptions extends PlatformSocketOptions {
+
+ public SolarisSocketOptions() { }
+
+ @Override native int setFlowOption(int fd, int priority, long bandwidth)
+ throws SocketException;
+
+ @Override native int getFlowOption(int fd, SocketFlow f)
+ throws SocketException;
+
+ @Override native boolean flowSupported();
+
+ private static native void init();
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("extnet");
+ return null;
+ }
+ });
+ init();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+#include "SolarisSocketOptions.h"
+
+static jfieldID sf_priority;
+static jfieldID sf_bandwidth;
+
+static int initialized = 0;
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jdk_net_SolarisSocketOptions_init
+ (JNIEnv *env, jclass unused)
+{
+ if (!initialized) {
+ jclass c = (*env)->FindClass(env, "jdk/net/SocketFlow");
+ CHECK_NULL(c);
+ sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
+ CHECK_NULL(sf_priority);
+ sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
+ CHECK_NULL(sf_bandwidth);
+ initialized = 1;
+ }
+}
+
+/** Return the Status value. */
+static jint toStatus(int errval)
+{
+ switch (errval) {
+ case 0: return jdk_net_SocketFlow_OK_VALUE;
+ case EPERM: return jdk_net_SocketFlow_NO_PERMISSION_VALUE;
+ case ENOTCONN: return jdk_net_SocketFlow_NOT_CONNECTED_VALUE;
+ case EOPNOTSUPP: return jdk_net_SocketFlow_NOT_SUPPORTED_VALUE;
+ case EALREADY: return jdk_net_SocketFlow_ALREADY_CREATED_VALUE;
+ case EINPROGRESS: return jdk_net_SocketFlow_IN_PROGRESS_VALUE;
+ default: return jdk_net_SocketFlow_OTHER_VALUE;
+ }
+}
+
+void throwByNameWithLastError
+ (JNIEnv *env, const char *name, const char *defaultDetail)
+{
+ char defaultMsg[255];
+ sprintf(defaultMsg, "errno: %d, %s", errno, defaultDetail);
+ JNU_ThrowByNameWithLastError(env, name, defaultMsg);
+}
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: setFlowOption0
+ * Signature: (IIJ)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_setFlowOption
+ (JNIEnv *env, jobject unused, jint fd, jint priority, jlong bandwidth)
+{
+ int rv;
+ sock_flow_props_t props;
+ memset(&props, 0, sizeof(props));
+ props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+
+ if (priority != jdk_net_SocketFlow_UNSET) {
+ props.sfp_mask |= SFP_PRIORITY;
+ props.sfp_priority = priority;
+ }
+ if (bandwidth > jdk_net_SocketFlow_UNSET) {
+ props.sfp_mask |= SFP_MAXBW;
+ props.sfp_maxbw = (uint64_t) bandwidth;
+ }
+
+ rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else if (errno == EACCES || errno == EPERM) {
+ JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+ } else {
+ throwByNameWithLastError(env, "java/net/SocketException",
+ "set option SO_FLOW_SLA failed");
+ }
+ return 0;
+ }
+ return toStatus(props.sfp_status);
+}
+
+/*
+ * Class: jdk_net_SolarisSocketOptions
+ * Method: getFlowOption0
+ * Signature: (ILjdk/net/SocketFlow;)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_getFlowOption
+ (JNIEnv *env, jobject unused, jint fd, jobject flow)
+{
+ sock_flow_props_t props;
+ socklen_t sz = sizeof(props);
+
+ int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
+
+ if (rv < 0) {
+ if (errno == ENOPROTOOPT) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "unsupported socket option");
+ } else if (errno == EACCES || errno == EPERM) {
+ JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+ } else {
+ throwByNameWithLastError(env, "java/net/SocketException",
+ "get option SO_FLOW_SLA failed");
+ }
+ return -1;
+ }
+ /* first check status to see if flow exists */
+ if (props.sfp_status == 0) { /* OK */
+ /* can set the other fields now */
+ if (props.sfp_mask & SFP_PRIORITY) {
+ (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
+ }
+ if (props.sfp_mask & SFP_MAXBW) {
+ (*env)->SetLongField(env, flow, sf_bandwidth,
+ (jlong)props.sfp_maxbw);
+ }
+ }
+ return toStatus(props.sfp_status);
+}
+
+JNIEXPORT jboolean JNICALL Java_jdk_net_SolarisSocketOptions_flowSupported
+ (JNIEnv *env, jobject unused)
+{
+ /* Do a simple dummy call, and try to figure out from that */
+ sock_flow_props_t props;
+ int rv, s;
+
+ s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0) {
+ return JNI_FALSE;
+ }
+ memset(&props, 0, sizeof(props));
+ props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+ props.sfp_mask |= SFP_PRIORITY;
+ props.sfp_priority = SFP_PRIO_NORMAL;
+ rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+ if (rv != 0 && errno == ENOPROTOOPT) {
+ rv = JNI_FALSE;
+ } else {
+ rv = JNI_TRUE;
+ }
+ close(s);
+ return rv;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.h Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SOLARIS_SOCKET_OPTIONS_H
+#define SOLARIS_SOCKET_OPTIONS_H
+
+#include <sys/socket.h>
+#include <jni.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "jni_util.h"
+#include "jdk_net_SocketFlow.h"
+#include "SolarisSocketOptions.h"
+#include "jdk_net_SolarisSocketOptions.h"
+
+#ifndef SO_FLOW_SLA
+#define SO_FLOW_SLA 0x1018
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+/*
+ * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
+ * per socket service level properties.
+ * When the application uses per-socket API, we will enforce the properties
+ * on both outbound and inbound packets.
+ *
+ * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
+ */
+typedef struct sock_flow_props_s {
+ int sfp_version;
+ uint32_t sfp_mask;
+ int sfp_priority; /* flow priority */
+ uint64_t sfp_maxbw; /* bandwidth limit in bps */
+ int sfp_status; /* flow create status for getsockopt */
+} sock_flow_props_t;
+
+#define SOCK_FLOW_PROP_VERSION1 1
+
+/* bit mask values for sfp_mask */
+#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */
+#define SFP_PRIORITY 0x00000008 /* Flow priority */
+
+/* possible values for sfp_priority */
+#define SFP_PRIO_NORMAL 1
+#define SFP_PRIO_HIGH 2
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif /* _LONG_LONG_ALIGNMENT */
+
+#endif /* SO_FLOW_SLA */
+
+#endif /* SOLARIS_SOCKET_OPTIONS_H */
--- a/jdk/src/jdk.policytool/share/classes/module-info.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/src/jdk.policytool/share/classes/module-info.java Wed Apr 27 20:36:02 2016 +0100
@@ -28,6 +28,7 @@
requires java.logging;
requires java.management;
requires java.sql;
+ requires jdk.net;
requires java.security.jgss;
requires jdk.security.jgss;
}
--- a/jdk/test/java/net/SocketOption/OptionsTest.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/java/net/SocketOption/OptionsTest.java Wed Apr 27 20:36:02 2016 +0100
@@ -23,11 +23,13 @@
/*
* @test
- * @bug 8036979 8072384
+ * @bug 8036979 8072384 8044773
* @run main/othervm -Xcheck:jni OptionsTest
* @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base OptionsTest
*/
+import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
@@ -43,7 +45,7 @@
}
Object option;
Object testValue;
- };
+ }
// The tests set the option using the new API, read back the set value
// which could be diferent, and then use the legacy get API to check
@@ -223,8 +225,7 @@
} else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
} else if (option.equals(StandardSocketOptions.IP_TOS)) {
- return Integer.valueOf(jdk.net.Sockets.getOption(
- socket, StandardSocketOptions.IP_TOS));
+ return getServerSocketTrafficClass(socket);
} else {
throw new RuntimeException("unexecpted socket option");
}
@@ -281,4 +282,20 @@
doDgSocketTests();
doMcSocketTests();
}
+
+ // Reflectively access jdk.net.Sockets.getOption so that the test can run
+ // without the jdk.net module.
+ static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {
+ try {
+ Class<?> c = Class.forName("jdk.net.Sockets");
+ Method m = c.getDeclaredMethod("getOption", ServerSocket.class, SocketOption.class);
+ return m.invoke(null, ss, StandardSocketOptions.IP_TOS);
+ } catch (ClassNotFoundException e) {
+ // Ok, jdk.net module not present, just fall back
+ System.out.println("jdk.net module not present, falling back.");
+ return Integer.valueOf(ss.getOption(StandardSocketOptions.IP_TOS));
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
}
--- a/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java Wed Apr 27 20:36:02 2016 +0100
@@ -21,34 +21,48 @@
* questions.
*/
-import jdk.net.ExtendedSocketOptions;
-
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
/*
* @test
- * @bug 8143554
- * @run main UnsupportedOptionsTest
+ * @bug 8143554 8044773
* @summary Test checks that UnsupportedOperationException for unsupported
* SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
+ * @run main UnsupportedOptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base UnsupportedOptionsTest
*/
+
public class UnsupportedOptionsTest {
- private static final SocketOption[] SOCKET_OPTIONS = {
- StandardSocketOptions.IP_MULTICAST_IF,
- StandardSocketOptions.IP_MULTICAST_LOOP,
- StandardSocketOptions.IP_MULTICAST_TTL,
- StandardSocketOptions.IP_TOS,
- StandardSocketOptions.SO_BROADCAST,
- StandardSocketOptions.SO_KEEPALIVE,
- StandardSocketOptions.SO_LINGER,
- StandardSocketOptions.SO_RCVBUF,
- StandardSocketOptions.SO_REUSEADDR,
- StandardSocketOptions.SO_SNDBUF,
- StandardSocketOptions.TCP_NODELAY,
- ExtendedSocketOptions.SO_FLOW_SLA
- };
+ private static final List<SocketOption<?>> socketOptions = new ArrayList<>();
+
+ static {
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_IF);
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+ socketOptions.add(StandardSocketOptions.IP_MULTICAST_TTL);
+ socketOptions.add(StandardSocketOptions.IP_TOS);
+ socketOptions.add(StandardSocketOptions.SO_BROADCAST);
+ socketOptions.add(StandardSocketOptions.SO_KEEPALIVE);
+ socketOptions.add(StandardSocketOptions.SO_LINGER);
+ socketOptions.add(StandardSocketOptions.SO_RCVBUF);
+ socketOptions.add(StandardSocketOptions.SO_REUSEADDR);
+ socketOptions.add(StandardSocketOptions.SO_SNDBUF);
+ socketOptions.add(StandardSocketOptions.TCP_NODELAY);
+
+ try {
+ Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+ Field field = c.getField("SO_FLOW_SLA");
+ socketOptions.add((SocketOption<?>)field.get(null));
+ } catch (ClassNotFoundException e) {
+ // ignore, jdk.net module not present
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
public static void main(String[] args) throws IOException {
Socket s = new Socket();
@@ -56,7 +70,7 @@
DatagramSocket ds = new DatagramSocket();
MulticastSocket ms = new MulticastSocket();
- for (SocketOption option : SOCKET_OPTIONS) {
+ for (SocketOption option : socketOptions) {
if (!s.supportedOptions().contains(option)) {
testUnsupportedSocketOption(s, option);
}
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Wed Apr 27 20:36:02 2016 +0100
@@ -22,8 +22,10 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test for setOption/getOption/options methods
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Wed Apr 27 20:36:02 2016 +0100
@@ -22,9 +22,11 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test for ServerSocketChannel setOption/getOption/options
* methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java Wed Apr 27 20:36:02 2016 +0100
@@ -22,9 +22,11 @@
*/
/* @test
- * @bug 4640544
+ * @bug 4640544 8044773
* @summary Unit test to check SocketChannel setOption/getOption/options
* methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
*/
import java.nio.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java Wed Apr 27 20:36:02 2016 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8765432
+ * @summary Basic test for SocketFlow API
+ * @run testng SocketFlowBasic
+ */
+
+import jdk.net.SocketFlow;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static jdk.net.SocketFlow.*;
+import static org.testng.Assert.*;
+
+public class SocketFlowBasic {
+
+ @DataProvider
+ public Object[][] validPriorities() {
+ return new Object[][] { {HIGH_PRIORITY}, {NORMAL_PRIORITY} };
+ }
+
+ @Test(dataProvider = "validPriorities")
+ public void priority(long validPriority) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(validPriority);
+ long bandwidth = flow.bandwidth();
+ assertTrue(bandwidth == validPriority, "Expected " + validPriority + ", got" + bandwidth);
+ }
+
+ @DataProvider
+ public Object[][] invalidPriorities() {
+ return new Object[][] { {HIGH_PRIORITY+10}, {NORMAL_PRIORITY-10000} };
+ }
+
+ @Test(dataProvider = "invalidPriorities", expectedExceptions = IllegalArgumentException.class)
+ public void priority(int invalidPriority) {
+ SocketFlow flow = SocketFlow.create();
+ flow.priority(invalidPriority);
+ }
+
+ @DataProvider
+ public Object[][] positiveBandwidth() {
+ return new Object[][] { {0}, {100}, {Integer.MAX_VALUE}, {Long.MAX_VALUE} };
+ }
+
+ @Test(dataProvider = "positiveBandwidth")
+ public void bandwidth(long posBandwidth) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(posBandwidth);
+ long bandwidth = flow.bandwidth();
+ assertTrue(bandwidth == posBandwidth, "Expected " + posBandwidth + ", got" + bandwidth);
+ }
+
+
+ @DataProvider
+ public Object[][] negativeBandwidth() {
+ return new Object[][] { {-1}, {-100}, {Integer.MIN_VALUE}, {Long.MIN_VALUE} };
+ }
+
+ @Test(dataProvider = "negativeBandwidth", expectedExceptions = IllegalArgumentException.class)
+ public void invalidBandwidth(long negBandwidth) {
+ SocketFlow flow = SocketFlow.create();
+ flow.bandwidth(negBandwidth);
+ }
+
+ @Test
+ public void status() {
+ SocketFlow flow = SocketFlow.create();
+ assertTrue(flow.status() == Status.NO_STATUS);
+ }
+}
--- a/jdk/test/jdk/net/Sockets/Test.java Wed Apr 27 12:06:51 2016 -0700
+++ b/jdk/test/jdk/net/Sockets/Test.java Wed Apr 27 20:36:02 2016 +0100
@@ -23,8 +23,9 @@
/*
* @test
- * @bug 8032808
- * @run main/othervm -Xcheck:jni Test
+ * @bug 8032808 8044773
+ * @modules jdk.net
+ * @run main/othervm -Xcheck:jni Test success
* @run main/othervm/policy=policy.fail -Xcheck:jni Test fail
* @run main/othervm/policy=policy.success -Xcheck:jni Test success
*/
@@ -35,15 +36,13 @@
import java.util.concurrent.*;
import java.util.Set;
import jdk.net.*;
+import static java.lang.System.out;
public class Test {
- static boolean security;
- static boolean success;
+ interface Runner { void run() throws Exception; }
- interface Runner {
- public void run() throws Exception;
- }
+ static boolean expectSuccess;
public static void main(String[] args) throws Exception {
@@ -52,95 +51,107 @@
Sockets.supportedOptions(Socket.class);
- security = System.getSecurityManager() != null;
- success = security && args[0].equals("success");
+ expectSuccess = args[0].equals("success");
// Main thing is to check for JNI problems
// Doesn't matter if current system does not support the option
// and currently setting the option with the loopback interface
// doesn't work either
- System.out.println ("Security Manager enabled: " + security);
- if (security) {
- System.out.println ("Success expected: " + success);
- }
+ boolean sm = System.getSecurityManager() != null;
+ out.println("Security Manager enabled: " + sm);
+ out.println("Success expected: " + expectSuccess);
- final SocketFlow flowIn = SocketFlow.create()
- .bandwidth(1000)
- .priority(SocketFlow.HIGH_PRIORITY);
+ SocketFlow flowIn = SocketFlow.create()
+ .bandwidth(1000)
+ .priority(SocketFlow.HIGH_PRIORITY);
- ServerSocket ss = new ServerSocket(0);
- int tcp_port = ss.getLocalPort();
- final InetAddress loop = InetAddress.getByName("127.0.0.1");
- final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+ try (ServerSocket ss = new ServerSocket(0);
+ DatagramSocket dg = new DatagramSocket(0)) {
- DatagramSocket dg = new DatagramSocket(0);
- final int udp_port = dg.getLocalPort();
+ int tcp_port = ss.getLocalPort();
+ final InetAddress loop = InetAddress.getByName("127.0.0.1");
+ final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+
+ final int udp_port = dg.getLocalPort();
- // If option not available, end test
- Set<SocketOption<?>> options = dg.supportedOptions();
- if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
- System.out.println("SO_FLOW_SLA not supported");
- return;
- }
+ // If option not available, end test
+ Set<SocketOption<?>> options = dg.supportedOptions();
+ if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
+ System.out.println("SO_FLOW_SLA not supported");
+ return;
+ }
- final Socket s = new Socket("127.0.0.1", tcp_port);
- final SocketChannel sc = SocketChannel.open();
- sc.connect (new InetSocketAddress("127.0.0.1", tcp_port));
+ final Socket s = new Socket("127.0.0.1", tcp_port);
+ final SocketChannel sc = SocketChannel.open();
+ sc.connect(new InetSocketAddress("127.0.0.1", tcp_port));
- doTest(()->{
- Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
- });
- doTest(()->{
- sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA);
- });
- doTest(()->{
- DatagramSocket dg1 = new DatagramSocket(0);
- dg1.connect(loop, udp_port);
- Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- DatagramChannel dg2 = DatagramChannel.open();
- dg2.bind(new InetSocketAddress(loop, 0));
- dg2.connect(new InetSocketAddress(loop, udp_port));
- dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- MulticastSocket mc1 = new MulticastSocket(0);
- mc1.connect(loop, udp_port);
- Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
- doTest(()->{
- AsynchronousSocketChannel asc = AsynchronousSocketChannel.open();
- Future<Void> f = asc.connect(loopad);
- f.get();
- asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
- });
+ doTest("Sockets.setOption Socket", () -> {
+ out.println(flowIn);
+ Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ out.println(flowIn);
+ });
+ doTest("Sockets.getOption Socket",() -> {
+ Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
+ out.println(flowIn);
+ });
+ doTest("Sockets.setOption SocketChannel",() ->
+ sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn)
+ );
+ doTest("Sockets.getOption SocketChannel",() ->
+ sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA)
+ );
+ doTest("Sockets.setOption DatagramSocket",() -> {
+ try (DatagramSocket dg1 = new DatagramSocket(0)) {
+ dg1.connect(loop, udp_port);
+ Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption DatagramSocket 2", () -> {
+ try (DatagramChannel dg2 = DatagramChannel.open()) {
+ dg2.bind(new InetSocketAddress(loop, 0));
+ dg2.connect(new InetSocketAddress(loop, udp_port));
+ dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption MulticastSocket", () -> {
+ try (MulticastSocket mc1 = new MulticastSocket(0)) {
+ mc1.connect(loop, udp_port);
+ Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ doTest("Sockets.setOption AsynchronousSocketChannel", () -> {
+ try (AsynchronousSocketChannel asc = AsynchronousSocketChannel.open()) {
+ Future<Void> f = asc.connect(loopad);
+ f.get();
+ asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+ }
+ });
+ }
}
- static void doTest(Runner func) throws Exception {
+ static void doTest(String message, Runner func) throws Exception {
+ out.println(message);
try {
func.run();
- if (security && !success) {
- throw new RuntimeException("Test failed");
+ if (expectSuccess) {
+ out.println("Completed as expected");
+ } else {
+ throw new RuntimeException("Operation succeeded, but expected SecurityException");
}
} catch (SecurityException e) {
- if (success) {
- throw new RuntimeException("Test failed");
+ if (expectSuccess) {
+ throw new RuntimeException("Unexpected SecurityException", e);
+ } else {
+ out.println("Caught expected: " + e);
}
} catch (UnsupportedOperationException e) {
- System.out.println (e);
+ System.out.println(e);
} catch (IOException e) {
// Probably a permission error, but we're not
// going to check unless a specific permission exception
// is defined.
- System.out.println (e);
+ System.out.println(e);
}
}
}