8216978: Drop support for pre JDK 1.4 SocketImpl implementations

Reviewed-by: chegar, alanb, dfuchs
This commit is contained in:
Michael McMahon 2019-05-02 17:29:10 +01:00
parent 5a496e21d5
commit 70ea5ab6e1
14 changed files with 109 additions and 463 deletions

View file

@ -74,6 +74,12 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
/* 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;
@ -105,6 +111,10 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
return isReusePortAvailable;
}
AbstractPlainSocketImpl(boolean isServer) {
super(isServer);
}
/**
* Returns a set of SocketOptions supported by this impl and by this impl's
* socket (Socket or ServerSocket)
@ -148,10 +158,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
socketCreate(true);
SocketCleanable.register(fd);
}
if (socket != null)
socket.setCreated();
if (serverSocket != null)
serverSocket.setCreated();
}
/**
@ -180,6 +186,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
it will be passed up the call stack */
}
}
isConnected = connected;
}
}
@ -195,6 +202,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
try {
connectToAddress(address, port, timeout);
isConnected = true;
return;
} catch (IOException e) {
// everything failed
@ -236,6 +244,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
it will be passed up the call stack */
}
}
isConnected = connected;
}
}
@ -393,7 +402,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
synchronized (fdLock) {
if (!closePending && (socket == null || !socket.isBound())) {
if (!closePending && !isBound) {
NetHooks.beforeTcpConnect(fd, address, port);
}
}
@ -407,14 +416,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
throw new SocketException ("Socket closed");
}
}
// If we have a ref. to the Socket, then sets the flags
// created, bound & connected to true.
// This is normally done in Socket.connect() but some
// subclasses of Socket may call impl.connect() directly!
if (socket != null) {
socket.setBound();
socket.setConnected();
}
} finally {
releaseFD();
}
@ -433,15 +434,12 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
throws IOException
{
synchronized (fdLock) {
if (!closePending && (socket == null || !socket.isBound())) {
if (!closePending && !isBound) {
NetHooks.beforeTcpBind(fd, address, lport);
}
}
socketBind(address, lport);
if (socket != null)
socket.setBound();
if (serverSocket != null)
serverSocket.setBound();
isBound = true;
}
/**
@ -727,7 +725,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl implements PlatformSoc
socketClose0(false);
}
abstract void socketCreate(boolean isServer) throws IOException;
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)

View file

@ -51,6 +51,7 @@ import java.util.Set;
private static final Method doTunneling;
private final String server;
private final Socket socket;
private InetSocketAddress external_address;
private HashMap<Integer, Object> optionsMap = new HashMap<>();
@ -75,8 +76,9 @@ import java.util.Set;
}
}
HttpConnectSocketImpl(Proxy proxy, SocketImpl delegate) {
HttpConnectSocketImpl(Proxy proxy, SocketImpl delegate, Socket socket) {
super(delegate);
this.socket = socket;
SocketAddress a = proxy.address();
if ( !(a instanceof InetSocketAddress) )
throw new IllegalArgumentException("Unsupported address type");
@ -96,17 +98,6 @@ import java.util.Set;
connect(new InetSocketAddress(address, port), 0);
}
@Override
void setSocket(Socket socket) {
delegate.socket = socket;
super.setSocket(socket);
}
@Override
void setServerSocket(ServerSocket socket) {
throw new InternalError("should not get here");
}
@Override
protected void connect(SocketAddress endpoint, int timeout)
throws IOException
@ -137,7 +128,7 @@ import java.util.Set;
// update the Sockets impl to the impl from the http Socket
SocketImpl si = httpSocket.impl;
getSocket().setImpl(si);
socket.setImpl(si);
// best effort is made to try and reset options previously set
Set<Map.Entry<Integer,Object>> options = optionsMap.entrySet();

View file

@ -71,11 +71,6 @@ class ServerSocket implements java.io.Closeable {
*/
private SocketImpl impl;
/**
* Are we using an older SocketImpl?
*/
private boolean oldImpl = false;
/**
* Creates a server socket with a user-specified {@code SocketImpl}.
*
@ -87,7 +82,6 @@ class ServerSocket implements java.io.Closeable {
*/
protected ServerSocket(SocketImpl impl) {
this.impl = impl;
impl.setServerSocket(this);
}
/**
@ -270,36 +264,13 @@ class ServerSocket implements java.io.Closeable {
return impl;
}
private void checkOldImpl() {
if (impl == null)
return;
// SocketImpl.connect() is a protected method, therefore we need to use
// getDeclaredMethod, therefore we need permission to access the member
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() throws NoSuchMethodException {
impl.getClass().getDeclaredMethod("connect",
SocketAddress.class,
int.class);
return null;
}
});
} catch (java.security.PrivilegedActionException e) {
oldImpl = true;
}
}
private void setImpl() {
SocketImplFactory factory = ServerSocket.factory;
if (factory != null) {
impl = factory.createSocketImpl();
checkOldImpl();
} else {
impl = SocketImpl.createPlatformSocketImpl(true);
}
if (impl != null)
impl.setServerSocket(this);
}
/**
@ -368,7 +339,7 @@ class ServerSocket implements java.io.Closeable {
public void bind(SocketAddress endpoint, int backlog) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
if (!oldImpl && isBound())
if (isBound())
throw new SocketException("Already bound");
if (endpoint == null)
endpoint = new InetSocketAddress(0);
@ -722,8 +693,7 @@ class ServerSocket implements java.io.Closeable {
* @since 1.4
*/
public boolean isBound() {
// Before 1.3 ServerSockets were always bound during creation
return bound || oldImpl;
return bound;
}
/**
@ -866,14 +836,6 @@ class ServerSocket implements java.io.Closeable {
",localport=" + impl.getLocalPort() + "]";
}
void setBound() {
bound = true;
}
void setCreated() {
created = true;
}
/**
* The factory for all server sockets.
*/

View file

@ -71,11 +71,6 @@ class Socket implements java.io.Closeable {
*/
SocketImpl impl;
/**
* Are we using an older SocketImpl?
*/
private boolean oldImpl = false;
/**
* Socket input/output streams
*/
@ -158,8 +153,7 @@ class Socket implements java.io.Closeable {
// create a SOCKS or HTTP SocketImpl that delegates to a platform SocketImpl
SocketImpl delegate = SocketImpl.createPlatformSocketImpl(false);
impl = (type == Proxy.Type.SOCKS) ? new SocksSocketImpl(p, delegate)
: new HttpConnectSocketImpl(p, delegate);
impl.setSocket(this);
: new HttpConnectSocketImpl(p, delegate, this);
} else {
if (p == Proxy.NO_PROXY) {
// create a platform or custom SocketImpl for the DIRECT case
@ -169,7 +163,6 @@ class Socket implements java.io.Closeable {
} else {
impl = factory.createSocketImpl();
}
impl.setSocket(this);
} else
throw new IllegalArgumentException("Invalid Proxy");
}
@ -188,10 +181,6 @@ class Socket implements java.io.Closeable {
*/
protected Socket(SocketImpl impl) throws SocketException {
this.impl = impl;
if (impl != null) {
checkOldImpl();
this.impl.setSocket(this);
}
}
/**
@ -486,37 +475,8 @@ class Socket implements java.io.Closeable {
}
}
private void checkOldImpl() {
if (impl == null)
return;
// SocketImpl.connect() is a protected method, therefore we need to use
// getDeclaredMethod, therefore we need permission to access the member
oldImpl = AccessController.doPrivileged
(new PrivilegedAction<>() {
public Boolean run() {
Class<?> clazz = impl.getClass();
while (true) {
try {
clazz.getDeclaredMethod("connect", SocketAddress.class, int.class);
return Boolean.FALSE;
} catch (NoSuchMethodException e) {
clazz = clazz.getSuperclass();
// java.net.SocketImpl class will always have this abstract method.
// If we have not found it by now in the hierarchy then it does not
// exist, we are an old style impl.
if (clazz.equals(java.net.SocketImpl.class)) {
return Boolean.TRUE;
}
}
}
}
});
}
void setImpl(SocketImpl si) {
impl = si;
impl.setSocket(this);
}
/**
@ -527,14 +487,11 @@ class Socket implements java.io.Closeable {
SocketImplFactory factory = Socket.factory;
if (factory != null) {
impl = factory.createSocketImpl();
checkOldImpl();
} else {
// create a SOCKS SocketImpl that delegates to a platform SocketImpl
SocketImpl delegate = SocketImpl.createPlatformSocketImpl(false);
impl = new SocksSocketImpl(delegate);
}
if (impl != null)
impl.setSocket(this);
}
/**
@ -596,7 +553,7 @@ class Socket implements java.io.Closeable {
if (isClosed())
throw new SocketException("Socket is closed");
if (!oldImpl && isConnected())
if (isConnected())
throw new SocketException("already connected");
if (!(endpoint instanceof InetSocketAddress))
@ -616,15 +573,7 @@ class Socket implements java.io.Closeable {
}
if (!created)
createImpl(true);
if (!oldImpl)
impl.connect(epoint, timeout);
else if (timeout == 0) {
if (epoint.isUnresolved())
impl.connect(addr.getHostName(), port);
else
impl.connect(addr, port);
} else
throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
impl.connect(epoint, timeout);
connected = true;
/*
* If the socket was not bound before the connect, it is now because
@ -654,7 +603,7 @@ class Socket implements java.io.Closeable {
public void bind(SocketAddress bindpoint) throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
if (!oldImpl && isBound())
if (isBound())
throw new SocketException("Already bound");
if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress)))
@ -694,18 +643,6 @@ class Socket implements java.io.Closeable {
bound = true;
}
void setCreated() {
created = true;
}
void setBound() {
bound = true;
}
void setConnected() {
connected = true;
}
/**
* Returns the address to which the socket is connected.
* <p>
@ -957,6 +894,7 @@ class Socket implements java.io.Closeable {
private static class SocketInputStream extends InputStream {
private final Socket parent;
private final InputStream in;
SocketInputStream(Socket parent, InputStream in) {
this.parent = parent;
this.in = in;
@ -975,6 +913,7 @@ class Socket implements java.io.Closeable {
public int available() throws IOException {
return in.available();
}
@Override
public void close() throws IOException {
parent.close();
@ -1040,6 +979,7 @@ class Socket implements java.io.Closeable {
public void write(byte b[], int off, int len) throws IOException {
out.write(b, off, len);
}
@Override
public void close() throws IOException {
parent.close();
@ -1672,8 +1612,7 @@ class Socket implements java.io.Closeable {
* @since 1.4
*/
public boolean isConnected() {
// Before 1.3 Sockets were always connected during creation
return connected || oldImpl;
return connected;
}
/**
@ -1689,8 +1628,7 @@ class Socket implements java.io.Closeable {
* @see #bind
*/
public boolean isBound() {
// Before 1.3 Sockets were always bound during creation
return bound || oldImpl;
return bound;
}
/**

View file

@ -51,15 +51,9 @@ public abstract class SocketImpl implements SocketOptions {
*/
@SuppressWarnings("unchecked")
static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {
return (S) new PlainSocketImpl();
return (S) new PlainSocketImpl(server);
}
/**
* The actual Socket object.
*/
Socket socket = null;
ServerSocket serverSocket = null;
/**
* The file descriptor object for this socket.
*/
@ -80,6 +74,23 @@ public abstract class SocketImpl implements SocketOptions {
*/
protected int localport;
/**
* Whether this is a server or not.
*/
final boolean isServer;
SocketImpl(boolean isServer) {
this.isServer = isServer;
}
/**
* Initialize a new instance of this class
*/
public SocketImpl() {
this.isServer = false;
}
/**
* Creates either a stream or a datagram socket.
*
@ -300,22 +311,6 @@ public abstract class SocketImpl implements SocketOptions {
return localport;
}
void setSocket(Socket soc) {
this.socket = soc;
}
Socket getSocket() {
return socket;
}
void setServerSocket(ServerSocket soc) {
this.serverSocket = soc;
}
ServerSocket getServerSocket() {
return serverSocket;
}
/**
* Returns the address and port of this socket as a {@code String}.
*
@ -395,11 +390,9 @@ public abstract class SocketImpl implements SocketOptions {
* @since 9
*/
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
if (name == StandardSocketOptions.SO_KEEPALIVE &&
(getSocket() != null)) {
if (name == StandardSocketOptions.SO_KEEPALIVE && !isServer) {
setOption(SocketOptions.SO_KEEPALIVE, value);
} else if (name == StandardSocketOptions.SO_SNDBUF &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.SO_SNDBUF && !isServer) {
setOption(SocketOptions.SO_SNDBUF, value);
} else if (name == StandardSocketOptions.SO_RCVBUF) {
setOption(SocketOptions.SO_RCVBUF, value);
@ -408,13 +401,11 @@ public abstract class SocketImpl implements SocketOptions {
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
supportedOptions().contains(name)) {
setOption(SocketOptions.SO_REUSEPORT, value);
} else if (name == StandardSocketOptions.SO_LINGER &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.SO_LINGER && !isServer) {
setOption(SocketOptions.SO_LINGER, value);
} else if (name == StandardSocketOptions.IP_TOS) {
setOption(SocketOptions.IP_TOS, value);
} else if (name == StandardSocketOptions.TCP_NODELAY &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.TCP_NODELAY && !isServer) {
setOption(SocketOptions.TCP_NODELAY, value);
} else {
throw new UnsupportedOperationException("unsupported option");
@ -438,11 +429,9 @@ public abstract class SocketImpl implements SocketOptions {
*/
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
if (name == StandardSocketOptions.SO_KEEPALIVE &&
(getSocket() != null)) {
if (name == StandardSocketOptions.SO_KEEPALIVE && !isServer) {
return (T)getOption(SocketOptions.SO_KEEPALIVE);
} else if (name == StandardSocketOptions.SO_SNDBUF &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.SO_SNDBUF && !isServer) {
return (T)getOption(SocketOptions.SO_SNDBUF);
} else if (name == StandardSocketOptions.SO_RCVBUF) {
return (T)getOption(SocketOptions.SO_RCVBUF);
@ -451,13 +440,11 @@ public abstract class SocketImpl implements SocketOptions {
} else if (name == StandardSocketOptions.SO_REUSEPORT &&
supportedOptions().contains(name)) {
return (T)getOption(SocketOptions.SO_REUSEPORT);
} else if (name == StandardSocketOptions.SO_LINGER &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.SO_LINGER && !isServer) {
return (T)getOption(SocketOptions.SO_LINGER);
} else if (name == StandardSocketOptions.IP_TOS) {
return (T)getOption(SocketOptions.IP_TOS);
} else if (name == StandardSocketOptions.TCP_NODELAY &&
(getSocket() != null)) {
} else if (name == StandardSocketOptions.TCP_NODELAY && !isServer) {
return (T)getOption(SocketOptions.TCP_NODELAY);
} else {
throw new UnsupportedOperationException("unsupported option");
@ -504,7 +491,7 @@ public abstract class SocketImpl implements SocketOptions {
* @since 9
*/
protected Set<SocketOption<?>> supportedOptions() {
if (getSocket() != null) {
if (!isServer) {
return socketOptions;
} else {
return serverSocketOptions;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@ -48,7 +48,6 @@ class SocketInputStream extends FileInputStream {
private boolean eof;
private AbstractPlainSocketImpl impl = null;
private byte temp[];
private Socket socket = null;
/**
* Creates a new SocketInputStream. Can only be called
@ -59,7 +58,6 @@ class SocketInputStream extends FileInputStream {
SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
}
/**
@ -236,27 +234,16 @@ class SocketInputStream extends FileInputStream {
return eof ? 0 : available;
}
/**
* Closes the stream.
*/
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}
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;
}
/**
* Overrides finalize, the fd is closed by the Socket.
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@ -45,7 +45,6 @@ class SocketOutputStream extends FileOutputStream {
private AbstractPlainSocketImpl impl = null;
private byte temp[] = new byte[1];
private Socket socket = null;
/**
* Creates a new SocketOutputStream. Can only be called
@ -56,7 +55,6 @@ class SocketOutputStream extends FileOutputStream {
SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
super(impl.getFileDescriptor());
this.impl = impl;
socket = impl.getSocket();
}
/**
@ -150,21 +148,10 @@ class SocketOutputStream extends FileOutputStream {
socketWrite(b, off, len);
}
/**
* Closes the stream.
*/
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
// No longer used. Socket.getOutputStream returns an
// OutputStream which calls Socket.close directly
assert false;
}
/**

View file

@ -256,17 +256,6 @@ class SocksSocketImpl extends DelegatingSocketImpl implements SocksConsts {
connect(new InetSocketAddress(address, port), 0);
}
@Override
void setSocket(Socket soc) {
delegate.socket = soc;
super.setSocket(soc);
}
@Override
void setServerSocket(ServerSocket soc) {
throw new InternalError("should not get here");
}
/**
* Connects the Socks Socket to the specified endpoint. It will first
* connect to the SOCKS proxy and negotiate the access. If the proxy