summaryrefslogtreecommitdiff
path: root/cppe/src
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2005-06-20 16:43:38 +0000
committerDwayne Boone <dwayne@zeroc.com>2005-06-20 16:43:38 +0000
commit8b0d67e9ad16a3b6bdfff6d9900ea009442249a0 (patch)
treed1cfce0274d58c377392d56f64d57b10d8a1c8fb /cppe/src
parentImproved fix for bug #377 (diff)
downloadice-8b0d67e9ad16a3b6bdfff6d9900ea009442249a0.tar.bz2
ice-8b0d67e9ad16a3b6bdfff6d9900ea009442249a0.tar.xz
ice-8b0d67e9ad16a3b6bdfff6d9900ea009442249a0.zip
Separated TCP into separate transport library
Diffstat (limited to 'cppe/src')
-rw-r--r--cppe/src/Makefile3
-rw-r--r--cppe/src/TcpTransport/.depend5
-rw-r--r--cppe/src/TcpTransport/Acceptor.cpp142
-rw-r--r--cppe/src/TcpTransport/Connector.cpp63
-rw-r--r--cppe/src/TcpTransport/Endpoint.cpp377
-rw-r--r--cppe/src/TcpTransport/EndpointFactory.cpp82
-rw-r--r--cppe/src/TcpTransport/Makefile53
-rw-r--r--cppe/src/TcpTransport/Transceiver.cpp469
8 files changed, 1193 insertions, 1 deletions
diff --git a/cppe/src/Makefile b/cppe/src/Makefile
index 5975862445e..4c1a7c1b216 100644
--- a/cppe/src/Makefile
+++ b/cppe/src/Makefile
@@ -11,7 +11,8 @@ top_srcdir = ..
include $(top_srcdir)/config/Make.rules
-SUBDIRS = Ice
+SUBDIRS = Ice \
+ TcpTransport
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cppe/src/TcpTransport/.depend b/cppe/src/TcpTransport/.depend
new file mode 100644
index 00000000000..11c5c9215c1
--- /dev/null
+++ b/cppe/src/TcpTransport/.depend
@@ -0,0 +1,5 @@
+Acceptor.o: Acceptor.cpp ../../include/Ice/Acceptor.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/TransceiverF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/AcceptorF.h ../../include/Ice/Transceiver.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/EndpointFactoryF.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h
+Connector.o: Connector.cpp ../../include/Ice/Connector.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/TransceiverF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectorF.h ../../include/Ice/Transceiver.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/EndpointFactoryF.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h
+EndpointFactory.o: EndpointFactory.cpp ../../include/Ice/EndpointFactory.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/EndpointF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/InstanceF.h ../../include/Ice/EndpointFactoryF.h ../../include/Ice/Endpoint.h ../../include/Ice/AcceptorF.h ../../include/Ice/ConnectorF.h ../../include/Ice/TransceiverF.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h
+Endpoint.o: Endpoint.cpp ../../include/Ice/Endpoint.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/EndpointF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/AcceptorF.h ../../include/Ice/ConnectorF.h ../../include/Ice/TransceiverF.h ../../include/Ice/InstanceF.h ../Ice/Network.h ../../include/Ice/Acceptor.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Connector.h ../../include/Ice/Transceiver.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/EndpointFactoryF.h ../Ice/DefaultsAndOverrides.h ../../include/IceUtil/SafeStdio.h
+Transceiver.o: Transceiver.cpp ../../include/Ice/Transceiver.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/InstanceF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/TransceiverF.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/Ice/CommunicatorF.h ../../include/Ice/PropertiesF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/EndpointFactoryF.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Buffer.h ../Ice/Network.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BuiltinSequences.h ../../include/IceUtil/SafeStdio.h
diff --git a/cppe/src/TcpTransport/Acceptor.cpp b/cppe/src/TcpTransport/Acceptor.cpp
new file mode 100644
index 00000000000..14725d5f774
--- /dev/null
+++ b/cppe/src/TcpTransport/Acceptor.cpp
@@ -0,0 +1,142 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#include <Ice/Acceptor.h>
+#include <Ice/Transceiver.h>
+#include <Ice/Instance.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/Network.h>
+#include <Ice/Exception.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+
+void IceInternal::incRef(Acceptor* p) { p->__incRef(); }
+void IceInternal::decRef(Acceptor* p) { p->__decRef(); }
+
+SOCKET
+IceInternal::Acceptor::fd()
+{
+ return _fd;
+}
+
+void
+IceInternal::Acceptor::close()
+{
+ if(_traceLevels->network >= 1)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "stopping to accept tcp connections at " << toString();
+ }
+
+ SOCKET fd = _fd;
+ _fd = INVALID_SOCKET;
+ closeSocket(fd);
+}
+
+void
+IceInternal::Acceptor::listen()
+{
+ try
+ {
+ doListen(_fd, _backlog);
+ }
+ catch(...)
+ {
+ _fd = INVALID_SOCKET;
+ throw;
+ }
+
+ if(_traceLevels->network >= 1)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "accepting tcp connections at " << toString();
+ }
+}
+
+TransceiverPtr
+IceInternal::Acceptor::accept(int timeout)
+{
+ SOCKET fd = doAccept(_fd, timeout);
+ setBlock(fd, false);
+
+ if(_traceLevels->network >= 1)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "accepted tcp connection\n" << fdToString(fd);
+ }
+
+ return new Transceiver(_instance, fd);
+}
+
+void
+IceInternal::Acceptor::connectToSelf()
+{
+ SOCKET fd = createSocket();
+ setBlock(fd, false);
+ doConnect(fd, _addr, -1);
+ closeSocket(fd);
+}
+
+string
+IceInternal::Acceptor::toString() const
+{
+ return addrToString(_addr);
+}
+
+bool
+IceInternal::Acceptor::equivalent(const string& host, int port) const
+{
+ struct sockaddr_in addr;
+ getAddress(host, port, addr);
+ return compareAddress(addr, _addr);
+}
+
+int
+IceInternal::Acceptor::effectivePort()
+{
+ return ntohs(_addr.sin_port);
+}
+
+IceInternal::Acceptor::Acceptor(const InstancePtr& instance, const string& host, int port) :
+ _instance(instance),
+ _traceLevels(instance->traceLevels()),
+ _logger(instance->logger()),
+ _backlog(0)
+{
+ if(_backlog <= 0)
+ {
+ _backlog = 5;
+ }
+
+ try
+ {
+ _fd = createSocket();
+ setBlock(_fd, false);
+ getAddress(host, port, _addr);
+ if(_traceLevels->network >= 2)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "attempting to bind to tcp socket " << toString();
+ }
+ doBind(_fd, _addr);
+ }
+ catch(...)
+ {
+ _fd = INVALID_SOCKET;
+ throw;
+ }
+}
+
+IceInternal::Acceptor::~Acceptor()
+{
+ assert(_fd == INVALID_SOCKET);
+}
diff --git a/cppe/src/TcpTransport/Connector.cpp b/cppe/src/TcpTransport/Connector.cpp
new file mode 100644
index 00000000000..cee89eb201e
--- /dev/null
+++ b/cppe/src/TcpTransport/Connector.cpp
@@ -0,0 +1,63 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#include <Ice/Connector.h>
+#include <Ice/Transceiver.h>
+#include <Ice/Instance.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/Network.h>
+#include <Ice/Exception.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+
+void IceInternal::incRef(Connector* p) { p->__incRef(); }
+void IceInternal::decRef(Connector* p) { p->__decRef(); }
+
+TransceiverPtr
+Connector::connect(int timeout)
+{
+ if(_traceLevels->network >= 2)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "trying to establish tcp connection to " << toString();
+ }
+
+ SOCKET fd = createSocket();
+ setBlock(fd, false);
+ doConnect(fd, _addr, timeout);
+
+ if(_traceLevels->network >= 1)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "tcp connection established\n" << fdToString(fd);
+ }
+
+ return new Transceiver(_instance, fd);
+}
+
+string
+Connector::toString() const
+{
+ return addrToString(_addr);
+}
+
+Connector::Connector(const InstancePtr& instance, const string& host, int port) :
+ _instance(instance),
+ _traceLevels(instance->traceLevels()),
+ _logger(instance->logger())
+{
+ getAddress(host, port, _addr);
+}
+
+Connector::~Connector()
+{
+}
diff --git a/cppe/src/TcpTransport/Endpoint.cpp b/cppe/src/TcpTransport/Endpoint.cpp
new file mode 100644
index 00000000000..dc02bf4a9a0
--- /dev/null
+++ b/cppe/src/TcpTransport/Endpoint.cpp
@@ -0,0 +1,377 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#include <Ice/Endpoint.h>
+#include <Ice/Network.h>
+#include <Ice/Acceptor.h>
+#include <Ice/Connector.h>
+#include <Ice/Transceiver.h>
+#include <Ice/BasicStream.h>
+#include <Ice/LocalException.h>
+#include <Ice/Instance.h>
+#include <Ice/DefaultsAndOverrides.h>
+#include <IceUtil/SafeStdio.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+
+void IceInternal::incRef(Endpoint* p) { p->__incRef(); }
+void IceInternal::decRef(Endpoint* p) { p->__decRef(); }
+
+IceInternal::Endpoint::Endpoint(const InstancePtr& instance, const string& ho, Int po, Int ti) :
+ _instance(instance),
+ _host(ho),
+ _port(po),
+ _timeout(ti)
+{
+}
+
+IceInternal::Endpoint::Endpoint(const InstancePtr& instance, const string& str) :
+ _instance(instance),
+ _port(0),
+ _timeout(-1)
+{
+ const string delim = " \t\n\r";
+
+ string::size_type beg;
+ string::size_type end = 0;
+
+ while(true)
+ {
+ beg = str.find_first_not_of(delim, end);
+ if(beg == string::npos)
+ {
+ break;
+ }
+
+ end = str.find_first_of(delim, beg);
+ if(end == string::npos)
+ {
+ end = str.length();
+ }
+
+ string option = str.substr(beg, end - beg);
+ if(option.length() != 2 || option[0] != '-')
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
+
+ string argument;
+ string::size_type argumentBeg = str.find_first_not_of(delim, end);
+ if(argumentBeg != string::npos && str[argumentBeg] != '-')
+ {
+ beg = argumentBeg;
+ end = str.find_first_of(delim, beg);
+ if(end == string::npos)
+ {
+ end = str.length();
+ }
+ argument = str.substr(beg, end - beg);
+ }
+
+ switch(option[1])
+ {
+ case 'h':
+ {
+ if(argument.empty())
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
+ const_cast<string&>(_host) = argument;
+ break;
+ }
+
+ case 'p':
+ {
+ const_cast<Int&>(_port) = atoi(argument.c_str());
+ if(_port == 0)
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
+ break;
+ }
+
+ case 't':
+ {
+ const_cast<Int&>(_timeout) = atoi(argument.c_str());
+ if(_timeout == 0)
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
+ break;
+ }
+
+ case 'z':
+ {
+ // Ignore compression flag.
+ break;
+ }
+
+ default:
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "tcp " + str;
+ throw ex;
+ }
+ }
+ }
+
+ if(_host.empty())
+ {
+ const_cast<string&>(_host) = _instance->defaultsAndOverrides()->defaultHost;
+ }
+}
+
+IceInternal::Endpoint::Endpoint(BasicStream* s) :
+ _instance(s->instance()),
+ _port(0),
+ _timeout(-1)
+{
+ bool dummy;
+
+ s->startReadEncaps();
+ s->read(const_cast<string&>(_host));
+ s->read(const_cast<Int&>(_port));
+ s->read(const_cast<Int&>(_timeout));
+ s->read(const_cast<bool&>(dummy));
+ s->endReadEncaps();
+}
+
+void
+IceInternal::Endpoint::streamWrite(BasicStream* s) const
+{
+ s->write(TcpEndpointType);
+ s->startWriteEncaps();
+ s->write(_host);
+ s->write(_port);
+ s->write(_timeout);
+ s->write(false);
+ s->endWriteEncaps();
+}
+
+string
+IceInternal::Endpoint::toString() const
+{
+ string s;
+ s += "tcp -h ";
+ s += _host;
+
+ s += IceUtil::printfToString(" -p %d", _port);
+
+ if(_timeout != -1)
+ {
+ s += IceUtil::printfToString(" -t %d", _timeout);
+ }
+ return s;
+}
+
+Short
+IceInternal::Endpoint::type() const
+{
+ return TcpEndpointType;
+}
+
+Int
+IceInternal::Endpoint::timeout() const
+{
+ return _timeout;
+}
+
+EndpointPtr
+IceInternal::Endpoint::timeout(Int timeout) const
+{
+ if(timeout == _timeout)
+ {
+ return const_cast<Endpoint*>(this);
+ }
+ else
+ {
+ return new Endpoint(_instance, _host, _port, timeout);
+ }
+}
+
+bool
+IceInternal::Endpoint::unknown() const
+{
+ return false;
+}
+
+TransceiverPtr
+IceInternal::Endpoint::clientTransceiver() const
+{
+ return 0;
+}
+
+TransceiverPtr
+IceInternal::Endpoint::serverTransceiver(EndpointPtr& endp) const
+{
+ endp = const_cast<Endpoint*>(this);
+ return 0;
+}
+
+ConnectorPtr
+IceInternal::Endpoint::connector() const
+{
+ return new Connector(_instance, _host, _port);
+}
+
+AcceptorPtr
+IceInternal::Endpoint::acceptor(EndpointPtr& endp) const
+{
+ Acceptor* p = new Acceptor(_instance, _host, _port);
+ endp = new Endpoint(_instance, _host, p->effectivePort(), _timeout);
+ return p;
+}
+
+bool
+IceInternal::Endpoint::equivalent(const TransceiverPtr&) const
+{
+ return false;
+}
+
+bool
+IceInternal::Endpoint::equivalent(const AcceptorPtr& acceptor) const
+{
+ const Acceptor* tcpAcceptor = dynamic_cast<const Acceptor*>(acceptor.get());
+ if(!tcpAcceptor)
+ {
+ return false;
+ }
+ return tcpAcceptor->equivalent(_host, _port);
+}
+
+bool
+IceInternal::Endpoint::operator==(const Endpoint& r) const
+{
+ const Endpoint* p = dynamic_cast<const Endpoint*>(&r);
+ if(!p)
+ {
+ return false;
+ }
+
+ if(this == p)
+ {
+ return true;
+ }
+
+ if(_port != p->_port)
+ {
+ return false;
+ }
+
+ if(_timeout != p->_timeout)
+ {
+ return false;
+ }
+
+ if(_host != p->_host)
+ {
+ //
+ // We do the most time-consuming part of the comparison last.
+ //
+ struct sockaddr_in laddr;
+ struct sockaddr_in raddr;
+ try
+ {
+ getAddress(_host, _port, laddr);
+ getAddress(p->_host, p->_port, raddr);
+ }
+ catch(const DNSException&)
+ {
+ return false;
+ }
+
+ return compareAddress(laddr, raddr);
+ }
+
+ return true;
+}
+
+bool
+IceInternal::Endpoint::operator!=(const Endpoint& r) const
+{
+ return !operator==(r);
+}
+
+bool
+IceInternal::Endpoint::operator<(const Endpoint& r) const
+{
+ const Endpoint* p = dynamic_cast<const Endpoint*>(&r);
+ if(!p)
+ {
+ return type() < r.type();
+ }
+
+ if(this == p)
+ {
+ return false;
+ }
+
+ if(_port < p->_port)
+ {
+ return true;
+ }
+ else if(p->_port < _port)
+ {
+ return false;
+ }
+
+ if(_timeout < p->_timeout)
+ {
+ return true;
+ }
+ else if(p->_timeout < _timeout)
+ {
+ return false;
+ }
+
+ if(_host != p->_host)
+ {
+ //
+ // We do the most time-consuming part of the comparison last.
+ //
+ struct sockaddr_in laddr;
+ try
+ {
+ getAddress(_host, _port, laddr);
+ }
+ catch(const DNSException&)
+ {
+ }
+
+ struct sockaddr_in raddr;
+ try
+ {
+ getAddress(p->_host, p->_port, raddr);
+ }
+ catch(const DNSException&)
+ {
+ }
+
+ if(laddr.sin_addr.s_addr < raddr.sin_addr.s_addr)
+ {
+ return true;
+ }
+ else if(raddr.sin_addr.s_addr < laddr.sin_addr.s_addr)
+ {
+ return false;
+ }
+ }
+
+ return false;
+}
diff --git a/cppe/src/TcpTransport/EndpointFactory.cpp b/cppe/src/TcpTransport/EndpointFactory.cpp
new file mode 100644
index 00000000000..d7a0a61525a
--- /dev/null
+++ b/cppe/src/TcpTransport/EndpointFactory.cpp
@@ -0,0 +1,82 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#include <Ice/EndpointFactory.h>
+#include <Ice/Endpoint.h>
+#include <Ice/LocalException.h>
+#include <Ice/BasicStream.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+
+void IceInternal::incRef(EndpointFactory* p) { p->__incRef(); }
+void IceInternal::decRef(EndpointFactory* p) { p->__decRef(); }
+
+IceInternal::EndpointFactory::EndpointFactory(const InstancePtr& instance)
+ : _instance(instance)
+{
+}
+
+IceInternal::EndpointFactory::~EndpointFactory()
+{
+}
+
+EndpointPtr
+IceInternal::EndpointFactory::create(const std::string& str) const
+{
+ const string delim = " \t\n\r";
+
+ string::size_type beg = str.find_first_not_of(delim);
+ if(beg == string::npos)
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = str;
+ throw ex;
+ }
+
+ string::size_type end = str.find_first_of(delim, beg);
+ if(end == string::npos)
+ {
+ end = str.length();
+ }
+
+ string protocol = str.substr(beg, end - beg);
+
+ if(protocol == "default" || protocol == "tcp")
+ {
+ return new Endpoint(_instance, str.substr(end));
+ }
+
+ EndpointParseException ex(__FILE__, __LINE__);
+}
+
+EndpointPtr
+IceInternal::EndpointFactory::read(BasicStream* s) const
+{
+ Short type;
+ s->read(type);
+
+ if(type == TcpEndpointType)
+ {
+ return new Endpoint(s);
+ }
+
+ //
+ // XXX: What should this do? Old code returned UnknownEndpoint. Maybe that needs
+ // to be added back?
+ //
+ return 0;
+}
+
+void
+IceInternal::EndpointFactory::destroy()
+{
+ _instance = 0;
+}
diff --git a/cppe/src/TcpTransport/Makefile b/cppe/src/TcpTransport/Makefile
new file mode 100644
index 00000000000..ae1b5b07bd2
--- /dev/null
+++ b/cppe/src/TcpTransport/Makefile
@@ -0,0 +1,53 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2005 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.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,IceETCP,$(VERSION))
+SONAME = $(call mksoname,IceETCP,$(SOVERSION))
+LIBNAME = $(call mklibname,IceETCP)
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+OBJS = Acceptor.o \
+ Connector.o \
+ EndpointFactory.o \
+ Endpoint.o \
+ Transceiver.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I.. $(CPPFLAGS) -DICE_TRANSPORT_API_EXPORTS
+
+LINKWITH := $(ICE_OS_LIBS)
+
+ifeq ($(STATICLIBS),yes)
+$(libdir)/$(LIBNAME): $(OBJS)
+ rm -f $@
+ $(call mklib,$@,$(OBJS))
+else
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ rm -f $@
+ ln -s $(SONAME) $@
+endif
+
+install:: all
+ $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
+
+include .depend
diff --git a/cppe/src/TcpTransport/Transceiver.cpp b/cppe/src/TcpTransport/Transceiver.cpp
new file mode 100644
index 00000000000..7709777fc87
--- /dev/null
+++ b/cppe/src/TcpTransport/Transceiver.cpp
@@ -0,0 +1,469 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#include <Ice/Transceiver.h>
+#include <Ice/Instance.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/Buffer.h>
+#include <Ice/Network.h>
+#include <Ice/LocalException.h>
+#include <IceUtil/SafeStdio.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+
+void IceInternal::incRef(Transceiver* p) { p->__incRef(); }
+void IceInternal::decRef(Transceiver* p) { p->__decRef(); }
+
+
+SOCKET
+IceInternal::Transceiver::fd()
+{
+ assert(_fd != INVALID_SOCKET);
+ return _fd;
+}
+
+void
+IceInternal::Transceiver::close()
+{
+ if(_traceLevels->network >= 1)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "closing tcp connection\n" << toString();
+ }
+
+#ifdef _WIN32_WCE
+ assert(_event != 0);
+ WSACloseEvent(_event);
+ _event = 0;
+#endif
+
+ assert(_fd != INVALID_SOCKET);
+ try
+ {
+ closeSocket(_fd);
+ _fd = INVALID_SOCKET;
+ }
+ catch(const SocketException&)
+ {
+ _fd = INVALID_SOCKET;
+ throw;
+ }
+}
+
+void
+IceInternal::Transceiver::shutdownWrite()
+{
+ if(_traceLevels->network >= 2)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "shutting down tcp connection for writing\n" << toString();
+ }
+
+ assert(_fd != INVALID_SOCKET);
+ shutdownSocketWrite(_fd);
+}
+
+void
+IceInternal::Transceiver::shutdownReadWrite()
+{
+ if(_traceLevels->network >= 2)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << "shutting down tcp connection for reading and writing\n" << toString();
+ }
+
+ assert(_fd != INVALID_SOCKET);
+ shutdownSocketReadWrite(_fd);
+}
+
+void
+IceInternal::Transceiver::write(Buffer& buf, int timeout)
+{
+ Buffer::Container::difference_type packetSize =
+ static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+
+#ifdef _WIN32
+ //
+ // Limit packet size to avoid performance problems on WIN32
+ //
+ if(packetSize > 64 * 1024)
+ {
+ packetSize = 64 * 1024;
+ }
+#endif
+
+ while(buf.i != buf.b.end())
+ {
+ assert(_fd != INVALID_SOCKET);
+ ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&*buf.i), packetSize, 0);
+
+ if(ret == 0)
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
+ }
+
+ if(ret == SOCKET_ERROR)
+ {
+#ifdef _WIN32_WCE
+ repeatError:
+#endif
+ if(interrupted())
+ {
+ continue;
+ }
+
+ if(noBuffers() && packetSize > 1024)
+ {
+ packetSize /= 2;
+ continue;
+ }
+
+ if(wouldBlock())
+ {
+#ifdef _WIN32_WCE
+ WSAEVENT events[1];
+ events[0] = _event;
+ long tout = (timeout >= 0) ? timeout : WSA_INFINITE;
+ DWORD rc = WSAWaitForMultipleEvents(1, events, FALSE, tout, FALSE);
+ if(rc == WSA_WAIT_FAILED)
+ {
+ //
+ // This an error from WSAWaitForMultipleEvents
+ // itself (similar to an error from select). None
+ // of these errors are recoverable (such as
+ // EINTR).
+ //
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = WSAGetLastError();
+ throw ex;
+ }
+
+ if(rc == WSA_WAIT_TIMEOUT)
+ {
+ assert(timeout >= 0);
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+ assert(rc == WSA_WAIT_EVENT_0);
+
+ WSANETWORKEVENTS nevents;
+ if(WSAEnumNetworkEvents(_fd, _event, &nevents) == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = WSAGetLastError();
+ throw ex;
+ }
+ //
+ // This checks for an error on the fd (this would be
+ // same as recv itself returning an error).
+ //
+ // In the event of an error we set the error code, and
+ // // repeat the error handling.
+ //
+ if(nevents.lNetworkEvents & FD_READ && nevents.iErrorCode[FD_READ_BIT] != 0)
+ {
+ WSASetLastError(nevents.iErrorCode[FD_READ_BIT]);
+ goto repeatError;
+ }
+ if(nevents.lNetworkEvents & FD_CLOSE && nevents.iErrorCode[FD_CLOSE_BIT] != 0)
+ {
+ WSASetLastError(nevents.iErrorCode[FD_CLOSE_BIT]);
+ goto repeatError;
+ }
+#else
+ repeatSelect:
+ int rs;
+ assert(_fd != INVALID_SOCKET);
+ FD_SET(_fd, &_wFdSet);
+
+ if(timeout >= 0)
+ {
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
+ rs = ::select(_fd + 1, 0, &_wFdSet, 0, &tv);
+ }
+ else
+ {
+ rs = ::select(_fd + 1, 0, &_wFdSet, 0, 0);
+ }
+
+ if(rs == SOCKET_ERROR)
+ {
+ if(interrupted())
+ {
+ goto repeatSelect;
+ }
+
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ if(rs == 0)
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+#endif
+ continue;
+ }
+
+ if(connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+
+ if(_traceLevels->network >= 3)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << IceUtil::printfToString("sent %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
+ }
+
+ buf.i += ret;
+
+ if(packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+ }
+ }
+}
+
+void
+IceInternal::Transceiver::read(Buffer& buf, int timeout)
+{
+ Buffer::Container::difference_type packetSize =
+ static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+
+ while(buf.i != buf.b.end())
+ {
+ assert(_fd != INVALID_SOCKET);
+ ssize_t ret = ::recv(_fd, reinterpret_cast<char*>(&*buf.i), packetSize, 0);
+
+ if(ret == 0)
+ {
+ //
+ // If the connection is lost when reading data, we shut
+ // down the write end of the socket. This helps to unblock
+ // threads that are stuck in send() or select() while
+ // sending data. Note: I don't really understand why
+ // send() or select() sometimes don't detect a connection
+ // loss. Therefore this helper to make them detect it.
+ //
+ //assert(_fd != INVALID_SOCKET);
+ //shutdownSocketReadWrite(_fd);
+
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
+ }
+
+ if(ret == SOCKET_ERROR)
+ {
+#ifdef _WIN32_WCE
+ repeatError:
+#endif
+ if(interrupted())
+ {
+ continue;
+ }
+
+ if(noBuffers() && packetSize > 1024)
+ {
+ packetSize /= 2;
+ continue;
+ }
+
+ if(wouldBlock())
+ {
+#ifdef _WIN32_WCE
+ //
+ // This code is basically the same as the code in
+ // ::send above. Check that for detailed comments.
+ //
+ WSAEVENT events[1];
+ events[0] = _event;
+ long tout = (timeout >= 0) ? timeout : WSA_INFINITE;
+ DWORD rc = WSAWaitForMultipleEvents(1, events, FALSE, tout, FALSE);
+ if(rc == WSA_WAIT_FAILED)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = WSAGetLastError();
+ throw ex;
+ }
+ if(rc == WSA_WAIT_TIMEOUT)
+ {
+ assert(timeout >= 0);
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+ assert(rc == WSA_WAIT_EVENT_0);
+
+ WSANETWORKEVENTS nevents;
+ if(WSAEnumNetworkEvents(_fd, _event, &nevents) == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = WSAGetLastError();
+ throw ex;
+ }
+
+ if(nevents.lNetworkEvents & FD_READ && nevents.iErrorCode[FD_READ_BIT] != 0)
+ {
+ WSASetLastError(nevents.iErrorCode[FD_READ_BIT]);
+ goto repeatError;
+ }
+ if(nevents.lNetworkEvents & FD_CLOSE && nevents.iErrorCode[FD_CLOSE_BIT] != 0)
+ {
+ WSASetLastError(nevents.iErrorCode[FD_CLOSE_BIT]);
+ goto repeatError;
+ }
+#else
+ repeatSelect:
+
+ int rs;
+ assert(_fd != INVALID_SOCKET);
+ FD_SET(_fd, &_rFdSet);
+
+ if(timeout >= 0)
+ {
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
+ rs = ::select(_fd + 1, &_rFdSet, 0, 0, &tv);
+ }
+ else
+ {
+ rs = ::select(_fd + 1, &_rFdSet, 0, 0, 0);
+ }
+
+ if(rs == SOCKET_ERROR)
+ {
+ if(interrupted())
+ {
+ goto repeatSelect;
+ }
+
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ if(rs == 0)
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+#endif
+ continue;
+ }
+
+ if(connectionLost())
+ {
+ //
+ // See the commment above about shutting down the
+ // socket if the connection is lost while reading
+ // data.
+ //
+ //assert(_fd != INVALID_SOCKET);
+ //shutdownSocketReadWrite(_fd);
+
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+
+ if(_traceLevels->network >= 3)
+ {
+ Trace out(_logger, _traceLevels->networkCat);
+ out << IceUtil::printfToString("received %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
+ }
+
+ buf.i += ret;
+
+ if(packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+ }
+ }
+}
+
+string
+IceInternal::Transceiver::type() const
+{
+ return "tcp";
+}
+
+string
+IceInternal::Transceiver::toString() const
+{
+ return _desc;
+}
+
+IceInternal::Transceiver::Transceiver(const InstancePtr& instance, SOCKET fd) :
+ _traceLevels(instance->traceLevels()),
+ _logger(instance->logger()),
+ _fd(fd),
+ _desc(fdToString(fd))
+{
+#ifdef _WIN32_WCE
+ _event = WSACreateEvent();
+ if(_event == 0)
+ {
+ closeSocket(_fd);
+
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ //
+ // Create a WSAEVENT which selects read/write and close for
+ // trigging.
+ //
+ if(WSAEventSelect(_fd, _event, FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR)
+ {
+ int error = WSAGetLastError();
+
+ WSACloseEvent(_event);
+ closeSocket(_fd);
+
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = error;
+ throw ex;
+ }
+#else
+ FD_ZERO(&_wFdSet);
+ FD_ZERO(&_rFdSet);
+#endif
+}
+
+IceInternal::Transceiver::~Transceiver()
+{
+ assert(_fd == INVALID_SOCKET);
+#ifdef _WIN32_WCE
+ assert(_event == 0);
+#endif
+}