OpenJDK / jdk7u / jdk7u-dev / jdk
changeset 6322:cc656d61e713
8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
Reviewed-by: alanb, chegar, hawtin
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/net/NetUtil.java Thu Mar 28 14:59:22 2013 -0700 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, 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.security.AccessController; +import java.security.PrivilegedExceptionAction; + +class NetUtil { + + // Value of jdk.net.revealLocalAddress + private static boolean revealLocalAddress; + + // True if jdk.net.revealLocalAddress had been read + private static volatile boolean propRevealLocalAddr; + + /* + * Returns true if security check on localAddress is disabled + */ + static boolean doRevealLocalAddress() { + return propRevealLocalAddr ? revealLocalAddress + : readRevealLocalAddr(); + + } + + private static boolean readRevealLocalAddr() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + revealLocalAddress = Boolean.parseBoolean( + AccessController.doPrivileged( + new PrivilegedExceptionAction<String>() { + @Override + public String run() { + return System.getProperty( + "jdk.net.revealLocalAddress"); + } + })); + + } catch (Exception e) { + //revealLocalAddress is false + } + propRevealLocalAddr = true; + } + /* + * No security manager, or security check passed or + * jdk.net.revealLocalAddress set to true + */ + return revealLocalAddress; + } + +}
--- a/src/share/classes/java/net/ServerSocket.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/java/net/ServerSocket.java Thu Mar 28 14:59:22 2013 -0700 @@ -399,7 +399,15 @@ if (!isBound()) return null; try { - return getImpl().getInetAddress(); + InetAddress in = getImpl().getInetAddress(); + if (!NetUtil.doRevealLocalAddress()) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkConnect(in.getHostAddress(), -1); + } + return in; + } catch (SecurityException e) { + return InetAddress.getLoopbackAddress(); } catch (SocketException e) { // nothing // If we're bound, the impl has been created @@ -712,13 +720,20 @@ * * @return a string representation of this socket. */ - public String toString() { + public String toString() { if (!isBound()) return "ServerSocket[unbound]"; - return "ServerSocket[addr=" + impl.getInetAddress() + - ",port=" + impl.getPort() + + InetAddress in; + if (!NetUtil.doRevealLocalAddress() && + System.getSecurityManager() != null) + { + in = InetAddress.getLoopbackAddress(); + } else { + in = impl.getInetAddress(); + } + return "ServerSocket[addr=" + in + ",localport=" + impl.getLocalPort() + "]"; - } + } void setBound() { bound = true;
--- a/src/share/classes/java/net/Socket.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/java/net/Socket.java Thu Mar 28 14:59:22 2013 -0700 @@ -693,9 +693,17 @@ InetAddress in = null; try { in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); + + if (!NetUtil.doRevealLocalAddress()) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkConnect(in.getHostAddress(), -1); + } if (in.isAnyLocalAddress()) { in = InetAddress.anyLocalAddress(); } + } catch (SecurityException e) { + in = InetAddress.getLoopbackAddress(); } catch (Exception e) { in = InetAddress.anyLocalAddress(); // "0.0.0.0" }
--- a/src/share/classes/java/net/SocksSocketImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/java/net/SocksSocketImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -28,6 +28,7 @@ import java.io.OutputStream; import java.io.BufferedOutputStream; import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import sun.net.SocksProxy; import sun.net.www.ParseUtil; @@ -590,7 +591,13 @@ /* Test for AnyLocal */ InetAddress naddr = baddr; if (naddr.isAnyLocalAddress()) { - naddr = cmdsock.getLocalAddress(); + naddr = AccessController.doPrivileged( + new PrivilegedAction<InetAddress>() { + public InetAddress run() { + return cmdsock.getLocalAddress(); + + } + }); addr1 = naddr.getAddress(); } out.write(PROTO_VERS4);
--- a/src/share/classes/sun/net/NetworkClient.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/net/NetworkClient.java Thu Mar 28 14:59:22 2013 -0700 @@ -200,7 +200,13 @@ protected InetAddress getLocalAddress() throws IOException { if (serverSocket == null) throw new IOException("not connected"); - return serverSocket.getLocalAddress(); + return AccessController.doPrivileged( + new PrivilegedAction<InetAddress>() { + public InetAddress run() { + return serverSocket.getLocalAddress(); + + } + }); } /** Close an open connection to the server. */
--- a/src/share/classes/sun/net/ftp/impl/FtpClient.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/net/ftp/impl/FtpClient.java Thu Mar 28 14:59:22 2013 -0700 @@ -28,6 +28,7 @@ import java.io.*; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -76,7 +77,10 @@ private FtpReplyCode lastReplyCode = null; /** Welcome message from the server, if any. */ 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 long restartOffset = 0; private long lastTransSize = -1; // -1 means 'unknown size' @@ -645,9 +649,19 @@ } else { 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 // is needed in case of multi-homed systems. - s.bind(new InetSocketAddress(server.getLocalAddress(), 0)); + s.bind(new InetSocketAddress(serverAddress, 0)); + if (connectTimeout >= 0) { s.connect(dest, connectTimeout); } else { @@ -816,7 +830,8 @@ * @see #setActiveMode() */ public sun.net.ftp.FtpClient enablePassiveMode(boolean passive) { - passiveMode = passive; + // Only passive mode used in JDK. See Bug 8010784. + // passiveMode = passive; return this; }
--- a/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -34,6 +34,8 @@ import java.util.logging.Level; import javax.net.ssl.*; import com.sun.net.httpserver.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import sun.net.httpserver.HttpConnection.State; /** @@ -244,7 +246,14 @@ } public InetSocketAddress getAddress() { - return (InetSocketAddress)schan.socket().getLocalSocketAddress(); + return AccessController.doPrivileged( + new PrivilegedAction<InetSocketAddress>() { + public InetSocketAddress run() { + return + (InetSocketAddress)schan.socket() + .getLocalSocketAddress(); + } + }); } Selector getSelector () {
--- a/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -51,7 +51,7 @@ protected final FileDescriptor fd; // 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 private final Object stateLock = new Object(); @@ -173,7 +173,7 @@ public final SocketAddress getLocalAddress() throws IOException { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return Net.getRevealedLocalAddress(localAddress); } @Override @@ -251,7 +251,7 @@ if (localAddress == null) { sb.append("unbound"); } else { - sb.append(localAddress.toString()); + sb.append(Net.getRevealedLocalAddressAsString(localAddress)); } } sb.append(']');
--- a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -53,8 +53,8 @@ // protects state, localAddress, and remoteAddress protected final Object stateLock = new Object(); - protected volatile SocketAddress localAddress = null; - protected volatile SocketAddress remoteAddress = null; + protected volatile InetSocketAddress localAddress = null; + protected volatile InetSocketAddress remoteAddress = null; // State, increases monotonically static final int ST_UNINITIALIZED = -1; @@ -442,7 +442,7 @@ public final SocketAddress getLocalAddress() throws IOException { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return Net.getRevealedLocalAddress(localAddress); } @Override @@ -582,7 +582,8 @@ } if (localAddress != null) { sb.append(" local="); - sb.append(localAddress.toString()); + sb.append( + Net.getRevealedLocalAddressAsString(localAddress)); } if (remoteAddress != null) { sb.append(" remote=");
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -86,8 +86,8 @@ private int state = ST_UNINITIALIZED; // Binding - private SocketAddress localAddress; - private SocketAddress remoteAddress; + private InetSocketAddress localAddress; + private InetSocketAddress remoteAddress; // Our socket adaptor, if any private DatagramSocket socket; @@ -169,7 +169,7 @@ synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return Net.getRevealedLocalAddress(localAddress); } } @@ -722,6 +722,7 @@ } } + @Override public DatagramChannel connect(SocketAddress sa) throws IOException { int localPort = 0; @@ -743,7 +744,7 @@ // Connection succeeded; disallow further invocation state = ST_CONNECTED; - remoteAddress = sa; + remoteAddress = isa; sender = isa; cachedSenderInetAddress = isa.getAddress(); cachedSenderPort = isa.getPort(); @@ -762,7 +763,7 @@ synchronized (stateLock) { if (!isConnected() || !isOpen()) return this; - InetSocketAddress isa = (InetSocketAddress)remoteAddress; + InetSocketAddress isa = remoteAddress; SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(),
--- a/src/share/classes/sun/nio/ch/Net.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/Net.java Thu Mar 28 14:59:22 2013 -0700 @@ -31,6 +31,7 @@ import java.util.*; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; class Net { // package-private @@ -44,6 +45,12 @@ } }; + // Value of jdk.net.revealLocalAddress + private static boolean revealLocalAddress; + + // True if jdk.net.revealLocalAddress had been read + private static volatile boolean propRevealLocalAddress; + // set to true if exclusive binding is on for Windows private static final boolean exclusiveBind; @@ -52,8 +59,8 @@ if (availLevel >= 0) { String exclBindProp = java.security.AccessController.doPrivileged( - new PrivilegedAction<String>() { - @Override + new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty( "sun.net.useExclusiveBind"); @@ -183,6 +190,58 @@ } /** + * 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; + + if (!getRevealLocalAddress()) { + // Return loopback address only if security check fails + try{ + sm.checkConnect(addr.getAddress().getHostAddress(), -1); + //Security check passed + } catch (SecurityException e) { + //Return loopback address + addr = getLoopbackAddress(addr.getPort()); + } + } + return addr; + } + + static String getRevealedLocalAddressAsString(InetSocketAddress addr) { + if (!getRevealLocalAddress() && System.getSecurityManager() != null) + addr = getLoopbackAddress(addr.getPort()); + return addr.toString(); + } + + private static boolean getRevealLocalAddress() { + if (!propRevealLocalAddress) { + try { + revealLocalAddress = Boolean.parseBoolean( + AccessController.doPrivileged( + new PrivilegedExceptionAction<String>() { + public String run() { + return System.getProperty( + "jdk.net.revealLocalAddress"); + } + })); + + } catch (Exception e) { + // revealLocalAddress is false + } + propRevealLocalAddress = true; + } + return revealLocalAddress; + } + + private static InetSocketAddress getLoopbackAddress(int port) { + return new InetSocketAddress(InetAddress.getLoopbackAddress(), + port); + } + + /** * Returns any IPv4 address of the given network interface, or * null if the interface does not have any IPv4 addresses. */
--- a/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 28 14:59:22 2013 -0700 @@ -80,7 +80,8 @@ public InetAddress getInetAddress() { if (!ssc.isBound()) return null; - return Net.asInetSocketAddress(ssc.localAddress()).getAddress(); + return Net.getRevealedLocalAddress(ssc.localAddress()).getAddress(); + } public int getLocalPort() {
--- a/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -72,7 +72,7 @@ private int state = ST_UNINITIALIZED; // Binding - private SocketAddress localAddress; // null => unbound + private InetSocketAddress localAddress; // null => unbound // set true when exclusive binding is on and SO_REUSEADDR is emulated private boolean isReuseAddress; @@ -116,7 +116,9 @@ synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return localAddress == null? localAddress + : Net.getRevealedLocalAddress( + Net.asInetSocketAddress(localAddress)); } } @@ -190,7 +192,7 @@ } } - public SocketAddress localAddress() { + public InetSocketAddress localAddress() { synchronized (stateLock) { return localAddress; } @@ -362,14 +364,15 @@ StringBuffer sb = new StringBuffer(); sb.append(this.getClass().getName()); sb.append('['); - if (!isOpen()) + if (!isOpen()) { sb.append("closed"); - else { + } else { synchronized (stateLock) { - if (localAddress() == null) { + InetSocketAddress addr = localAddress(); + if (addr == null) { sb.append("unbound"); } else { - sb.append(localAddress().toString()); + sb.append(Net.getRevealedLocalAddressAsString(addr)); } } }
--- a/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 28 14:59:22 2013 -0700 @@ -159,9 +159,9 @@ public InetAddress getLocalAddress() { if (sc.isOpen()) { - SocketAddress local = sc.localAddress(); + InetSocketAddress local = sc.localAddress(); if (local != null) - return ((InetSocketAddress)local).getAddress(); + return Net.getRevealedLocalAddress(local).getAddress(); } return new InetSocketAddress(0).getAddress(); }
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -83,8 +83,8 @@ private int state = ST_UNINITIALIZED; // Binding - private SocketAddress localAddress; - private SocketAddress remoteAddress; + private InetSocketAddress localAddress; + private InetSocketAddress remoteAddress; // Input/Output open private boolean isInputOpen = true; @@ -146,7 +146,7 @@ synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return Net.getRevealedLocalAddress(localAddress); } } @@ -547,7 +547,7 @@ IOUtil.configureBlocking(fd, block); } - public SocketAddress localAddress() { + public InetSocketAddress localAddress() { synchronized (stateLock) { return localAddress; } @@ -952,6 +952,7 @@ return fdVal; } + @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append(this.getClass().getSuperclass().getName()); @@ -975,9 +976,10 @@ sb.append(" oshut"); break; } - if (localAddress() != null) { + InetSocketAddress addr = localAddress(); + if (addr != null) { sb.append(" local="); - sb.append(localAddress().toString()); + sb.append(Net.getRevealedLocalAddressAsString(addr)); } if (remoteAddress() != null) { sb.append(" remote=");
--- a/src/share/classes/sun/rmi/server/Activation.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/rmi/server/Activation.java Thu Mar 28 14:59:22 2013 -0700 @@ -2224,7 +2224,13 @@ } public InetAddress getInetAddress() { - return serverSocket.getInetAddress(); + return AccessController.doPrivileged( + new PrivilegedAction<InetAddress>() { + @Override + public InetAddress run() { + return serverSocket.getInetAddress(); + } + }); } public int getLocalPort() { @@ -2232,7 +2238,13 @@ } public SocketAddress getLocalSocketAddress() { - return serverSocket.getLocalSocketAddress(); + return AccessController.doPrivileged( + new PrivilegedAction<SocketAddress>() { + @Override + public SocketAddress run() { + return serverSocket.getLocalSocketAddress(); + } + }); } /**
--- a/src/share/classes/sun/rmi/transport/proxy/WrappedSocket.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/share/classes/sun/rmi/transport/proxy/WrappedSocket.java Thu Mar 28 14:59:22 2013 -0700 @@ -28,6 +28,8 @@ import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; +import java.security.AccessController; +import java.security.PrivilegedAction; /** * The WrappedSocket class provides a general wrapper for providing an @@ -78,7 +80,14 @@ * Get the local address to which the socket is bound. */ public InetAddress getLocalAddress() { - return socket.getLocalAddress(); + return AccessController.doPrivileged( + new PrivilegedAction<InetAddress>() { + @Override + public InetAddress run() { + return socket.getLocalAddress(); + + } + }); } /**
--- a/src/solaris/classes/sun/nio/ch/SctpNet.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/solaris/classes/sun/nio/ch/SctpNet.java Thu Mar 28 14:59:22 2013 -0700 @@ -36,11 +36,18 @@ import sun.security.action.GetPropertyAction; import com.sun.nio.sctp.SctpSocketOption; import static com.sun.nio.sctp.SctpStandardSocketOptions.*; +import java.security.PrivilegedExceptionAction; public class SctpNet { static final String osName = AccessController.doPrivileged( new GetPropertyAction("os.name")); + // Value of jdk.net.revealLocalAddress + private static boolean revealLocalAddress; + + // True if jdk.net.revealLocalAddress had been read + private static volatile boolean propRevealLocalAddr; + /* -- Miscellaneous SCTP utilities -- */ private static boolean IPv4MappedAddresses() { @@ -92,18 +99,65 @@ static Set<SocketAddress> getLocalAddresses(int fd) throws IOException { - HashSet<SocketAddress> set = null; + Set<SocketAddress> set = null; SocketAddress[] saa = getLocalAddresses0(fd); if (saa != null) { - set = new HashSet<SocketAddress>(saa.length); - for (SocketAddress sa : saa) - set.add(sa); + set = getRevealedLocalAddressSet(saa); } 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; + if (!propRevealLocalAddr) { + try { + revealLocalAddress = Boolean.parseBoolean( + AccessController.doPrivileged( + new PrivilegedExceptionAction<String>() { + public String run() { + return System.getProperty( + "jdk.net.revealLocalAddress"); + } + })); + + } catch (Exception e) { + // revealLocalAddress is false + } + propRevealLocalAddr = true; + } + if (!revealLocalAddress) { + try{ + sm.checkConnect(ia.getAddress().getHostAddress(), -1); + //Security check passed + } catch (SecurityException e) { + //Return loopback address + return new InetSocketAddress( + InetAddress.getLoopbackAddress(), ia.getPort()); + } + } + + // Security check passed or jdk.net.revealLocalAddress set to true + return sa; + + } + static Set<SocketAddress> getRemoteAddresses(int fd, int assocId) throws IOException { HashSet<SocketAddress> set = null;
--- a/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -241,7 +241,7 @@ synchronized (stateLock) { state = ST_CONNECTED; localAddress = Net.localAddress(fd); - remoteAddress = pendingRemote; + remoteAddress = (InetSocketAddress)pendingRemote; } }
--- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Mar 28 23:39:28 2013 +0400 +++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Mar 28 14:59:22 2013 -0700 @@ -137,7 +137,9 @@ // invoked by WindowsAsynchronousServerSocketChannelImpl when new connection // accept - void setConnected(SocketAddress localAddress, SocketAddress remoteAddress) { + void setConnected(InetSocketAddress localAddress, + InetSocketAddress remoteAddress) + { synchronized (stateLock) { state = ST_CONNECTED; this.localAddress = localAddress;