8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
Reviewed-by: alanb, chegar, hawtin
This commit is contained in:
parent
7fc34775d1
commit
7938121238
@ -390,15 +390,29 @@ class ServerSocket implements java.io.Closeable {
|
|||||||
* If the socket was bound prior to being {@link #close closed},
|
* If the socket was bound prior to being {@link #close closed},
|
||||||
* then this method will continue to return the local address
|
* then this method will continue to return the local address
|
||||||
* after the socket is closed.
|
* after the socket is closed.
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* the {@link InetAddress#getLoopbackAddress loopback} address is returned.
|
||||||
*
|
*
|
||||||
* @return the address to which this socket is bound,
|
* @return the address to which this socket is bound,
|
||||||
* or <code>null</code> if the socket is unbound.
|
* or the loopback address if denied by the security manager,
|
||||||
|
* or {@code null} if the socket is unbound.
|
||||||
|
*
|
||||||
|
* @see SecurityManager#checkConnect
|
||||||
*/
|
*/
|
||||||
public InetAddress getInetAddress() {
|
public InetAddress getInetAddress() {
|
||||||
if (!isBound())
|
if (!isBound())
|
||||||
return null;
|
return null;
|
||||||
try {
|
try {
|
||||||
return getImpl().getInetAddress();
|
InetAddress in = getImpl().getInetAddress();
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm != null)
|
||||||
|
sm.checkConnect(in.getHostAddress(), -1);
|
||||||
|
return in;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
return InetAddress.getLoopbackAddress();
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
// nothing
|
// nothing
|
||||||
// If we're bound, the impl has been created
|
// If we're bound, the impl has been created
|
||||||
@ -431,18 +445,28 @@ class ServerSocket implements java.io.Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the address of the endpoint this socket is bound to, or
|
* Returns the address of the endpoint this socket is bound to.
|
||||||
* <code>null</code> if it is not bound yet.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the socket was bound prior to being {@link #close closed},
|
* If the socket was bound prior to being {@link #close closed},
|
||||||
* then this method will continue to return the address of the endpoint
|
* then this method will continue to return the address of the endpoint
|
||||||
* after the socket is closed.
|
* after the socket is closed.
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link InetAddress#getLoopbackAddress loopback} address and the local
|
||||||
|
* port to which the socket is bound is returned.
|
||||||
|
*
|
||||||
|
* @return a {@code SocketAddress} representing the local endpoint of
|
||||||
|
* this socket, or a {@code SocketAddress} representing the
|
||||||
|
* loopback address if denied by the security manager,
|
||||||
|
* or {@code null} if the socket is not bound yet.
|
||||||
*
|
*
|
||||||
* @return a <code>SocketAddress</code> representing the local endpoint of this
|
|
||||||
* socket, or <code>null</code> if it is not bound yet.
|
|
||||||
* @see #getInetAddress()
|
* @see #getInetAddress()
|
||||||
* @see #getLocalPort()
|
* @see #getLocalPort()
|
||||||
* @see #bind(SocketAddress)
|
* @see #bind(SocketAddress)
|
||||||
|
* @see SecurityManager#checkConnect
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -708,13 +732,25 @@ class ServerSocket implements java.io.Closeable {
|
|||||||
/**
|
/**
|
||||||
* Returns the implementation address and implementation port of
|
* Returns the implementation address and implementation port of
|
||||||
* this socket as a <code>String</code>.
|
* this socket as a <code>String</code>.
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* an {@code InetAddress} representing the
|
||||||
|
* {@link InetAddress#getLoopbackAddress loopback} address is returned as
|
||||||
|
* the implementation address.
|
||||||
*
|
*
|
||||||
* @return a string representation of this socket.
|
* @return a string representation of this socket.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (!isBound())
|
if (!isBound())
|
||||||
return "ServerSocket[unbound]";
|
return "ServerSocket[unbound]";
|
||||||
return "ServerSocket[addr=" + impl.getInetAddress() +
|
InetAddress in;
|
||||||
|
if (System.getSecurityManager() != null)
|
||||||
|
in = InetAddress.getLoopbackAddress();
|
||||||
|
else
|
||||||
|
in = impl.getInetAddress();
|
||||||
|
return "ServerSocket[addr=" + in +
|
||||||
",localport=" + impl.getLocalPort() + "]";
|
",localport=" + impl.getLocalPort() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,11 +682,18 @@ class Socket implements java.io.Closeable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local address to which the socket is bound.
|
* Gets the local address to which the socket is bound.
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* the {@link InetAddress#getLoopbackAddress loopback} address is returned.
|
||||||
*
|
*
|
||||||
* @return the local address to which the socket is bound, or
|
* @return the local address to which the socket is bound,
|
||||||
* the {@link InetAddress#isAnyLocalAddress wildcard} address
|
* the loopback address if denied by the security manager, or
|
||||||
* if the socket is closed or not bound yet.
|
* the wildcard address if the socket is closed or not bound yet.
|
||||||
* @since JDK1.1
|
* @since JDK1.1
|
||||||
|
*
|
||||||
|
* @see SecurityManager#checkConnect
|
||||||
*/
|
*/
|
||||||
public InetAddress getLocalAddress() {
|
public InetAddress getLocalAddress() {
|
||||||
// This is for backward compatibility
|
// This is for backward compatibility
|
||||||
@ -695,9 +702,14 @@ class Socket implements java.io.Closeable {
|
|||||||
InetAddress in = null;
|
InetAddress in = null;
|
||||||
try {
|
try {
|
||||||
in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
|
in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm != null)
|
||||||
|
sm.checkConnect(in.getHostAddress(), -1);
|
||||||
if (in.isAnyLocalAddress()) {
|
if (in.isAnyLocalAddress()) {
|
||||||
in = InetAddress.anyLocalAddress();
|
in = InetAddress.anyLocalAddress();
|
||||||
}
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
in = InetAddress.getLoopbackAddress();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
in = InetAddress.anyLocalAddress(); // "0.0.0.0"
|
in = InetAddress.anyLocalAddress(); // "0.0.0.0"
|
||||||
}
|
}
|
||||||
@ -770,8 +782,7 @@ class Socket implements java.io.Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the address of the endpoint this socket is bound to, or
|
* Returns the address of the endpoint this socket is bound to.
|
||||||
* <code>null</code> if it is not bound yet.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If a socket bound to an endpoint represented by an
|
* If a socket bound to an endpoint represented by an
|
||||||
* <code>InetSocketAddress </code> is {@link #close closed},
|
* <code>InetSocketAddress </code> is {@link #close closed},
|
||||||
@ -780,12 +791,23 @@ class Socket implements java.io.Closeable {
|
|||||||
* <code>InetSocketAddress</code>'s address is the
|
* <code>InetSocketAddress</code>'s address is the
|
||||||
* {@link InetAddress#isAnyLocalAddress wildcard} address
|
* {@link InetAddress#isAnyLocalAddress wildcard} address
|
||||||
* and its port is the local port that it was bound to.
|
* and its port is the local port that it was bound to.
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link InetAddress#getLoopbackAddress loopback} address and the local
|
||||||
|
* port to which this socket is bound is returned.
|
||||||
|
*
|
||||||
|
* @return a {@code SocketAddress} representing the local endpoint of
|
||||||
|
* this socket, or a {@code SocketAddress} representing the
|
||||||
|
* loopback address if denied by the security manager, or
|
||||||
|
* {@code null} if the socket is not bound yet.
|
||||||
*
|
*
|
||||||
* @return a <code>SocketAddress</code> representing the local endpoint of this
|
|
||||||
* socket, or <code>null</code> if it is not bound yet.
|
|
||||||
* @see #getLocalAddress()
|
* @see #getLocalAddress()
|
||||||
* @see #getLocalPort()
|
* @see #getLocalPort()
|
||||||
* @see #bind(SocketAddress)
|
* @see #bind(SocketAddress)
|
||||||
|
* @see SecurityManager#checkConnect
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import sun.net.SocksProxy;
|
import sun.net.SocksProxy;
|
||||||
import sun.net.www.ParseUtil;
|
import sun.net.www.ParseUtil;
|
||||||
@ -590,7 +591,13 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
|
|||||||
/* Test for AnyLocal */
|
/* Test for AnyLocal */
|
||||||
InetAddress naddr = baddr;
|
InetAddress naddr = baddr;
|
||||||
if (naddr.isAnyLocalAddress()) {
|
if (naddr.isAnyLocalAddress()) {
|
||||||
naddr = cmdsock.getLocalAddress();
|
naddr = AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetAddress>() {
|
||||||
|
public InetAddress run() {
|
||||||
|
return cmdsock.getLocalAddress();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
addr1 = naddr.getAddress();
|
addr1 = naddr.getAddress();
|
||||||
}
|
}
|
||||||
out.write(PROTO_VERS4);
|
out.write(PROTO_VERS4);
|
||||||
|
@ -297,4 +297,25 @@ public abstract class AsynchronousServerSocketChannel
|
|||||||
* If this channel's socket has not yet been bound
|
* If this channel's socket has not yet been bound
|
||||||
*/
|
*/
|
||||||
public abstract Future<AsynchronousSocketChannel> accept();
|
public abstract Future<AsynchronousSocketChannel> accept();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
|
||||||
|
* local port of the channel's socket is returned.
|
||||||
|
*
|
||||||
|
* @return The {@code SocketAddress} that the socket is bound to, or the
|
||||||
|
* {@code SocketAddress} representing the loopback address if
|
||||||
|
* denied by the security manager, or {@code null} if the
|
||||||
|
* channel's socket is not bound
|
||||||
|
*
|
||||||
|
* @throws ClosedChannelException {@inheritDoc}
|
||||||
|
* @throws IOException {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract SocketAddress getLocalAddress() throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -645,4 +645,24 @@ public abstract class AsynchronousSocketChannel
|
|||||||
TimeUnit unit,
|
TimeUnit unit,
|
||||||
A attachment,
|
A attachment,
|
||||||
CompletionHandler<Long,? super A> handler);
|
CompletionHandler<Long,? super A> handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
|
||||||
|
* local port of the channel's socket is returned.
|
||||||
|
*
|
||||||
|
* @return The {@code SocketAddress} that the socket is bound to, or the
|
||||||
|
* {@code SocketAddress} representing the loopback address if
|
||||||
|
* denied by the security manager, or {@code null} if the
|
||||||
|
* channel's socket is not bound
|
||||||
|
*
|
||||||
|
* @throws ClosedChannelException {@inheritDoc}
|
||||||
|
* @throws IOException {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public abstract SocketAddress getLocalAddress() throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -565,4 +565,25 @@ public abstract class DatagramChannel
|
|||||||
return write(srcs, 0, srcs.length);
|
return write(srcs, 0, srcs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
|
||||||
|
* local port of the channel's socket is returned.
|
||||||
|
*
|
||||||
|
* @return The {@code SocketAddress} that the socket is bound to, or the
|
||||||
|
* {@code SocketAddress} representing the loopback address if
|
||||||
|
* denied by the security manager, or {@code null} if the
|
||||||
|
* channel's socket is not bound
|
||||||
|
*
|
||||||
|
* @throws ClosedChannelException {@inheritDoc}
|
||||||
|
* @throws IOException {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract SocketAddress getLocalAddress() throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,7 @@ public interface NetworkChannel
|
|||||||
NetworkChannel bind(SocketAddress local) throws IOException;
|
NetworkChannel bind(SocketAddress local) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the socket address that this channel's socket is bound to, or
|
* Returns the socket address that this channel's socket is bound to.
|
||||||
* {@code null} if the socket is not bound.
|
|
||||||
*
|
*
|
||||||
* <p> Where the channel is {@link #bind bound} to an Internet Protocol
|
* <p> Where the channel is {@link #bind bound} to an Internet Protocol
|
||||||
* socket address then the return value from this method is of type {@link
|
* socket address then the return value from this method is of type {@link
|
||||||
|
@ -265,4 +265,25 @@ public abstract class ServerSocketChannel
|
|||||||
*/
|
*/
|
||||||
public abstract SocketChannel accept() throws IOException;
|
public abstract SocketChannel accept() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
|
||||||
|
* local port of the channel's socket is returned.
|
||||||
|
*
|
||||||
|
* @return The {@code SocketAddress} that the socket is bound to, or the
|
||||||
|
* {@code SocketAddress} representing the loopback address if
|
||||||
|
* denied by the security manager, or {@code null} if the
|
||||||
|
* channel's socket is not bound
|
||||||
|
*
|
||||||
|
* @throws ClosedChannelException {@inheritDoc}
|
||||||
|
* @throws IOException {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract SocketAddress getLocalAddress() throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -493,4 +493,25 @@ public abstract class SocketChannel
|
|||||||
return write(srcs, 0, srcs.length);
|
return write(srcs, 0, srcs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* If there is a security manager set, its {@code checkConnect} method is
|
||||||
|
* called with the local address and {@code -1} as its arguments to see
|
||||||
|
* if the operation is allowed. If the operation is not allowed,
|
||||||
|
* a {@code SocketAddress} representing the
|
||||||
|
* {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
|
||||||
|
* local port of the channel's socket is returned.
|
||||||
|
*
|
||||||
|
* @return The {@code SocketAddress} that the socket is bound to, or the
|
||||||
|
* {@code SocketAddress} representing the loopback address if
|
||||||
|
* denied by the security manager, or {@code null} if the
|
||||||
|
* channel's socket is not bound
|
||||||
|
*
|
||||||
|
* @throws ClosedChannelException {@inheritDoc}
|
||||||
|
* @throws IOException {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract SocketAddress getLocalAddress() throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,13 @@ public class NetworkClient {
|
|||||||
protected InetAddress getLocalAddress() throws IOException {
|
protected InetAddress getLocalAddress() throws IOException {
|
||||||
if (serverSocket == null)
|
if (serverSocket == null)
|
||||||
throw new IOException("not connected");
|
throw new IOException("not connected");
|
||||||
|
return AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetAddress>() {
|
||||||
|
public InetAddress run() {
|
||||||
return serverSocket.getLocalAddress();
|
return serverSocket.getLocalAddress();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Close an open connection to the server. */
|
/** Close an open connection to the server. */
|
||||||
|
@ -76,7 +76,10 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
|||||||
private FtpReplyCode lastReplyCode = null;
|
private FtpReplyCode lastReplyCode = null;
|
||||||
/** Welcome message from the server, if any. */
|
/** Welcome message from the server, if any. */
|
||||||
private String welcomeMsg;
|
private String welcomeMsg;
|
||||||
private boolean passiveMode = true;
|
/**
|
||||||
|
* Only passive mode used in JDK. See Bug 8010784.
|
||||||
|
*/
|
||||||
|
private final boolean passiveMode = true;
|
||||||
private TransferType type = TransferType.BINARY;
|
private TransferType type = TransferType.BINARY;
|
||||||
private long restartOffset = 0;
|
private long restartOffset = 0;
|
||||||
private long lastTransSize = -1; // -1 means 'unknown size'
|
private long lastTransSize = -1; // -1 means 'unknown size'
|
||||||
@ -645,9 +648,18 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
|||||||
} else {
|
} else {
|
||||||
s = new Socket();
|
s = new Socket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InetAddress serverAddress = AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetAddress>() {
|
||||||
|
@Override
|
||||||
|
public InetAddress run() {
|
||||||
|
return server.getLocalAddress();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Bind the socket to the same address as the control channel. This
|
// Bind the socket to the same address as the control channel. This
|
||||||
// is needed in case of multi-homed systems.
|
// is needed in case of multi-homed systems.
|
||||||
s.bind(new InetSocketAddress(server.getLocalAddress(), 0));
|
s.bind(new InetSocketAddress(serverAddress, 0));
|
||||||
if (connectTimeout >= 0) {
|
if (connectTimeout >= 0) {
|
||||||
s.connect(dest, connectTimeout);
|
s.connect(dest, connectTimeout);
|
||||||
} else {
|
} else {
|
||||||
@ -816,7 +828,9 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
|||||||
* @see #setActiveMode()
|
* @see #setActiveMode()
|
||||||
*/
|
*/
|
||||||
public sun.net.ftp.FtpClient enablePassiveMode(boolean passive) {
|
public sun.net.ftp.FtpClient enablePassiveMode(boolean passive) {
|
||||||
passiveMode = passive;
|
|
||||||
|
// Only passive mode used in JDK. See Bug 8010784.
|
||||||
|
// passiveMode = passive;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ import java.util.logging.Logger;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
import com.sun.net.httpserver.*;
|
import com.sun.net.httpserver.*;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import sun.net.httpserver.HttpConnection.State;
|
import sun.net.httpserver.HttpConnection.State;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,7 +246,14 @@ class ServerImpl implements TimeSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress getAddress() {
|
public InetSocketAddress getAddress() {
|
||||||
return (InetSocketAddress)schan.socket().getLocalSocketAddress();
|
return AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetSocketAddress>() {
|
||||||
|
public InetSocketAddress run() {
|
||||||
|
return
|
||||||
|
(InetSocketAddress)schan.socket()
|
||||||
|
.getLocalSocketAddress();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Selector getSelector () {
|
Selector getSelector () {
|
||||||
|
@ -51,7 +51,7 @@ abstract class AsynchronousServerSocketChannelImpl
|
|||||||
protected final FileDescriptor fd;
|
protected final FileDescriptor fd;
|
||||||
|
|
||||||
// the local address to which the channel's socket is bound
|
// the local address to which the channel's socket is bound
|
||||||
protected volatile SocketAddress localAddress = null;
|
protected volatile InetSocketAddress localAddress = null;
|
||||||
|
|
||||||
// need this lock to set local address
|
// need this lock to set local address
|
||||||
private final Object stateLock = new Object();
|
private final Object stateLock = new Object();
|
||||||
@ -173,7 +173,7 @@ abstract class AsynchronousServerSocketChannelImpl
|
|||||||
public final SocketAddress getLocalAddress() throws IOException {
|
public final SocketAddress getLocalAddress() throws IOException {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
return localAddress;
|
return Net.getRevealedLocalAddress(localAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -251,7 +251,7 @@ abstract class AsynchronousServerSocketChannelImpl
|
|||||||
if (localAddress == null) {
|
if (localAddress == null) {
|
||||||
sb.append("unbound");
|
sb.append("unbound");
|
||||||
} else {
|
} else {
|
||||||
sb.append(localAddress.toString());
|
sb.append(Net.getRevealedLocalAddressAsString(localAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append(']');
|
sb.append(']');
|
||||||
|
@ -53,8 +53,8 @@ abstract class AsynchronousSocketChannelImpl
|
|||||||
// protects state, localAddress, and remoteAddress
|
// protects state, localAddress, and remoteAddress
|
||||||
protected final Object stateLock = new Object();
|
protected final Object stateLock = new Object();
|
||||||
|
|
||||||
protected volatile SocketAddress localAddress = null;
|
protected volatile InetSocketAddress localAddress = null;
|
||||||
protected volatile SocketAddress remoteAddress = null;
|
protected volatile InetSocketAddress remoteAddress = null;
|
||||||
|
|
||||||
// State, increases monotonically
|
// State, increases monotonically
|
||||||
static final int ST_UNINITIALIZED = -1;
|
static final int ST_UNINITIALIZED = -1;
|
||||||
@ -442,7 +442,7 @@ abstract class AsynchronousSocketChannelImpl
|
|||||||
public final SocketAddress getLocalAddress() throws IOException {
|
public final SocketAddress getLocalAddress() throws IOException {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
return localAddress;
|
return Net.getRevealedLocalAddress(localAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -582,7 +582,8 @@ abstract class AsynchronousSocketChannelImpl
|
|||||||
}
|
}
|
||||||
if (localAddress != null) {
|
if (localAddress != null) {
|
||||||
sb.append(" local=");
|
sb.append(" local=");
|
||||||
sb.append(localAddress.toString());
|
sb.append(
|
||||||
|
Net.getRevealedLocalAddressAsString(localAddress));
|
||||||
}
|
}
|
||||||
if (remoteAddress != null) {
|
if (remoteAddress != null) {
|
||||||
sb.append(" remote=");
|
sb.append(" remote=");
|
||||||
|
@ -85,8 +85,8 @@ class DatagramChannelImpl
|
|||||||
private int state = ST_UNINITIALIZED;
|
private int state = ST_UNINITIALIZED;
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
private SocketAddress localAddress;
|
private InetSocketAddress localAddress;
|
||||||
private SocketAddress remoteAddress;
|
private InetSocketAddress remoteAddress;
|
||||||
|
|
||||||
// Our socket adaptor, if any
|
// Our socket adaptor, if any
|
||||||
private DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
@ -168,7 +168,8 @@ class DatagramChannelImpl
|
|||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
return localAddress;
|
// Perform security check before returning address
|
||||||
|
return Net.getRevealedLocalAddress(localAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,6 +722,7 @@ class DatagramChannelImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public DatagramChannel connect(SocketAddress sa) throws IOException {
|
public DatagramChannel connect(SocketAddress sa) throws IOException {
|
||||||
int localPort = 0;
|
int localPort = 0;
|
||||||
|
|
||||||
@ -742,7 +744,7 @@ class DatagramChannelImpl
|
|||||||
|
|
||||||
// Connection succeeded; disallow further invocation
|
// Connection succeeded; disallow further invocation
|
||||||
state = ST_CONNECTED;
|
state = ST_CONNECTED;
|
||||||
remoteAddress = sa;
|
remoteAddress = isa;
|
||||||
sender = isa;
|
sender = isa;
|
||||||
cachedSenderInetAddress = isa.getAddress();
|
cachedSenderInetAddress = isa.getAddress();
|
||||||
cachedSenderPort = isa.getPort();
|
cachedSenderPort = isa.getPort();
|
||||||
@ -761,7 +763,7 @@ class DatagramChannelImpl
|
|||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (!isConnected() || !isOpen())
|
if (!isConnected() || !isOpen())
|
||||||
return this;
|
return this;
|
||||||
InetSocketAddress isa = (InetSocketAddress)remoteAddress;
|
InetSocketAddress isa = remoteAddress;
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if (sm != null)
|
if (sm != null)
|
||||||
sm.checkConnect(isa.getAddress().getHostAddress(),
|
sm.checkConnect(isa.getAddress().getHostAddress(),
|
||||||
|
@ -31,6 +31,7 @@ import java.nio.channels.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
|
||||||
|
|
||||||
public class Net {
|
public class Net {
|
||||||
@ -182,6 +183,34 @@ public class Net {
|
|||||||
translateException(x, false);
|
translateException(x, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local address after performing a SecurityManager#checkConnect.
|
||||||
|
*/
|
||||||
|
static InetSocketAddress getRevealedLocalAddress(InetSocketAddress addr) {
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (addr == null || sm == null)
|
||||||
|
return addr;
|
||||||
|
|
||||||
|
try{
|
||||||
|
sm.checkConnect(addr.getAddress().getHostAddress(), -1);
|
||||||
|
// Security check passed
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// Return loopback address only if security check fails
|
||||||
|
addr = getLoopbackAddress(addr.getPort());
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getRevealedLocalAddressAsString(InetSocketAddress addr) {
|
||||||
|
return System.getSecurityManager() == null ? addr.toString() :
|
||||||
|
getLoopbackAddress(addr.getPort()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InetSocketAddress getLoopbackAddress(int port) {
|
||||||
|
return new InetSocketAddress(InetAddress.getLoopbackAddress(),
|
||||||
|
port);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns any IPv4 address of the given network interface, or
|
* Returns any IPv4 address of the given network interface, or
|
||||||
* null if the interface does not have any IPv4 addresses.
|
* null if the interface does not have any IPv4 addresses.
|
||||||
|
@ -80,7 +80,8 @@ public class ServerSocketAdaptor // package-private
|
|||||||
public InetAddress getInetAddress() {
|
public InetAddress getInetAddress() {
|
||||||
if (!ssc.isBound())
|
if (!ssc.isBound())
|
||||||
return null;
|
return null;
|
||||||
return Net.asInetSocketAddress(ssc.localAddress()).getAddress();
|
return Net.getRevealedLocalAddress(ssc.localAddress()).getAddress();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLocalPort() {
|
public int getLocalPort() {
|
||||||
|
@ -72,7 +72,7 @@ class ServerSocketChannelImpl
|
|||||||
private int state = ST_UNINITIALIZED;
|
private int state = ST_UNINITIALIZED;
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
private SocketAddress localAddress; // null => unbound
|
private InetSocketAddress localAddress; // null => unbound
|
||||||
|
|
||||||
// set true when exclusive binding is on and SO_REUSEADDR is emulated
|
// set true when exclusive binding is on and SO_REUSEADDR is emulated
|
||||||
private boolean isReuseAddress;
|
private boolean isReuseAddress;
|
||||||
@ -116,7 +116,9 @@ class ServerSocketChannelImpl
|
|||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
return localAddress;
|
return localAddress == null ? localAddress
|
||||||
|
: Net.getRevealedLocalAddress(
|
||||||
|
Net.asInetSocketAddress(localAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +192,7 @@ class ServerSocketChannelImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketAddress localAddress() {
|
public InetSocketAddress localAddress() {
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
return localAddress;
|
return localAddress;
|
||||||
}
|
}
|
||||||
@ -384,14 +386,15 @@ class ServerSocketChannelImpl
|
|||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(this.getClass().getName());
|
sb.append(this.getClass().getName());
|
||||||
sb.append('[');
|
sb.append('[');
|
||||||
if (!isOpen())
|
if (!isOpen()) {
|
||||||
sb.append("closed");
|
sb.append("closed");
|
||||||
else {
|
} else {
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (localAddress() == null) {
|
InetSocketAddress addr = localAddress();
|
||||||
|
if (addr == null) {
|
||||||
sb.append("unbound");
|
sb.append("unbound");
|
||||||
} else {
|
} else {
|
||||||
sb.append(localAddress().toString());
|
sb.append(Net.getRevealedLocalAddressAsString(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,9 +149,10 @@ public class SocketAdaptor
|
|||||||
|
|
||||||
public InetAddress getLocalAddress() {
|
public InetAddress getLocalAddress() {
|
||||||
if (sc.isOpen()) {
|
if (sc.isOpen()) {
|
||||||
SocketAddress local = sc.localAddress();
|
InetSocketAddress local = sc.localAddress();
|
||||||
if (local != null)
|
if (local != null) {
|
||||||
return ((InetSocketAddress)local).getAddress();
|
return Net.getRevealedLocalAddress(local).getAddress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new InetSocketAddress(0).getAddress();
|
return new InetSocketAddress(0).getAddress();
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,8 @@ class SocketChannelImpl
|
|||||||
private int state = ST_UNINITIALIZED;
|
private int state = ST_UNINITIALIZED;
|
||||||
|
|
||||||
// Binding
|
// Binding
|
||||||
private SocketAddress localAddress;
|
private InetSocketAddress localAddress;
|
||||||
private SocketAddress remoteAddress;
|
private InetSocketAddress remoteAddress;
|
||||||
|
|
||||||
// Input/Output open
|
// Input/Output open
|
||||||
private boolean isInputOpen = true;
|
private boolean isInputOpen = true;
|
||||||
@ -146,7 +146,7 @@ class SocketChannelImpl
|
|||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new ClosedChannelException();
|
throw new ClosedChannelException();
|
||||||
return localAddress;
|
return Net.getRevealedLocalAddress(localAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,7 +547,7 @@ class SocketChannelImpl
|
|||||||
IOUtil.configureBlocking(fd, block);
|
IOUtil.configureBlocking(fd, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketAddress localAddress() {
|
public InetSocketAddress localAddress() {
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
return localAddress;
|
return localAddress;
|
||||||
}
|
}
|
||||||
@ -974,6 +974,7 @@ class SocketChannelImpl
|
|||||||
return fdVal;
|
return fdVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(this.getClass().getSuperclass().getName());
|
sb.append(this.getClass().getSuperclass().getName());
|
||||||
@ -997,9 +998,10 @@ class SocketChannelImpl
|
|||||||
sb.append(" oshut");
|
sb.append(" oshut");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (localAddress() != null) {
|
InetSocketAddress addr = localAddress();
|
||||||
|
if (addr != null) {
|
||||||
sb.append(" local=");
|
sb.append(" local=");
|
||||||
sb.append(localAddress().toString());
|
sb.append(Net.getRevealedLocalAddressAsString(addr));
|
||||||
}
|
}
|
||||||
if (remoteAddress() != null) {
|
if (remoteAddress() != null) {
|
||||||
sb.append(" remote=");
|
sb.append(" remote=");
|
||||||
|
@ -2230,16 +2230,28 @@ public class Activation implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InetAddress getInetAddress() {
|
public InetAddress getInetAddress() {
|
||||||
|
return AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetAddress>() {
|
||||||
|
@Override
|
||||||
|
public InetAddress run() {
|
||||||
return serverSocket.getInetAddress();
|
return serverSocket.getInetAddress();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public int getLocalPort() {
|
public int getLocalPort() {
|
||||||
return serverSocket.getLocalPort();
|
return serverSocket.getLocalPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketAddress getLocalSocketAddress() {
|
public SocketAddress getLocalSocketAddress() {
|
||||||
|
return AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<SocketAddress>() {
|
||||||
|
@Override
|
||||||
|
public SocketAddress run() {
|
||||||
return serverSocket.getLocalSocketAddress();
|
return serverSocket.getLocalSocketAddress();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delays calling accept on the underlying server socket until the
|
* Delays calling accept on the underlying server socket until the
|
||||||
|
@ -28,6 +28,8 @@ import java.io.*;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The WrappedSocket class provides a general wrapper for providing an
|
* The WrappedSocket class provides a general wrapper for providing an
|
||||||
@ -78,7 +80,14 @@ class WrappedSocket extends Socket {
|
|||||||
* Get the local address to which the socket is bound.
|
* Get the local address to which the socket is bound.
|
||||||
*/
|
*/
|
||||||
public InetAddress getLocalAddress() {
|
public InetAddress getLocalAddress() {
|
||||||
|
return AccessController.doPrivileged(
|
||||||
|
new PrivilegedAction<InetAddress>() {
|
||||||
|
@Override
|
||||||
|
public InetAddress run() {
|
||||||
return socket.getLocalAddress();
|
return socket.getLocalAddress();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,7 +241,7 @@ class UnixAsynchronousSocketChannelImpl
|
|||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
state = ST_CONNECTED;
|
state = ST_CONNECTED;
|
||||||
localAddress = Net.localAddress(fd);
|
localAddress = Net.localAddress(fd);
|
||||||
remoteAddress = pendingRemote;
|
remoteAddress = (InetSocketAddress)pendingRemote;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +94,44 @@ public class SctpNet {
|
|||||||
|
|
||||||
static Set<SocketAddress> getLocalAddresses(int fd)
|
static Set<SocketAddress> getLocalAddresses(int fd)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
HashSet<SocketAddress> set = null;
|
Set<SocketAddress> set = null;
|
||||||
SocketAddress[] saa = getLocalAddresses0(fd);
|
SocketAddress[] saa = getLocalAddresses0(fd);
|
||||||
|
|
||||||
if (saa != null) {
|
if (saa != null) {
|
||||||
set = new HashSet<SocketAddress>(saa.length);
|
set = getRevealedLocalAddressSet(saa);
|
||||||
for (SocketAddress sa : saa)
|
|
||||||
set.add(sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<SocketAddress> getRevealedLocalAddressSet(
|
||||||
|
SocketAddress[] saa)
|
||||||
|
{
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
Set<SocketAddress> set = new HashSet<>(saa.length);
|
||||||
|
for (SocketAddress sa : saa) {
|
||||||
|
set.add(getRevealedLocalAddress(sa, sm));
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SocketAddress getRevealedLocalAddress(SocketAddress sa,
|
||||||
|
SecurityManager sm)
|
||||||
|
{
|
||||||
|
if (sm == null || sa == null)
|
||||||
|
return sa;
|
||||||
|
InetSocketAddress ia = (InetSocketAddress)sa;
|
||||||
|
try{
|
||||||
|
sm.checkConnect(ia.getAddress().getHostAddress(), -1);
|
||||||
|
// Security check passed
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// Return loopback address
|
||||||
|
return new InetSocketAddress(InetAddress.getLoopbackAddress(),
|
||||||
|
ia.getPort());
|
||||||
|
}
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
|
||||||
static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
|
static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
HashSet<SocketAddress> set = null;
|
HashSet<SocketAddress> set = null;
|
||||||
|
@ -137,7 +137,9 @@ class WindowsAsynchronousSocketChannelImpl
|
|||||||
|
|
||||||
// invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
|
// invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
|
||||||
// accept
|
// accept
|
||||||
void setConnected(SocketAddress localAddress, SocketAddress remoteAddress) {
|
void setConnected(InetSocketAddress localAddress,
|
||||||
|
InetSocketAddress remoteAddress)
|
||||||
|
{
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
state = ST_CONNECTED;
|
state = ST_CONNECTED;
|
||||||
this.localAddress = localAddress;
|
this.localAddress = localAddress;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user