8253119: Remove the legacy PlainSocketImpl and PlainDatagramSocketImpl implementation

Reviewed-by: alanb, dfuchs, chegar
This commit is contained in:
Patrick Concannon 2021-07-06 13:46:02 +00:00
parent f485171ce8
commit 326b2e1344
78 changed files with 207 additions and 10924 deletions

View File

@ -1,530 +0,0 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import sun.net.ResourceManager;
import sun.net.ext.ExtendedSocketOptions;
import sun.net.util.IPAddressUtil;
import sun.security.action.GetPropertyAction;
/**
* Abstract datagram and multicast socket implementation base class.
* Note: This is not a public class, so that applets cannot call
* into the implementation directly and hence cannot bypass the
* security checks present in the DatagramSocket and MulticastSocket
* classes.
*
* @author Pavani Diwanji
*/
abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
{
/* timeout value for receive() */
int timeout = 0;
boolean connected = false;
private int trafficClass = 0;
protected InetAddress connectedAddress = null;
private int connectedPort = -1;
private final boolean isMulticast;
private static final String os =
GetPropertyAction.privilegedGetProperty("os.name");
/**
* flag set if the native connect() call not to be used
*/
private static final boolean connectDisabled = os.contains("OS X");
/**
* Load net library into runtime.
*/
static {
jdk.internal.loader.BootLoader.loadLibrary("net");
}
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;
}
AbstractPlainDatagramSocketImpl(boolean isMulticast) {
this.isMulticast = isMulticast;
}
/**
* Creates a datagram socket
*/
protected synchronized void create() throws SocketException {
ResourceManager.beforeUdpCreate();
fd = new FileDescriptor();
try {
datagramSocketCreate();
SocketCleanable.register(fd, false);
} catch (SocketException ioe) {
ResourceManager.afterUdpClose();
fd = null;
throw ioe;
}
}
/**
* Binds a datagram socket to a local port.
*/
protected synchronized void bind(int lport, InetAddress laddr)
throws SocketException {
if (laddr.isLinkLocalAddress()) {
laddr = IPAddressUtil.toScopedAddress(laddr);
}
bind0(lport, laddr);
}
protected abstract void bind0(int lport, InetAddress laddr)
throws SocketException;
/**
* Sends a datagram packet. The packet contains the data and the
* destination address to send the packet to.
* @param p the packet to be sent.
*/
protected void send(DatagramPacket p) throws IOException {
InetAddress orig = p.getAddress();
if (orig.isLinkLocalAddress()) {
InetAddress scoped = IPAddressUtil.toScopedAddress(orig);
if (orig != scoped) {
p = new DatagramPacket(p.getData(), p.getOffset(),
p.getLength(), scoped, p.getPort());
}
}
send0(p);
}
protected abstract void send0(DatagramPacket p) throws IOException;
/**
* Connects a datagram socket to a remote destination. This associates the remote
* address with the local socket so that datagrams may only be sent to this destination
* and received from this destination.
* @param address the remote InetAddress to connect to
* @param port the remote port number
*/
protected void connect(InetAddress address, int port) throws SocketException {
if (address.isLinkLocalAddress()) {
address = IPAddressUtil.toScopedAddress(address);
}
connect0(address, port);
connectedAddress = address;
connectedPort = port;
connected = true;
}
/**
* Disconnects a previously connected socket. Does nothing if the socket was
* not connected already.
*/
protected void disconnect() {
disconnect0(connectedAddress.holder().getFamily());
connected = false;
connectedAddress = null;
connectedPort = -1;
}
/**
* Peek at the packet to see who it is from.
* @param i the address to populate with the sender address
*/
protected abstract int peek(InetAddress i) throws IOException;
protected abstract int peekData(DatagramPacket p) throws IOException;
/**
* Receive the datagram packet.
* @param p the packet to receive into
*/
protected synchronized void receive(DatagramPacket p)
throws IOException {
receive0(p);
}
protected abstract void receive0(DatagramPacket p)
throws IOException;
/**
* Set the TTL (time-to-live) option.
* @param ttl TTL to be set.
*/
protected abstract void setTimeToLive(int ttl) throws IOException;
/**
* Get the TTL (time-to-live) option.
*/
protected abstract int getTimeToLive() throws IOException;
/**
* Set the TTL (time-to-live) option.
* @param ttl TTL to be set.
*/
@Deprecated
protected abstract void setTTL(byte ttl) throws IOException;
/**
* Get the TTL (time-to-live) option.
*/
@Deprecated
protected abstract byte getTTL() throws IOException;
/**
* Join the multicast group.
* @param inetaddr multicast address to join.
*/
protected void join(InetAddress inetaddr) throws IOException {
join(inetaddr, null);
}
/**
* Leave the multicast group.
* @param inetaddr multicast address to leave.
*/
protected void leave(InetAddress inetaddr) throws IOException {
leave(inetaddr, null);
}
/**
* Join the multicast group.
* @param mcastaddr multicast address to join.
* @param netIf specifies the local interface to receive multicast
* datagram packets
* @throws IllegalArgumentException if mcastaddr is null or is a
* SocketAddress subclass not supported by this socket
* @since 1.4
*/
protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
throws IOException {
if (!(mcastaddr instanceof InetSocketAddress addr))
throw new IllegalArgumentException("Unsupported address type");
join(addr.getAddress(), netIf);
}
protected abstract void join(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
/**
* Leave the multicast group.
* @param mcastaddr multicast address to leave.
* @param netIf specified the local interface to leave the group at
* @throws IllegalArgumentException if mcastaddr is null or is a
* SocketAddress subclass not supported by this socket
* @since 1.4
*/
protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
throws IOException {
if (!(mcastaddr instanceof InetSocketAddress addr))
throw new IllegalArgumentException("Unsupported address type");
leave(addr.getAddress(), netIf);
}
protected abstract void leave(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
/**
* Close the socket.
*/
protected void close() {
if (fd != null) {
SocketCleanable.unregister(fd);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;
}
}
protected boolean isClosed() {
return (fd == null) ? true : false;
}
/**
* set a value - since we only support (setting) binary options
* here, o must be a Boolean
*/
public void setOption(int optID, Object o) throws SocketException {
if (isClosed()) {
throw new SocketException("Socket Closed");
}
switch (optID) {
/* check type safety b4 going native. These should never
* fail, since only java.Socket* has access to
* PlainSocketImpl.setOption().
*/
case SO_TIMEOUT:
if (!(o instanceof Integer)) {
throw new SocketException("bad argument for SO_TIMEOUT");
}
int tmp = ((Integer) o).intValue();
if (tmp < 0)
throw new IllegalArgumentException("timeout < 0");
timeout = tmp;
return;
case IP_TOS:
if (!(o instanceof Integer)) {
throw new SocketException("bad argument for IP_TOS");
}
trafficClass = ((Integer)o).intValue();
break;
case SO_REUSEADDR:
if (!(o instanceof Boolean)) {
throw new SocketException("bad argument for SO_REUSEADDR");
}
break;
case SO_BROADCAST:
if (!(o instanceof Boolean)) {
throw new SocketException("bad argument for SO_BROADCAST");
}
break;
case SO_BINDADDR:
throw new SocketException("Cannot re-bind Socket");
case SO_RCVBUF:
case SO_SNDBUF:
if (!(o instanceof Integer) ||
((Integer)o).intValue() < 0) {
throw new SocketException("bad argument for SO_SNDBUF or " +
"SO_RCVBUF");
}
break;
case IP_MULTICAST_IF:
if (!(o instanceof InetAddress))
throw new SocketException("bad argument for IP_MULTICAST_IF");
break;
case IP_MULTICAST_IF2:
if (!(o instanceof NetworkInterface))
throw new SocketException("bad argument for IP_MULTICAST_IF2");
break;
case IP_MULTICAST_LOOP:
if (!(o instanceof Boolean))
throw new SocketException("bad argument for IP_MULTICAST_LOOP");
break;
case SO_REUSEPORT:
if (!(o instanceof Boolean)) {
throw new SocketException("bad argument for SO_REUSEPORT");
}
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
break;
default:
throw new SocketException("invalid option: " + optID);
}
socketSetOption(optID, o);
}
/*
* get option's state - set or not
*/
public Object getOption(int optID) throws SocketException {
if (isClosed()) {
throw new SocketException("Socket Closed");
}
Object result;
switch (optID) {
case SO_TIMEOUT:
result = timeout;
break;
case IP_TOS:
result = socketGetOption(optID);
if ( ((Integer)result).intValue() == -1) {
result = trafficClass;
}
break;
case SO_BINDADDR:
case IP_MULTICAST_IF:
case IP_MULTICAST_IF2:
case SO_RCVBUF:
case SO_SNDBUF:
case IP_MULTICAST_LOOP:
case SO_REUSEADDR:
case SO_BROADCAST:
result = socketGetOption(optID);
break;
case SO_REUSEPORT:
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
result = socketGetOption(optID);
break;
default:
throw new SocketException("invalid option: " + optID);
}
return result;
}
static final ExtendedSocketOptions extendedOptions =
ExtendedSocketOptions.getInstance();
private static final Set<SocketOption<?>> datagramSocketOptions = datagramSocketOptions();
private static Set<SocketOption<?>> datagramSocketOptions() {
HashSet<SocketOption<?>> options = new HashSet<>();
options.add(StandardSocketOptions.SO_SNDBUF);
options.add(StandardSocketOptions.SO_RCVBUF);
options.add(StandardSocketOptions.SO_REUSEADDR);
options.add(StandardSocketOptions.SO_BROADCAST);
options.add(StandardSocketOptions.IP_TOS);
options.add(StandardSocketOptions.IP_MULTICAST_IF);
options.add(StandardSocketOptions.IP_MULTICAST_TTL);
options.add(StandardSocketOptions.IP_MULTICAST_LOOP);
if (isReusePortAvailable())
options.add(StandardSocketOptions.SO_REUSEPORT);
options.addAll(ExtendedSocketOptions.datagramSocketOptions());
return Collections.unmodifiableSet(options);
}
@Override
protected Set<SocketOption<?>> supportedOptions() {
return datagramSocketOptions;
}
@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 (isClosed())
throw new SocketException("Socket closed");
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_BROADCAST) {
setOption(SocketOptions.SO_BROADCAST, 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.IP_MULTICAST_IF ) {
setOption(SocketOptions.IP_MULTICAST_IF2, value);
} else if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
int i = ((Integer)value).intValue();
if (i < 0 || i > 255)
throw new IllegalArgumentException("Invalid TTL/hop value: " + value);
setTimeToLive((Integer)value);
} else if (name == StandardSocketOptions.IP_MULTICAST_LOOP) {
boolean enable = (boolean) value;
// Legacy setOption expects true to mean 'disabled'
setOption(SocketOptions.IP_MULTICAST_LOOP, !enable);
} 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 (isClosed())
throw new SocketException("Socket closed");
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_BROADCAST) {
return (T) getOption(SocketOptions.SO_BROADCAST);
} else if (name == StandardSocketOptions.IP_TOS) {
return (T) getOption(SocketOptions.IP_TOS);
} else if (name == StandardSocketOptions.IP_MULTICAST_IF) {
return (T) getOption(SocketOptions.IP_MULTICAST_IF2);
} else if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
return (T) ((Integer) getTimeToLive());
} else if (name == StandardSocketOptions.IP_MULTICAST_LOOP) {
boolean disabled = (boolean) getOption(SocketOptions.IP_MULTICAST_LOOP);
// Legacy getOption returns true when disabled
return (T) Boolean.valueOf(!disabled);
} else if (extendedOptions.isOptionSupported(name)) {
return (T) extendedOptions.getOption(fd, name);
} else {
throw new AssertionError("unknown option: " + name);
}
}
protected abstract void datagramSocketCreate() throws SocketException;
protected abstract void datagramSocketClose();
protected abstract void socketSetOption(int opt, Object val)
throws SocketException;
protected abstract Object socketGetOption(int opt) throws SocketException;
protected abstract void connect0(InetAddress address, int port) throws SocketException;
protected abstract void disconnect0(int family);
protected boolean nativeConnectDisabled() {
return connectDisabled;
}
abstract int dataAvailable();
private static native boolean isReusePortAvailable0();
}

View File

