summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES10
-rwxr-xr-xjava/allTests.py4
-rw-r--r--java/src/Ice/ConnectionI.java2
-rw-r--r--java/src/IceInternal/EndpointHostResolver.java58
-rw-r--r--java/src/IceInternal/EndpointI.java22
-rw-r--r--java/src/IceInternal/Instance.java24
-rw-r--r--java/src/IceInternal/Network.java77
-rw-r--r--java/src/IceInternal/NetworkProxy.java48
-rw-r--r--java/src/IceInternal/ProtocolPluginFacade.java5
-rw-r--r--java/src/IceInternal/ProtocolPluginFacadeI.java8
-rw-r--r--java/src/IceInternal/SOCKSNetworkProxy.java104
-rw-r--r--java/src/IceInternal/TcpAcceptor.java2
-rw-r--r--java/src/IceInternal/TcpConnector.java20
-rw-r--r--java/src/IceInternal/TcpEndpointI.java25
-rw-r--r--java/src/IceInternal/TcpTransceiver.java180
-rw-r--r--java/src/IceInternal/Transceiver.java2
-rw-r--r--java/src/IceInternal/UdpEndpointI.java25
-rw-r--r--java/src/IceInternal/UdpTransceiver.java2
-rw-r--r--java/src/IceSSL/AcceptorI.java2
-rw-r--r--java/src/IceSSL/ConnectorI.java13
-rw-r--r--java/src/IceSSL/EndpointI.java25
-rw-r--r--java/src/IceSSL/TransceiverI.java266
-rw-r--r--java/test/Glacier2/sessionHelper/Client.java2
-rw-r--r--java/test/Ice/background/Transceiver.java16
24 files changed, 748 insertions, 194 deletions
diff --git a/CHANGES b/CHANGES
index 83eb14924c8..089374b3510 100644
--- a/CHANGES
+++ b/CHANGES
@@ -23,12 +23,22 @@ subdirectory of each language mapping (e.g., cpp/CHANGES).
Changes since version 3.5.0
======================================================================
+
+General Changes
+===============
+
+- Added support for SOCKSv4 proxies to the Ice core in C++, C# and
+ Java. This allows outgoing TCP & SSL connections using IPv4 to be
+ mediated by a network proxy service.
+
+
C++ Changes
===========
- Fixed a bug in slice2cpp that generated invalid C++ code for C++11
asynchronous invocations.
+
C# Changes
==========
diff --git a/java/allTests.py b/java/allTests.py
index 4175079aa75..ba28b83b8f0 100755
--- a/java/allTests.py
+++ b/java/allTests.py
@@ -35,7 +35,7 @@ tests = [
("Ice/seqMapping", ["core"]),
("Ice/exceptions", ["core"]),
("Ice/ami", ["core"]),
- ("Ice/info", ["core", "noipv6", "nocompress"]),
+ ("Ice/info", ["core", "noipv6", "nocompress", "nosocks"]),
("Ice/inheritance", ["core"]),
("Ice/facets", ["core"]),
("Ice/objects", ["core"]),
@@ -68,7 +68,7 @@ tests = [
("Ice/hash", ["once"]),
("Ice/optional", ["once"]),
("Ice/admin", ["core"]),
- ("Ice/metrics", ["core", "nossl", "noipv6", "nocompress"]),
+ ("Ice/metrics", ["core", "nossl", "noipv6", "nocompress", "nosocks"]),
("Ice/enums", ["once"]),
("IceBox/admin", ["core", "noipv6", "nomx"]),
("IceBox/configuration", ["core", "noipv6", "nomx"]),
diff --git a/java/src/Ice/ConnectionI.java b/java/src/Ice/ConnectionI.java
index f597ee65ec9..cf74ec87305 100644
--- a/java/src/Ice/ConnectionI.java
+++ b/java/src/Ice/ConnectionI.java
@@ -1930,7 +1930,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne
private boolean
initialize(int operation)
{
- int s = _transceiver.initialize();
+ int s = _transceiver.initialize(_readStream.getBuffer(), _writeStream.getBuffer());
if(s != IceInternal.SocketOperation.None)
{
scheduleTimeout(s, connectTimeout());
diff --git a/java/src/IceInternal/EndpointHostResolver.java b/java/src/IceInternal/EndpointHostResolver.java
index b5908e3d28a..25f144c66a5 100644
--- a/java/src/IceInternal/EndpointHostResolver.java
+++ b/java/src/IceInternal/EndpointHostResolver.java
@@ -34,9 +34,24 @@ public class EndpointHostResolver
}
}
- public java.util.List<Connector>
+ public java.util.List<Connector>
resolve(String host, int port, Ice.EndpointSelectionType selType, EndpointI endpoint)
{
+ //
+ // Try to get the addresses without DNS lookup. If this doesn't
+ // work, we retry with DNS lookup (and observer).
+ //
+ NetworkProxy networkProxy = _instance.networkProxy();
+ if(networkProxy == null)
+ {
+ java.util.List<java.net.InetSocketAddress> addrs =
+ Network.getAddresses(host, port, _protocol, selType, _preferIPv6);
+ if(!addrs.isEmpty())
+ {
+ return endpoint.connectors(addrs, null);
+ }
+ }
+
Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
Ice.Instrumentation.Observer observer = null;
if(obsv != null)
@@ -47,11 +62,17 @@ public class EndpointHostResolver
observer.attach();
}
}
-
+
java.util.List<Connector> connectors = null;
- try
+ try
{
- connectors = endpoint.connectors(Network.getAddresses(host, port, _protocol, selType, _preferIPv6));
+ if(networkProxy != null)
+ {
+ networkProxy = networkProxy.resolveHost();
+ }
+
+ connectors = endpoint.connectors(Network.getAddresses(host, port, _protocol, selType, _preferIPv6),
+ networkProxy);
}
catch(Ice.LocalException ex)
{
@@ -70,7 +91,7 @@ public class EndpointHostResolver
}
return connectors;
}
-
+
synchronized public void
resolve(String host, int port, Ice.EndpointSelectionType selType, EndpointI endpoint, EndpointI_connectors callback)
{
@@ -163,19 +184,26 @@ public class EndpointHostResolver
{
if(threadObserver != null)
{
- threadObserver.stateChanged(Ice.Instrumentation.ThreadState.ThreadStateIdle,
+ threadObserver.stateChanged(Ice.Instrumentation.ThreadState.ThreadStateIdle,
Ice.Instrumentation.ThreadState.ThreadStateInUseForOther);
}
- r.callback.connectors(r.endpoint.connectors(Network.getAddresses(r.host,
- r.port,
- _protocol,
+ NetworkProxy networkProxy = _instance.networkProxy();
+ if(networkProxy != null)
+ {
+ networkProxy = networkProxy.resolveHost();
+ }
+
+ r.callback.connectors(r.endpoint.connectors(Network.getAddresses(r.host,
+ r.port,
+ _protocol,
r.selType,
- _preferIPv6)));
+ _preferIPv6),
+ networkProxy));
if(threadObserver != null)
{
- threadObserver.stateChanged(Ice.Instrumentation.ThreadState.ThreadStateInUseForOther,
+ threadObserver.stateChanged(Ice.Instrumentation.ThreadState.ThreadStateInUseForOther,
Ice.Instrumentation.ThreadState.ThreadStateIdle);
}
}
@@ -215,9 +243,9 @@ public class EndpointHostResolver
Ice.Instrumentation.CommunicatorObserver obsv = _instance.initializationData().observer;
if(obsv != null)
{
- _observer = obsv.getThreadObserver("Communicator",
- _thread.getName(),
- Ice.Instrumentation.ThreadState.ThreadStateIdle,
+ _observer = obsv.getThreadObserver("Communicator",
+ _thread.getName(),
+ Ice.Instrumentation.ThreadState.ThreadStateIdle,
_observer);
if(_observer != null)
{
@@ -242,7 +270,7 @@ public class EndpointHostResolver
private boolean _destroyed;
private java.util.LinkedList<ResolveEntry> _queue = new java.util.LinkedList<ResolveEntry>();
private Ice.Instrumentation.ThreadObserver _observer;
-
+
private final class HelperThread extends Thread
{
HelperThread()
diff --git a/java/src/IceInternal/EndpointI.java b/java/src/IceInternal/EndpointI.java
index ed4cd9aa195..c50499ac481 100644
--- a/java/src/IceInternal/EndpointI.java
+++ b/java/src/IceInternal/EndpointI.java
@@ -126,6 +126,17 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable<En
//
public abstract boolean equivalent(EndpointI endpoint);
+ public java.util.List<Connector>
+ connectors(java.util.List<java.net.InetSocketAddress> addresses, NetworkProxy proxy)
+ {
+ //
+ // This method must be extended by endpoints which use the EndpointHostResolver to create
+ // connectors from IP addresses.
+ //
+ assert(false);
+ return null;
+ }
+
//
// Compare endpoints for sorting purposes.
//
@@ -148,16 +159,5 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable<En
return 0;
}
- public java.util.List<Connector>
- connectors(java.util.List<java.net.InetSocketAddress> addresses)
- {
- //
- // This method must be extended by endpoints which use the EndpointHostResolver to create
- // connectors from IP addresses.
- //
- assert(false);
- return null;
- }
-
protected String _connectionId = "";
}
diff --git a/java/src/IceInternal/Instance.java b/java/src/IceInternal/Instance.java
index ac49c4cd576..bd20af30ff6 100644
--- a/java/src/IceInternal/Instance.java
+++ b/java/src/IceInternal/Instance.java
@@ -189,6 +189,12 @@ public final class Instance
return _preferIPv6;
}
+ public NetworkProxy
+ networkProxy()
+ {
+ return _networkProxy;
+ }
+
public synchronized ThreadPool
clientThreadPool()
{
@@ -760,8 +766,17 @@ public final class Instance
_proxyFactory = new ProxyFactory(this);
+ final String proxyHost = _initData.properties.getProperty("Ice.SOCKSProxyHost");
+ int defaultIPv6 = 1; // IPv6 enabled by default.
+ if(proxyHost.length() > 0)
+ {
+ final int proxyPort = _initData.properties.getPropertyAsIntWithDefault("Ice.SOCKSProxyPort", 1080);
+ _networkProxy = new SOCKSNetworkProxy(proxyHost, proxyPort);
+ defaultIPv6 = 0; // IPv6 is not supported with SOCKS
+ }
+
boolean ipv4 = _initData.properties.getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0;
- boolean ipv6 = _initData.properties.getPropertyAsIntWithDefault("Ice.IPv6", 1) > 0;
+ boolean ipv6 = _initData.properties.getPropertyAsIntWithDefault("Ice.IPv6", defaultIPv6) > 0;
if(!ipv4 && !ipv6)
{
throw new Ice.InitializationException("Both IPV4 and IPv6 support cannot be disabled.");
@@ -779,6 +794,12 @@ public final class Instance
_protocolSupport = Network.EnableIPv6;
}
_preferIPv6 = _initData.properties.getPropertyAsInt("Ice.PreferIPv6Address") > 0;
+
+ if(ipv6 && _networkProxy instanceof SOCKSNetworkProxy)
+ {
+ throw new Ice.InitializationException("IPv6 is not supported with SOCKS4 proxies");
+ }
+
_endpointFactoryManager = new EndpointFactoryManager(this);
EndpointFactory tcpEndpointFactory = new TcpEndpointFactory(this);
_endpointFactoryManager.add(tcpEndpointFactory);
@@ -1204,6 +1225,7 @@ public final class Instance
private ObjectAdapterFactory _objectAdapterFactory;
private int _protocolSupport;
private boolean _preferIPv6;
+ private NetworkProxy _networkProxy;
private ThreadPool _clientThreadPool;
private ThreadPool _serverThreadPool;
private EndpointHostResolver _endpointHostResolver;
diff --git a/java/src/IceInternal/Network.java b/java/src/IceInternal/Network.java
index c406ef7b893..e37abd25c75 100644
--- a/java/src/IceInternal/Network.java
+++ b/java/src/IceInternal/Network.java
@@ -1041,6 +1041,41 @@ public final class Network
}
public static String
+ fdToString(java.nio.channels.SelectableChannel fd, NetworkProxy proxy, java.net.InetSocketAddress target)
+ {
+ if(fd == null)
+ {
+ return "<closed>";
+ }
+
+ java.net.InetAddress localAddr = null, remoteAddr = null;
+ int localPort = -1, remotePort = -1;
+
+ if(fd instanceof java.nio.channels.SocketChannel)
+ {
+ java.net.Socket socket = ((java.nio.channels.SocketChannel)fd).socket();
+ localAddr = socket.getLocalAddress();
+ localPort = socket.getLocalPort();
+ remoteAddr = socket.getInetAddress();
+ remotePort = socket.getPort();
+ }
+ else if(fd instanceof java.nio.channels.DatagramChannel)
+ {
+ java.net.DatagramSocket socket = ((java.nio.channels.DatagramChannel)fd).socket();
+ localAddr = socket.getLocalAddress();
+ localPort = socket.getLocalPort();
+ remoteAddr = socket.getInetAddress();
+ remotePort = socket.getPort();
+ }
+ else
+ {
+ assert(false);
+ }
+
+ return addressesToString(localAddr, localPort, remoteAddr, remotePort, proxy, target);
+ }
+
+ public static String
fdToString(java.nio.channels.SelectableChannel fd)
{
if(fd == null)
@@ -1092,25 +1127,57 @@ public final class Network
}
public static String
- addressesToString(java.net.InetAddress localAddr, int localPort, java.net.InetAddress remoteAddr, int remotePort)
+ addressesToString(java.net.InetAddress localAddr, int localPort, java.net.InetAddress remoteAddr, int remotePort,
+ NetworkProxy proxy, java.net.InetSocketAddress target)
{
StringBuilder s = new StringBuilder(128);
s.append("local address = ");
s.append(addrToString(localAddr, localPort));
- if(remoteAddr == null)
+
+ if(proxy != null)
{
- s.append("\nremote address = <not connected>");
+ if(remoteAddr == null)
+ {
+ java.net.InetSocketAddress addr = proxy.getAddress();
+ remoteAddr = addr.getAddress();
+ remotePort = addr.getPort();
+ }
+ s.append("\n");
+ s.append(proxy.getName());
+ s.append(" proxy address = ");
+ s.append(addrToString(remoteAddr, remotePort));
+ s.append("\nremote address = ");
+ s.append(addrToString(target.getAddress(), target.getPort()));
}
else
{
- s.append("\nremote address = ");
- s.append(addrToString(remoteAddr, remotePort));
+ if(remoteAddr == null && target != null)
+ {
+ remoteAddr = target.getAddress();
+ remotePort = target.getPort();
+ }
+
+ if(remoteAddr == null)
+ {
+ s.append("\nremote address = <not connected>");
+ }
+ else
+ {
+ s.append("\nremote address = ");
+ s.append(addrToString(remoteAddr, remotePort));
+ }
}
return s.toString();
}
public static String
+ addressesToString(java.net.InetAddress localAddr, int localPort, java.net.InetAddress remoteAddr, int remotePort)
+ {
+ return addressesToString(localAddr, localPort, remoteAddr, remotePort, null, null);
+ }
+
+ public static String
addrToString(java.net.InetSocketAddress addr)
{
StringBuilder s = new StringBuilder(128);
diff --git a/java/src/IceInternal/NetworkProxy.java b/java/src/IceInternal/NetworkProxy.java
new file mode 100644
index 00000000000..c035770fd97
--- /dev/null
+++ b/java/src/IceInternal/NetworkProxy.java
@@ -0,0 +1,48 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceInternal;
+
+public interface NetworkProxy
+{
+ //
+ // Write the connection request on the connection established
+ // with the network proxy server. This is called right after
+ // the connection establishment succeeds.
+ //
+ void beginWriteConnectRequest(java.net.InetSocketAddress endpoint, Buffer buf);
+ void endWriteConnectRequest(Buffer buf);
+
+ //
+ // Once the connection request has been sent, this is called
+ // to prepare and read the response from the proxy server.
+ //
+ void beginReadConnectRequestResponse(Buffer buf);
+ void endReadConnectRequestResponse(Buffer buf);
+
+ //
+ // If the proxy host needs to be resolved, this should return
+ // a new NetworkProxy containing the IP address of the proxy.
+ // This is called from the endpoint host resolver thread, so
+ // it's safe if this this method blocks.
+ //
+ NetworkProxy resolveHost();
+
+ //
+ // Returns the IP address of the network proxy. This method
+ // must not block. It's only called on a network proxy object
+ // returned by resolveHost().
+ //
+ java.net.InetSocketAddress getAddress();
+
+ //
+ // Returns the name of the proxy, used for tracing purposes.
+ //
+ String getName();
+}
diff --git a/java/src/IceInternal/ProtocolPluginFacade.java b/java/src/IceInternal/ProtocolPluginFacade.java
index 94533a3eb50..9dfe234ac1e 100644
--- a/java/src/IceInternal/ProtocolPluginFacade.java
+++ b/java/src/IceInternal/ProtocolPluginFacade.java
@@ -33,6 +33,11 @@ public interface ProtocolPluginFacade
boolean getPreferIPv6();
//
+ // Get the network proxy.
+ //
+ NetworkProxy getNetworkProxy();
+
+ //
// Get the default encoding to be used in endpoints.
//
Ice.EncodingVersion getDefaultEncoding();
diff --git a/java/src/IceInternal/ProtocolPluginFacadeI.java b/java/src/IceInternal/ProtocolPluginFacadeI.java
index 229bae0a663..1171e258725 100644
--- a/java/src/IceInternal/ProtocolPluginFacadeI.java
+++ b/java/src/IceInternal/ProtocolPluginFacadeI.java
@@ -53,6 +53,14 @@ public class ProtocolPluginFacadeI implements ProtocolPluginFacade
}
//
+ // Get the network proxy.
+ //
+ public NetworkProxy getNetworkProxy()
+ {
+ return _instance.networkProxy();
+ }
+
+ //
// Get the default encoding to be used in endpoints.
//
public Ice.EncodingVersion
diff --git a/java/src/IceInternal/SOCKSNetworkProxy.java b/java/src/IceInternal/SOCKSNetworkProxy.java
new file mode 100644
index 00000000000..140db18c20f
--- /dev/null
+++ b/java/src/IceInternal/SOCKSNetworkProxy.java
@@ -0,0 +1,104 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceInternal;
+
+public final class SOCKSNetworkProxy implements NetworkProxy
+{
+ public SOCKSNetworkProxy(String host, int port)
+ {
+ _host = host;
+ _port = port;
+ }
+
+ private SOCKSNetworkProxy(java.net.InetSocketAddress address)
+ {
+ _address = address;
+ }
+
+ public void beginWriteConnectRequest(java.net.InetSocketAddress endpoint, Buffer buf)
+ {
+ final java.net.InetAddress addr = endpoint.getAddress();
+ if(addr == null)
+ {
+ throw new Ice.FeatureNotSupportedException("SOCKS4 does not support domain names");
+ }
+ else if(!(addr instanceof java.net.Inet4Address))
+ {
+ throw new Ice.FeatureNotSupportedException("SOCKS4 only supports IPv4 addresses");
+ }
+
+ //
+ // SOCKS connect request
+ //
+ buf.resize(9, false);
+ final java.nio.ByteOrder order = buf.b.order();
+ buf.b.order(java.nio.ByteOrder.BIG_ENDIAN); // Network byte order.
+ buf.b.position(0);
+ buf.b.put((byte)0x04); // SOCKS version 4.
+ buf.b.put((byte)0x01); // Command, establish a TCP/IP stream connection
+ buf.b.putShort((short)endpoint.getPort()); // Port
+ buf.b.put(addr.getAddress()); // IPv4 address
+ buf.b.put((byte)0x00); // User ID.
+ buf.b.position(0);
+ buf.b.limit(buf.size());
+ buf.b.order(order);
+ }
+
+ public void endWriteConnectRequest(Buffer buf)
+ {
+ buf.reset();
+ }
+
+ public void beginReadConnectRequestResponse(Buffer buf)
+ {
+ //
+ // Read the SOCKS4 response whose size is 8 bytes.
+ //
+ buf.resize(8, true);
+ buf.b.position(0);
+ }
+
+ public void endReadConnectRequestResponse(Buffer buf)
+ {
+ buf.b.position(0);
+ byte b1 = buf.b.get();
+ byte b2 = buf.b.get();
+ if(b1 != 0x00 || b2 != 0x5a)
+ {
+ throw new Ice.ConnectFailedException();
+ }
+ buf.reset();
+ }
+
+ public NetworkProxy resolveHost()
+ {
+ assert(_host != null);
+ return new SOCKSNetworkProxy(Network.getAddresses(_host,
+ _port,
+ Network.EnableIPv4,
+ Ice.EndpointSelectionType.Random,
+ false).get(0));
+ }
+
+ public java.net.InetSocketAddress getAddress()
+ {
+ assert(_address != null); // Host must be resolved.
+ return _address;
+ }
+
+ public String getName()
+ {
+ return "SOCKS";
+ }
+
+ private String _host;
+ private int _port;
+ private java.net.InetSocketAddress _address;
+}
diff --git a/java/src/IceInternal/TcpAcceptor.java b/java/src/IceInternal/TcpAcceptor.java
index 44c64957b0b..8d5e2f86989 100644
--- a/java/src/IceInternal/TcpAcceptor.java
+++ b/java/src/IceInternal/TcpAcceptor.java
@@ -66,7 +66,7 @@ class TcpAcceptor implements Acceptor
_logger.trace(_traceLevels.networkCat, s);
}
- return new TcpTransceiver(_instance, fd, true, null);
+ return new TcpTransceiver(_instance, fd);
}
public String
diff --git a/java/src/IceInternal/TcpConnector.java b/java/src/IceInternal/TcpConnector.java
index be65420bb09..2598123423c 100644
--- a/java/src/IceInternal/TcpConnector.java
+++ b/java/src/IceInternal/TcpConnector.java
@@ -25,16 +25,9 @@ final class TcpConnector implements Connector
java.nio.channels.SocketChannel fd = Network.createTcpSocket();
Network.setBlock(fd, false);
Network.setTcpBufSize(fd, _instance.initializationData().properties, _logger);
- boolean connected = Network.doConnect(fd, _addr);
- if(connected)
- {
- if(_traceLevels.network >= 1)
- {
- String s = "tcp connection established\n" + Network.fdToString(fd);
- _logger.trace(_traceLevels.networkCat, s);
- }
- }
- return new TcpTransceiver(_instance, fd, connected, _addr);
+ final java.net.InetSocketAddress addr = _proxy != null ? _proxy.getAddress() : _addr;
+ Network.doConnect(fd, addr);
+ return new TcpTransceiver(_instance, fd, _proxy, _addr);
}
catch(Ice.LocalException ex)
{
@@ -56,7 +49,7 @@ final class TcpConnector implements Connector
public String
toString()
{
- return Network.addrToString(_addr);
+ return Network.addrToString(_proxy == null ? _addr : _proxy.getAddress());
}
public int
@@ -68,12 +61,14 @@ final class TcpConnector implements Connector
//
// Only for use by TcpEndpoint
//
- TcpConnector(Instance instance, java.net.InetSocketAddress addr, int timeout, String connectionId)
+ TcpConnector(Instance instance, java.net.InetSocketAddress addr, NetworkProxy proxy, int timeout,
+ String connectionId)
{
_instance = instance;
_traceLevels = instance.traceLevels();
_logger = instance.initializationData().logger;
_addr = addr;
+ _proxy = proxy;
_timeout = timeout;
_connectionId = connectionId;
@@ -115,6 +110,7 @@ final class TcpConnector implements Connector
private TraceLevels _traceLevels;
private Ice.Logger _logger;
private java.net.InetSocketAddress _addr;
+ private NetworkProxy _proxy;
private int _timeout;
private String _connectionId = "";
private int _hashCode;
diff --git a/java/src/IceInternal/TcpEndpointI.java b/java/src/IceInternal/TcpEndpointI.java
index 5030431f7fb..3b99a9b6a05 100644
--- a/java/src/IceInternal/TcpEndpointI.java
+++ b/java/src/IceInternal/TcpEndpointI.java
@@ -392,8 +392,7 @@ final class TcpEndpointI extends EndpointI
public java.util.List<Connector>
connectors(Ice.EndpointSelectionType selType)
{
- return connectors(Network.getAddresses(_host, _port, _instance.protocolSupport(), selType,
- _instance.preferIPv6()));
+ return _instance.endpointHostResolver().resolve(_host, _port, selType, this);
}
public void
@@ -454,6 +453,17 @@ final class TcpEndpointI extends EndpointI
return tcpEndpointI._host.equals(_host) && tcpEndpointI._port == _port;
}
+ public java.util.List<Connector>
+ connectors(java.util.List<java.net.InetSocketAddress> addresses, NetworkProxy proxy)
+ {
+ java.util.List<Connector> connectors = new java.util.ArrayList<Connector>();
+ for(java.net.InetSocketAddress p : addresses)
+ {
+ connectors.add(new TcpConnector(_instance, p, proxy, _timeout, _connectionId));
+ }
+ return connectors;
+ }
+
public int
hashCode()
{
@@ -515,17 +525,6 @@ final class TcpEndpointI extends EndpointI
return _host.compareTo(p._host);
}
- public java.util.List<Connector>
- connectors(java.util.List<java.net.InetSocketAddress> addresses)
- {
- java.util.List<Connector> connectors = new java.util.ArrayList<Connector>();
- for(java.net.InetSocketAddress p : addresses)
- {
- connectors.add(new TcpConnector(_instance, p, _timeout, _connectionId));
- }
- return connectors;
- }
-
private void
calcHashValue()
{
diff --git a/java/src/IceInternal/TcpTransceiver.java b/java/src/IceInternal/TcpTransceiver.java
index 166cab15488..0f451b9d74b 100644
--- a/java/src/IceInternal/TcpTransceiver.java
+++ b/java/src/IceInternal/TcpTransceiver.java
@@ -19,45 +19,106 @@ final class TcpTransceiver implements Transceiver
}
public int
- initialize()
+ initialize(Buffer readBuffer, Buffer writeBuffer)
{
- if(_state == StateNeedConnect)
- {
- _state = StateConnectPending;
- return SocketOperation.Connect;
- }
- else if(_state <= StateConnectPending)
+ try
{
- try
+ if(_state == StateNeedConnect)
{
- Network.doFinishConnect(_fd);
- _state = StateConnected;
- _desc = Network.fdToString(_fd);
+ _state = StateConnectPending;
+ return SocketOperation.Connect;
}
- catch(Ice.LocalException ex)
+ else if(_state == StateConnectPending)
{
- if(_traceLevels.network >= 2)
+ Network.doFinishConnect(_fd);
+ _desc = Network.fdToString(_fd, _proxy, _addr);
+
+ if(_proxy != null)
{
- java.net.Socket fd = (java.net.Socket)_fd.socket();
- StringBuilder s = new StringBuilder(128);
- s.append("failed to establish tcp connection\n");
- s.append("local address = ");
- s.append(Network.addrToString(fd.getLocalAddress(), fd.getLocalPort()));
- s.append("\nremote address = ");
- assert(_connectAddr != null);
- s.append(Network.addrToString(_connectAddr));
- _logger.trace(_traceLevels.networkCat, s.toString());
+ //
+ // Prepare the read & write buffers in advance.
+ //
+ _proxy.beginWriteConnectRequest(_addr, writeBuffer);
+ _proxy.beginReadConnectRequestResponse(readBuffer);
+
+ //
+ // Write the proxy connection message.
+ //
+ if(write(writeBuffer))
+ {
+ //
+ // Write completed without blocking.
+ //
+ _proxy.endWriteConnectRequest(writeBuffer);
+
+ //
+ // Try to read the response.
+ //
+ Ice.BooleanHolder dummy = new Ice.BooleanHolder();
+ if(read(readBuffer, dummy))
+ {
+ //
+ // Read completed without blocking - fall through.
+ //
+ _proxy.endReadConnectRequestResponse(readBuffer);
+ }
+ else
+ {
+ //
+ // Return SocketOperationRead to indicate we need to complete the read.
+ //
+ _state = StateProxyConnectRequestPending; // Wait for proxy response
+ return SocketOperation.Read;
+ }
+ }
+ else
+ {
+ //
+ // Return SocketOperationWrite to indicate we need to complete the write.
+ //
+ _state = StateProxyConnectRequest; // Send proxy connect request
+ return SocketOperation.Write;
+ }
}
- throw ex;
- }
- if(_traceLevels.network >= 1)
+ _state = StateConnected;
+ }
+ else if(_state == StateProxyConnectRequest)
+ {
+ //
+ // Write completed.
+ //
+ _proxy.endWriteConnectRequest(writeBuffer);
+ _state = StateProxyConnectRequestPending; // Wait for proxy response
+ return SocketOperation.Read;
+ }
+ else if(_state == StateProxyConnectRequestPending)
+ {
+ //
+ // Read completed.
+ //
+ _proxy.endReadConnectRequestResponse(readBuffer);
+ _state = StateConnected;
+ }
+ }
+ catch(Ice.LocalException ex)
+ {
+ if(_traceLevels.network >= 2)
{
- String s = "tcp connection established\n" + _desc;
- _logger.trace(_traceLevels.networkCat, s);
+ StringBuilder s = new StringBuilder(128);
+ s.append("failed to establish tcp connection\n");
+ s.append(Network.fdToString(_fd, _proxy, _addr));
+ _logger.trace(_traceLevels.networkCat, s.toString());
}
+ throw ex;
}
+
assert(_state == StateConnected);
+ if(_traceLevels.network >= 1)
+ {
+ String s = "tcp connection established\n" + _desc;
+ _logger.trace(_traceLevels.networkCat, s);
+ }
return SocketOperation.None;
}
@@ -73,7 +134,7 @@ final class TcpTransceiver implements Transceiver
assert(_fd != null);
try
{
- _fd.close();
+ _fd.close();
}
catch(java.io.IOException ex)
{
@@ -84,8 +145,8 @@ final class TcpTransceiver implements Transceiver
_fd = null;
}
}
-
- @SuppressWarnings("deprecation")
+
+ @SuppressWarnings("deprecation")
public boolean
write(Buffer buf)
{
@@ -169,7 +230,7 @@ final class TcpTransceiver implements Transceiver
return true;
}
- @SuppressWarnings("deprecation")
+ @SuppressWarnings("deprecation")
public boolean
read(Buffer buf, Ice.BooleanHolder moreData)
{
@@ -182,17 +243,17 @@ final class TcpTransceiver implements Transceiver
{
assert(_fd != null);
int ret = _fd.read(buf.b);
-
+
if(ret == -1)
{
throw new Ice.ConnectionLostException();
}
-
+
if(ret == 0)
{
return false;
}
-
+
if(ret > 0)
{
if(_traceLevels.network >= 3)
@@ -261,19 +322,43 @@ final class TcpTransceiver implements Transceiver
}
}
- //
- // Only for use by TcpConnector, TcpAcceptor
- //
- @SuppressWarnings("deprecation")
- TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd, boolean connected,
- java.net.InetSocketAddress connectAddr)
+ @SuppressWarnings("deprecation")
+ TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd, NetworkProxy proxy,
+ java.net.InetSocketAddress addr)
+ {
+ _fd = fd;
+ _proxy = proxy;
+ _addr = addr;
+ _traceLevels = instance.traceLevels();
+ _logger = instance.initializationData().logger;
+ _stats = instance.initializationData().stats;
+ _state = StateNeedConnect;
+ _desc = "";
+
+ _maxSendPacketSize = 0;
+ if(System.getProperty("os.name").startsWith("Windows"))
+ {
+ //
+ // On Windows, limiting the buffer size is important to prevent
+ // poor throughput performances when transfering large amount of
+ // data. See Microsoft KB article KB823764.
+ //
+ _maxSendPacketSize = Network.getSendBufferSize(_fd) / 2;
+ if(_maxSendPacketSize < 512)
+ {
+ _maxSendPacketSize = 0;
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd)
{
_fd = fd;
- _connectAddr = connectAddr;
_traceLevels = instance.traceLevels();
_logger = instance.initializationData().logger;
_stats = instance.initializationData().stats;
- _state = connected ? StateConnected : StateNeedConnect;
+ _state = StateConnected;
_desc = Network.fdToString(_fd);
_maxSendPacketSize = 0;
@@ -310,17 +395,20 @@ final class TcpTransceiver implements Transceiver
}
private java.nio.channels.SocketChannel _fd;
- private java.net.InetSocketAddress _connectAddr;
+ private NetworkProxy _proxy;
+ private java.net.InetSocketAddress _addr;
private TraceLevels _traceLevels;
private Ice.Logger _logger;
-
+
@SuppressWarnings("deprecation")
private Ice.Stats _stats;
private String _desc;
private int _state;
private int _maxSendPacketSize;
-
+
private static final int StateNeedConnect = 0;
private static final int StateConnectPending = 1;
- private static final int StateConnected = 2;
+ private static final int StateProxyConnectRequest = 2;
+ private static final int StateProxyConnectRequestPending = 3;
+ private static final int StateConnected = 4;
}
diff --git a/java/src/IceInternal/Transceiver.java b/java/src/IceInternal/Transceiver.java
index 3ad423f5067..49585e7d708 100644
--- a/java/src/IceInternal/Transceiver.java
+++ b/java/src/IceInternal/Transceiver.java
@@ -18,7 +18,7 @@ public interface Transceiver
//
// Returns the status if the initialize operation.
//
- int initialize();
+ int initialize(Buffer readBuffer, Buffer writeBuffer);
void close();
diff --git a/java/src/IceInternal/UdpEndpointI.java b/java/src/IceInternal/UdpEndpointI.java
index 08bd67b1b15..6568b7ec2b4 100644
--- a/java/src/IceInternal/UdpEndpointI.java
+++ b/java/src/IceInternal/UdpEndpointI.java
@@ -453,8 +453,7 @@ final class UdpEndpointI extends EndpointI
public java.util.List<Connector>
connectors(Ice.EndpointSelectionType selType)
{
- return connectors(Network.getAddresses(_host, _port, _instance.protocolSupport(), selType,
- _instance.preferIPv6()));
+ return _instance.endpointHostResolver().resolve(_host, _port, selType, this);
}
public void
@@ -516,6 +515,17 @@ final class UdpEndpointI extends EndpointI
return udpEndpointI._host.equals(_host) && udpEndpointI._port == _port;
}
+ public java.util.List<Connector>
+ connectors(java.util.List<java.net.InetSocketAddress> addresses, NetworkProxy proxy)
+ {
+ java.util.ArrayList<Connector> connectors = new java.util.ArrayList<Connector>();
+ for(java.net.InetSocketAddress p : addresses)
+ {
+ connectors.add(new UdpConnector(_instance, p, _mcastInterface, _mcastTtl, _connectionId));
+ }
+ return connectors;
+ }
+
public int
hashCode()
{
@@ -589,17 +599,6 @@ final class UdpEndpointI extends EndpointI
return _host.compareTo(p._host);
}
- public java.util.List<Connector>
- connectors(java.util.List<java.net.InetSocketAddress> addresses)
- {
- java.util.ArrayList<Connector> connectors = new java.util.ArrayList<Connector>();
- for(java.net.InetSocketAddress p : addresses)
- {
- connectors.add(new UdpConnector(_instance, p, _mcastInterface, _mcastTtl, _connectionId));
- }
- return connectors;
- }
-
private void
calcHashValue()
{
diff --git a/java/src/IceInternal/UdpTransceiver.java b/java/src/IceInternal/UdpTransceiver.java
index 1b17f8591ab..17ca53e8081 100644
--- a/java/src/IceInternal/UdpTransceiver.java
+++ b/java/src/IceInternal/UdpTransceiver.java
@@ -19,7 +19,7 @@ final class UdpTransceiver implements Transceiver
}
public int
- initialize()
+ initialize(Buffer readBuffer, Buffer writeBuffer)
{
//
// Nothing to do.
diff --git a/java/src/IceSSL/AcceptorI.java b/java/src/IceSSL/AcceptorI.java
index b35ddf1d208..546cdd1213b 100644
--- a/java/src/IceSSL/AcceptorI.java
+++ b/java/src/IceSSL/AcceptorI.java
@@ -89,7 +89,7 @@ final class AcceptorI implements IceInternal.Acceptor
IceInternal.Network.fdToString(fd));
}
- return new TransceiverI(_instance, engine, fd, "", true, true, _adapterName, null);
+ return new TransceiverI(_instance, engine, fd, _adapterName);
}
public String
diff --git a/java/src/IceSSL/ConnectorI.java b/java/src/IceSSL/ConnectorI.java
index 385532102ea..788287c6d0d 100644
--- a/java/src/IceSSL/ConnectorI.java
+++ b/java/src/IceSSL/ConnectorI.java
@@ -35,11 +35,12 @@ final class ConnectorI implements IceInternal.Connector
java.nio.channels.SocketChannel fd = IceInternal.Network.createTcpSocket();
IceInternal.Network.setBlock(fd, false);
IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger);
- boolean connected = IceInternal.Network.doConnect(fd, _addr);
+ final java.net.InetSocketAddress addr = _proxy != null ? _proxy.getAddress() : _addr;
+ IceInternal.Network.doConnect(fd, addr);
try
{
javax.net.ssl.SSLEngine engine = _instance.createSSLEngine(false, _addr);
- return new TransceiverI(_instance, engine, fd, _host, connected, false, "", _addr);
+ return new TransceiverI(_instance, engine, fd, _proxy, _host, _addr);
}
catch(RuntimeException ex)
{
@@ -67,7 +68,7 @@ final class ConnectorI implements IceInternal.Connector
public String
toString()
{
- return IceInternal.Network.addrToString(_addr);
+ return IceInternal.Network.addrToString(_proxy == null ? _addr : _proxy.getAddress());
}
public int
@@ -79,13 +80,14 @@ final class ConnectorI implements IceInternal.Connector
//
// Only for use by EndpointI.
//
- ConnectorI(Instance instance, String host, java.net.InetSocketAddress addr, int timeout,
- String connectionId)
+ ConnectorI(Instance instance, String host, java.net.InetSocketAddress addr, IceInternal.NetworkProxy proxy,
+ int timeout, String connectionId)
{
_instance = instance;
_logger = instance.communicator().getLogger();
_host = host;
_addr = addr;
+ _proxy = proxy;
_timeout = timeout;
_connectionId = connectionId;
@@ -127,6 +129,7 @@ final class ConnectorI implements IceInternal.Connector
private Ice.Logger _logger;
private String _host;
private java.net.InetSocketAddress _addr;
+ private IceInternal.NetworkProxy _proxy;
private int _timeout;
private String _connectionId;
private int _hashCode;
diff --git a/java/src/IceSSL/EndpointI.java b/java/src/IceSSL/EndpointI.java
index b5c9f16cd29..dbd46bda378 100644
--- a/java/src/IceSSL/EndpointI.java
+++ b/java/src/IceSSL/EndpointI.java
@@ -392,8 +392,7 @@ final class EndpointI extends IceInternal.EndpointI
public java.util.List<IceInternal.Connector>
connectors(Ice.EndpointSelectionType selType)
{
- return connectors(IceInternal.Network.getAddresses(_host, _port, _instance.protocolSupport(), selType,
- _instance.preferIPv6()));
+ return _instance.endpointHostResolver().resolve(_host, _port, selType, this);
}
public void
@@ -455,6 +454,17 @@ final class EndpointI extends IceInternal.EndpointI
return sslEndpointI._host.equals(_host) && sslEndpointI._port == _port;
}
+ public java.util.List<IceInternal.Connector>
+ connectors(java.util.List<java.net.InetSocketAddress> addresses, IceInternal.NetworkProxy proxy)
+ {
+ java.util.List<IceInternal.Connector> connectors = new java.util.ArrayList<IceInternal.Connector>();
+ for(java.net.InetSocketAddress p : addresses)
+ {
+ connectors.add(new ConnectorI(_instance, _host, p, proxy, _timeout, _connectionId));
+ }
+ return connectors;
+ }
+
public int
hashCode()
{
@@ -516,17 +526,6 @@ final class EndpointI extends IceInternal.EndpointI
return _host.compareTo(p._host);
}
- public java.util.List<IceInternal.Connector>
- connectors(java.util.List<java.net.InetSocketAddress> addresses)
- {
- java.util.List<IceInternal.Connector> connectors = new java.util.ArrayList<IceInternal.Connector>();
- for(java.net.InetSocketAddress p : addresses)
- {
- connectors.add(new ConnectorI(_instance, _host, p, _timeout, _connectionId));
- }
- return connectors;
- }
-
private void
calcHashValue()
{
diff --git a/java/src/IceSSL/TransceiverI.java b/java/src/IceSSL/TransceiverI.java
index 13d0304ea7e..09435e145ef 100644
--- a/java/src/IceSSL/TransceiverI.java
+++ b/java/src/IceSSL/TransceiverI.java
@@ -23,7 +23,7 @@ final class TransceiverI implements IceInternal.Transceiver
}
public int
- initialize()
+ initialize(IceInternal.Buffer readBuffer, IceInternal.Buffer writeBuffer)
{
try
{
@@ -32,42 +32,90 @@ final class TransceiverI implements IceInternal.Transceiver
_state = StateConnectPending;
return IceInternal.SocketOperation.Connect;
}
- else if(_state <= StateConnectPending)
+ else if(_state == StateConnectPending)
{
IceInternal.Network.doFinishConnect(_fd);
+ _desc = IceInternal.Network.fdToString(_fd, _proxy, _addr);
+
+ if(_proxy != null)
+ {
+ //
+ // Prepare the read & write buffers in advance.
+ //
+ _proxy.beginWriteConnectRequest(_addr, writeBuffer);
+ _proxy.beginReadConnectRequestResponse(readBuffer);
+
+ //
+ // Write the proxy connection message.
+ //
+ if(writeRaw(writeBuffer))
+ {
+ //
+ // Write completed without blocking.
+ //
+ _proxy.endWriteConnectRequest(writeBuffer);
+
+ //
+ // Try to read the response.
+ //
+ if(readRaw(readBuffer))
+ {
+ //
+ // Read completed without blocking - fall through.
+ //
+ _proxy.endReadConnectRequestResponse(readBuffer);
+ }
+ else
+ {
+ //
+ // Return SocketOperationRead to indicate we need to complete the read.
+ //
+ _state = StateProxyConnectRequestPending; // Wait for proxy response
+ return IceInternal.SocketOperation.Read;
+ }
+ }
+ else
+ {
+ //
+ // Return SocketOperationWrite to indicate we need to complete the write.
+ //
+ _state = StateProxyConnectRequest; // Send proxy connect request
+ return IceInternal.SocketOperation.Write;
+ }
+ }
+
+ _state = StateConnected;
+ }
+ else if(_state == StateProxyConnectRequest)
+ {
+ //
+ // Write completed.
+ //
+ _proxy.endWriteConnectRequest(writeBuffer);
+ _state = StateProxyConnectRequestPending; // Wait for proxy response
+ return IceInternal.SocketOperation.Read;
+ }
+ else if(_state == StateProxyConnectRequestPending)
+ {
+ //
+ // Read completed.
+ //
+ _proxy.endReadConnectRequestResponse(readBuffer);
_state = StateConnected;
- _desc = IceInternal.Network.fdToString(_fd);
}
- assert(_state == StateConnected);
- int status = handshakeNonBlocking();
- if(status != IceInternal.SocketOperation.None)
+ if(_state == StateConnected)
{
- return status;
+ return handshakeNonBlocking();
}
}
catch(Ice.LocalException ex)
{
if(_instance.networkTraceLevel() >= 2)
{
- java.net.Socket fd = (java.net.Socket)_fd.socket();
StringBuilder s = new StringBuilder(128);
s.append("failed to establish ssl connection\n");
- s.append("local address = ");
- s.append(IceInternal.Network.addrToString(fd.getLocalAddress(), fd.getLocalPort()));
- s.append("\nremote address = ");
- if(_incoming)
- {
- final java.net.InetSocketAddress addr = (java.net.InetSocketAddress)fd.getRemoteSocketAddress();
- final java.net.InetAddress remoteAddr = addr != null ? addr.getAddress() : null;
- final int remotePort = addr != null ? addr.getPort() : -1;
- s.append(IceInternal.Network.addrToString(remoteAddr, remotePort));
- }
- else
- {
- assert(_connectAddr != null);
- s.append(IceInternal.Network.addrToString(_connectAddr));
- }
+ s.append(IceInternal.Network.fdToString(_fd, _proxy, _addr));
_logger.trace(_instance.networkTraceCategory(), s.toString());
}
throw ex;
@@ -155,6 +203,14 @@ final class TransceiverI implements IceInternal.Transceiver
public boolean
write(IceInternal.Buffer buf)
{
+ if(_state == StateProxyConnectRequest)
+ {
+ //
+ // We need to write the proxy message, but we have to use TCP and not SSL.
+ //
+ return writeRaw(buf);
+ }
+
//
// If the handshake isn't completed yet, we shouldn't be writing.
//
@@ -186,6 +242,16 @@ final class TransceiverI implements IceInternal.Transceiver
public boolean
read(IceInternal.Buffer buf, Ice.BooleanHolder moreData)
{
+ moreData.value = false;
+
+ if(_state == StateProxyConnectRequestPending)
+ {
+ //
+ // We need to read the proxy reply, but we have to use TCP and not SSL.
+ //
+ return readRaw(buf);
+ }
+
//
// If the handshake isn't completed yet, we shouldn't be reading (read can be
// called by the thread pool when the connection is registered/unregistered
@@ -244,7 +310,6 @@ final class TransceiverI implements IceInternal.Transceiver
if(status != IceInternal.SocketOperation.None)
{
assert(status == IceInternal.SocketOperation.Read);
- moreData.value = false;
return false;
}
continue;
@@ -313,22 +378,35 @@ final class TransceiverI implements IceInternal.Transceiver
}
}
- //
- // Only for use by ConnectorI, AcceptorI.
- //
- @SuppressWarnings("deprecation")
TransceiverI(Instance instance, javax.net.ssl.SSLEngine engine, java.nio.channels.SocketChannel fd,
- String host, boolean connected, boolean incoming, String adapterName,
- java.net.InetSocketAddress connectAddr)
+ IceInternal.NetworkProxy proxy, String host, java.net.InetSocketAddress addr)
+ {
+ init(instance, engine, fd);
+ _proxy = proxy;
+ _host = host;
+ _incoming = false;
+ _addr = addr;
+ _state = StateNeedConnect;
+ _desc = IceInternal.Network.fdToString(_fd, _proxy, _addr);
+ }
+
+ TransceiverI(Instance instance, javax.net.ssl.SSLEngine engine, java.nio.channels.SocketChannel fd,
+ String adapterName)
+ {
+ init(instance, engine, fd);
+ _host = "";
+ _adapterName = adapterName;
+ _incoming = true;
+ _state = StateConnected;
+ _desc = IceInternal.Network.fdToString(_fd);
+ }
+
+ @SuppressWarnings("deprecation")
+ private void init(Instance instance, javax.net.ssl.SSLEngine engine, java.nio.channels.SocketChannel fd)
{
_instance = instance;
_engine = engine;
_fd = fd;
- _host = host;
- _incoming = incoming;
- _adapterName = adapterName;
- _connectAddr = connectAddr;
- _state = connected ? StateConnected : StateNeedConnect;
_logger = instance.communicator().getLogger();
try
{
@@ -338,7 +416,6 @@ final class TransceiverI implements IceInternal.Transceiver
{
// Ignore.
}
- _desc = IceInternal.Network.fdToString(_fd);
_maxPacketSize = 0;
if(System.getProperty("os.name").startsWith("Windows"))
{
@@ -817,13 +894,122 @@ final class TransceiverI implements IceInternal.Transceiver
_appInput.compact();
}
+ @SuppressWarnings("deprecation")
+ private boolean
+ writeRaw(IceInternal.Buffer buf)
+ {
+ //
+ // We don't want write to be called on android main thread as this will cause
+ // NetworkOnMainThreadException to be thrown. If that is the android main thread
+ // we return false and this method will be later called from the thread pool.
+ //
+ if(IceInternal.Util.isAndroidMainThread(Thread.currentThread()))
+ {
+ return false;
+ }
+
+ final int size = buf.b.limit();
+ int packetSize = size - buf.b.position();
+
+ while(buf.b.hasRemaining())
+ {
+ try
+ {
+ assert(_fd != null);
+ int ret = _fd.write(buf.b);
+
+ if(ret == -1)
+ {
+ throw new Ice.ConnectionLostException();
+ }
+ else if(ret == 0)
+ {
+ return false;
+ }
+
+ if(_instance.networkTraceLevel() >= 3)
+ {
+ String s = "sent " + ret + " of " + packetSize + " bytes via tcp\n" + toString();
+ _logger.trace(_instance.networkTraceCategory(), s);
+ }
+
+ if(_stats != null)
+ {
+ _stats.bytesSent(type(), ret);
+ }
+ }
+ catch(java.io.InterruptedIOException ex)
+ {
+ continue;
+ }
+ catch(java.io.IOException ex)
+ {
+ throw new Ice.SocketException(ex);
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("deprecation")
+ private boolean
+ readRaw(IceInternal.Buffer buf)
+ {
+ int packetSize = buf.b.remaining();
+
+ while(buf.b.hasRemaining())
+ {
+ try
+ {
+ assert(_fd != null);
+ int ret = _fd.read(buf.b);
+
+ if(ret == -1)
+ {
+ throw new Ice.ConnectionLostException();
+ }
+
+ if(ret == 0)
+ {
+ return false;
+ }
+
+ if(ret > 0)
+ {
+ if(_instance.networkTraceLevel() >= 3)
+ {
+ String s = "received " + ret + " of " + packetSize + " bytes via tcp\n" + toString();
+ _logger.trace(_instance.networkTraceCategory(), s);
+ }
+
+ if(_stats != null)
+ {
+ _stats.bytesReceived(type(), ret);
+ }
+ }
+
+ packetSize = buf.b.remaining();
+ }
+ catch(java.io.InterruptedIOException ex)
+ {
+ continue;
+ }
+ catch(java.io.IOException ex)
+ {
+ throw new Ice.ConnectionLostException(ex);
+ }
+ }
+
+ return true;
+ }
+
private Instance _instance;
private java.nio.channels.SocketChannel _fd;
private javax.net.ssl.SSLEngine _engine;
+ private IceInternal.NetworkProxy _proxy;
private String _host;
private boolean _incoming;
private String _adapterName;
- private java.net.InetSocketAddress _connectAddr;
+ private java.net.InetSocketAddress _addr;
private int _state;
private Ice.Logger _logger;
@@ -838,6 +1024,8 @@ final class TransceiverI implements IceInternal.Transceiver
private static final int StateNeedConnect = 0;
private static final int StateConnectPending = 1;
- private static final int StateConnected = 2;
- private static final int StateHandshakeComplete = 3;
+ private static final int StateProxyConnectRequest = 2;
+ private static final int StateProxyConnectRequestPending = 3;
+ private static final int StateConnected = 4;
+ private static final int StateHandshakeComplete = 5;
}
diff --git a/java/test/Glacier2/sessionHelper/Client.java b/java/test/Glacier2/sessionHelper/Client.java
index c2b4975b3c5..022f36c4125 100644
--- a/java/test/Glacier2/sessionHelper/Client.java
+++ b/java/test/Glacier2/sessionHelper/Client.java
@@ -334,7 +334,7 @@ public class Client extends test.Util.Application
{
throw exception;
}
- catch(Ice.ConnectionRefusedException ex)
+ catch(Ice.ConnectFailedException ex)
{
out.println("ok");
synchronized(test.Glacier2.sessionHelper.Client.this)
diff --git a/java/test/Ice/background/Transceiver.java b/java/test/Ice/background/Transceiver.java
index 2939954f7f9..72e33c9557a 100644
--- a/java/test/Ice/background/Transceiver.java
+++ b/java/test/Ice/background/Transceiver.java
@@ -18,14 +18,14 @@ final class Transceiver implements IceInternal.Transceiver
}
public int
- initialize()
+ initialize(IceInternal.Buffer readBuffer, IceInternal.Buffer writeBuffer)
{
int status = _configuration.initializeSocketStatus();
if(status == IceInternal.SocketOperation.Connect || status == IceInternal.SocketOperation.Write)
{
if(!_initialized)
{
- status = _transceiver.initialize();
+ status = _transceiver.initialize(readBuffer, writeBuffer);
if(status != IceInternal.SocketOperation.None)
{
return status;
@@ -42,7 +42,7 @@ final class Transceiver implements IceInternal.Transceiver
_configuration.checkInitializeException();
if(!_initialized)
{
- status = _transceiver.initialize();
+ status = _transceiver.initialize(readBuffer, writeBuffer);
if(status != IceInternal.SocketOperation.None)
{
return status;
@@ -61,11 +61,6 @@ final class Transceiver implements IceInternal.Transceiver
public boolean
write(IceInternal.Buffer buf)
{
- if(!_initialized)
- {
- throw new Ice.SocketException();
- }
-
if(!_configuration.writeReady())
{
return false;
@@ -77,11 +72,6 @@ final class Transceiver implements IceInternal.Transceiver
public boolean
read(IceInternal.Buffer buf, Ice.BooleanHolder moreData)
{
- if(!_initialized)
- {
- throw new Ice.SocketException();
- }
-
if(!moreData.value)
{
if(!_configuration.readReady())