< prev index next >

src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java

Print this page

        

*** 33,48 **** --- 33,50 ---- import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Collections; import java.util.HashSet; + import java.util.Objects; import java.util.Set; import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.PlatformSocketImpl; import sun.net.ResourceManager; + import sun.net.ext.ExtendedSocketOptions; import sun.net.util.SocketExceptions; /** * Default Socket Implementation. This implementation does * not implement any security checks.
*** 82,91 **** --- 84,96 ---- /* whether this Socket is a stream (TCP) socket or not (UDP) */ protected boolean stream; + /* whether this is a server or not */ + final boolean isServer; + /** * Load net library into runtime. */ static { java.security.AccessController.doPrivileged(
*** 110,140 **** } return isReusePortAvailable; } AbstractPlainSocketImpl(boolean isServer) { ! super(isServer); ! } ! ! /** ! * Returns a set of SocketOptions supported by this impl and by this impl's ! * socket (Socket or ServerSocket) ! * ! * @return a Set of SocketOptions ! */ ! @Override ! protected Set<SocketOption<?>> supportedOptions() { ! Set<SocketOption<?>> options; ! if (isReusePortAvailable()) { ! options = new HashSet<>(); ! options.addAll(super.supportedOptions()); ! options.add(StandardSocketOptions.SO_REUSEPORT); ! options = Collections.unmodifiableSet(options); ! } else { ! options = super.supportedOptions(); ! } ! return options; } /** * Creates a socket with a boolean that specifies whether this * is a stream socket (true) or an unconnected UDP socket (false). --- 115,125 ---- } return isReusePortAvailable; } AbstractPlainSocketImpl(boolean isServer) { ! this.isServer = isServer; } /** * Creates a socket with a boolean that specifies whether this * is a stream socket (true) or an unconnected UDP socket (false).
*** 392,401 **** --- 377,501 ---- default: return null; } } + static final ExtendedSocketOptions extendedOptions = + ExtendedSocketOptions.getInstance(); + + private static final Set<SocketOption<?>> clientSocketOptions = clientSocketOptions(); + private static final Set<SocketOption<?>> serverSocketOptions = serverSocketOptions(); + + private static Set<SocketOption<?>> clientSocketOptions() { + HashSet<SocketOption<?>> options = new HashSet<>(); + options.add(StandardSocketOptions.SO_KEEPALIVE); + options.add(StandardSocketOptions.SO_SNDBUF); + options.add(StandardSocketOptions.SO_RCVBUF); + options.add(StandardSocketOptions.SO_REUSEADDR); + options.add(StandardSocketOptions.SO_LINGER); + options.add(StandardSocketOptions.IP_TOS); + options.add(StandardSocketOptions.TCP_NODELAY); + if (isReusePortAvailable()) + options.add(StandardSocketOptions.SO_REUSEPORT); + options.addAll(ExtendedSocketOptions.clientSocketOptions()); + return Collections.unmodifiableSet(options); + } + + private static Set<SocketOption<?>> serverSocketOptions() { + HashSet<SocketOption<?>> options = new HashSet<>(); + options.add(StandardSocketOptions.SO_RCVBUF); + options.add(StandardSocketOptions.SO_REUSEADDR); + options.add(StandardSocketOptions.IP_TOS); + if (isReusePortAvailable()) + options.add(StandardSocketOptions.SO_REUSEPORT); + options.addAll(ExtendedSocketOptions.serverSocketOptions()); + return Collections.unmodifiableSet(options); + } + + @Override + protected Set<SocketOption<?>> supportedOptions() { + if (isServer) + return serverSocketOptions; + else + return clientSocketOptions; + } + + @Override + protected <T> void setOption(SocketOption<T> name, T value) throws IOException { + Objects.requireNonNull(name); + if (!supportedOptions().contains(name)) + throw new UnsupportedOperationException("'" + name + "' not supported"); + + if (!name.type().isInstance(value)) + throw new IllegalArgumentException("Invalid value '" + value + "'"); + + if (isClosedOrPending()) + throw new SocketException("Socket closed"); + + if (name == StandardSocketOptions.SO_KEEPALIVE) { + setOption(SocketOptions.SO_KEEPALIVE, value); + } else if (name == StandardSocketOptions.SO_SNDBUF) { + if (((Integer)value).intValue() < 0) + throw new IllegalArgumentException("Invalid send buffer size:" + value); + setOption(SocketOptions.SO_SNDBUF, value); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + if (((Integer)value).intValue() < 0) + throw new IllegalArgumentException("Invalid recv buffer size:" + value); + setOption(SocketOptions.SO_RCVBUF, value); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + setOption(SocketOptions.SO_REUSEADDR, value); + } else if (name == StandardSocketOptions.SO_REUSEPORT) { + setOption(SocketOptions.SO_REUSEPORT, value); + } else if (name == StandardSocketOptions.SO_LINGER ) { + setOption(SocketOptions.SO_LINGER, value); + } else if (name == StandardSocketOptions.IP_TOS) { + int i = ((Integer)value).intValue(); + if (i < 0 || i > 255) + throw new IllegalArgumentException("Invalid IP_TOS value: " + value); + setOption(SocketOptions.IP_TOS, value); + } else if (name == StandardSocketOptions.TCP_NODELAY) { + setOption(SocketOptions.TCP_NODELAY, value); + } else if (extendedOptions.isOptionSupported(name)) { + extendedOptions.setOption(fd, name, value); + } else { + throw new AssertionError("unknown option: " + name); + } + } + + @Override + @SuppressWarnings("unchecked") + protected <T> T getOption(SocketOption<T> name) throws IOException { + Objects.requireNonNull(name); + if (!supportedOptions().contains(name)) + throw new UnsupportedOperationException("'" + name + "' not supported"); + + if (isClosedOrPending()) + throw new SocketException("Socket closed"); + + if (name == StandardSocketOptions.SO_KEEPALIVE) { + return (T)getOption(SocketOptions.SO_KEEPALIVE); + } else if (name == StandardSocketOptions.SO_SNDBUF) { + return (T)getOption(SocketOptions.SO_SNDBUF); + } else if (name == StandardSocketOptions.SO_RCVBUF) { + return (T)getOption(SocketOptions.SO_RCVBUF); + } else if (name == StandardSocketOptions.SO_REUSEADDR) { + return (T)getOption(SocketOptions.SO_REUSEADDR); + } else if (name == StandardSocketOptions.SO_REUSEPORT) { + return (T)getOption(SocketOptions.SO_REUSEPORT); + } else if (name == StandardSocketOptions.SO_LINGER) { + return (T)getOption(SocketOptions.SO_LINGER); + } else if (name == StandardSocketOptions.IP_TOS) { + return (T)getOption(SocketOptions.IP_TOS); + } else if (name == StandardSocketOptions.TCP_NODELAY) { + return (T)getOption(SocketOptions.TCP_NODELAY); + } else if (extendedOptions.isOptionSupported(name)) { + return (T) extendedOptions.getOption(fd, name); + } else { + throw new AssertionError("unknown option: " + name); + } + } + /** * The workhorse of the connection operation. Tries several times to * establish a connection to the given <host, port>. If unsuccessful, * throws an IOException indicating what went wrong. */
< prev index next >