@ -1,875 +0,0 @@
/*
* Copyright (c) 1995, 2021, 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 java.net;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.IPAddressUtil;
import sun.net.util.SocketExceptions;
/**
* Default Socket Implementation. This implementation does
* not implement any security checks.
* Note this class should <b>NOT</b> be public.
*
* @author Steven B. Byrne
*/
abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSocketImpl {
/* instance variable for SO_TIMEOUT */
int timeout; // timeout in millisec
// traffic class
private int trafficClass;
private boolean shut_rd = false;
private boolean shut_wr = false;
private SocketInputStream socketInputStream = null;
private SocketOutputStream socketOutputStream = null;
/* number of threads using the FileDescriptor */
protected int fdUseCount = 0;
/* lock when increment/decrementing fdUseCount */
protected final Object fdLock = new Object();
/* indicates a close is pending on the file descriptor */
protected boolean closePending = false;
/* indicates connection reset state */
private volatile boolean connectionReset;
/* indicates whether impl is bound */
boolean isBound;
/* indicates whether impl is connected */
volatile boolean isConnected;
/* 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 {
jdk.internal.loader.BootLoader.loadLibrary("net");
}
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;
}
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).
*/
protected synchronized void create(boolean stream) throws IOException {
this.stream = stream;
if (!stream) {
ResourceManager.beforeUdpCreate();
// only create the fd after we know we will be able to create the socket
fd = new FileDescriptor();
try {
socketCreate(false);
SocketCleanable.register(fd, false);
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
fd = null;
throw ioe;
}
} else {
fd = new FileDescriptor();
socketCreate(true);
SocketCleanable.register(fd, true);
}
}
/**
* Creates a socket and connects it to the specified port on
* the specified host.
* @param host the specified host
* @param port the specified port
*/
protected void connect(String host, int port)
throws UnknownHostException, IOException
{
boolean connected = false;
try {
InetAddress address = InetAddress.getByName(host);
// recording this.address as supplied by caller before calling connect
this.address = address;
this.port = port;
if (address.isLinkLocalAddress()) {
address = IPAddressUtil.toScopedAddress(address);
}
connectToAddress(address, port, timeout);
connected = true;
} finally {
if (!connected) {
try {
close();
} catch (IOException ioe) {
/* Do nothing. If connect threw an exception then
it will be passed up the call stack */
}
}
isConnected = connected;
}
}
/**
* Creates a socket and connects it to the specified address on
* the specified port.
* @param address the address
* @param port the specified port
*/
protected void connect(InetAddress address, int port) throws IOException {
// recording this.address as supplied by caller before calling connect
this.address = address;
this.port = port;
if (address.isLinkLocalAddress()) {
address = IPAddressUtil.toScopedAddress(address);
}
try {
connectToAddress(address, port, timeout);
isConnected = true;
return;
} catch (IOException e) {
// everything failed
close();
throw e;
}
}
/**
* Creates a socket and connects it to the specified address on
* the specified port.
* @param address the address
* @param timeout the timeout value in milliseconds, or zero for no timeout.
* @throws IOException if connection fails
* @throws IllegalArgumentException if address is null or is a
* SocketAddress subclass not supported by this socket
* @since 1.4
*/
protected void connect(SocketAddress address, int timeout)
throws IOException {
boolean connected = false;
try {
if (!(address instanceof InetSocketAddress addr))
throw new IllegalArgumentException("unsupported address type");
if (addr.isUnresolved())
throw new UnknownHostException(addr.getHostName());
// recording this.address as supplied by caller before calling connect
InetAddress ia = addr.getAddress();
this.address = ia;
this.port = addr.getPort();
if (ia.isLinkLocalAddress()) {
ia = IPAddressUtil.toScopedAddress(ia);
}
connectToAddress(ia, port, timeout);
connected = true;
} finally {
if (!connected) {
try {
close();
} catch (IOException ioe) {
/* Do nothing. If connect threw an exception then
it will be passed up the call stack */
}
}
isConnected = connected;
}
}
private void connectToAddress(InetAddress address, int port, int timeout) throws IOException {
if (address.isAnyLocalAddress()) {
doConnect(InetAddress.getLocalHost(), port, timeout);
} else {
doConnect(address, port, timeout);
}
}
public void setOption(int opt, Object val) throws SocketException {
if (isClosedOrPending()) {
throw new SocketException("Socket Closed");
}
boolean on = true;
switch (opt) {
/* check type safety b4 going native. These should never
* fail, since only java.Socket* has access to
* PlainSocketImpl.setOption().
*/
case SO_LINGER:
if (!(val instanceof Integer) && !(val instanceof Boolean))
throw new SocketException("Bad parameter for option");
if (val instanceof Boolean) {
/* true only if disabling - enabling should be Integer */
on = false;
}
break;
case SO_TIMEOUT:
if (!(val instanceof Integer))
throw new SocketException("Bad parameter for SO_TIMEOUT");
int tmp = ((Integer) val).intValue();
if (tmp < 0)
throw new IllegalArgumentException("timeout < 0");
timeout = tmp;
break;
case IP_TOS:
if (!(val instanceof Integer)) {
throw new SocketException("bad argument for IP_TOS");
}
trafficClass = ((Integer)val).intValue();
break;
case SO_BINDADDR:
throw new SocketException("Cannot re-bind socket");
case TCP_NODELAY:
if (!(val instanceof Boolean))
throw new SocketException("bad parameter for TCP_NODELAY");
on = ((Boolean)val).booleanValue();
break;
case SO_SNDBUF:
case SO_RCVBUF:
if (!(val instanceof Integer) ||
!(((Integer)val).intValue() > 0)) {
throw new SocketException("bad parameter for SO_SNDBUF " +
"or SO_RCVBUF");
}
break;
case SO_KEEPALIVE:
if (!(val instanceof Boolean))
throw new SocketException("bad parameter for SO_KEEPALIVE");
on = ((Boolean)val).booleanValue();
break;
case SO_OOBINLINE:
if (!(val instanceof Boolean))
throw new SocketException("bad parameter for SO_OOBINLINE");
on = ((Boolean)val).booleanValue();
break;
case SO_REUSEADDR:
if (!(val instanceof Boolean))
throw new SocketException("bad parameter for SO_REUSEADDR");
on = ((Boolean)val).booleanValue();
break;
case SO_REUSEPORT:
if (!(val instanceof Boolean))
throw new SocketException("bad parameter for SO_REUSEPORT");
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT))
throw new UnsupportedOperationException("unsupported option");
on = ((Boolean)val).booleanValue();
break;
default:
throw new SocketException("unrecognized TCP option: " + opt);
}
socketSetOption(opt, on, val);
}
public Object getOption(int opt) throws SocketException {
if (isClosedOrPending()) {
throw new SocketException("Socket Closed");
}
if (opt == SO_TIMEOUT) {
return timeout;
}
int ret = 0;
/*
* The native socketGetOption() knows about 3 options.
* The 32 bit value it returns will be interpreted according
* to what we're asking. A return of -1 means it understands
* the option but its turned off. It will raise a SocketException
* if "opt" isn't one it understands.
*/
switch (opt) {
case TCP_NODELAY:
ret = socketGetOption(opt, null);
return Boolean.valueOf(ret != -1);
case SO_OOBINLINE:
ret = socketGetOption(opt, null);
return Boolean.valueOf(ret != -1);
case SO_LINGER:
ret = socketGetOption(opt, null);
return (ret == -1) ? Boolean.FALSE: (Object)(ret);
case SO_REUSEADDR:
ret = socketGetOption(opt, null);
return Boolean.valueOf(ret != -1);
case SO_BINDADDR:
InetAddressContainer in = new InetAddressContainer();
ret = socketGetOption(opt, in);
return in.addr;
case SO_SNDBUF:
case SO_RCVBUF:
ret = socketGetOption(opt, null);
return ret;
case IP_TOS:
try {
ret = socketGetOption(opt, null);
if (ret == -1) { // ipv6 tos
return trafficClass;
} else {
return ret;
}
} catch (SocketException se) {
// TODO - should make better effort to read TOS or TCLASS
return trafficClass; // ipv6 tos
}
case SO_KEEPALIVE:
ret = socketGetOption(opt, null);
return Boolean.valueOf(ret != -1);
case SO_REUSEPORT:
if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
ret = socketGetOption(opt, null);
return Boolean.valueOf(ret != -1);
// should never get here
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 ) {
if (((Integer)value).intValue() < 0)
setOption(SocketOptions.SO_LINGER, false);
else
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) {
Object value = getOption(SocketOptions.SO_LINGER);
if (value instanceof Boolean) {
assert ((Boolean)value).booleanValue() == false;
value = -1;
}
return (T)value;
} 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.
*/
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
synchronized (fdLock) {
if (!closePending && !isBound) {
NetHooks.beforeTcpConnect(fd, address, port);
}
}
try {
acquireFD();
try {
socketConnect(address, port, timeout);
/* socket may have been closed during poll/select */
synchronized (fdLock) {
if (closePending) {
throw new SocketException ("Socket closed");
}
}
} finally {
releaseFD();
}
} catch (IOException e) {
close();
throw SocketExceptions.of(e, new InetSocketAddress(address, port));
}
}
/**
* Binds the socket to the specified address of the specified local port.
* @param address the address
* @param lport the port
*/
protected synchronized void bind(InetAddress address, int lport)
throws IOException
{
synchronized (fdLock) {
if (!closePending && !isBound) {
NetHooks.beforeTcpBind(fd, address, lport);
}
}
if (address.isLinkLocalAddress()) {
address = IPAddressUtil.toScopedAddress(address);
}
socketBind(address, lport);
isBound = true;
}
/**
* Listens, for a specified amount of time, for connections.
* @param count the amount of time to listen for connections
*/
protected synchronized void listen(int count) throws IOException {
socketListen(count);
}
/**
* Accepts connections.
* @param si the socket impl
*/
protected void accept(SocketImpl si) throws IOException {
si.fd = new FileDescriptor();
acquireFD();
try {
socketAccept(si);
} finally {
releaseFD();
}
SocketCleanable.register(si.fd, true);
}
/**
* Gets an InputStream for this socket.
*/
@SuppressWarnings("removal")
protected synchronized InputStream getInputStream() throws IOException {
synchronized (fdLock) {
if (isClosedOrPending())
throw new IOException("Socket Closed");
if (shut_rd)
throw new IOException("Socket input is shutdown");
if (socketInputStream == null) {
PrivilegedExceptionAction<SocketInputStream> pa = () -> new SocketInputStream(this);
try {
socketInputStream = AccessController.doPrivileged(pa);
} catch (PrivilegedActionException e) {
throw (IOException) e.getCause();
}
}
}
return socketInputStream;
}
void setInputStream(SocketInputStream in) {
socketInputStream = in;
}
/**
* Gets an OutputStream for this socket.
*/
@SuppressWarnings("removal")
protected synchronized OutputStream getOutputStream() throws IOException {
synchronized (fdLock) {
if (isClosedOrPending())
throw new IOException("Socket Closed");
if (shut_wr)
throw new IOException("Socket output is shutdown");
if (socketOutputStream == null) {
PrivilegedExceptionAction<SocketOutputStream> pa = () -> new SocketOutputStream(this);
try {
socketOutputStream = AccessController.doPrivileged(pa);
} catch (PrivilegedActionException e) {
throw (IOException) e.getCause();
}
}
}
return socketOutputStream;
}
void setFileDescriptor(FileDescriptor fd) {
this.fd = fd;
}
void setAddress(InetAddress address) {
this.address = address;
}
void setPort(int port) {
this.port = port;
}
void setLocalPort(int localport) {
this.localport = localport;
}
/**
* Returns the number of bytes that can be read without blocking.
*/
protected synchronized int available() throws IOException {
if (isClosedOrPending()) {
throw new IOException("Stream closed.");
}
/*
* If connection has been reset or shut down for input, then return 0
* to indicate there are no buffered bytes.
*/
if (isConnectionReset() || shut_rd) {
return 0;
}
/*
* If no bytes available and we were previously notified
* of a connection reset then we move to the reset state.
*
* If are notified of a connection reset then check
* again if there are bytes buffered on the socket.
*/
int n = 0;
try {
n = socketAvailable();
} catch (ConnectionResetException exc1) {
setConnectionReset();
}
return n;
}
/**
* Closes the socket.
*/
protected void close() throws IOException {
synchronized(fdLock) {
if (fd != null) {
if (fdUseCount == 0) {
if (closePending) {
return;
}
closePending = true;
/*
* We close the FileDescriptor in two-steps - first the
* "pre-close" which closes the socket but doesn't
* release the underlying file descriptor. This operation
* may be lengthy due to untransmitted data and a long
* linger interval. Once the pre-close is done we do the
* actual socket to release the fd.
*/
try {
socketPreClose();
} finally {
socketClose();
}
fd = null;
return;
} else {
/*
* If a thread has acquired the fd and a close
* isn't pending then use a deferred close.
* Also decrement fdUseCount to signal the last
* thread that releases the fd to close it.
*/
if (!closePending) {
closePending = true;
fdUseCount--;
socketPreClose();
}
}
}
}
}
void reset() {
throw new InternalError("should not get here");
}
/**
* Shutdown read-half of the socket connection;
*/
protected void shutdownInput() throws IOException {
if (fd != null) {
socketShutdown(SHUT_RD);
if (socketInputStream != null) {
socketInputStream.setEOF(true);
}
shut_rd = true;
}
}
/**
* Shutdown write-half of the socket connection;
*/
protected void shutdownOutput() throws IOException {
if (fd != null) {
socketShutdown(SHUT_WR);
shut_wr = true;
}
}
protected boolean supportsUrgentData () {
return true;
}
protected void sendUrgentData (int data) throws IOException {
if (fd == null) {
throw new IOException("Socket Closed");
}
socketSendUrgentData (data);
}
/*
* "Acquires" and returns the FileDescriptor for this impl
*
* A corresponding releaseFD is required to "release" the
* FileDescriptor.
*/
FileDescriptor acquireFD() {
synchronized (fdLock) {
fdUseCount++;
return fd;
}
}
/*
* "Release" the FileDescriptor for this impl.
*
* If the use count goes to -1 then the socket is closed.
*/
void releaseFD() {
synchronized (fdLock) {
fdUseCount--;
if (fdUseCount == -1) {
if (fd != null) {
try {
socketClose();
} catch (IOException e) {
} finally {
fd = null;
}
}
}
}
}
boolean isConnectionReset() {
return connectionReset;
}
void setConnectionReset() {
connectionReset = true;
}
/*
* Return true if already closed or close is pending
*/
public boolean isClosedOrPending() {
/*
* Lock on fdLock to ensure that we wait if a
* close is in progress.
*/
synchronized (fdLock) {
if (closePending || (fd == null)) {
return true;
} else {
return false;
}
}
}
/*
* Return the current value of SO_TIMEOUT
*/
public int getTimeout() {
return timeout;
}
/*
* "Pre-close" a socket by dup'ing the file descriptor - this enables
* the socket to be closed without releasing the file descriptor.
*/
private void socketPreClose() throws IOException {
socketClose0(true);
}
/*
* Close the socket (and release the file descriptor).
*/
protected void socketClose() throws IOException {
SocketCleanable.unregister(fd);
try {
socketClose0(false);
} finally {
if (!stream) {
ResourceManager.afterUdpClose();
}
}
}
abstract void socketCreate(boolean stream) throws IOException;
abstract void socketConnect(InetAddress address, int port, int timeout)
throws IOException;
abstract void socketBind(InetAddress address, int port)
throws IOException;
abstract void socketListen(int count)
throws IOException;
abstract void socketAccept(SocketImpl s)
throws IOException;
abstract int socketAvailable()
throws IOException;
abstract void socketClose0(boolean useDeferredClose)
throws IOException;
abstract void socketShutdown(int howto)
throws IOException;
abstract void socketSetOption(int cmd, boolean on, Object value)
throws SocketException;
abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
abstract void socketSendUrgentData(int data)
throws IOException;
public static final int SHUT_RD = 0;
public static final int SHUT_WR = 1;
private static native boolean isReusePortAvailable0();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2021, 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
@ -52,14 +52,6 @@ package java.net;
public final
class DatagramPacket {
/**
* Perform class initialization
*/
static {
jdk.internal.loader.BootLoader.loadLibrary("net");
init();
}
/*
* The fields of this class are package-private since DatagramSocketImpl
* classes needs to access them.
@ -424,9 +416,4 @@ class DatagramPacket {
this.length = length;
this.bufLength = this.length;
}
/**
* Perform class load-time initializations.
*/
private static native void init();
}

View File

