1e573e88e89daf5efb323719c54117c5a423eb245Yi Kong/* 2e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 5e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * This code is free software; you can redistribute it and/or modify it 6e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * under the terms of the GNU General Public License version 2 only, as 7e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * published by the Free Software Foundation. Oracle designates this 8e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * particular file as subject to the "Classpath" exception as provided 9e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * by Oracle in the LICENSE file that accompanied this code. 10e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 11e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * This code is distributed in the hope that it will be useful, but WITHOUT 12e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * version 2 for more details (a copy is included in the LICENSE file that 15e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * accompanied this code). 16e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 17e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * You should have received a copy of the GNU General Public License version 18e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 2 along with this work; if not, write to the Free Software Foundation, 19e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 21e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * or visit www.oracle.com if you need additional information or have any 23e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * questions. 24e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 25e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 26e573e88e89daf5efb323719c54117c5a423eb245Yi Kongpackage jdk.net; 27e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 28e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.net.*; 29e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.io.IOException; 30e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.io.FileDescriptor; 31e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.security.PrivilegedAction; 32e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.security.AccessController; 33e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.lang.reflect.*; 34e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.util.Set; 35e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.util.HashSet; 36e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.util.HashMap; 37e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport java.util.Collections; 38e573e88e89daf5efb323719c54117c5a423eb245Yi Kongimport sun.net.ExtendedOptionsImpl; 39e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 40e573e88e89daf5efb323719c54117c5a423eb245Yi Kong/** 41e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Defines static methods to set and get socket options defined by the 42e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * {@link java.net.SocketOption} interface. All of the standard options defined 43e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and 44e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * {@link java.net.DatagramSocket} can be set this way, as well as additional 45e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * or platform specific options supported by each socket type. 46e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * <p> 47e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * The {@link #supportedOptions(Class)} method can be called to determine 48e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the complete set of options available (per socket type) on the 49e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * current system. 50e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * <p> 51e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * When a security manager is installed, some non-standard socket options 52e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * may require a security permission before being set or get. 53e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * The details are specified in {@link ExtendedSocketOptions}. No permission 54e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * is required for {@link java.net.StandardSocketOptions}. 55e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 56e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.nio.channels.NetworkChannel 57e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 58e573e88e89daf5efb323719c54117c5a423eb245Yi Kong//@jdk.Exported 59e573e88e89daf5efb323719c54117c5a423eb245Yi Kongpublic class Sockets { 60e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 61e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private final static HashMap<Class<?>,Set<SocketOption<?>>> 62e573e88e89daf5efb323719c54117c5a423eb245Yi Kong options = new HashMap<>(); 63e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 64e573e88e89daf5efb323719c54117c5a423eb245Yi Kong static { 65e573e88e89daf5efb323719c54117c5a423eb245Yi Kong initOptionSets(); 66e573e88e89daf5efb323719c54117c5a423eb245Yi Kong AccessController.doPrivileged( 67e573e88e89daf5efb323719c54117c5a423eb245Yi Kong new java.security.PrivilegedAction<Void>() { 68e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public Void run() { 69e573e88e89daf5efb323719c54117c5a423eb245Yi Kong initMethods(); 70e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return null; 71e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 72e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 73e573e88e89daf5efb323719c54117c5a423eb245Yi Kong ); 74e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 75e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 76e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static Method siSetOption; 77e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static Method siGetOption; 78e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static Method dsiSetOption; 79e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static Method dsiGetOption; 80e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 81e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static void initMethods() { 82e573e88e89daf5efb323719c54117c5a423eb245Yi Kong try { 83e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Class<?> clazz = Class.forName("java.net.SocketSecrets"); 84e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 85e573e88e89daf5efb323719c54117c5a423eb245Yi Kong siSetOption = clazz.getDeclaredMethod( 86e573e88e89daf5efb323719c54117c5a423eb245Yi Kong "setOption", Object.class, 87e573e88e89daf5efb323719c54117c5a423eb245Yi Kong SocketOption.class, Object.class 88e573e88e89daf5efb323719c54117c5a423eb245Yi Kong ); 89e573e88e89daf5efb323719c54117c5a423eb245Yi Kong siSetOption.setAccessible(true); 90e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 91e573e88e89daf5efb323719c54117c5a423eb245Yi Kong siGetOption = clazz.getDeclaredMethod( 92e573e88e89daf5efb323719c54117c5a423eb245Yi Kong "getOption", Object.class, SocketOption.class 93e573e88e89daf5efb323719c54117c5a423eb245Yi Kong ); 94e573e88e89daf5efb323719c54117c5a423eb245Yi Kong siGetOption.setAccessible(true); 95e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 96e573e88e89daf5efb323719c54117c5a423eb245Yi Kong dsiSetOption = clazz.getDeclaredMethod( 97e573e88e89daf5efb323719c54117c5a423eb245Yi Kong "setOption", DatagramSocket.class, 98e573e88e89daf5efb323719c54117c5a423eb245Yi Kong SocketOption.class, Object.class 99e573e88e89daf5efb323719c54117c5a423eb245Yi Kong ); 100e573e88e89daf5efb323719c54117c5a423eb245Yi Kong dsiSetOption.setAccessible(true); 101e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 102e573e88e89daf5efb323719c54117c5a423eb245Yi Kong dsiGetOption = clazz.getDeclaredMethod( 103e573e88e89daf5efb323719c54117c5a423eb245Yi Kong "getOption", DatagramSocket.class, SocketOption.class 104e573e88e89daf5efb323719c54117c5a423eb245Yi Kong ); 105e573e88e89daf5efb323719c54117c5a423eb245Yi Kong dsiGetOption.setAccessible(true); 106e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } catch (ReflectiveOperationException e) { 107e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new InternalError(e); 108e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 109e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 110e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 111e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static <T> void invokeSet( 112e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Method method, Object socket, 113e573e88e89daf5efb323719c54117c5a423eb245Yi Kong SocketOption<T> option, T value) throws IOException 114e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 115e573e88e89daf5efb323719c54117c5a423eb245Yi Kong try { 116e573e88e89daf5efb323719c54117c5a423eb245Yi Kong method.invoke(null, socket, option, value); 117e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } catch (Exception e) { 118e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (e instanceof InvocationTargetException) { 119e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Throwable t = ((InvocationTargetException)e).getTargetException(); 120e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (t instanceof IOException) { 121e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw (IOException)t; 122e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } else if (t instanceof RuntimeException) { 123e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw (RuntimeException)t; 124e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 125e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 126e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new RuntimeException(e); 127e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 128e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 129e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 130e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static <T> T invokeGet( 131e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Method method, Object socket, SocketOption<T> option) throws IOException 132e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 133e573e88e89daf5efb323719c54117c5a423eb245Yi Kong try { 134e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return (T)method.invoke(null, socket, option); 135e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } catch (Exception e) { 136e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (e instanceof InvocationTargetException) { 137e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Throwable t = ((InvocationTargetException)e).getTargetException(); 138e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (t instanceof IOException) { 139e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw (IOException)t; 140e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } else if (t instanceof RuntimeException) { 141e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw (RuntimeException)t; 142e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 143e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 144e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new RuntimeException(e); 145e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 146e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 147e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 148e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private Sockets() {} 149e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 150e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 151e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Sets the value of a socket option on a {@link java.net.Socket} 152e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 153e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 154e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 155e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param value The value of the socket option. May be null for some 156e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * options. 157e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 158e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 159e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 160e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 161e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IllegalArgumentException if the value is not valid for 162e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 163e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 164e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs, or socket is closed. 165e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 166e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 167e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 168e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 169e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 170e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 171e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 172e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 173e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException 174e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 175e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(Socket.class, name)) { 176e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 177e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 178e573e88e89daf5efb323719c54117c5a423eb245Yi Kong invokeSet(siSetOption, s, name, value); 179e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 180e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 181e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 182e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Returns the value of a socket option from a {@link java.net.Socket} 183e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 184e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 185e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 186e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 187e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @return The value of the socket option. 188e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 189e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 190e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 191e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 192e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs 193e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 194e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 195e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 196e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 197e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 198e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 199e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 200e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 201e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException 202e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 203e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(Socket.class, name)) { 204e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 205e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 206e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return invokeGet(siGetOption, s, name); 207e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 208e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 209e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 210e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Sets the value of a socket option on a {@link java.net.ServerSocket} 211e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 212e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 213e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 214e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param value The value of the socket option. 215e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 216e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 217e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 218e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 219e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IllegalArgumentException if the value is not valid for 220e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 221e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 222e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs 223e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 224e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 225e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 226e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 227e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 228e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 229e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 230e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 231e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException 232e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 233e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(ServerSocket.class, name)) { 234e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 235e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 236e573e88e89daf5efb323719c54117c5a423eb245Yi Kong invokeSet(siSetOption, s, name, value); 237e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 238e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 239e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 240e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Returns the value of a socket option from a {@link java.net.ServerSocket} 241e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 242e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 243e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 244e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 245e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @return The value of the socket option. 246e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 247e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 248e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 249e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 250e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs 251e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 252e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 253e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 254e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 255e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 256e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 257e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 258e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 259e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException 260e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 261e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(ServerSocket.class, name)) { 262e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 263e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 264e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return invokeGet(siGetOption, s, name); 265e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 266e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 267e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 268e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Sets the value of a socket option on a {@link java.net.DatagramSocket} 269e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * or {@link java.net.MulticastSocket} 270e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 271e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 272e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 273e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param value The value of the socket option. 274e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 275e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 276e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 277e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 278e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IllegalArgumentException if the value is not valid for 279e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 280e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 281e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs 282e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 283e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 284e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 285e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 286e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 287e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 288e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 289e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 290e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException 291e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 292e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(s.getClass(), name)) { 293e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 294e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 295e573e88e89daf5efb323719c54117c5a423eb245Yi Kong invokeSet(dsiSetOption, s, name, value); 296e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 297e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 298e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 299e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Returns the value of a socket option from a 300e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket} 301e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 302e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param s the socket 303e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param name The socket option 304e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 305e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @return The value of the socket option. 306e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 307e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws UnsupportedOperationException if the socket does not support 308e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * the option. 309e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 310e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IOException if an I/O error occurs 311e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 312e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws NullPointerException if name is null 313e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 314e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws SecurityException if a security manager is set and the 315e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * caller does not have any required permission. 316e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 317e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @see java.net.StandardSocketOptions 318e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 319e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException 320e573e88e89daf5efb323719c54117c5a423eb245Yi Kong { 321e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (!isSupported(s.getClass(), name)) { 322e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new UnsupportedOperationException(name.name()); 323e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 324e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return invokeGet(dsiGetOption, s, name); 325e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 326e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 327e573e88e89daf5efb323719c54117c5a423eb245Yi Kong /** 328e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * Returns a set of {@link java.net.SocketOption}s supported by the 329e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * given socket type. This set may include standard options and also 330e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * non standard extended options. 331e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 332e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @param socketType the type of java.net socket 333e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * 334e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * @throws IllegalArgumentException if socketType is not a valid 335e573e88e89daf5efb323719c54117c5a423eb245Yi Kong * socket type from the java.net package. 336e573e88e89daf5efb323719c54117c5a423eb245Yi Kong */ 337e573e88e89daf5efb323719c54117c5a423eb245Yi Kong public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) { 338e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Set<SocketOption<?>> set = options.get(socketType); 339e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (set == null) { 340e573e88e89daf5efb323719c54117c5a423eb245Yi Kong throw new IllegalArgumentException("unknown socket type"); 341e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 342e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return set; 343e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 344e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 345e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static boolean isSupported(Class<?> type, SocketOption<?> option) { 346e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Set<SocketOption<?>> options = supportedOptions(type); 347e573e88e89daf5efb323719c54117c5a423eb245Yi Kong return options.contains(option); 348e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 349e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 350e573e88e89daf5efb323719c54117c5a423eb245Yi Kong private static void initOptionSets() { 351e573e88e89daf5efb323719c54117c5a423eb245Yi Kong boolean flowsupported = ExtendedOptionsImpl.flowSupported(); 352e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 353e573e88e89daf5efb323719c54117c5a423eb245Yi Kong // Socket 354e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 355e573e88e89daf5efb323719c54117c5a423eb245Yi Kong Set<SocketOption<?>> set = new HashSet<>(); 356e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_KEEPALIVE); 357e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_SNDBUF); 358e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_RCVBUF); 359e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_REUSEADDR); 360e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_LINGER); 361e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_TOS); 362e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.TCP_NODELAY); 363e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (flowsupported) { 364e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(ExtendedSocketOptions.SO_FLOW_SLA); 365e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 366e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = Collections.unmodifiableSet(set); 367e573e88e89daf5efb323719c54117c5a423eb245Yi Kong options.put(Socket.class, set); 368e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 369e573e88e89daf5efb323719c54117c5a423eb245Yi Kong // ServerSocket 370e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 371e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = new HashSet<>(); 372e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_RCVBUF); 373e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_REUSEADDR); 374e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_TOS); 375e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = Collections.unmodifiableSet(set); 376e573e88e89daf5efb323719c54117c5a423eb245Yi Kong options.put(ServerSocket.class, set); 377e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 378e573e88e89daf5efb323719c54117c5a423eb245Yi Kong // DatagramSocket 379e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 380e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = new HashSet<>(); 381e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_SNDBUF); 382e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_RCVBUF); 383e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_REUSEADDR); 384e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_TOS); 385e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (flowsupported) { 386e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(ExtendedSocketOptions.SO_FLOW_SLA); 387e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 388e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = Collections.unmodifiableSet(set); 389e573e88e89daf5efb323719c54117c5a423eb245Yi Kong options.put(DatagramSocket.class, set); 390e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 391e573e88e89daf5efb323719c54117c5a423eb245Yi Kong // MulticastSocket 392e573e88e89daf5efb323719c54117c5a423eb245Yi Kong 393e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = new HashSet<>(); 394e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_SNDBUF); 395e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_RCVBUF); 396e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.SO_REUSEADDR); 397e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_TOS); 398e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_MULTICAST_IF); 399e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_MULTICAST_TTL); 400e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(StandardSocketOptions.IP_MULTICAST_LOOP); 401e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (flowsupported) { 402e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(ExtendedSocketOptions.SO_FLOW_SLA); 403e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 404e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set = Collections.unmodifiableSet(set); 405e573e88e89daf5efb323719c54117c5a423eb245Yi Kong options.put(MulticastSocket.class, set); 406e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 407e573e88e89daf5efb323719c54117c5a423eb245Yi Kong} 408