@ -31,6 +31,7 @@ import java.nio.channels.DatagramChannel;
import java.nio.channels.MulticastChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import java.util.Set;
import sun.net.NetProperties;
import sun.nio.ch.DefaultSelectorProvider;
@ -1338,14 +1339,6 @@ public class DatagramSocket implements java.io.Closeable {
// Temporary solution until JDK-8237352 is addressed
private static final SocketAddress NO_DELEGATE = new SocketAddress() {};
private static final boolean USE_PLAINDATAGRAMSOCKET = usePlainDatagramSocketImpl();
private static boolean usePlainDatagramSocketImpl() {
PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainDatagramSocketImpl");
@SuppressWarnings("removal")
String s = AccessController.doPrivileged(pa);
return (s != null) && (s.isEmpty() || s.equalsIgnoreCase("true"));
}
/**
* Best effort to convert an {@link IOException}
@ -1398,14 +1391,11 @@ public class DatagramSocket implements java.io.Closeable {
boolean initialized = false;
try {
DatagramSocketImplFactory factory = DatagramSocket.factory;
if (USE_PLAINDATAGRAMSOCKET || factory != null) {
if (factory != null) {
// create legacy DatagramSocket delegate
DatagramSocketImpl impl;
if (factory != null) {
impl = factory.createDatagramSocketImpl();
} else {
impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(multicast);
}
DatagramSocketImpl impl = factory.createDatagramSocketImpl();
Objects.requireNonNull(impl,
"Implementation returned by installed DatagramSocketImplFactory is null");
delegate = new NetMulticastSocket(impl);
((NetMulticastSocket) delegate).getImpl(); // ensure impl.create() is called.
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2021, 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
@ -33,24 +33,6 @@ import java.util.Set;
/**
* Abstract datagram and multicast socket implementation base class.
*
* @implNote Sockets created with the {@code DatagramSocket} and {@code
* MulticastSocket} public constructors historically delegated all socket
* operations to a {@code DatagramSocketImpl} implementation named
* "PlainDatagramSocketImpl". {@code DatagramSocket} and {@code MulticastSocket}
* have since been changed to a new implementation based on {@code DatagramChannel}.
* The JDK continues to ship with the older implementation to allow code to run
* that depends on unspecified behavior that differs between the old and new
* implementations. The old implementation will be used if the Java virtual
* machine is started with the system property {@systemProperty
* jdk.net.usePlainDatagramSocketImpl} set to use the old implementation. It may
* also be set in the JDK's network configuration file, located in {@code
* ${java.home}/conf/net.properties}. The value of the property is the string
* representation of a boolean. If set without a value then it defaults to {@code
* true}, hence running with {@code -Djdk.net.usePlainDatagramSocketImpl} or
* {@code -Djdk.net.usePlainDatagramSocketImpl=true} will configure the Java
* virtual machine to use the old implementation. The property and old
* implementation will be removed in a future version.
*
* @author Pavani Diwanji
* @since 1.1
*/

View File

@ -136,8 +136,7 @@ final class NetMulticastSocket extends MulticastSocket {
bind(new InetSocketAddress(0));
// old impls do not support connect/disconnect
if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
((AbstractPlainDatagramSocketImpl) impl).nativeConnectDisabled())) {
if (oldImpl) {
connectState = ST_CONNECTED_NO_IMPL;
} else {
try {

View File

@ -1,119 +0,0 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.ref.PhantomCleanable;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.ref.Cleaner;
import sun.net.ResourceManager;
/**
* Cleanable for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
* Create a cleanup if the raw fd != -1. Windows closes sockets using the fd.
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the socket fd is closed by any means
* other than calling {@link FileDescriptor#close}.
* Otherwise, it might incorrectly close the handle or fd after it has been reused.
*/
final class SocketCleanable extends PhantomCleanable<FileDescriptor> {
// Access to FileDescriptor private fields
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
// Native function to call NET_SocketClose(fd)
// Used only for last chance cleanup.
private static native void cleanupClose0(int fd) throws IOException;
// The raw fd to close
private final int fd;
// true for socket, false for datagram socket
private final boolean stream;
/**
* Register a socket specific Cleanable with the FileDescriptor
* if the FileDescriptor is non-null and the raw fd is != -1.
*
* @param fdo the FileDescriptor; may be null
* @param stream false for datagram socket
*/
static void register(FileDescriptor fdo, boolean stream) {
if (fdo != null && fdo.valid()) {
int fd = fdAccess.get(fdo);
fdAccess.registerCleanup(fdo,
new SocketCleanable(fdo, CleanerFactory.cleaner(),
fd, stream));
}
}
/**
* Unregister a Cleanable from the FileDescriptor.
* @param fdo the FileDescriptor; may be null
*/
static void unregister(FileDescriptor fdo) {
if (fdo != null) {
fdAccess.unregisterCleanup(fdo);
}
}
/**
* Constructor for a phantom cleanable reference.
*
* @param obj the object to monitor
* @param cleaner the cleaner
* @param fd file descriptor to close
* @param stream false for datagram socket
*/
private SocketCleanable(FileDescriptor obj, Cleaner cleaner,
int fd, boolean stream) {
super(obj, cleaner);
this.fd = fd;
this.stream = stream;
}
/**
* Close the native handle or fd.
*/
@Override
protected void performCleanup() {
try {
cleanupClose0(fd);
} catch (IOException ioe) {
throw new UncheckedIOException("close", ioe);
} finally {
if (!stream) {
ResourceManager.afterUdpClose();
}
}
}
}

View File

@ -29,12 +29,9 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import java.util.Set;
import sun.net.NetProperties;
import sun.net.PlatformSocketImpl;
import sun.nio.ch.NioSocketImpl;
@ -43,45 +40,16 @@ import sun.nio.ch.NioSocketImpl;
* of all classes that actually implement sockets. It is used to
* create both client and server sockets.
*
* @implNote Client and server sockets created with the {@code Socket} and
* {@code SocketServer} public constructors create a system-default
* {@code SocketImpl}. The JDK historically used a {@code SocketImpl}
* implementation type named "PlainSocketImpl" that has since been replaced by a
* newer implementation. The JDK continues to ship with the older implementation
* to allow code to run that depends on unspecified behavior that differs between
* the old and new implementations. The old implementation will be used if the
* Java virtual machine is started with the system property {@systemProperty
* jdk.net.usePlainSocketImpl} set to use the old implementation. It may also be
* set in the JDK's network configuration file, located in {@code
* ${java.home}/conf/net.properties}. The value of the property is the string
* representation of a boolean. If set without a value then it defaults to {@code
* true}, hence running with {@code -Djdk.net.usePlainSocketImpl} or {@code
* -Djdk.net.usePlainSocketImpl=true} will configure the Java virtual machine
* to use the old implementation. The property and old implementation will be
* removed in a future version.
*
* @since 1.0
*/
public abstract class SocketImpl implements SocketOptions {
private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();
private static boolean usePlainSocketImpl() {
PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainSocketImpl");
@SuppressWarnings("removal")
String s = AccessController.doPrivileged(pa);
return (s != null) && !s.equalsIgnoreCase("false");
}
/**
* Creates an instance of platform's SocketImpl
*/
@SuppressWarnings("unchecked")
static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {
if (USE_PLAINSOCKETIMPL) {
return (S) new PlainSocketImpl(server);
} else {
return (S) new NioSocketImpl(server);
}
return (S) new NioSocketImpl(server);
}
/**

View File

@ -1,250 +0,0 @@
/*
* Copyright (c) 1995, 2021, 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 java.net;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import sun.net.ConnectionResetException;
/**
* This stream extends FileInputStream to implement a
* SocketInputStream. Note that this class should <b>NOT</b> be
* public.
*
* @author Jonathan Payne
* @author Arthur van Hoff
*/
class SocketInputStream extends FileInputStream {
static {
init();
}
private boolean eof;
private AbstractPlainSocketImpl impl = null;
private byte temp[];
/**
* Creates a new SocketInputStream. Can only be called
* by a Socket. This method needs to hang on to the owner Socket so
* that the fd will not be closed.
* @param impl the implemented socket input stream
*/
SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file input stream.</p>
*
* The {@code getChannel} method of {@code SocketInputStream}
* returns {@code null} since it is a socket based stream.</p>
*
* @return the file channel associated with this file input stream
*
* @since 1.4
*/
public final FileChannel getChannel() {
return null;
}
/**
* Reads into an array of bytes at the specified offset using
* the received socket primitive.
* @param fd the FileDescriptor
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param len the maximum number of bytes read
* @param timeout the read timeout in ms
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @throws IOException If an I/O error has occurred.
*/
private native int socketRead0(FileDescriptor fd,
byte b[], int off, int len,
int timeout)
throws IOException;
// wrap native call to allow instrumentation
/**
* Reads into an array of bytes at the specified offset using
* the received socket primitive.
* @param fd the FileDescriptor
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param len the maximum number of bytes read
* @param timeout the read timeout in ms
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @throws IOException If an I/O error has occurred.
*/
private int socketRead(FileDescriptor fd,
byte b[], int off, int len,
int timeout)
throws IOException {
return socketRead0(fd, b, off, len, timeout);
}
/**
* Reads into a byte array data from the socket.
* @param b the buffer into which the data is read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @throws IOException If an I/O error has occurred.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads into a byte array <i>b</i> at offset <i>off</i>,
* <i>length</i> bytes of data.
* @param b the buffer into which the data is read
* @param off the start offset of the data
* @param length the maximum number of bytes read
* @return the actual number of bytes read, -1 is
* returned when the end of the stream is reached.
* @throws IOException If an I/O error has occurred.
*/
public int read(byte b[], int off, int length) throws IOException {
return read(b, off, length, impl.getTimeout());
}
int read(byte b[], int off, int length, int timeout) throws IOException {
int n;
// EOF already encountered
if (eof) {
return -1;
}
// connection reset
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
// bounds check
if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException("length == " + length
+ " off == " + off + " buffer length == " + b.length);
}
// acquire file descriptor and do the read
FileDescriptor fd = impl.acquireFD();
try {
n = socketRead(fd, b, off, length, timeout);
if (n > 0) {
return n;
}
} catch (ConnectionResetException rstExc) {
impl.setConnectionReset();
} finally {
impl.releaseFD();
}
/*
* If we get here we are at EOF, the socket has been closed,
* or the connection has been reset.
*/
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
}
if (impl.isConnectionReset()) {
throw new SocketException("Connection reset");
}
eof = true;
return -1;
}
/**
* Reads a single byte from the socket.
*/
public int read() throws IOException {
if (eof) {
return -1;
}
temp = new byte[1];
int n = read(temp, 0, 1);
if (n <= 0) {
return -1;
}
return temp[0] & 0xff;
}
/**
* Skips n bytes of input.
* @param numbytes the number of bytes to skip
* @return the actual number of bytes skipped.
* @throws IOException If an I/O error has occurred.
*/
public long skip(long numbytes) throws IOException {
if (numbytes <= 0) {
return 0;
}
long n = numbytes;
int buflen = (int) Math.min(1024, n);
byte data[] = new byte[buflen];
while (n > 0) {
int r = read(data, 0, (int) Math.min((long) buflen, n));
if (r < 0) {
break;
}
n -= r;
}
return numbytes - n;
}
/**
* Returns the number of bytes that can be read without blocking.
* @return the number of immediately available bytes
*/
public int available() throws IOException {
int available = impl.available();
return eof ? 0 : available;
}
void setEOF(boolean eof) {
this.eof = eof;
}
public void close() throws IOException {
// No longer used. Socket.getInputStream returns an
// InputStream which calls Socket.close directly
assert false;
}
/**
* Perform class load-time initializations.
*/
private static native void init();
}

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 1995, 2021, 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 java.net;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
/**
* This stream extends FileOutputStream to implement a
* SocketOutputStream. Note that this class should <b>NOT</b> be
* public.
*
* @author Jonathan Payne
* @author Arthur van Hoff
*/
class SocketOutputStream extends FileOutputStream {
static {
init();
}
private AbstractPlainSocketImpl impl = null;
private byte temp[] = new byte[1];
/**
* Creates a new SocketOutputStream. Can only be called
* by a Socket. This method needs to hang on to the owner Socket so
* that the fd will not be closed.
* @param impl the socket output stream implemented
*/
SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
}
/**
* Returns the unique {@link java.nio.channels.FileChannel FileChannel}
* object associated with this file output stream. </p>
*
* The {@code getChannel} method of {@code SocketOutputStream}
* returns {@code null} since it is a socket based stream.</p>
*
* @return the file channel associated with this file output stream
*
* @since 1.4
*/
public final FileChannel getChannel() {
return null;
}
/**
* Writes to the socket.
* @param fd the FileDescriptor
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @throws IOException If an I/O error has occurred.
*/
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;
/**
* Writes to the socket with appropriate locking of the
* FileDescriptor.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @throws IOException If an I/O error has occurred.
*/
private void socketWrite(byte b[], int off, int len) throws IOException {
if (len <= 0 || off < 0 || len > b.length - off) {
if (len == 0) {
return;
}
throw new ArrayIndexOutOfBoundsException("len == " + len
+ " off == " + off + " buffer length == " + b.length);
}
FileDescriptor fd = impl.acquireFD();
try {
socketWrite0(fd, b, off, len);
} catch (SocketException se) {
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
} else {
throw se;
}
} finally {
impl.releaseFD();
}
}
/**
* Writes a byte to the socket.
* @param b the data to be written
* @throws IOException If an I/O error has occurred.
*/
public void write(int b) throws IOException {
temp[0] = (byte)b;
socketWrite(temp, 0, 1);
}
/**
* Writes the contents of the buffer <i>b</i> to the socket.
* @param b the data to be written
* @throws SocketException If an I/O error has occurred.
*/
public void write(byte b[]) throws IOException {
socketWrite(b, 0, b.length);
}
/**
* Writes <i>length</i> bytes from buffer <i>b</i> starting at
* offset <i>len</i>.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @throws SocketException If an I/O error has occurred.
*/
public void write(byte b[], int off, int len) throws IOException {
socketWrite(b, off, len);
}
public void close() throws IOException {
// No longer used. Socket.getOutputStream returns an
// OutputStream which calls Socket.close directly
assert false;
}
/**
* Perform class load-time initializations.
*/
private static native void init();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@ -252,7 +252,7 @@ public abstract class SocketFactory
// out through firewalls (e.g. SOCKS V4 or V5) or in through them
// (e.g. using SSL), or that some ports are reserved for use with SSL.
//
// Note that at least JDK 1.1 has a low level "plainSocketImpl" that
// Note that at least JDK 1.1 has a low level "SocketImpl" that
// knows about SOCKS V4 tunneling, so this isn't a totally bogus default.
//
// ALSO: we may want to expose this class somewhere so other folk

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -64,9 +64,6 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS;
/**
* NIO based SocketImpl.
*
* This implementation attempts to be compatible with legacy PlainSocketImpl,
* including behavior and exceptions that are not specified by SocketImpl.
*
* The underlying socket used by this SocketImpl is initially configured
* blocking. If the connect method is used to establish a connection with a
* timeout then the socket is configured non-blocking for the connect attempt,
@ -641,8 +638,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp
throw new SocketException("Already bound");
NetHooks.beforeTcpBind(fd, host, port);
Net.bind(fd, host, port);
// set the address field to the given host address to keep
// compatibility with PlainSocketImpl. When binding to 0.0.0.0
// set the address field to the given host address to
// maintain long standing behavior. When binding to 0.0.0.0
// then the actual local address will be ::0 when IPv6 is enabled.
address = host;
localport = Net.localAddress(fd).getPort();

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 1997, 2002, 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 "java_net_DatagramPacket.h"
#include "net_util.h"
/************************************************************************
* DatagramPacket
*/
jfieldID dp_addressID;
jfieldID dp_portID;
jfieldID dp_bufID;
jfieldID dp_offsetID;
jfieldID dp_lengthID;
jfieldID dp_bufLengthID;
/*
* Class: java_net_DatagramPacket
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_DatagramPacket_init (JNIEnv *env, jclass cls) {
dp_addressID = (*env)->GetFieldID(env, cls, "address",
"Ljava/net/InetAddress;");
CHECK_NULL(dp_addressID);
dp_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(dp_portID);
dp_bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
CHECK_NULL(dp_bufID);
dp_offsetID = (*env)->GetFieldID(env, cls, "offset", "I");
CHECK_NULL(dp_offsetID);
dp_lengthID = (*env)->GetFieldID(env, cls, "length", "I");
CHECK_NULL(dp_lengthID);
dp_bufLengthID = (*env)->GetFieldID(env, cls, "bufLength", "I");
CHECK_NULL(dp_bufLengthID);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@ -45,7 +45,6 @@
*
* The naming convention for field IDs is
* <class abbrv>_<fieldName>ID
* i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID.
*/
extern jclass ia_class;
extern jfieldID iac_addressID;
@ -84,13 +83,6 @@ extern jfieldID ni_addrsID;
extern jfieldID ni_descID;
extern jmethodID ni_ctrID;
/* PlainSocketImpl fields */
extern jfieldID psi_timeoutID;
extern jfieldID psi_fdID;
extern jfieldID psi_addressID;
extern jfieldID psi_portID;
extern jfieldID psi_localportID;
/* DatagramPacket fields */
extern jfieldID dp_addressID;
extern jfieldID dp_portID;

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import sun.security.action.GetPropertyAction;
/**
* This class defines a factory for creating DatagramSocketImpls. It defaults
* to creating plain DatagramSocketImpls, but may create other DatagramSocketImpls
* by setting the impl.prefix system property.
*
* @author Chris Hegarty
*/
class DefaultDatagramSocketImplFactory {
static Class<?> prefixImplClass = null;
static {
String prefix = null;
try {
prefix = GetPropertyAction.privilegedGetProperty("impl.prefix");
if (prefix != null)
prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
} catch (Exception e) {
System.err.println("Can't find class: java.net." +
prefix +
"DatagramSocketImpl: check impl.prefix property");
//prefixImplClass = null;
}
}
/**
* Creates a new <code>DatagramSocketImpl</code> instance.
*
* @param isMulticast true if this impl if for a MutlicastSocket
* @return a new instance of a <code>DatagramSocketImpl</code>.
*/
static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast /*unused on unix*/)
throws SocketException {
if (prefixImplClass != null) {
try {
@SuppressWarnings("deprecation")
DatagramSocketImpl result = (DatagramSocketImpl)prefixImplClass.newInstance();
return result;
} catch (Exception e) {
throw new SocketException("can't instantiate DatagramSocketImpl");
}
} else {
return new java.net.PlainDatagramSocketImpl(isMulticast);
}
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
*
* @author Chris Hegarty
*/
class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
PlainDatagramSocketImpl(boolean isMulticast) {
super(isMulticast);
}
static {
init();
}
protected void socketSetOption(int opt, Object val) throws SocketException {
if (opt == SocketOptions.SO_REUSEPORT &&
!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
socketSetOption0(opt, val);
} catch (SocketException se) {
if (!connected)
throw se;
}
}
protected synchronized native void bind0(int lport, InetAddress laddr)
throws SocketException;
protected native void send0(DatagramPacket p) throws IOException;
protected synchronized native int peek(InetAddress i) throws IOException;
protected synchronized native int peekData(DatagramPacket p) throws IOException;
protected synchronized native void receive0(DatagramPacket p)
throws IOException;
protected native void setTimeToLive(int ttl) throws IOException;
protected native int getTimeToLive() throws IOException;
@Deprecated
protected native void setTTL(byte ttl) throws IOException;
@Deprecated
protected native byte getTTL() throws IOException;
protected native void join(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
protected native void leave(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
protected native void datagramSocketCreate() throws SocketException;
protected native void datagramSocketClose();
protected native void socketSetOption0(int opt, Object val)
throws SocketException;
protected native Object socketGetOption(int opt) throws SocketException;
protected native void connect0(InetAddress address, int port) throws SocketException;
protected native void disconnect0(int family);
native int dataAvailable();
/**
* Perform class load-time initializations.
*/
private static native void init();
}

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import java.io.IOException;
import java.util.Set;
import java.util.HashSet;
import sun.net.ext.ExtendedSocketOptions;
/*
* On Unix systems we simply delegate to native methods.
*
* @author Chris Hegarty
*/
class PlainSocketImpl extends AbstractPlainSocketImpl
{
static {
initProto();
}
/**
* Constructs an empty instance.
*/
PlainSocketImpl(boolean isServer) {
super(isServer);
}
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
if (opt == SocketOptions.SO_REUSEPORT &&
!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option");
}
try {
socketSetOption0(opt, b, val);
} catch (SocketException se) {
if (!isConnected)
throw se;
}
}
void socketCreate(boolean stream) throws IOException {
socketCreate(stream, isServer);
}
native void socketCreate(boolean stream, boolean isServer) throws IOException;
native void socketConnect(InetAddress address, int port, int timeout)
throws IOException;
native void socketBind(InetAddress address, int port)
throws IOException;
native void socketListen(int count) throws IOException;
native void socketAccept(SocketImpl s) throws IOException;
native int socketAvailable() throws IOException;
native void socketClose0(boolean useDeferredClose) throws IOException;
native void socketShutdown(int howto) throws IOException;
static native void initProto();
native void socketSetOption0(int cmd, boolean on, Object value)
throws SocketException;
native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
native void socketSendUrgentData(int data) throws IOException;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,994 +0,0 @@
/*
* Copyright (c) 1997, 2020, 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 <errno.h>
#include "jvm.h"
#include "net_util.h"
#include "java_net_SocketOptions.h"
#include "java_net_PlainSocketImpl.h"
/************************************************************************
* PlainSocketImpl
*/
static jfieldID IO_fd_fdID;
jfieldID psi_fdID;
jfieldID psi_addressID;
jfieldID psi_ipaddressID;
jfieldID psi_portID;
jfieldID psi_localportID;
jfieldID psi_timeoutID;
jfieldID psi_trafficClassID;
jfieldID psi_fdLockID;
jfieldID psi_closePendingID;
/*
* file descriptor used for dup2
*/
static int marker_fd = -1;
#define SET_NONBLOCKING(fd) { \
int flags = fcntl(fd, F_GETFL); \
flags |= O_NONBLOCK; \
fcntl(fd, F_SETFL, flags); \
}
#define SET_BLOCKING(fd) { \
int flags = fcntl(fd, F_GETFL); \
flags &= ~O_NONBLOCK; \
fcntl(fd, F_SETFL, flags); \
}
/*
* Create the marker file descriptor by establishing a loopback connection
* which we shutdown but do not close the fd. The result is an fd that
* can be used for read/write.
*/
static int getMarkerFD()
{
int sv[2];
#ifdef AF_UNIX
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
return -1;
}
#else
return -1;
#endif
/*
* Finally shutdown sv[0] (any reads to this fd will get
* EOF; any writes will get an error).
*/
shutdown(sv[0], 2);
close(sv[1]);
return sv[0];
}
/*
* Return the file descriptor given a PlainSocketImpl
*/
static int getFD(JNIEnv *env, jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
CHECK_NULL_RETURN(fdObj, -1);
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
/*
* The initroto function is called whenever PlainSocketImpl is
* loaded, to cache field IDs for efficiency. This is called every time
* the Java class is loaded.
*
* Class: java_net_PlainSocketImpl
* Method: initProto
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_initProto(JNIEnv *env, jclass cls) {
psi_fdID = (*env)->GetFieldID(env, cls , "fd",
"Ljava/io/FileDescriptor;");
CHECK_NULL(psi_fdID);
psi_addressID = (*env)->GetFieldID(env, cls, "address",
"Ljava/net/InetAddress;");
CHECK_NULL(psi_addressID);
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(psi_portID);
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
CHECK_NULL(psi_localportID);
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
CHECK_NULL(psi_timeoutID);
psi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
CHECK_NULL(psi_trafficClassID);
psi_fdLockID = (*env)->GetFieldID(env, cls, "fdLock",
"Ljava/lang/Object;");
CHECK_NULL(psi_fdLockID);
psi_closePendingID = (*env)->GetFieldID(env, cls, "closePending", "Z");
CHECK_NULL(psi_closePendingID);
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
initInetAddressIDs(env);
JNU_CHECK_EXCEPTION(env);
/* Create the marker fd used for dup2 */
marker_fd = getMarkerFD();
}
/* a global reference to the java.net.SocketException class. In
* socketCreate, we ensure that this is initialized. This is to
* prevent the problem where socketCreate runs out of file
* descriptors, and is then unable to load the exception class.
*/
static jclass socketExceptionCls;
/*
* Class: java_net_PlainSocketImpl
* Method: socketCreate
* Signature: (ZZ)V */
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
jboolean stream, jboolean isServer) {
jobject fdObj, ssObj;
int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
int domain = ipv6_available() ? AF_INET6 : AF_INET;
if (socketExceptionCls == NULL) {
jclass c = (*env)->FindClass(env, "java/net/SocketException");
CHECK_NULL(c);
socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
CHECK_NULL(socketExceptionCls);
}
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
if (fdObj == NULL) {
(*env)->ThrowNew(env, socketExceptionCls, "null fd object");
return;
}
if ((fd = socket(domain, type, 0)) == -1) {
/* note: if you run out of fds, you may not be able to load
* the exception class, and get a NoClassDefFoundError
* instead.
*/
NET_ThrowNew(env, errno, "can't create socket");
return;
}
/*
* If IPv4 is available, disable IPV6_V6ONLY to ensure dual-socket support.
*/
if (domain == AF_INET6 && ipv4_available()) {
int arg = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
sizeof(int)) < 0) {
NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
close(fd);
return;
}
}
/*
* If this is a server socket then enable SO_REUSEADDR
* automatically and set to non blocking.
*/
if (isServer) {
int arg = 1;
SET_NONBLOCKING(fd);
if (NET_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
sizeof(arg)) < 0) {
NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
close(fd);
return;
}
}
(*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
}
/*
* inetAddress is the address object passed to the socket connect
* call.
*
* Class: java_net_PlainSocketImpl
* Method: socketConnect
* Signature: (Ljava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
jobject iaObj, jint port,
jint timeout)
{
jint localport = (*env)->GetIntField(env, this, psi_localportID);
int len = 0;
/* fdObj is the FileDescriptor field on this */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
jclass clazz = (*env)->GetObjectClass(env, this);
jobject fdLock;
jint trafficClass = (*env)->GetIntField(env, this, psi_trafficClassID);
/* fd is an int field on iaObj */
jint fd;
SOCKETADDRESS sa;
/* The result of the connection */
int connect_rv = -1;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (IS_NULL(iaObj)) {
JNU_ThrowNullPointerException(env, "inet address argument null.");
return;
}
/* connect */
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa, &len,
JNI_TRUE) != 0) {
return;
}
if (trafficClass != 0 && ipv6_available()) {
NET_SetTrafficClass(&sa, trafficClass);
}
if (timeout <= 0) {
connect_rv = NET_Connect(fd, &sa.sa, len);
} else {
/*
* A timeout was specified. We put the socket into non-blocking
* mode, connect, and then wait for the connection to be
* established, fail, or timeout.
*/
SET_NONBLOCKING(fd);
/* no need to use NET_Connect as non-blocking */
connect_rv = connect(fd, &sa.sa, len);
/* connection not established immediately */
if (connect_rv != 0) {
socklen_t optlen;
jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC;
jlong prevNanoTime = JVM_NanoTime(env, 0);
if (errno != EINPROGRESS) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
"connect failed");
SET_BLOCKING(fd);
return;
}
/*
* Wait for the connection to be established or a
* timeout occurs. poll needs to handle EINTR in
* case lwp sig handler redirects any process signals to
* this thread.
*/
while (1) {
jlong newNanoTime;
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLOUT;
errno = 0;
connect_rv = NET_Poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC);
if (connect_rv >= 0) {
break;
}
if (errno != EINTR) {
break;
}
/*
* The poll was interrupted so adjust timeout and
* restart
*/
newNanoTime = JVM_NanoTime(env, 0);
nanoTimeout -= (newNanoTime - prevNanoTime);
if (nanoTimeout < NET_NSEC_PER_MSEC) {
connect_rv = 0;
break;
}
prevNanoTime = newNanoTime;
} /* while */
if (connect_rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"connect timed out");
/*
* Timeout out but connection may still be established.
* At the high level it should be closed immediately but
* just in case we make the socket blocking again and
* shutdown input & output.
*/
SET_BLOCKING(fd);
shutdown(fd, 2);
return;
}
/* has connection been established */
optlen = sizeof(connect_rv);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
&optlen) <0) {
connect_rv = errno;
}
}
/* make socket blocking again */
SET_BLOCKING(fd);
/* restore errno */
if (connect_rv != 0) {
errno = connect_rv;
connect_rv = -1;
}
}
/* report the appropriate exception */
if (connect_rv < 0) {
#ifdef __linux__
/*
* Linux/GNU distribution setup /etc/hosts so that
* InetAddress.getLocalHost gets back the loopback address
* rather than the host address. Thus a socket can be
* bound to the loopback address and the connect will
* fail with EADDRNOTAVAIL. In addition the Linux kernel
* returns the wrong error in this case - it returns EINVAL
* instead of EADDRNOTAVAIL. We handle this here so that
* a more descriptive exception text is used.
*/
if (connect_rv == -1 && errno == EINVAL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Invalid argument or cannot assign requested address");
return;
}
#endif
#if defined(EPROTO)
if (errno == EPROTO) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ProtocolException",
"Protocol error");
return;
}
#endif
if (errno == ECONNREFUSED) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
"Connection refused");
} else if (errno == ETIMEDOUT) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
"Connection timed out");
} else if (errno == EHOSTUNREACH) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
"Host unreachable");
} else if (errno == EADDRNOTAVAIL) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
"Address not available");
} else if ((errno == EISCONN) || (errno == EBADF)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "connect failed");
}
return;
}
(*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
/* set the remote peer address and port */
(*env)->SetObjectField(env, this, psi_addressID, iaObj);
(*env)->SetIntField(env, this, psi_portID, port);
/*
* we need to initialize the local port field if bind was called
* previously to the connect (by the client) then localport field
* will already be initialized
*/
if (localport == 0) {
/* Now that we're a connected socket, let's extract the port number
* that the system chose for us and store it in the Socket object.
*/
socklen_t slen = sizeof(SOCKETADDRESS);
if (getsockname(fd, &sa.sa, &slen) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
} else {
localport = NET_GetPortFromSockaddr(&sa);
(*env)->SetIntField(env, this, psi_localportID, localport);
}
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketBind
* Signature: (Ljava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketBind(JNIEnv *env, jobject this,
jobject iaObj, jint localport) {
/* fdObj is the FileDescriptor field on this */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
/* fd is an int field on fdObj */
int fd;
int len = 0;
SOCKETADDRESS sa;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (IS_NULL(iaObj)) {
JNU_ThrowNullPointerException(env, "iaObj is null.");
return;
}
/* bind */
if (NET_InetAddressToSockaddr(env, iaObj, localport, &sa,
&len, JNI_TRUE) != 0) {
return;
}
if (NET_Bind(fd, &sa, len) < 0) {
if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
errno == EPERM || errno == EACCES) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
"Bind failed");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Bind failed");
}
return;
}
/* set the address */
(*env)->SetObjectField(env, this, psi_addressID, iaObj);
/* initialize the local port */
if (localport == 0) {
socklen_t slen = sizeof(SOCKETADDRESS);
/* Now that we're a connected socket, let's extract the port number
* that the system chose for us and store it in the Socket object.
*/
if (getsockname(fd, &sa.sa, &slen) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return;
}
localport = NET_GetPortFromSockaddr(&sa);
(*env)->SetIntField(env, this, psi_localportID, localport);
} else {
(*env)->SetIntField(env, this, psi_localportID, localport);
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketListen
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketListen(JNIEnv *env, jobject this,
jint count)
{
/* this FileDescriptor fd field */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
/* fdObj's int fd field */
int fd;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
/*
* Workaround for bugid 4101691 in Solaris 2.6. See 4106600.
* If listen backlog is Integer.MAX_VALUE then subtract 1.
*/
if (count == 0x7fffffff)
count -= 1;
if (listen(fd, count) == -1) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Listen failed");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketAccept
* Signature: (Ljava/net/SocketImpl;)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
jobject socket)
{
/* fields on this */
int port;
jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
jlong prevNanoTime = 0;
jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC;
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
/* the FileDescriptor field on socket */
jobject socketFdObj;
/* the InetAddress field on socket */
jobject socketAddressObj;
/* the ServerSocket fd int field on fdObj */
jint fd;
/* accepted fd */
jint newfd;
SOCKETADDRESS sa;
socklen_t slen = sizeof(SOCKETADDRESS);
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (IS_NULL(socket)) {
JNU_ThrowNullPointerException(env, "socket is null");
return;
}
/*
* accept connection but ignore ECONNABORTED indicating that
* connection was eagerly accepted by the OS but was reset
* before accept() was called.
*
* If accept timeout in place and timeout is adjusted with
* each ECONNABORTED or EWOULDBLOCK or EAGAIN to ensure that
* semantics of timeout are preserved.
*/
for (;;) {
int ret;
jlong currNanoTime;
/* first usage pick up current time */
if (prevNanoTime == 0 && nanoTimeout > 0) {
prevNanoTime = JVM_NanoTime(env, 0);
}
/* passing a timeout of 0 to poll will return immediately,
but in the case of ServerSocket 0 means infinite. */
if (timeout <= 0) {
ret = NET_Timeout(env, fd, -1, 0);
} else {
ret = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime);
}
if (ret == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"Accept timed out");
return;
} else if (ret == -1) {
if (errno == EBADF) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
} else if (errno == ENOMEM) {
JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Accept failed");
}
return;
}
newfd = NET_Accept(fd, &sa.sa, &slen);
/* connection accepted */
if (newfd >= 0) {
SET_BLOCKING(newfd);
break;
}
/* non (ECONNABORTED or EWOULDBLOCK or EAGAIN) error */
if (!(errno == ECONNABORTED || errno == EWOULDBLOCK || errno == EAGAIN)) {
break;
}
/* ECONNABORTED or EWOULDBLOCK or EAGAIN error so adjust timeout if there is one. */
if (nanoTimeout >= NET_NSEC_PER_MSEC) {
currNanoTime = JVM_NanoTime(env, 0);
nanoTimeout -= (currNanoTime - prevNanoTime);
if (nanoTimeout < NET_NSEC_PER_MSEC) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"Accept timed out");
return;
}
prevNanoTime = currNanoTime;
}
}
if (newfd < 0) {
if (newfd == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
} else {
if (errno == EINVAL) {
errno = EBADF;
}
if (errno == EBADF) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Accept failed");
}
}
return;
}
/*
* fill up the remote peer port and address in the new socket structure.
*/
socketAddressObj = NET_SockaddrToInetAddress(env, &sa, &port);
if (socketAddressObj == NULL) {
/* should be pending exception */
close(newfd);
return;
}
/*
* Populate SocketImpl.fd.fd
*/
socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, newfd);
(*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
(*env)->SetIntField(env, socket, psi_portID, port);
/* also fill up the local port information */
port = (*env)->GetIntField(env, this, psi_localportID);
(*env)->SetIntField(env, socket, psi_localportID, port);
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_java_net_PlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
int count = 0;
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
jint fd;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (NET_SocketAvailable(fd, &count) != 0) {
if (errno == ECONNRESET) {
JNU_ThrowByName(env, "sun/net/ConnectionResetException", "");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "ioctl FIONREAD failed");
}
}
return (jint) count;
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketClose0
* Signature: (Z)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
jboolean useDeferredClose) {
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
jint fd;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"socket already closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (fd != -1) {
if (useDeferredClose && marker_fd >= 0) {
NET_Dup2(marker_fd, fd);
} else {
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
NET_SocketClose(fd);
}
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketShutdown
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
jint howto)
{
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
jint fd;
/*
* WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
* -1 already?
*/
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"socket already closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
shutdown(fd, howto);
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketSetOption0
* Signature: (IZLjava/lang/Object;)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketSetOption0
(JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
{
int fd;
int level, optname, optlen;
union {
int i;
struct linger ling;
} optval;
/*
* Check that socket hasn't been closed
*/
fd = getFD(env, this);
if (fd < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
}
/*
* SO_TIMEOUT is a NOOP on Solaris/Linux
*/
if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
return;
}
/*
* Map the Java level socket option to the platform specific
* level and option name.
*/
if (NET_MapSocketOption(cmd, &level, &optname)) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return;
}
switch (cmd) {
case java_net_SocketOptions_SO_SNDBUF :
case java_net_SocketOptions_SO_RCVBUF :
case java_net_SocketOptions_SO_LINGER :
case java_net_SocketOptions_IP_TOS :
{
jclass cls;
jfieldID fid;
cls = (*env)->FindClass(env, "java/lang/Integer");
CHECK_NULL(cls);
fid = (*env)->GetFieldID(env, cls, "value", "I");
CHECK_NULL(fid);
if (cmd == java_net_SocketOptions_SO_LINGER) {
if (on) {
optval.ling.l_onoff = 1;
optval.ling.l_linger = (*env)->GetIntField(env, value, fid);
} else {
optval.ling.l_onoff = 0;
optval.ling.l_linger = 0;
}
optlen = sizeof(optval.ling);
} else {
optval.i = (*env)->GetIntField(env, value, fid);
optlen = sizeof(optval.i);
}
break;
}
/* Boolean -> int */
default :
optval.i = (on ? 1 : 0);
optlen = sizeof(optval.i);
}
if (NET_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
#if defined(_AIX)
if (errno == EINVAL) {
// On AIX setsockopt will set errno to EINVAL if the socket
// is closed. The default error message is then confusing
char fullMsg[128];
jio_snprintf(fullMsg, sizeof(fullMsg), "Invalid option or socket reset by remote peer");
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg);
return;
}
#endif /* _AIX */
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketGetOption
* Signature: (ILjava/lang/Object;)I
*/
JNIEXPORT jint JNICALL
Java_java_net_PlainSocketImpl_socketGetOption
(JNIEnv *env, jobject this, jint cmd, jobject iaContainerObj)
{
int fd;
int level, optname, optlen;
union {
int i;
struct linger ling;
} optval;
/*
* Check that socket hasn't been closed
*/
fd = getFD(env, this);
if (fd < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
/*
* SO_BINDADDR isn't a socket option
*/
if (cmd == java_net_SocketOptions_SO_BINDADDR) {
SOCKETADDRESS sa;
socklen_t len = sizeof(SOCKETADDRESS);
int port;
jobject iaObj;
jclass iaCntrClass;
jfieldID iaFieldID;
if (getsockname(fd, &sa.sa, &len) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
return -1;
}
iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
CHECK_NULL_RETURN(iaObj, -1);
iaCntrClass = (*env)->GetObjectClass(env, iaContainerObj);
iaFieldID = (*env)->GetFieldID(env, iaCntrClass, "addr", "Ljava/net/InetAddress;");
CHECK_NULL_RETURN(iaFieldID, -1);
(*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
return 0; /* notice change from before */
}
/*
* Map the Java level socket option to the platform specific
* level and option name.
*/
if (NET_MapSocketOption(cmd, &level, &optname)) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return -1;
}
/*
* Args are int except for SO_LINGER
*/
if (cmd == java_net_SocketOptions_SO_LINGER) {
optlen = sizeof(optval.ling);
} else {
optlen = sizeof(optval.i);
}
if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
return -1;
}
switch (cmd) {
case java_net_SocketOptions_SO_LINGER:
return (optval.ling.l_onoff ? optval.ling.l_linger: -1);
case java_net_SocketOptions_SO_SNDBUF:
case java_net_SocketOptions_SO_RCVBUF:
case java_net_SocketOptions_IP_TOS:
return optval.i;
default :
return (optval.i == 0) ? -1 : 1;
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: socketSendUrgentData
* Signature: (B)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
jint data) {
/* The fd field */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
int n, fd;
unsigned char d = data & 0xFF;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
/* Bug 4086704 - If the Socket associated with this file descriptor
* was closed (sysCloseFD), the file descriptor is set to -1.
*/
if (fd == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return;
}
}
n = NET_Send(fd, (char *)&d, 1, MSG_OOB);
if (n == -1) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2016, 2018, 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 "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View File

@ -1,170 +0,0 @@
/*
* Copyright (c) 1997, 2017, 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 <errno.h>
#include <stdlib.h>
#include <string.h>
#include "jvm.h"
#include "net_util.h"
#include "java_net_SocketInputStream.h"
/*
* SocketInputStream
*/
static jfieldID IO_fd_fdID;
/*
* Class: java_net_SocketInputStream
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {
IO_fd_fdID = NET_GetFileDescriptorID(env);
}
static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
int result = 0;
jlong prevNanoTime = JVM_NanoTime(env, 0);
jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC;
while (nanoTimeout >= NET_NSEC_PER_MSEC) {
result = NET_Timeout(env, fd, nanoTimeout / NET_NSEC_PER_MSEC, prevNanoTime);
if (result <= 0) {
if (result == 0) {
JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out");
} else if (result == -1) {
if (errno == EBADF) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
} else if (errno == ENOMEM) {
JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
} else {
JNU_ThrowByNameWithMessageAndLastError
(env, "java/net/SocketException", "select/poll failed");
}
}
return -1;
}
result = NET_NonBlockingRead(fd, bufP, len);
if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
jlong newtNanoTime = JVM_NanoTime(env, 0);
nanoTimeout -= newtNanoTime - prevNanoTime;
if (nanoTimeout >= NET_NSEC_PER_MSEC) {
prevNanoTime = newtNanoTime;
}
} else {
break;
}
}
return result;
}
/*
* Class: java_net_SocketInputStream
* Method: socketRead0
* Signature: (Ljava/io/FileDescriptor;[BIII)I
*/
JNIEXPORT jint JNICALL
Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
jobject fdObj, jbyteArray data,
jint off, jint len, jint timeout)
{
char BUF[MAX_BUFFER_LEN];
char *bufP;
jint fd, nread;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, "java/net/SocketException",
"Socket closed");
return -1;
}
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (fd == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return -1;
}
/*
* If the read is greater than our stack allocated buffer then
* we allocate from the heap (up to a limit)
*/
if (len > MAX_BUFFER_LEN) {
if (len > MAX_HEAP_BUFFER_LEN) {
len = MAX_HEAP_BUFFER_LEN;
}
bufP = (char *)malloc((size_t)len);
if (bufP == NULL) {
bufP = BUF;
len = MAX_BUFFER_LEN;
}
} else {
bufP = BUF;
}
if (timeout) {
nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
if ((*env)->ExceptionCheck(env)) {
if (bufP != BUF) {
free(bufP);
}
return nread;
}
} else {
nread = NET_Read(fd, bufP, len);
}
if (nread <= 0) {
if (nread < 0) {
switch (errno) {
case ECONNRESET:
case EPIPE:
JNU_ThrowByName(env, "sun/net/ConnectionResetException",
"Connection reset");
break;
case EBADF:
JNU_ThrowByName(env, "java/net/SocketException",
"Socket closed");
break;
case EINTR:
JNU_ThrowByName(env, "java/io/InterruptedIOException",
"Operation interrupted");
break;
default:
JNU_ThrowByNameWithMessageAndLastError
(env, "java/net/SocketException", "Read failed");
}
}
} else {
(*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
}
if (bufP != BUF) {
free(bufP);
}
return nread;
}

View File

@ -1,126 +0,0 @@
/*
* Copyright (c) 1997, 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 <errno.h>
#include <stdlib.h>
#include <string.h>
#include "net_util.h"
#include "java_net_SocketOutputStream.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
/*
* SocketOutputStream
*/
static jfieldID IO_fd_fdID;
/*
* Class: java_net_SocketOutputStream
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {
IO_fd_fdID = NET_GetFileDescriptorID(env);
}
/*
* Class: java_net_SocketOutputStream
* Method: socketWrite0
* Signature: (Ljava/io/FileDescriptor;[BII)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
jobject fdObj,
jbyteArray data,
jint off, jint len) {
char *bufP;
char BUF[MAX_BUFFER_LEN];
int buflen;
int fd;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
/* Bug 4086704 - If the Socket associated with this file descriptor
* was closed (sysCloseFD), the file descriptor is set to -1.
*/
if (fd == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return;
}
}
if (len <= MAX_BUFFER_LEN) {
bufP = BUF;
buflen = MAX_BUFFER_LEN;
} else {
buflen = min(MAX_HEAP_BUFFER_LEN, len);
bufP = (char *)malloc((size_t)buflen);
/* if heap exhausted resort to stack buffer */
if (bufP == NULL) {
bufP = BUF;
buflen = MAX_BUFFER_LEN;
}
}
while(len > 0) {
int loff = 0;
int chunkLen = min(buflen, len);
int llen = chunkLen;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
break;
} else {
while(llen > 0) {
int n = NET_Send(fd, bufP + loff, llen, 0);
if (n > 0) {
llen -= n;
loff += n;
continue;
}
JNU_ThrowByNameWithMessageAndLastError
(env, "java/net/SocketException", "Write failed");
if (bufP != BUF) {
free(bufP);
}
return;
}
len -= chunkLen;
off += chunkLen;
}
}
if (bufP != BUF) {
free(bufP);
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2007, 2021, 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 java.net;
import java.util.Properties;
import sun.security.action.GetPropertyAction;
/**
* This class defines a factory for creating DatagramSocketImpls. It defaults
* to creating plain DatagramSocketImpls, but may create other DatagramSocketImpls
* by setting the impl.prefix system property.
*
* For Windows versions lower than Windows Vista a TwoStacksPlainDatagramSocketImpl
* is always created. This impl supports IPv6 on these platform where available.
*
* On Windows platforms greater than Vista that support a dual layer TCP/IP stack
* a DualStackPlainDatagramSocketImpl is created for DatagramSockets. For MulticastSockets
* a TwoStacksPlainDatagramSocketImpl is always created. This is to overcome the lack
* of behavior defined for multicasting over a dual layer socket by the RFC.
*
* @author Chris Hegarty
*/
class DefaultDatagramSocketImplFactory
{
private static final Class<?> prefixImplClass;
/* java.net.preferIPv4Stack */
private static final boolean preferIPv4Stack;
/* True if exclusive binding is on for Windows */
private static final boolean exclusiveBind;
static {
Class<?> prefixImplClassLocal = null;
Properties props = GetPropertyAction.privilegedGetProperties();
preferIPv4Stack = Boolean.parseBoolean(
props.getProperty("java.net.preferIPv4Stack"));
String exclBindProp = props.getProperty("sun.net.useExclusiveBind", "");
exclusiveBind = (exclBindProp.isEmpty())
? true
: Boolean.parseBoolean(exclBindProp);
// impl.prefix
String prefix = null;
try {
prefix = props.getProperty("impl.prefix");
if (prefix != null)
prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
} catch (Exception e) {
System.err.println("Can't find class: java.net." +
prefix +
"DatagramSocketImpl: check impl.prefix property");
}
prefixImplClass = prefixImplClassLocal;
}
/**
* Creates a new <code>DatagramSocketImpl</code> instance.
*
* @param isMulticast true if this impl is to be used for a MutlicastSocket
* @return a new instance of <code>PlainDatagramSocketImpl</code>.
*/
static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast)
throws SocketException {
if (prefixImplClass != null) {
try {
@SuppressWarnings("deprecation")
Object result = prefixImplClass.newInstance();
return (DatagramSocketImpl) result;
} catch (Exception e) {
throw new SocketException("can't instantiate DatagramSocketImpl");
}
} else {
// Always use TwoStacksPlainDatagramSocketImpl since we need
// to support multicasting at DatagramSocket level
return new TwoStacksPlainDatagramSocketImpl(exclusiveBind && !isMulticast, isMulticast);
}
}
}

View File

@ -1,324 +0,0 @@
/*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import sun.net.ext.ExtendedSocketOptions;
/**
* This class defines the plain DatagramSocketImpl that is used on
* Windows platforms greater than or equal to Windows Vista. These
* platforms have a dual layer TCP/IP stack and can handle both IPv4
* and IPV6 through a single file descriptor.
* <p>
* Note: Multicasting on a dual layer TCP/IP stack is always done with
* TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
* of behavior defined for multicasting over a dual layer socket by the RFC.
*
* @author Chris Hegarty
*/
class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
static {
initIDs();
}
// true if this socket is exclusively bound
private final boolean exclusiveBind;
/*
* Set to true if SO_REUSEADDR is set after the socket is bound to
* indicate SO_REUSEADDR is being emulated
*/
private boolean reuseAddressEmulated;
// emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
private boolean isReuseAddress;
DualStackPlainDatagramSocketImpl(boolean exclBind) {
super(false);
exclusiveBind = exclBind;
}
protected void datagramSocketCreate() throws SocketException {
if (fd == null)
throw new SocketException("Socket closed");
int newfd = socketCreate();
fdAccess.set(fd, newfd);
}
protected synchronized void bind0(int lport, InetAddress laddr)
throws SocketException {
int nativefd = checkAndReturnNativeFD();
if (laddr == null)
throw new NullPointerException("argument address");
socketBind(nativefd, laddr, lport, exclusiveBind);
if (lport == 0) {
localPort = socketLocalPort(nativefd);
} else {
localPort = lport;
}
}
protected synchronized int peek(InetAddress address) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("Null address in peek()");
// Use peekData()
DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
int peekPort = peekData(peekPacket);
address = peekPacket.getAddress();
return peekPort;
}
protected synchronized int peekData(DatagramPacket p) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (p == null)
throw new NullPointerException("packet");
if (p.getData() == null)
throw new NullPointerException("packet buffer");
return socketReceiveOrPeekData(nativefd, p, timeout, connected, true /*peek*/);
}
protected synchronized void receive0(DatagramPacket p) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (p == null)
throw new NullPointerException("packet");
if (p.getData() == null)
throw new NullPointerException("packet buffer");
socketReceiveOrPeekData(nativefd, p, timeout, connected, false /*receive*/);
}
protected void send0(DatagramPacket p) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (p == null)
throw new NullPointerException("null packet");
if (p.getAddress() == null ||p.getData() ==null)
throw new NullPointerException("null address || null buffer");
socketSend(nativefd, p.getData(), p.getOffset(), p.getLength(),
p.getAddress(), p.getPort(), connected);
}
protected void connect0(InetAddress address, int port) throws SocketException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("address");
socketConnect(nativefd, address, port);
}
protected void disconnect0(int family /*unused*/) {
if (fd == null || !fd.valid())
return; // disconnect doesn't throw any exceptions
socketDisconnect(fdAccess.get(fd));
}
protected void datagramSocketClose() {
if (fd == null || !fd.valid())
return; // close doesn't throw any exceptions
socketClose(fdAccess.get(fd));
fdAccess.set(fd, -1);
}
@SuppressWarnings("fallthrough")
protected void socketSetOption(int opt, Object val) throws SocketException {
int nativefd = checkAndReturnNativeFD();
int optionValue = 0;
// SO_REUSEPORT is not supported on Windows.
if (opt == SO_REUSEPORT) {
throw new UnsupportedOperationException("unsupported option");
}
switch(opt) {
case IP_TOS :
case SO_RCVBUF :
case SO_SNDBUF :
optionValue = ((Integer)val).intValue();
break;
case SO_REUSEADDR :
if (exclusiveBind && localPort != 0) {
// socket already bound, emulate SO_REUSEADDR
reuseAddressEmulated = true;
isReuseAddress = (Boolean)val;
return;
}
//Intentional fallthrough
case SO_BROADCAST :
optionValue = ((Boolean)val).booleanValue() ? 1 : 0;
break;
default: /* shouldn't get here */
throw new SocketException("Option not supported");
}
socketSetIntOption(nativefd, opt, optionValue);
}
protected Object socketGetOption(int opt) throws SocketException {
int nativefd = checkAndReturnNativeFD();
// SO_BINDADDR is not a socket option.
if (opt == SO_BINDADDR) {
return socketLocalAddress(nativefd);
}
if (opt == SO_REUSEADDR && reuseAddressEmulated)
return isReuseAddress;
// SO_REUSEPORT is not supported on Windows.
if (opt == SO_REUSEPORT)
throw new UnsupportedOperationException("unsupported option");
int value = socketGetIntOption(nativefd, opt);
Object returnValue = null;
switch (opt) {
case SO_REUSEADDR :
case SO_BROADCAST :
returnValue = (value == 0) ? Boolean.FALSE : Boolean.TRUE;
break;
case IP_TOS :
case SO_RCVBUF :
case SO_SNDBUF :
returnValue = Integer.valueOf(value);
break;
default: /* shouldn't get here */
throw new SocketException("Option not supported");
}
return returnValue;
}
@Override
protected Set<SocketOption<?>> supportedOptions() {
HashSet<SocketOption<?>> options = new HashSet<>();
options.add(StandardSocketOptions.SO_SNDBUF);
options.add(StandardSocketOptions.SO_RCVBUF);
options.add(StandardSocketOptions.SO_REUSEADDR);
options.add(StandardSocketOptions.SO_BROADCAST);
options.add(StandardSocketOptions.IP_TOS);
options.addAll(ExtendedSocketOptions.datagramSocketOptions());
return Collections.unmodifiableSet(options);
}
/* Multicast specific methods.
* Multicasting on a dual layer TCP/IP stack is always done with
* TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
* of behavior defined for multicasting over a dual layer socket by the RFC.
*/
protected void join(InetAddress inetaddr, NetworkInterface netIf)
throws IOException {
throw new IOException("Method not implemented!");
}
protected void leave(InetAddress inetaddr, NetworkInterface netIf)
throws IOException {
throw new IOException("Method not implemented!");
}
protected void setTimeToLive(int ttl) throws IOException {
throw new IOException("Method not implemented!");
}
protected int getTimeToLive() throws IOException {
throw new IOException("Method not implemented!");
}
@Deprecated
protected void setTTL(byte ttl) throws IOException {
throw new IOException("Method not implemented!");
}
@Deprecated
protected byte getTTL() throws IOException {
throw new IOException("Method not implemented!");
}
/* END Multicast specific methods */
private int checkAndReturnNativeFD() throws SocketException {
if (fd == null || !fd.valid())
throw new SocketException("Socket closed");
return fdAccess.get(fd);
}
/* Native methods */
private static native void initIDs();
private static native int socketCreate();
private static native void socketBind(int fd, InetAddress localAddress,
int localport, boolean exclBind) throws SocketException;
private static native void socketConnect(int fd, InetAddress address, int port)
throws SocketException;
private static native void socketDisconnect(int fd);
private static native void socketClose(int fd);
private static native int socketLocalPort(int fd) throws SocketException;
private static native Object socketLocalAddress(int fd) throws SocketException;
private static native int socketReceiveOrPeekData(int fd, DatagramPacket packet,
int timeout, boolean connected, boolean peek) throws IOException;
private static native void socketSend(int fd, byte[] data, int offset, int length,
InetAddress address, int port, boolean connected) throws IOException;
private static native void socketSetIntOption(int fd, int cmd,
int optionValue) throws SocketException;
private static native int socketGetIntOption(int fd, int cmd) throws SocketException;
native int dataAvailable();
}

View File

@ -1,354 +0,0 @@
/*
* Copyright (c) 2007, 2021, 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 java.net;
import java.io.IOException;
import java.io.FileDescriptor;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaIOFileDescriptorAccess;
/**
* On Windows system we simply delegate to native methods.
*
* @author Chris Hegarty
*/
class PlainSocketImpl extends AbstractPlainSocketImpl {
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
@SuppressWarnings("removal")
private static final boolean preferIPv4Stack =
Boolean.parseBoolean(AccessController.doPrivileged(
new GetPropertyAction("java.net.preferIPv4Stack", "false")));
/**
* Empty value of sun.net.useExclusiveBind is treated as 'true'.
*/
private static final boolean useExclusiveBind;
static {
@SuppressWarnings("removal")
String exclBindProp = AccessController.doPrivileged(
new GetPropertyAction("sun.net.useExclusiveBind", ""));
useExclusiveBind = exclBindProp.isEmpty()
|| Boolean.parseBoolean(exclBindProp);
}
// emulates SO_REUSEADDR when useExclusiveBind is true
private boolean isReuseAddress;
/**
* Constructs an empty instance.
*/
PlainSocketImpl(boolean isServer) {
super(isServer);
}
@Override
void socketCreate(boolean stream) throws IOException {
if (fd == null)
throw new SocketException("Socket closed");
int newfd = socket0(stream);
fdAccess.set(fd, newfd);
}
@Override
void socketConnect(InetAddress address, int port, int timeout)
throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("inet address argument is null.");
if (preferIPv4Stack && !(address instanceof Inet4Address))
throw new SocketException("Protocol family not supported");
int connectResult;
if (timeout <= 0) {
connectResult = connect0(nativefd, address, port);
} else {
configureBlocking(nativefd, false);
try {
connectResult = connect0(nativefd, address, port);
if (connectResult == WOULDBLOCK) {
waitForConnect(nativefd, timeout);
}
} finally {
configureBlocking(nativefd, true);
}
}
/*
* We need to set the local port field. If bind was called
* previous to the connect (by the client) then localport field
* will already be set.
*/
if (localport == 0)
localport = localPort0(nativefd);
}
@Override
void socketBind(InetAddress address, int port) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (address == null)
throw new NullPointerException("inet address argument is null.");
if (preferIPv4Stack && !(address instanceof Inet4Address))
throw new SocketException("Protocol family not supported");
bind0(nativefd, address, port, useExclusiveBind);
if (port == 0) {
localport = localPort0(nativefd);
} else {
localport = port;
}
this.address = address;
}
@Override
void socketListen(int backlog) throws IOException {
int nativefd = checkAndReturnNativeFD();
listen0(nativefd, backlog);
}
@Override
void socketAccept(SocketImpl s) throws IOException {
int nativefd = checkAndReturnNativeFD();
if (s == null)
throw new NullPointerException("socket is null");
int newfd = -1;
InetSocketAddress[] isaa = new InetSocketAddress[1];
if (timeout <= 0) {
newfd = accept0(nativefd, isaa);
} else {
configureBlocking(nativefd, false);
try {
waitForNewConnection(nativefd, timeout);
newfd = accept0(nativefd, isaa);
if (newfd != -1) {
configureBlocking(newfd, true);
}
} finally {
configureBlocking(nativefd, true);
}
}
/* Update (SocketImpl)s' fd */
fdAccess.set(s.fd, newfd);
/* Update socketImpls remote port, address and localport */
InetSocketAddress isa = isaa[0];
s.port = isa.getPort();
s.address = isa.getAddress();
s.localport = localport;
if (preferIPv4Stack && !(s.address instanceof Inet4Address))
throw new SocketException("Protocol family not supported");
}
@Override
int socketAvailable() throws IOException {
int nativefd = checkAndReturnNativeFD();
return available0(nativefd);
}
@Override
void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
if (fd == null)
throw new SocketException("Socket closed");
if (!fd.valid())
return;
final int nativefd = fdAccess.get(fd);
fdAccess.set(fd, -1);
close0(nativefd);
}
@Override
void socketShutdown(int howto) throws IOException {
int nativefd = checkAndReturnNativeFD();
shutdown0(nativefd, howto);
}
// Intentional fallthrough after SO_REUSEADDR
@SuppressWarnings("fallthrough")
@Override
void socketSetOption(int opt, boolean on, Object value)
throws SocketException {
// SO_REUSEPORT is not supported on Windows.
if (opt == SO_REUSEPORT) {
throw new UnsupportedOperationException("unsupported option");
}
int nativefd = checkAndReturnNativeFD();
if (opt == SO_TIMEOUT) {
if (preferIPv4Stack) {
// Don't enable the socket option on ServerSocket as it's
// meaningless (we don't receive on a ServerSocket).
if (!isServer) {
setSoTimeout0(nativefd, ((Integer)value).intValue());
}
} // else timeout is implemented through select.
return;
}
int optionValue = 0;
switch(opt) {
case SO_REUSEADDR:
if (useExclusiveBind) {
// SO_REUSEADDR emulated when using exclusive bind
isReuseAddress = on;
return;
}
// intentional fallthrough
case TCP_NODELAY:
case SO_OOBINLINE:
case SO_KEEPALIVE:
optionValue = on ? 1 : 0;
break;
case SO_SNDBUF:
case SO_RCVBUF:
case IP_TOS:
optionValue = ((Integer)value).intValue();
break;
case SO_LINGER:
if (on) {
optionValue = ((Integer)value).intValue();
} else {
optionValue = -1;
}
break;
default :/* shouldn't get here */
throw new SocketException("Option not supported");
}
setIntOption(nativefd, opt, optionValue);
}
@Override
int socketGetOption(int opt, Object iaContainerObj)
throws SocketException {
// SO_REUSEPORT is not supported on Windows.
if (opt == SO_REUSEPORT) {
throw new UnsupportedOperationException("unsupported option");
}
int nativefd = checkAndReturnNativeFD();
// SO_BINDADDR is not a socket option.
if (opt == SO_BINDADDR) {
localAddress(nativefd, (InetAddressContainer)iaContainerObj);
return 0; // return value doesn't matter.
}
// SO_REUSEADDR emulated when using exclusive bind
if (opt == SO_REUSEADDR && useExclusiveBind)
return isReuseAddress ? 1 : -1;
int value = getIntOption(nativefd, opt);
switch (opt) {
case TCP_NODELAY:
case SO_OOBINLINE:
case SO_KEEPALIVE:
case SO_REUSEADDR:
return (value == 0) ? -1 : 1;
}
return value;
}
@Override
void socketSendUrgentData(int data) throws IOException {
int nativefd = checkAndReturnNativeFD();
sendOOB(nativefd, data);
}
private int checkAndReturnNativeFD() throws SocketException {
if (fd == null || !fd.valid())
throw new SocketException("Socket closed");
return fdAccess.get(fd);
}
static final int WOULDBLOCK = -2; // Nothing available (non-blocking)
static {
initIDs();
}
/* Native methods */
static native void initIDs();
static native int socket0(boolean stream) throws IOException;
static native void bind0(int fd, InetAddress localAddress, int localport,
boolean exclBind)
throws IOException;
static native int connect0(int fd, InetAddress remote, int remotePort)
throws IOException;
static native void waitForConnect(int fd, int timeout) throws IOException;
static native int localPort0(int fd) throws IOException;
static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
static native void listen0(int fd, int backlog) throws IOException;
static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
static native void waitForNewConnection(int fd, int timeout) throws IOException;
static native int available0(int fd) throws IOException;
static native void close0(int fd) throws IOException;
static native void shutdown0(int fd, int howto) throws IOException;
static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
static native void setSoTimeout0(int fd, int timeout) throws SocketException;
static native int getIntOption(int fd, int cmd) throws SocketException;
static native void sendOOB(int fd, int data) throws IOException;
static native void configureBlocking(int fd, boolean blocking) throws IOException;
}

View File

@ -1,238 +0,0 @@
/*
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 java.net;
import java.io.IOException;
import java.io.FileDescriptor;
import sun.net.ResourceManager;
/**
* This class defines the plain DatagramSocketImpl that is used for all
* Windows versions lower than Vista. It adds support for IPv6 on
* these platforms where available.
*
* For backward compatibility windows platforms that do not have IPv6
* support also use this implementation, and fd1 gets set to null
* during socket creation.
*
* @author Chris Hegarty
*/
final class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{
/* Used for IPv6 on Windows only */
private FileDescriptor fd1;
/*
* Needed for ipv6 on windows because we need to know
* if the socket was bound to ::0 or 0.0.0.0, when a caller
* asks for it. In this case, both sockets are used, but we
* don't know whether the caller requested ::0 or 0.0.0.0
* and need to remember it here.
*/
private InetAddress anyLocalBoundAddr=null;
private int fduse=-1; /* saved between peek() and receive() calls */
/* saved between successive calls to receive, if data is detected
* on both sockets at same time. To ensure that one socket is not
* starved, they rotate using this field
*/
private int lastfd=-1;
static {
init();
}
// true if this socket is exclusively bound
private final boolean exclusiveBind;
/*
* Set to true if SO_REUSEADDR is set after the socket is bound to
* indicate SO_REUSEADDR is being emulated
*/
private boolean reuseAddressEmulated;
// emulates SO_REUSEADDR when exclusiveBind is true and socket is bound
private boolean isReuseAddress;
TwoStacksPlainDatagramSocketImpl(boolean exclBind, boolean isMulticast) {
super(isMulticast);
exclusiveBind = exclBind;
}
protected synchronized void create() throws SocketException {
fd1 = new FileDescriptor();
try {
super.create();
// make SocketCleanable treat fd1 as a stream socket
// to avoid touching the counter in ResourceManager
SocketCleanable.register(fd1, true);
} catch (SocketException e) {
fd1 = null;
throw e;
}
}
protected synchronized void bind(int lport, InetAddress laddr)
throws SocketException {
super.bind(lport, laddr);
if (laddr.isAnyLocalAddress()) {
anyLocalBoundAddr = laddr;
}
}
@Override
protected synchronized void bind0(int lport, InetAddress laddr)
throws SocketException
{
// The native bind0 may close one or both of the underlying file
// descriptors, and even create new sockets, so the safest course of
// action is to unregister the socket cleaners, and register afterwards.
SocketCleanable.unregister(fd);
SocketCleanable.unregister(fd1);
bind0(lport, laddr, exclusiveBind);
SocketCleanable.register(fd, false);
// make SocketCleanable treat fd1 as a stream socket
// to avoid touching the counter in ResourceManager
SocketCleanable.register(fd1, true);
}
protected synchronized void receive(DatagramPacket p)
throws IOException {
try {
receive0(p);
} finally {
fduse = -1;
}
}
public Object getOption(int optID) throws SocketException {
if (isClosed()) {
throw new SocketException("Socket Closed");
}
if (optID == SO_BINDADDR) {
if ((fd != null && fd1 != null) && !connected) {
return anyLocalBoundAddr;
}
int family = connectedAddress == null ? -1 : connectedAddress.holder().getFamily();
return socketLocalAddress(family);
} else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
return isReuseAddress;
} else if (optID == SO_REUSEPORT) {
// SO_REUSEPORT is not supported on Windows.
throw new UnsupportedOperationException("unsupported option");
} else {
return super.getOption(optID);
}
}
protected void socketSetOption(int opt, Object val)
throws SocketException
{
if (opt == SO_REUSEADDR && exclusiveBind && localPort != 0) {
// socket already bound, emulate
reuseAddressEmulated = true;
isReuseAddress = (Boolean)val;
} else if (opt == SO_REUSEPORT) {
// SO_REUSEPORT is not supported on Windows.
throw new UnsupportedOperationException("unsupported option");
} else {
socketNativeSetOption(opt, val);
}
}
protected boolean isClosed() {
return (fd == null && fd1 == null) ? true : false;
}
protected void close() {
if (fd != null || fd1 != null) {
SocketCleanable.unregister(fd);
SocketCleanable.unregister(fd1);
datagramSocketClose();
ResourceManager.afterUdpClose();
fd = null;
fd1 = null;
}
}
/* Native methods */
protected synchronized native void bind0(int lport, InetAddress laddr,
boolean exclBind)
throws SocketException;
protected native void send0(DatagramPacket p) throws IOException;
protected synchronized native int peek(InetAddress i) throws IOException;
protected synchronized native int peekData(DatagramPacket p) throws IOException;
protected synchronized native void receive0(DatagramPacket p)
throws IOException;
protected native void setTimeToLive(int ttl) throws IOException;
protected native int getTimeToLive() throws IOException;
@Deprecated
protected native void setTTL(byte ttl) throws IOException;
@Deprecated
protected native byte getTTL() throws IOException;
protected native void join(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
protected native void leave(InetAddress inetaddr, NetworkInterface netIf)
throws IOException;
protected native void datagramSocketCreate() throws SocketException;
protected native void datagramSocketClose();
protected native void socketNativeSetOption(int opt, Object val)
throws SocketException;
protected native Object socketGetOption(int opt) throws SocketException;
protected native void connect0(InetAddress address, int port) throws SocketException;
protected native Object socketLocalAddress(int family) throws SocketException;
protected native void disconnect0(int family);
native int dataAvailable();
/**
* Perform class load-time initializations.
*/
private static native void init();
}

View File

@ -1,539 +0,0 @@
/*
* Copyright (c) 2007, 2018, 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 "net_util.h"
#include "java_net_DualStackPlainDatagramSocketImpl.h"
/*
* This function "purges" all outstanding ICMP port unreachable packets
* outstanding on a socket and returns JNI_TRUE if any ICMP messages
* have been purged. The rational for purging is to emulate normal BSD
* behaviour whereby receiving a "connection reset" status resets the
* socket.
*/
static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd)
{
jboolean got_icmp = JNI_FALSE;
char buf[1];
fd_set tbl;
struct timeval t = { 0, 0 };
SOCKETADDRESS rmtaddr;
int addrlen = sizeof(rmtaddr);
/*
* Peek at the queue to see if there is an ICMP port unreachable. If there
* is then receive it.
*/
FD_ZERO(&tbl);
FD_SET(fd, &tbl);
while(1) {
if (select(/*ignored*/fd+1, &tbl, 0, 0, &t) <= 0) {
break;
}
if (recvfrom(fd, buf, 1, MSG_PEEK,
&rmtaddr.sa, &addrlen) != SOCKET_ERROR) {
break;
}
if (WSAGetLastError() != WSAECONNRESET) {
/* some other error - we don't care here */
break;
}
recvfrom(fd, buf, 1, 0, &rmtaddr.sa, &addrlen);
got_icmp = JNI_TRUE;
}
return got_icmp;
}
static jfieldID IO_fd_fdID = NULL;
static jfieldID pdsi_fdID = NULL;
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_initIDs
(JNIEnv *env, jclass clazz)
{
pdsi_fdID = (*env)->GetFieldID(env, clazz, "fd",
"Ljava/io/FileDescriptor;");
CHECK_NULL(pdsi_fdID);
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
JNU_CHECK_EXCEPTION(env);
initInetAddressIDs(env);
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketCreate
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCreate
(JNIEnv *env, jclass clazz) {
int fd, rv, opt=0, t=TRUE;
DWORD x1, x2; /* ignored result codes */
fd = (int) socket(AF_INET6, SOCK_DGRAM, 0);
if (fd == INVALID_SOCKET) {
NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
return -1;
}
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
closesocket(fd);
return -1;
}
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
/* SIO_UDP_CONNRESET fixes a "bug" introduced in Windows 2000, which
* returns connection reset errors on unconnected UDP sockets (as well
* as connected sockets). The solution is to only enable this feature
* when the socket is connected.
*/
t = FALSE;
WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
return fd;
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketBind
* Signature: (ILjava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port, jboolean exclBind) {
SOCKETADDRESS sa;
int rv, sa_len = 0;
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, JNI_TRUE) != 0) {
return;
}
rv = NET_WinBind(fd, &sa, sa_len, exclBind);
if (rv == SOCKET_ERROR) {
if (WSAGetLastError() == WSAEACCES) {
WSASetLastError(WSAEADDRINUSE);
}
NET_ThrowNew(env, WSAGetLastError(), "Cannot bind");
}
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketConnect
* Signature: (ILjava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConnect
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
SOCKETADDRESS sa;
int rv, sa_len = 0, t;
DWORD x1, x2; /* ignored result codes */
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, JNI_TRUE) != 0) {
return;
}
rv = connect(fd, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "connect");
return;
}
/* see comment in socketCreate */
t = TRUE;
WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketDisconnect
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketDisconnect
(JNIEnv *env, jclass clazz, jint fd ) {
SOCKETADDRESS sa;
int sa_len = sizeof(sa);
DWORD x1, x2; /* ignored result codes */
int t = FALSE;
memset(&sa, 0, sa_len);
connect(fd, &sa.sa, sa_len);
/* see comment in socketCreate */
WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketClose
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketClose
(JNIEnv *env, jclass clazz , jint fd) {
NET_SocketClose(fd);
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketLocalPort
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalPort
(JNIEnv *env, jclass clazz, jint fd) {
SOCKETADDRESS sa;
int len = sizeof(sa);
if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "getsockname");
return -1;
}
return (int) ntohs((u_short)GET_PORT(&sa));
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketLocalAddress
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalAddress
(JNIEnv *env , jclass clazz, jint fd) {
SOCKETADDRESS sa;
int len = sizeof(sa);
jobject iaObj;
int port;
if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
return NULL;
}
iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
return iaObj;
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketReceiveOrPeekData
* Signature: (ILjava/net/DatagramPacket;IZZ)I
*/
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketReceiveOrPeekData
(JNIEnv *env, jclass clazz, jint fd, jobject dpObj,
jint timeout, jboolean connected, jboolean peek) {
SOCKETADDRESS sa;
int sa_len = sizeof(sa);
int port, rv, flags=0;
char BUF[MAX_BUFFER_LEN];
char *fullPacket;
BOOL retry;
jlong prevTime = 0;
jint packetBufferOffset, packetBufferLen;
jbyteArray packetBuffer;
/* if we are only peeking. Called from peekData */
if (peek) {
flags = MSG_PEEK;
}
packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID);
packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID);
packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID);
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
if (packetBufferLen > MAX_BUFFER_LEN) {
fullPacket = (char *)malloc(packetBufferLen);
if (!fullPacket) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
return -1;
}
} else {
fullPacket = &(BUF[0]);
}
do {
retry = FALSE;
if (timeout) {
if (prevTime == 0) {
prevTime = JVM_CurrentTimeMillis(env, 0);
}
rv = NET_Timeout(fd, timeout);
if (rv <= 0) {
if (rv == 0) {
JNU_ThrowByName(env,JNU_JAVANETPKG "SocketTimeoutException",
"Receive timed out");
} else if (rv == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
}
if (packetBufferLen > MAX_BUFFER_LEN) {
free(fullPacket);
}
return -1;
}
}
/* receive the packet */
rv = recvfrom(fd, fullPacket, packetBufferLen, flags,
&sa.sa, &sa_len);
if (rv == SOCKET_ERROR && (WSAGetLastError() == WSAECONNRESET)) {
/* An icmp port unreachable - we must receive this as Windows
* does not reset the state of the socket until this has been
* received.
*/
purgeOutstandingICMP(env, fd);
if (connected) {
JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
"ICMP Port Unreachable");
if (packetBufferLen > MAX_BUFFER_LEN)
free(fullPacket);
return -1;
} else if (timeout) {
/* Adjust timeout */
jlong newTime = JVM_CurrentTimeMillis(env, 0);
timeout -= (jint)(newTime - prevTime);
if (timeout <= 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"Receive timed out");
if (packetBufferLen > MAX_BUFFER_LEN)
free(fullPacket);
return -1;
}
prevTime = newTime;
}
retry = TRUE;
}
} while (retry);
port = (int) ntohs ((u_short) GET_PORT((SOCKETADDRESS *)&sa));
/* truncate the data if the packet's length is too small */
if (rv > packetBufferLen) {
rv = packetBufferLen;
}
if (rv < 0) {
if (WSAGetLastError() == WSAEMSGSIZE) {
/* it is because the buffer is too small. It's UDP, it's
* unreliable, it's all good. discard the rest of the
* data..
*/
rv = packetBufferLen;
} else {
/* failure */
(*env)->SetIntField(env, dpObj, dp_lengthID, 0);
}
}
if (rv == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
} else if (rv == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
} else if (rv < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
} else {
jobject packetAddress;
/*
* Check if there is an InetAddress already associated with this
* packet. If so, we check if it is the same source address. We
* can't update any existing InetAddress because it is immutable
*/
packetAddress = (*env)->GetObjectField(env, dpObj, dp_addressID);
if (packetAddress != NULL) {
if (!NET_SockaddrEqualsInetAddress(env, &sa, packetAddress)) {
/* force a new InetAddress to be created */
packetAddress = NULL;
}
}
if (!(*env)->ExceptionCheck(env)){
if (packetAddress == NULL ) {
packetAddress = NET_SockaddrToInetAddress(env, &sa, &port);
if (packetAddress != NULL) {
/* stuff the new InetAddress into the packet */
(*env)->SetObjectField(env, dpObj, dp_addressID, packetAddress);
}
}
/* populate the packet */
(*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, rv,
(jbyte *)fullPacket);
(*env)->SetIntField(env, dpObj, dp_portID, port);
(*env)->SetIntField(env, dpObj, dp_lengthID, rv);
}
}
if (packetBufferLen > MAX_BUFFER_LEN) {
free(fullPacket);
}
return port;
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketSend
* Signature: (I[BIILjava/net/InetAddress;IZ)V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend
(JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint offset, jint length,
jobject iaObj, jint port, jboolean connected) {
SOCKETADDRESS sa;
int rv, sa_len = 0;
struct sockaddr *sap = 0;
char BUF[MAX_BUFFER_LEN];
char *fullPacket;
// if already connected, sap arg to sendto() is null
if (!connected) {
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, JNI_TRUE) != 0) {
return;
}
sap = &sa.sa;
}
if (length > MAX_BUFFER_LEN) {
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*/
if (length > MAX_PACKET_LEN) {
length = MAX_PACKET_LEN;
}
fullPacket = (char *)malloc(length);
if (!fullPacket) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
return;
}
} else {
fullPacket = &(BUF[0]);
}
(*env)->GetByteArrayRegion(env, data, offset, length,
(jbyte *)fullPacket);
rv = sendto(fd, fullPacket, length, 0, sap, sa_len);
if (rv == SOCKET_ERROR) {
if (rv == -1) {
NET_ThrowNew(env, WSAGetLastError(), "Datagram send failed");
}
}
if (length > MAX_BUFFER_LEN) {
free(fullPacket);
}
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketSetIntOption
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_java_net_DualStackPlainDatagramSocketImpl_socketSetIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
{
int level = 0, opt = 0;
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return;
}
if (NET_SetSockOpt(fd, level, opt, (char *)&value, sizeof(value)) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
}
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketGetIntOption
* Signature: (II)I
*/
JNIEXPORT jint JNICALL
Java_java_net_DualStackPlainDatagramSocketImpl_socketGetIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd)
{
int level = 0, opt = 0, result = 0;
int result_len = sizeof(result);
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return -1;
}
if (NET_GetSockOpt(fd, level, opt, (void *)&result, &result_len) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
return -1;
}
return result;
}
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: dataAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_java_net_DualStackPlainDatagramSocketImpl_dataAvailable
(JNIEnv *env, jobject this)
{
SOCKET fd;
int rv = -1;
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
if (!IS_NULL(fdObj)) {
int retval = 0;
fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID);
rv = ioctlsocket(fd, FIONREAD, &retval);
if (retval > 0) {
return retval;
}
}
if (rv < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
return 0;
}

View File

@ -1,535 +0,0 @@
/*
* Copyright (c) 2007, 2018, 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 "net_util.h"
#include "java_net_PlainSocketImpl.h"
#include "java_net_SocketOptions.h"
#define SET_BLOCKING 0
#define SET_NONBLOCKING 1
static jclass isa_class; /* java.net.InetSocketAddress */
static jmethodID isa_ctorID; /* InetSocketAddress(InetAddress, int) */
/*
* Class: java_net_PlainSocketImpl
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_initIDs
(JNIEnv *env, jclass clazz) {
jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
CHECK_NULL(cls);
isa_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(isa_class);
isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/net/InetAddress;I)V");
CHECK_NULL(isa_ctorID);
initInetAddressIDs(env);
// implement read timeout with select.
isRcvTimeoutSupported = JNI_FALSE;
}
/*
* Class: java_net_PlainSocketImpl
* Method: socket0
* Signature: (ZZ)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_socket0
(JNIEnv *env, jclass clazz, jboolean stream) {
int fd, rv, opt = 0;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
int domain = ipv6_available() ? AF_INET6 : AF_INET;
fd = NET_Socket(domain, type, 0);
if (fd == INVALID_SOCKET) {
NET_ThrowNew(env, WSAGetLastError(), "create");
return -1;
}
if (domain == AF_INET6) {
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt,
sizeof(opt));
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "create");
closesocket(fd);
return -1;
}
}
return fd;
}
/*
* Class: java_net_PlainSocketImpl
* Method: bind0
* Signature: (ILjava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_bind0
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port,
jboolean exclBind)
{
SOCKETADDRESS sa;
int rv, sa_len = 0;
jboolean v4MappedAddress = ipv6_available() ? JNI_TRUE : JNI_FALSE;
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, v4MappedAddress) != 0) {
return;
}
rv = NET_WinBind(fd, &sa, sa_len, exclBind);
if (rv == SOCKET_ERROR)
NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
}
/*
* Class: java_net_PlainSocketImpl
* Method: connect0
* Signature: (ILjava/net/InetAddress;I)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_connect0
(JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
SOCKETADDRESS sa;
int rv, sa_len = 0;
jboolean v4MappedAddress = ipv6_available() ? JNI_TRUE : JNI_FALSE;
if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
&sa_len, v4MappedAddress) != 0) {
return -1;
}
rv = connect(fd, &sa.sa, sa_len);
if (rv == SOCKET_ERROR) {
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
return java_net_PlainSocketImpl_WOULDBLOCK;
} else if (err == WSAEADDRNOTAVAIL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
"connect: Address is invalid on local machine,"
" or port is not valid on remote machine");
} else {
NET_ThrowNew(env, err, "connect");
}
// return value not important.
}
return rv;
}
/*
* Class: java_net_PlainSocketImpl
* Method: waitForConnect
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_waitForConnect
(JNIEnv *env, jclass clazz, jint fd, jint timeout) {
int rv, retry;
int optlen = sizeof(rv);
fd_set wr, ex;
struct timeval t;
FD_ZERO(&wr);
FD_ZERO(&ex);
FD_SET(fd, &wr);
FD_SET(fd, &ex);
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
/*
* Wait for timeout, connection established or
* connection failed.
*/
rv = select(fd+1, 0, &wr, &ex, &t);
/*
* Timeout before connection is established/failed so
* we throw exception and shutdown input/output to prevent
* socket from being used.
* The socket should be closed immediately by the caller.
*/
if (rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"connect timed out");
shutdown(fd, SD_BOTH);
return;
}
/*
* Socket is writable or error occurred. On some Windows editions
* the socket will appear writable when the connect fails so we
* check for error rather than writable.
*/
if (!FD_ISSET(fd, &ex)) {
return; /* connection established */
}
/*
* Connection failed. The logic here is designed to work around
* bug on Windows NT whereby using getsockopt to obtain the
* last error (SO_ERROR) indicates there is no error. The workaround
* on NT is to allow winsock to be scheduled and this is done by
* yielding and retrying. As yielding is problematic in heavy
* load conditions we attempt up to 3 times to get the error reason.
*/
for (retry = 0; retry < 3; retry++) {
NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
(char*)&rv, &optlen);
if (rv) {
break;
}
Sleep(0);
}
if (rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Unable to establish connection");
} else if (!ipv6_available() && rv == WSAEADDRNOTAVAIL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
"connect: Address is invalid on local machine,"
" or port is not valid on remote machine");
} else {
NET_ThrowNew(env, rv, "connect");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: localPort0
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_localPort0
(JNIEnv *env, jclass clazz, jint fd) {
SOCKETADDRESS sa;
int len = sizeof(sa);
if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
if (WSAGetLastError() == WSAENOTSOCK) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
} else {
NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
}
return -1;
}
return (int) ntohs((u_short)GET_PORT(&sa));
}
/*
* Class: java_net_PlainSocketImpl
* Method: localAddress
* Signature: (ILjava/net/InetAddressContainer;)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_localAddress
(JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
int port;
SOCKETADDRESS sa;
int len = sizeof(sa);
jobject iaObj;
jclass iaContainerClass;
jfieldID iaFieldID;
if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
return;
}
iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
CHECK_NULL(iaObj);
iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
CHECK_NULL(iaFieldID);
(*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
}
/*
* Class: java_net_PlainSocketImpl
* Method: listen0
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_listen0
(JNIEnv *env, jclass clazz, jint fd, jint backlog) {
if (listen(fd, backlog) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "listen failed");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: accept0
* Signature: (I[Ljava/net/InetSocketAddress;)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_accept0
(JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) {
int newfd, port = 0;
jobject isa;
jobject ia;
SOCKETADDRESS sa;
int len = sizeof(sa);
memset((char *)&sa, 0, len);
newfd = accept(fd, &sa.sa, &len);
if (newfd == INVALID_SOCKET) {
NET_ThrowNew(env, WSAGetLastError(), "accept failed");
return -1;
}
SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
ia = NET_SockaddrToInetAddress(env, &sa, &port);
if (ia == NULL){
closesocket(newfd);
return -1;
}
isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
if (isa == NULL) {
closesocket(newfd);
return -1;
}
(*env)->SetObjectArrayElement(env, isaa, 0, isa);
return newfd;
}
/*
* Class: java_net_PlainSocketImpl
* Method: waitForNewConnection
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_waitForNewConnection
(JNIEnv *env, jclass clazz, jint fd, jint timeout) {
int rv;
rv = NET_Timeout(fd, timeout);
if (rv == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"Accept timed out");
} else if (rv == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
} else if (rv == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: available0
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_available0
(JNIEnv *env, jclass clazz, jint fd) {
jint available = -1;
if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "socket available");
}
return available;
}
/*
* Class: java_net_PlainSocketImpl
* Method: close0
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_close0
(JNIEnv *env, jclass clazz, jint fd) {
NET_SocketClose(fd);
}
/*
* Class: java_net_PlainSocketImpl
* Method: shutdown0
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_shutdown0
(JNIEnv *env, jclass clazz, jint fd, jint howto) {
shutdown(fd, howto);
}
/*
* Class: java_net_PlainSocketImpl
* Method: setIntOption
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_setIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
{
int level = 0, opt = 0;
struct linger linger = {0, 0};
char *parg;
int arglen;
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return;
}
if (opt == java_net_SocketOptions_SO_LINGER) {
parg = (char *)&linger;
arglen = sizeof(linger);
if (value >= 0) {
linger.l_onoff = 1;
linger.l_linger = (unsigned short)value;
} else {
linger.l_onoff = 0;
linger.l_linger = 0;
}
} else {
parg = (char *)&value;
arglen = sizeof(value);
}
if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: setSoTimeout0
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_java_net_PlainSocketImpl_setSoTimeout0
(JNIEnv *env, jclass clazz, jint fd, jint timeout)
{
/*
* SO_TIMEOUT is the socket option used to specify the timeout
* for ServerSocket.accept and Socket.getInputStream().read.
* It does not typically map to a native level socket option.
* For Windows we special-case this and use the SOL_SOCKET/SO_RCVTIMEO
* socket option to specify a receive timeout on the socket. This
* receive timeout is applicable to Socket only and the socket
* option should not be set on ServerSocket.
*/
/*
* SO_RCVTIMEO is only supported on Microsoft's implementation
* of Windows Sockets so if WSAENOPROTOOPT returned then
* reset flag and timeout will be implemented using
* select() -- see SocketInputStream.socketRead.
*/
if (isRcvTimeoutSupported) {
/*
* Disable SO_RCVTIMEO if timeout is <= 5 second.
*/
if (timeout <= 5000) {
timeout = 0;
}
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0) {
int err = WSAGetLastError();
if (err == WSAENOPROTOOPT) {
isRcvTimeoutSupported = JNI_FALSE;
} else {
NET_ThrowNew(env, err, "setsockopt SO_RCVTIMEO");
}
}
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: getIntOption
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_getIntOption
(JNIEnv *env, jclass clazz, jint fd, jint cmd)
{
int level = 0, opt = 0;
int result = 0;
struct linger linger = {0, 0};
char *arg;
int arglen;
if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
return -1;
}
if (opt == java_net_SocketOptions_SO_LINGER) {
arg = (char *)&linger;
arglen = sizeof(linger);
} else {
arg = (char *)&result;
arglen = sizeof(result);
}
if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
return -1;
}
if (opt == java_net_SocketOptions_SO_LINGER)
return linger.l_onoff ? linger.l_linger : -1;
else
return result;
}
/*
* Class: java_net_PlainSocketImpl
* Method: sendOOB
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_sendOOB
(JNIEnv *env, jclass clazz, jint fd, jint data) {
jint n;
unsigned char d = (unsigned char) data & 0xff;
n = send(fd, (char *)&data, 1, MSG_OOB);
if (n == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "send");
}
}
/*
* Class: java_net_PlainSocketImpl
* Method: configureBlocking
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_configureBlocking
(JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
u_long arg;
int result;
if (blocking == JNI_TRUE) {
arg = SET_BLOCKING; // 0
} else {
arg = SET_NONBLOCKING; // 1
}
result = ioctlsocket(fd, FIONBIO, &arg);
if (result == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2016, 2018, 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 "net_util.h"
#include "java_net_SocketCleanable.h"
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
// SO_REUSEPORT is not supported on Windows
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
// SO_REUSEPORT is not supported on Windows
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
{
// SO_REUSEPORT is not supported on Windows
return JNI_FALSE;
}
/*
* Class: java_net_SocketCleanable
* Method: cleanupClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketCleanable_cleanupClose0(JNIEnv *env, jclass c1, jint fd)
{
NET_SocketClose(fd);
}

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 1997, 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 <malloc.h>
#include "net_util.h"
#include "java_net_SocketInputStream.h"
/*************************************************************************
* SocketInputStream
*/
static jfieldID IO_fd_fdID;
/*
* Class: java_net_SocketInputStream
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {
IO_fd_fdID = NET_GetFileDescriptorID(env);
}
/*
* Class: java_net_SocketInputStream
* Method: socketRead
* Signature: (Ljava/io/FileDescriptor;[BIII)I
*/
JNIEXPORT jint JNICALL
Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
jobject fdObj, jbyteArray data,
jint off, jint len, jint timeout)
{
char BUF[MAX_BUFFER_LEN];
char *bufP;
jint fd, newfd, nread;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, "java/net/SocketException",
"Socket closed");
return -1;
}
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (fd == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
return -1;
}
/*
* If the caller buffer is large than our stack buffer then we allocate
* from the heap (up to a limit). If memory is exhausted we always use
* the stack buffer.
*/
if (len <= MAX_BUFFER_LEN) {
bufP = BUF;
} else {
if (len > MAX_HEAP_BUFFER_LEN) {
len = MAX_HEAP_BUFFER_LEN;
}
bufP = (char *)malloc((size_t)len);
if (bufP == NULL) {
/* allocation failed so use stack buffer */
bufP = BUF;
len = MAX_BUFFER_LEN;
}
}
if (timeout) {
if (timeout <= 5000 || !isRcvTimeoutSupported) {
int ret = NET_Timeout (fd, timeout);
if (ret <= 0) {
if (ret == 0) {
JNU_ThrowByName(env, "java/net/SocketTimeoutException",
"Read timed out");
} else if (ret == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "socket closed");
}
if (bufP != BUF) {
free(bufP);
}
return -1;
}
/*check if the socket has been closed while we were in timeout*/
newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (newfd == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
if (bufP != BUF) {
free(bufP);
}
return -1;
}
}
}
nread = recv(fd, bufP, len, 0);
if (nread > 0) {
(*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
} else {
if (nread < 0) {
int err = WSAGetLastError();
// Check if the socket has been closed since we last checked.
// This could be a reason for recv failing.
if ((*env)->GetIntField(env, fdObj, IO_fd_fdID) == -1) {
JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
} else {
switch (err) {
case WSAEINTR:
JNU_ThrowByName(env, "java/net/SocketException",
"socket closed");
break;
case WSAECONNRESET:
case WSAESHUTDOWN:
/*
* Connection has been reset - Windows sometimes reports
* the reset as a shutdown error.
*/
JNU_ThrowByName(env, "sun/net/ConnectionResetException",
"");
break;
case WSAETIMEDOUT :
JNU_ThrowByName(env, "java/net/SocketTimeoutException",
"Read timed out");
break;
default:
NET_ThrowCurrent(env, "recv failed");
}
}
}
}
if (bufP != BUF) {
free(bufP);
}
return nread;
}

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) 1997, 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 <malloc.h>
#include "net_util.h"
#include "java_net_SocketOutputStream.h"
/************************************************************************
* SocketOutputStream
*/
static jfieldID IO_fd_fdID;
/*
* Class: java_net_SocketOutputStream
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {
IO_fd_fdID = NET_GetFileDescriptorID(env);
}
/*
* Class: java_net_SocketOutputStream
* Method: socketWrite
* Signature: (Ljava/io/FileDescriptor;[BII)V
*/
JNIEXPORT void JNICALL
Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
jobject fdObj, jbyteArray data,
jint off, jint len) {
char *bufP;
char BUF[MAX_BUFFER_LEN];
int buflen;
int fd;
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
if (IS_NULL(data)) {
JNU_ThrowNullPointerException(env, "data argument");
return;
}
/*
* Use stack allocate buffer if possible. For large sizes we allocate
* an intermediate buffer from the heap (up to a maximum). If heap is
* unavailable just use our stack buffer.
*/
if (len <= MAX_BUFFER_LEN) {
bufP = BUF;
buflen = MAX_BUFFER_LEN;
} else {
buflen = min(MAX_HEAP_BUFFER_LEN, len);
bufP = (char *)malloc((size_t)buflen);
if (bufP == NULL) {
bufP = BUF;
buflen = MAX_BUFFER_LEN;
}
}
while(len > 0) {
int loff = 0;
int chunkLen = min(buflen, len);
int llen = chunkLen;
int retry = 0;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
break;
} else {
while(llen > 0) {
int n = send(fd, bufP + loff, llen, 0);
if (n > 0) {
llen -= n;
loff += n;
continue;
}
/*
* Due to a bug in Windows Sockets (observed on NT and Windows
* 2000) it may be necessary to retry the send. The issue is that
* on blocking sockets send/WSASend is supposed to block if there
* is insufficient buffer space available. If there are a large
* number of threads blocked on write due to congestion then it's
* possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
* The workaround we use is to retry the send. If we have a
* large buffer to send (>2k) then we retry with a maximum of
* 2k buffer. If we hit the issue with <=2k buffer then we backoff
* for 1 second and retry again. We repeat this up to a reasonable
* limit before bailing out and throwing an exception. In load
* conditions we've observed that the send will succeed after 2-3
* attempts but this depends on network buffers associated with
* other sockets draining.
*/
if (WSAGetLastError() == WSAENOBUFS) {
if (llen > MAX_BUFFER_LEN) {
buflen = MAX_BUFFER_LEN;
chunkLen = MAX_BUFFER_LEN;
llen = MAX_BUFFER_LEN;
continue;
}
if (retry >= 30) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"No buffer space available - exhausted attempts to queue buffer");
if (bufP != BUF) {
free(bufP);
}
return;
}
Sleep(1000);
retry++;
continue;
}
/*
* Send failed - can be caused by close or write error.
*/
if (WSAGetLastError() == WSAENOTSOCK) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
} else {
NET_ThrowCurrent(env, "socket write error");
}
if (bufP != BUF) {
free(bufP);
}
return;
}
len -= chunkLen;
off += chunkLen;
}
}
if (bufP != BUF) {
free(bufP);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, 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
@ -265,13 +265,6 @@ dbgsysNetworkToHostLong(uint32_t netlong) {
return (uint32_t)ntohl((u_long)netlong);
}
/*
* Below Adapted from PlainSocketImpl.c, win32 version 1.18. Changed exception
* throws to returns of SYS_ERR; we should improve the error codes
* eventually. Changed java objects to values the debugger back end can
* more easily deal with.
*/
int
dbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@
* @build jdk.test.lib.net.SimpleSSLContext
* @run main/othervm Test1
* @run main/othervm -Djava.net.preferIPv6Addresses=true Test1
* @run main/othervm -Djdk.net.usePlainSocketImpl Test1
* @run main/othervm -Dsun.net.httpserver.maxReqTime=10 Test1
* @run main/othervm -Dsun.net.httpserver.nodelay=true Test1
* @summary Light weight HTTP server

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -27,7 +27,6 @@
* @summary DatagramSocket.send should throw IllegalArgumentException
* when the packet address is not correctly set.
* @run main AddressNotSet
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl AddressNotSet
*/
import java.net.DatagramPacket;

View File

@ -33,8 +33,6 @@
* jdk.test.lib.net.IPSupport
* @run main/othervm DatagramSocketExample
* @run main/othervm -Djava.net.preferIPv4Stack=true DatagramSocketExample
* @run main/othervm -Djdk.usePlainDatagramSocketImpl=true DatagramSocketExample
* @run main/othervm -Djdk.usePlainDatagramSocketImpl=true -Djava.net.preferIPv4Stack=true DatagramSocketExample
*/
import java.io.IOException;

View File

@ -29,8 +29,6 @@
* jdk.test.lib.net.IPSupport
* @run main/othervm DatagramSocketMulticasting
* @run main/othervm -Djava.net.preferIPv4Stack=true DatagramSocketMulticasting
* @run main/othervm -Djdk.usePlainDatagramSocketImpl=true DatagramSocketMulticasting
* @run main/othervm -Djdk.usePlainDatagramSocketImpl=true -Djava.net.preferIPv4Stack=true DatagramSocketMulticasting
*/
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, 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
@ -27,7 +27,6 @@
* @summary Test to see if timeout hangs. Also checks that
* negative timeout value fails as expected.
* @run testng DatagramTimeout
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl DatagramTimeout
*/
import java.net.DatagramPacket;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -37,7 +37,6 @@ import static java.lang.Thread.sleep;
* @summary Check interrupt mechanism for DatagramSocket,
* MulticastSocket, and DatagramSocketAdaptor
* @run main InterruptibleDatagramSocket
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl InterruptibleDatagramSocket
*/
public class InterruptibleDatagramSocket {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2016, 2021, 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
@ -36,7 +36,6 @@ import java.net.SocketException;
* @summary Expected SocketException not thrown when calling bind() with
* setReuseAddress(false)
* @run main/othervm ReuseAddressTest
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl ReuseAddressTest
*/
public class ReuseAddressTest {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -48,7 +48,6 @@ import static org.testng.Assert.expectThrows;
* throw expected Execption when passed a DatagramPacket
* with invalid details
* @run testng SendCheck
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendCheck
*/
public class SendCheck {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,7 @@
*
* @summary DatagramSocket.send should throw exception when connected
* to an invalid destination (on platforms that support it).
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl=false SendDatagramToBadAddress
* @run main/othervm SendDatagramToBadAddress
*/
import java.net.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -49,7 +49,6 @@ import static org.testng.Assert.assertThrows;
* @summary Check that DatagramSocket throws expected
* Exception when sending a DatagramPacket with port 0
* @run testng/othervm -Djava.security.manager=allow SendPortZero
* @run testng/othervm -Djava.security.manager=allow -Djdk.net.usePlainDatagramSocketImpl SendPortZero
*/
public class SendPortZero {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -36,9 +36,6 @@
* @run testng/othervm SendReceiveMaxSize
* @run testng/othervm -Djava.net.preferIPv4Stack=true SendReceiveMaxSize
* @run testng/othervm -Djava.net.preferIPv6Addresses=true SendReceiveMaxSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendReceiveMaxSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl -Djava.net.preferIPv4Stack=true SendReceiveMaxSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl -Djava.net.preferIPv6Addresses=true SendReceiveMaxSize
*/
import jdk.test.lib.RandomFactory;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@ -23,14 +23,149 @@
package java.net;
public class MyDatagramSocketImplFactory implements DatagramSocketImplFactory {
public DatagramSocketImpl createDatagramSocketImpl() {
try {
return DefaultDatagramSocketImplFactory.createDatagramSocketImpl(false);
} catch (SocketException se) {
assert false;
}
import java.io.IOException;
import java.nio.channels.DatagramChannel;
return null;
public class MyDatagramSocketImplFactory implements DatagramSocketImplFactory {
static class MyDatagramSocketImpl extends DatagramSocketImpl {
DatagramSocket ds;
@Override
protected void create() throws SocketException {
try {
ds = DatagramChannel.open().socket();
} catch (IOException ex) { throw new SocketException(ex.getMessage());}
}
@Override
protected void bind(int lport, InetAddress laddr) throws SocketException {
ds.bind(new InetSocketAddress(laddr, lport));
localPort = ds.getLocalPort();
}
@Override
protected void send(DatagramPacket p) throws IOException {
ds.send(p);
}
@Override
protected int peek(InetAddress i) throws IOException {
return 0;
}
@Override
protected int peekData(DatagramPacket p) throws IOException {
return 0;
}
@Override
protected void receive(DatagramPacket p) throws IOException {
ds.receive(p);
}
@Override
protected void setTTL(byte ttl) throws IOException {
}
@Override
protected byte getTTL() throws IOException {
return 0;
}
@Override
protected void setTimeToLive(int ttl) throws IOException {
}
@Override
protected int getTimeToLive() throws IOException {
return 0;
}
@Override
protected void join(InetAddress inetaddr) throws IOException {
}
@Override
protected void leave(InetAddress inetaddr) throws IOException {
}
@Override
protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
}
@Override
protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
}
@Override
protected void close() {
ds.close();
}
@Override
public void setOption(int optID, Object value) throws SocketException {
try {
if (optID == SocketOptions.SO_SNDBUF) {
if (((Integer) value).intValue() < 0)
throw new IllegalArgumentException("Invalid send buffer size:" + value);
ds.setOption(StandardSocketOptions.SO_SNDBUF, (Integer) value);
} else if (optID == SocketOptions.SO_RCVBUF) {
if (((Integer) value).intValue() < 0)
throw new IllegalArgumentException("Invalid recv buffer size:" + value);
ds.setOption(StandardSocketOptions.SO_RCVBUF, (Integer) value);
} else if (optID == SocketOptions.SO_REUSEADDR) {
ds.setOption(StandardSocketOptions.SO_REUSEADDR, (Boolean) value);
} else if (optID == SocketOptions.SO_REUSEPORT) {
ds.setOption(StandardSocketOptions.SO_REUSEPORT, (Boolean) value);
} else if (optID == SocketOptions.SO_BROADCAST) {
ds.setOption(StandardSocketOptions.SO_BROADCAST, (Boolean) value);
} else if (optID == SocketOptions.IP_TOS) {
int i = ((Integer) value).intValue();
if (i < 0 || i > 255)
throw new IllegalArgumentException("Invalid IP_TOS value: " + value);
ds.setOption(StandardSocketOptions.IP_TOS, (Integer) value);
} else if (optID == SocketOptions.IP_MULTICAST_LOOP) {
boolean enable = (boolean) value;
// Legacy ds.setOption expects true to mean 'disabled'
ds.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, !enable);
} else {
throw new AssertionError("unknown option :" + optID);
}
} catch (IOException ex) { throw new SocketException(ex.getMessage()); }
}
@Override
public Object getOption(int optID) throws SocketException {
try {
if (optID == SocketOptions.SO_SNDBUF) {
return ds.getOption(StandardSocketOptions.SO_SNDBUF);
} else if (optID == SocketOptions.SO_RCVBUF) {
return ds.getOption(StandardSocketOptions.SO_RCVBUF);
} else if (optID == SocketOptions.SO_REUSEADDR) {
return ds.getOption(StandardSocketOptions.SO_REUSEADDR);
} else if (optID == SocketOptions.SO_REUSEPORT) {
return ds.getOption(StandardSocketOptions.SO_REUSEPORT);
} else if (optID == SocketOptions.SO_BROADCAST) {
return ds.getOption(StandardSocketOptions.SO_BROADCAST);
} else if (optID == SocketOptions.IP_TOS) {
return ds.getOption(StandardSocketOptions.IP_TOS);
} else if (optID == SocketOptions.IP_MULTICAST_LOOP) {
boolean disabled = (boolean) ds.getOption(StandardSocketOptions.IP_MULTICAST_LOOP);
// Legacy getOption returns true when disabled
return Boolean.valueOf(!disabled);
} else {
throw new AssertionError("unknown option: " + optID);
}
} catch (IOException ex) { throw new SocketException(ex.getMessage()); }
}
}
@Override
public MyDatagramSocketImpl createDatagramSocketImpl() {
return new MyDatagramSocketImpl();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@ -27,7 +27,6 @@
* @summary Check that setReceiveBufferSize and getReceiveBufferSize work as expected
* @run testng SetGetReceiveBufferSize
* @run testng/othervm -Djava.net.preferIPv4Stack=true SetGetReceiveBufferSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetGetReceiveBufferSize
*/
import org.testng.annotations.DataProvider;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@
* @summary Check that setSendBufferSize and getSendBufferSize work as expected
* @run testng SetGetSendBufferSize
* @run testng/othervm -Djava.net.preferIPv4Stack=true SetGetSendBufferSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetGetSendBufferSize
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl -Djava.net.preferIPv4Stack=true SetGetSendBufferSize
*/
import jdk.test.lib.Platform;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2021 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
@ -26,7 +26,6 @@
* @bug 6505016
* @summary Socket spec should clarify what getInetAddress/getPort/etc return after the Socket is closed
* @run main TestAfterClose
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl TestAfterClose
*/
import java.net.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@
* java.base/sun.net java.base/sun.nio.ch:+open
* @run main/othervm UnreferencedDatagramSockets
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedDatagramSockets
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl UnreferencedDatagramSockets
* @summary Check that unreferenced datagram sockets are closed
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2021 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
@ -26,7 +26,6 @@
* @bug 6427403
* @summary java.net.MulticastSocket.joinGroup() reports 'socket closed'
* @run main B6427403
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl B6427403
*/
import java.net.*;
import java.io.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@
* @summary Test that MutlicastSocket.joinGroup is working for
* various multicast and non-multicast addresses.
* @run main MulticastAddresses
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl MulticastAddresses
*/
import jdk.test.lib.NetworkConfiguration;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@
* @run main/othervm NoSetNetworkInterface
* @run main/othervm -Djava.net.preferIPv4Stack=true NoSetNetworkInterface
* @run main/othervm -Djava.net.preferIPv6Addresses=true NoSetNetworkInterface
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl NoSetNetworkInterface
* @summary Check that methods that are used to set and get the NetworkInterface
* for a MulticastSocket work as expected. This test also checks that getOption
* returns null correctly when a NetworkInterface has not been set

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021, 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
@ -26,7 +26,6 @@
* @library /test/lib
* @summary Test for interference when two sockets are bound to the same
* port but joined to different multicast groups
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl Promiscuous
* @run main Promiscuous
* @run main/othervm -Djava.net.preferIPv4Stack=true Promiscuous
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -49,7 +49,6 @@ import static org.testng.Assert.assertThrows;
* @summary Check that MulticastSocket throws expected
* Exception when sending a DatagramPacket with port 0
* @run testng/othervm -Djava.security.manager=allow SendPortZero
* @run testng/othervm -Djava.security.manager=allow -Djdk.net.usePlainDatagramSocketImpl SendPortZero
*/
public class SendPortZero {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@ -30,7 +30,6 @@
* @build jdk.test.lib.NetworkConfiguration
* jdk.test.lib.Platform
* @run main/othervm SetLoopbackMode
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackMode
*/
import java.lang.reflect.Method;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,8 +32,6 @@
* SetLoopbackMode
* SetLoopbackModeIPv4
* @run main/othervm -Djava.net.preferIPv4Stack=true SetLoopbackModeIPv4
* @run main/othervm -Djava.net.preferIPv4Stack=true
* -Djdk.net.usePlainDatagramSocketImpl SetLoopbackModeIPv4
*/
import jdk.test.lib.net.IPSupport;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -31,7 +31,6 @@
* @run testng/othervm SetLoopbackOption
* @run testng/othervm -Djava.net.preferIPv4Stack=true SetLoopbackOption
* @run testng/othervm -Djava.net.preferIPv6Addresses=true SetLoopbackOption
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackOption
*/
import java.io.FileDescriptor;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2021, 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
@ -26,7 +26,6 @@
* @bug 4742177 8241786
* @library /test/lib
* @run main/othervm SetOutgoingIf
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetOutgoingIf
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
*/
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021 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
@ -25,7 +25,6 @@
* @bug 4189640
* @summary Make setTTL/getTTL works
* @run main SetTTLAndGetTTL
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLAndGetTTL
*/
import java.net.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021 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
@ -25,7 +25,6 @@
* @bug 4148757
* @summary Make sure TTL can be set to 0
* @run main SetTTLTo0
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLTo0
*/
import java.net.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -27,7 +27,6 @@
* @modules java.management java.base/java.io:+open java.base/java.net:+open
* java.base/sun.net java.base/sun.nio.ch:+open
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedMulticastSockets
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl UnreferencedMulticastSockets
* @run main/othervm UnreferencedMulticastSockets
* @summary Check that unreferenced multicast sockets are closed
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021 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
@ -25,7 +25,7 @@
* @test
* @author Gary Ellison
* @bug 4106600
* @summary java.net.PlainSocketImpl backlog value bug avoidance
* @summary java.net.SocketImpl backlog value bug avoidance
*/
import java.io.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021 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
@ -24,7 +24,7 @@
/*
* @test
* @bug 8024952
* @summary ClassCastException in PlainSocketImpl.accept() when using custom socketImpl
* @summary ClassCastException in SocketImpl.accept() when using custom socketImpl
* @run main/othervm CustomSocketImplFactory
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2021, 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
@ -24,7 +24,7 @@
/*
* @test
* @bug 4165948
* @summary java.net.PlainSocketImpl {set,get}Option throws SocketException
* @summary java.net.SocketImpl {set,get}Option throws SocketException
* when socket is closed.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2021, 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
@ -41,7 +41,6 @@
* jdk.test.lib.process.*
* AcceptCauseFileDescriptorLeak
* @run main/othervm AcceptCauseFileDescriptorLeak root
* @run main/othervm -Djdk.net.usePlainSocketImpl AcceptCauseFileDescriptorLeak root
*/
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@ -27,7 +27,6 @@
* @modules java.management java.base/java.io:+open java.base/java.net:+open
* @run main/othervm UnreferencedSockets
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedSockets
* @run main/othervm -Djdk.net.usePlainSocketImpl UnreferencedSockets
* @summary Check that unreferenced sockets are closed
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@
* SocketAddress
* @run main AddressTest
* @run main/othervm -Djava.net.preferIPv4Stack=true AddressTest
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl AddressTest
*/
import java.net.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -24,7 +24,6 @@
/**
* @test
* @run testng ConnectionReset
* @run testng/othervm -Djdk.net.usePlainSocketImpl ConnectionReset
* @summary Test behavior of read and available when a connection is reset
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -24,11 +24,9 @@
/**
* @test
* @bug 8237858
* @summary PlainSocketImpl.socketAccept() handles EINTR incorrectly
* @summary SocketImpl.socketAccept() handles EINTR incorrectly
* @requires (os.family != "windows")
* @compile NativeThread.java
* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketAcceptInterruptTest 0
* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketAcceptInterruptTest 5000
* @run main/othervm/native SocketAcceptInterruptTest 0
* @run main/othervm/native SocketAcceptInterruptTest 5000
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 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
@ -24,12 +24,10 @@
/**
* @test
* @bug 8237858
* @summary PlainSocketImpl.socketAccept() handles EINTR incorrectly
* @summary SocketImpl.socketAccept() handles EINTR incorrectly
* @requires (os.family != "windows")
* @compile NativeThread.java
* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketReadInterruptTest 2000 3000
* @run main/othervm/native SocketReadInterruptTest 2000 3000
* @run main/othervm/native -Djdk.net.usePlainSocketImpl=true SocketReadInterruptTest 2000 0
* @run main/othervm/native SocketReadInterruptTest 2000 0
*/
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@ -35,7 +35,6 @@ import static java.util.concurrent.CompletableFuture.*;
* cause any thread blocked on the socket to throw a SocketException.
* @run main AsyncClose
* @run main/othervm -Djava.net.preferIPv4Stack=true AsyncClose
* @run main/othervm -Djdk.net.usePlainSocketImpl AsyncClose
*/
public class AsyncClose {

View File

@ -1,81 +0,0 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8221481
* @modules java.base/java.net:+open java.base/sun.nio.ch:+open
* @run testng CompareSocketOptions
* @summary Compare the set of socket options supported by the old and new SocketImpls
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class CompareSocketOptions {
/**
* Test that the old and new platform SocketImpl support the same set of
* client socket options.
*/
public void testClientSocketSupportedOptions() throws IOException {
Socket s1 = new Socket(createOldSocketImpl(false)) { };
Socket s2 = new Socket(createNewSocketImpl(false)) { };
assertEquals(s1.supportedOptions(), s2.supportedOptions());
}
/**
* Test that the old and new platform SocketImpl support the same set of
* server socket options.
*/
public void testServerSocketSupportedOptions() throws IOException {
ServerSocket ss1 = new ServerSocket(createOldSocketImpl(true)) { };
ServerSocket ss2 = new ServerSocket(createNewSocketImpl(true)) { };
assertEquals(ss1.supportedOptions(), ss2.supportedOptions());
}
private static SocketImpl createOldSocketImpl(boolean server) {
return newPlatformSocketImpl("java.net.PlainSocketImpl", server);
}
private static SocketImpl createNewSocketImpl(boolean server) {
return newPlatformSocketImpl("sun.nio.ch.NioSocketImpl", server);
}
private static SocketImpl newPlatformSocketImpl(String name, boolean server) {
try {
var ctor = Class.forName(name).getDeclaredConstructor(boolean.class);
ctor.setAccessible(true);
return (SocketImpl) ctor.newInstance(server);
} catch (Exception e) {
fail("Should not get here", e);
return null;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -26,8 +26,6 @@
* @bug 8224477
* @summary Ensures that IOException is thrown after the socket is closed
* @run testng AfterClose
* @run testng/othervm -Djdk.net.usePlainSocketImpl AfterClose
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl AfterClose
*/
import java.io.IOException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -26,7 +26,6 @@
* @bug 8224477
* @summary Basic test for NPE, UOE, and IAE for get/setOption
* @run testng NullsAndBadValues
* @run testng/othervm -Djdk.net.usePlainSocketImpl NullsAndBadValues
* @run testng/othervm -Dsun.net.useExclusiveBind=false NullsAndBadValues
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, 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
@ -27,8 +27,6 @@
* @library /test/lib
* @requires !vm.graal.enabled
* @run main/othervm -Xcheck:jni OptionsTest
* @run main/othervm -Djdk.net.usePlainSocketImpl OptionsTest
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl OptionsTest
* @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest
* @run main/othervm --limit-modules=java.base OptionsTest
* @run main/othervm/policy=options.policy OptionsTest

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 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
@ -43,7 +43,6 @@ import static java.net.StandardSocketOptions.*;
* @bug 8235141
* @summary verifies that our implementation supports the set
* of SocketOptions that are required by the API documentation.
* @run testng/othervm -Djdk.net.usePlainSocketImpl RequiredOptions
* @run testng/othervm RequiredOptions
*/
public class RequiredOptions {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,7 +32,6 @@
* @build jdk.test.lib.NetworkConfiguration
* jdk.test.lib.Platform
* @run main TcpTest -d
* @run main/othervm -Djdk.net.usePlainSocketImpl TcpTest -d
*/
import java.net.*;