summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2016-06-27 17:54:30 +0200
committerBenoit Foucher <benoit@zeroc.com>2016-06-27 17:54:30 +0200
commitc56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7 (patch)
tree5cb64dfe155e5d2349efb6c7dc4b0f5b5284d44a /cpp/src
parentFix Windows php build to restore nuget packages (diff)
downloadice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.tar.bz2
ice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.tar.xz
ice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.zip
Refactored SSL and iAP transports, support for running SSL on top
of TCP/iAP/Bluetooth.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier2/SessionRouterI.cpp27
-rw-r--r--cpp/src/Ice/ConnectionI.cpp12
-rw-r--r--cpp/src/Ice/EndpointFactory.h2
-rw-r--r--cpp/src/Ice/EndpointI.cpp9
-rw-r--r--cpp/src/Ice/EndpointI.h5
-rw-r--r--cpp/src/Ice/IPEndpointI.cpp26
-rw-r--r--cpp/src/Ice/IPEndpointI.h6
-rw-r--r--cpp/src/Ice/Incoming.cpp22
-rw-r--r--cpp/src/Ice/Instance.cpp12
-rw-r--r--cpp/src/Ice/InstrumentationI.cpp16
-rw-r--r--cpp/src/Ice/Makefile.mk2
-rwxr-xr-x[-rw-r--r--]cpp/src/Ice/Network.cpp112
-rwxr-xr-x[-rw-r--r--]cpp/src/Ice/Network.h15
-rw-r--r--cpp/src/Ice/OpaqueEndpointI.cpp8
-rw-r--r--cpp/src/Ice/OpaqueEndpointI.h1
-rw-r--r--cpp/src/Ice/Selector.cpp4
-rwxr-xr-x[-rw-r--r--]cpp/src/Ice/StreamSocket.cpp197
-rw-r--r--cpp/src/Ice/StreamSocket.h14
-rwxr-xr-x[-rw-r--r--]cpp/src/Ice/TcpAcceptor.cpp172
-rw-r--r--cpp/src/Ice/TcpAcceptor.h14
-rw-r--r--cpp/src/Ice/TcpEndpointI.cpp26
-rw-r--r--cpp/src/Ice/TcpEndpointI.h10
-rw-r--r--cpp/src/Ice/TcpTransceiver.cpp29
-rw-r--r--cpp/src/Ice/TcpTransceiver.h8
-rw-r--r--cpp/src/Ice/UdpEndpointI.cpp32
-rw-r--r--cpp/src/Ice/UdpEndpointI.h7
-rwxr-xr-x[-rw-r--r--]cpp/src/Ice/UdpTransceiver.cpp134
-rw-r--r--cpp/src/Ice/UdpTransceiver.h10
-rw-r--r--cpp/src/Ice/WSAcceptor.cpp8
-rw-r--r--cpp/src/Ice/WSAcceptor.h6
-rw-r--r--cpp/src/Ice/WSConnector.cpp8
-rw-r--r--cpp/src/Ice/WSConnector.h5
-rw-r--r--cpp/src/Ice/WSEndpoint.cpp80
-rw-r--r--cpp/src/Ice/WSEndpoint.h19
-rw-r--r--cpp/src/Ice/WSTransceiver.cpp20
-rw-r--r--cpp/src/Ice/WSTransceiver.h18
-rw-r--r--cpp/src/Ice/ios/RegisterPluginsInit.cpp30
-rw-r--r--cpp/src/Ice/ios/StreamEndpointI.cpp352
-rw-r--r--cpp/src/Ice/ios/StreamEndpointI.h23
-rw-r--r--cpp/src/Ice/ios/StreamTransceiver.cpp210
-rw-r--r--cpp/src/Ice/ios/StreamTransceiver.h10
-rw-r--r--cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj13
-rw-r--r--cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters29
-rw-r--r--cpp/src/Ice/uwp/RegisterPluginsInit.cpp46
-rw-r--r--cpp/src/Ice/uwp/TcpAcceptor.cpp221
-rw-r--r--cpp/src/Ice/uwp/TcpAcceptor.h65
-rw-r--r--cpp/src/Ice/uwp/TcpConnector.cpp126
-rw-r--r--cpp/src/Ice/uwp/TcpConnector.h47
-rw-r--r--cpp/src/Ice/uwp/TcpEndpointI.cpp426
-rw-r--r--cpp/src/Ice/uwp/TcpEndpointI.h100
-rw-r--r--cpp/src/Ice/uwp/TcpTransceiver.cpp399
-rw-r--r--cpp/src/Ice/uwp/TcpTransceiver.h94
-rw-r--r--cpp/src/Ice/uwp/TransceiverF.h31
-rw-r--r--cpp/src/IceBT/EndpointI.cpp7
-rw-r--r--cpp/src/IceBT/EndpointI.h7
-rw-r--r--cpp/src/IceBT/PluginI.cpp12
-rw-r--r--cpp/src/IceBT/StreamSocket.cpp8
-rw-r--r--cpp/src/IceBT/TransceiverI.cpp5
-rw-r--r--cpp/src/IceDiscovery/PluginI.cpp16
-rw-r--r--cpp/src/IceGrid/RegistryI.cpp22
-rw-r--r--cpp/src/IceIAP/Connector.h (renamed from cpp/src/Ice/ios/iAPConnector.h)0
-rw-r--r--cpp/src/IceIAP/Connector.mm (renamed from cpp/src/Ice/ios/iAPConnector.mm)6
-rw-r--r--cpp/src/IceIAP/EndpointI.h (renamed from cpp/src/Ice/ios/iAPEndpointI.h)5
-rw-r--r--cpp/src/IceIAP/EndpointI.mm (renamed from cpp/src/Ice/ios/iAPEndpointI.mm)114
-rw-r--r--cpp/src/IceIAP/Makefile.mk20
-rw-r--r--cpp/src/IceIAP/Transceiver.h (renamed from cpp/src/Ice/ios/iAPTransceiver.h)1
-rw-r--r--cpp/src/IceIAP/Transceiver.mm (renamed from cpp/src/Ice/ios/iAPTransceiver.mm)73
-rw-r--r--cpp/src/IceLocatorDiscovery/PluginI.cpp16
-rw-r--r--cpp/src/IcePatch2/Server.cpp6
-rw-r--r--cpp/src/IceSSL/AcceptorI.cpp178
-rw-r--r--cpp/src/IceSSL/AcceptorI.h17
-rwxr-xr-x[-rw-r--r--]cpp/src/IceSSL/Certificate.cpp606
-rw-r--r--cpp/src/IceSSL/ConnectorI.cpp58
-rw-r--r--cpp/src/IceSSL/ConnectorI.h10
-rw-r--r--cpp/src/IceSSL/EndpointI.cpp327
-rw-r--r--cpp/src/IceSSL/EndpointI.h43
-rw-r--r--cpp/src/IceSSL/Instance.cpp5
-rw-r--r--cpp/src/IceSSL/Instance.h6
-rw-r--r--cpp/src/IceSSL/Makefile.mk7
-rw-r--r--cpp/src/IceSSL/OpenSSLTransceiverI.cpp103
-rw-r--r--cpp/src/IceSSL/OpenSSLTransceiverI.h10
-rwxr-xr-x[-rw-r--r--]cpp/src/IceSSL/PluginI.cpp46
-rw-r--r--cpp/src/IceSSL/PluginI.h2
-rw-r--r--cpp/src/IceSSL/RFC2253.cpp6
-rw-r--r--cpp/src/IceSSL/SChannelTransceiverI.cpp174
-rw-r--r--cpp/src/IceSSL/SChannelTransceiverI.h10
-rw-r--r--cpp/src/IceSSL/SSLEngine.cpp18
-rw-r--r--cpp/src/IceSSL/SSLEngine.h24
-rw-r--r--cpp/src/IceSSL/SSLEngineF.h12
-rw-r--r--cpp/src/IceSSL/SecureTransportEngine.cpp145
-rw-r--r--cpp/src/IceSSL/SecureTransportTransceiverI.cpp170
-rw-r--r--cpp/src/IceSSL/SecureTransportTransceiverI.h13
-rw-r--r--cpp/src/IceSSL/TrustManager.cpp15
-rw-r--r--cpp/src/IceSSL/TrustManager.h2
-rwxr-xr-x[-rw-r--r--]cpp/src/IceSSL/Util.cpp445
-rw-r--r--cpp/src/IceSSL/Util.h14
-rwxr-xr-xcpp/src/IceSSL/WinRTEngine.cpp43
-rwxr-xr-xcpp/src/IceSSL/WinRTTransceiverI.cpp199
-rwxr-xr-xcpp/src/IceSSL/WinRTTransceiverI.h81
-rw-r--r--cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj16
-rw-r--r--cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters46
-rw-r--r--cpp/src/slice2cpp/Gen.cpp2
102 files changed, 2771 insertions, 3718 deletions
diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp
index 89508705051..4d46d210726 100644
--- a/cpp/src/Glacier2/SessionRouterI.cpp
+++ b/cpp/src/Glacier2/SessionRouterI.cpp
@@ -1,3 +1,4 @@
+
// **********************************************************************
//
// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
@@ -90,6 +91,21 @@ private:
const SessionRouterIPtr _router;
const Ice::ConnectionPtr _connection;
};
+
+Ice::IPConnectionInfoPtr
+getIPConnectionInfo(const Ice::ConnectionInfoPtr& info)
+{
+ for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying)
+ {
+ Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(p);
+ if(ipInfo)
+ {
+ return ipInfo;
+ }
+ }
+ return ICE_NULLPTR;
+}
+
}
namespace Glacier2
@@ -443,7 +459,7 @@ CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const strin
{
_context["_con.type"] = current.con->type();
{
- Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(current.con->getInfo());
+ Ice::IPConnectionInfoPtr info = getIPConnectionInfo(current.con->getInfo());
if(info)
{
ostringstream os;
@@ -832,10 +848,11 @@ SessionRouterI::createSessionFromSecureConnection_async(
amdCB->ice_exception(PermissionDeniedException("not ssl connection"));
return;
}
- sslinfo.remotePort = info->remotePort;
- sslinfo.remoteHost = info->remoteAddress;
- sslinfo.localPort = info->localPort;
- sslinfo.localHost = info->localAddress;
+ Ice::IPConnectionInfoPtr ipInfo = getIPConnectionInfo(info);
+ sslinfo.remotePort = ipInfo->remotePort;
+ sslinfo.remoteHost = ipInfo->remoteAddress;
+ sslinfo.localPort = ipInfo->localPort;
+ sslinfo.localHost = ipInfo->localAddress;
sslinfo.cipher = info->cipher;
sslinfo.certs = info->certs;
if(info->certs.size() > 0)
diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp
index 4f038bea61f..2abec6e1a82 100644
--- a/cpp/src/Ice/ConnectionI.cpp
+++ b/cpp/src/Ice/ConnectionI.cpp
@@ -3642,9 +3642,15 @@ Ice::ConnectionI::initConnectionInfo() const
{
_info = ICE_MAKE_SHARED(ConnectionInfo);
}
- _info->connectionId = _endpoint->connectionId();
- _info->incoming = _connector == 0;
- _info->adapterName = _adapter ? _adapter->getName() : string();
+
+ Ice::ConnectionInfoPtr info = _info;
+ while(info)
+ {
+ info->connectionId = _endpoint->connectionId();
+ info->incoming = _connector == 0;
+ info->adapterName = _adapter ? _adapter->getName() : string();
+ info = info->underlying;
+ }
return _info;
}
diff --git a/cpp/src/Ice/EndpointFactory.h b/cpp/src/Ice/EndpointFactory.h
index 09c4912d53e..07b3fbd32f2 100644
--- a/cpp/src/Ice/EndpointFactory.h
+++ b/cpp/src/Ice/EndpointFactory.h
@@ -39,7 +39,7 @@ public:
virtual EndpointIPtr read(Ice::InputStream*) const = 0;
virtual void destroy() = 0;
- virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const = 0;
+ virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const = 0;
protected:
diff --git a/cpp/src/Ice/EndpointI.cpp b/cpp/src/Ice/EndpointI.cpp
index 31e98dacbd6..af4a2244602 100644
--- a/cpp/src/Ice/EndpointI.cpp
+++ b/cpp/src/Ice/EndpointI.cpp
@@ -8,6 +8,7 @@
// **********************************************************************
#include <Ice/EndpointI.h>
+#include <Ice/OutputStream.h>
using namespace std;
@@ -16,6 +17,14 @@ IceUtil::Shared* IceInternal::upCast(EndpointI* p) { return p; }
IceUtil::Shared* IceInternal::upCast(EndpointI_connectors* p) { return p; }
#endif
+void
+IceInternal::EndpointI::streamWrite(Ice::OutputStream* s) const
+{
+ s->startEncapsulation();
+ streamWriteImpl(s);
+ s->endEncapsulation();
+}
+
string
IceInternal::EndpointI::toString() const
{
diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h
index 1f4ae56117e..b2260474d3d 100644
--- a/cpp/src/Ice/EndpointI.h
+++ b/cpp/src/Ice/EndpointI.h
@@ -46,7 +46,8 @@ public:
//
// Marshal the endpoint.
//
- virtual void streamWrite(Ice::OutputStream*) const = 0;
+ virtual void streamWrite(Ice::OutputStream*) const;
+ virtual void streamWriteImpl(Ice::OutputStream*) const = 0;
//
// Return the endpoint type.
@@ -177,6 +178,8 @@ public:
InfoI(const EndpointIPtr& endpoint) : _endpoint(endpoint)
{
+ T::compress = _endpoint->compress();
+ T::timeout = _endpoint->timeout();
}
virtual Ice::Short
diff --git a/cpp/src/Ice/IPEndpointI.cpp b/cpp/src/Ice/IPEndpointI.cpp
index 824864a7588..21f4def1c2d 100644
--- a/cpp/src/Ice/IPEndpointI.cpp
+++ b/cpp/src/Ice/IPEndpointI.cpp
@@ -106,11 +106,10 @@ IceInternal::IPEndpointI::secure() const
}
void
-IceInternal::IPEndpointI::streamWrite(OutputStream* s) const
+IceInternal::IPEndpointI::streamWriteImpl(OutputStream* s) const
{
- s->startEncapsulation();
- streamWriteImpl(s);
- s->endEncapsulation();
+ s->write(_host, false);
+ s->write(_port);
}
const string&
@@ -132,18 +131,6 @@ IceInternal::IPEndpointI::connectionId(const string& connectionId) const
}
}
-const std::string&
-IceInternal::IPEndpointI::host() const
-{
- return _host;
-}
-
-int
-IceInternal::IPEndpointI::port() const
-{
- return _port;
-}
-
void
IceInternal::IPEndpointI::connectors_async(Ice::EndpointSelectionType selType, const EndpointI_connectorsPtr& cb) const
{
@@ -355,13 +342,6 @@ IceInternal::IPEndpointI::connectors(const vector<Address>& addresses, const Net
}
void
-IceInternal::IPEndpointI::streamWriteImpl(OutputStream* s) const
-{
- s->write(_host, false);
- s->write(_port);
-}
-
-void
IceInternal::IPEndpointI::hashInit(Ice::Int& h) const
{
hashAdd(h, _host);
diff --git a/cpp/src/Ice/IPEndpointI.h b/cpp/src/Ice/IPEndpointI.h
index 3c6e520da2e..a2ed7984037 100644
--- a/cpp/src/Ice/IPEndpointI.h
+++ b/cpp/src/Ice/IPEndpointI.h
@@ -47,11 +47,12 @@ class ICE_API IPEndpointI : public EndpointI, public Ice::EnableSharedFromThis<I
{
public:
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
+
virtual Ice::EndpointInfoPtr getInfo() const;
virtual Ice::Short type() const;
virtual const std::string& protocol() const;
virtual bool secure() const;
- virtual void streamWrite(Ice::OutputStream*) const;
virtual const std::string& connectionId() const;
virtual EndpointIPtr connectionId(const ::std::string&) const;
@@ -71,10 +72,7 @@ public:
#endif
virtual std::vector<ConnectorPtr> connectors(const std::vector<Address>&, const NetworkProxyPtr&) const;
- const std::string& host() const;
- int port() const;
- virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual void hashInit(Ice::Int&) const;
virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp
index 5e7e0616943..5bd91cb36c3 100644
--- a/cpp/src/Ice/Incoming.cpp
+++ b/cpp/src/Ice/Incoming.cpp
@@ -183,11 +183,14 @@ IceInternal::IncomingBase::__warning(const Exception& ex) const
if(_current.con)
{
- Ice::ConnectionInfoPtr connInfo = _current.con->getInfo();
- Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo);
- if(ipConnInfo)
+ for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying)
{
- out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort;
+ Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo);
+ if(ipConnInfo)
+ {
+ out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort;
+ break;
+ }
}
}
}
@@ -204,11 +207,14 @@ IceInternal::IncomingBase::__warning(const string& msg) const
if(_current.con)
{
- Ice::ConnectionInfoPtr connInfo = _current.con->getInfo();
- Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo);
- if(ipConnInfo)
+ for(Ice::ConnectionInfoPtr connInfo = _current.con->getInfo(); connInfo; connInfo = connInfo->underlying)
{
- out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort;
+ Ice::IPConnectionInfoPtr ipConnInfo = ICE_DYNAMIC_CAST(Ice::IPConnectionInfo, connInfo);
+ if(ipConnInfo)
+ {
+ out << "\nremote host: " << ipConnInfo->remoteAddress << " remote port: " << ipConnInfo->remotePort;
+ break;
+ }
}
}
}
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index a561645ea64..460ec504c4f 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -1115,7 +1115,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
#endif
if(!logfile.empty())
{
- _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), logfile, true, ICE_NULLPTR,
+ _initData.logger = ICE_MAKE_SHARED(LoggerI, _initData.properties->getProperty("Ice.ProgramName"), logfile, true, ICE_NULLPTR,
_initData.properties->getPropertyAsIntWithDefault("Ice.LogFile.SizeMax", 0));
}
else
@@ -1330,13 +1330,13 @@ IceInternal::Instance::finishSetup(int& argc, char* argv[], const Ice::Communica
if(tcpFactory)
{
ProtocolInstancePtr instance = new ProtocolInstance(communicator, WSEndpointType, "ws", false);
- _endpointFactoryManager->add(new WSEndpointFactory(instance, tcpFactory->clone(instance)));
+ _endpointFactoryManager->add(new WSEndpointFactory(instance, tcpFactory->clone(instance, 0)));
}
EndpointFactoryPtr sslFactory = _endpointFactoryManager->get(SSLEndpointType);
if(sslFactory)
{
ProtocolInstancePtr instance = new ProtocolInstance(communicator, WSSEndpointType, "wss", true);
- _endpointFactoryManager->add(new WSEndpointFactory(instance, sslFactory->clone(instance)));
+ _endpointFactoryManager->add(new WSEndpointFactory(instance, sslFactory->clone(instance, 0)));
}
//
@@ -1838,9 +1838,9 @@ IceInternal::Instance::addObjectFactory(const Ice::ObjectFactoryPtr& factory, co
//
#ifdef ICE_CPP11_MAPPING
_initData.valueFactoryManager->add([factory](const string& id)
- {
- return factory->create(id);
- },
+ {
+ return factory->create(id);
+ },
id);
#else
class ValueFactoryWrapper: public Ice::ValueFactory
diff --git a/cpp/src/Ice/InstrumentationI.cpp b/cpp/src/Ice/InstrumentationI.cpp
index 6fbedad641f..62f8bda1285 100644
--- a/cpp/src/Ice/InstrumentationI.cpp
+++ b/cpp/src/Ice/InstrumentationI.cpp
@@ -74,6 +74,20 @@ struct ThreadStateChanged
ThreadState newState;
};
+IPConnectionInfo*
+getIPConnectionInfo(const ConnectionInfoPtr& info)
+{
+ for(ConnectionInfoPtr p = info; p; p = p->underlying)
+ {
+ IPConnectionInfo* ipInfo = dynamic_cast<IPConnectionInfo*>(p.get());
+ if(ipInfo)
+ {
+ return ipInfo;
+ }
+ }
+ return ICE_NULLPTR;
+}
+
class ConnectionHelper : public MetricsHelperT<ConnectionMetrics>
{
public:
@@ -108,7 +122,7 @@ public:
if(_id.empty())
{
ostringstream os;
- IPConnectionInfoPtr info = ICE_DYNAMIC_CAST(IPConnectionInfo, _connectionInfo);
+ IPConnectionInfo* info = getIPConnectionInfo(_connectionInfo);
if(info)
{
os << info->localAddress << ':' << info->localPort;
diff --git a/cpp/src/Ice/Makefile.mk b/cpp/src/Ice/Makefile.mk
index fe90b914e73..44890c32c18 100644
--- a/cpp/src/Ice/Makefile.mk
+++ b/cpp/src/Ice/Makefile.mk
@@ -26,8 +26,6 @@ Ice_excludes += src/IceUtil/ConvertUTF.cpp src/IceUtil/Unicode.cpp
endif
Ice[iphoneos]_extra_sources := $(wildcard $(addprefix $(currentdir)/ios/,*.cpp *.mm))
-Ice[iphoneos]_excludes := $(currentdir)/RegisterPluginsInit.cpp
Ice[iphonesimulator]_extra_sources = $(Ice[iphoneos]_extra_sources)
-Ice[iphonesimulator]_excludes = $(Ice[iphoneos]_excludes)
projects += $(project)
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index d1da40b9b51..317e1e3bbc4 100644..100755
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -812,12 +812,112 @@ IceInternal::NativeInfo::completed(SocketOperation operation)
#elif defined(ICE_OS_WINRT)
void
+IceInternal::NativeInfo::queueAction(SocketOperation op, IAsyncAction^ action, bool connect)
+{
+ AsyncInfo* asyncInfo = getAsyncInfo(op);
+ if(checkIfErrorOrCompleted(op, action, connect))
+ {
+ asyncInfo->count = 0;
+ }
+ else
+ {
+ action->Completed = ref new AsyncActionCompletedHandler(
+ [=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status)
+ {
+ if(status != Windows::Foundation::AsyncStatus::Completed)
+ {
+ asyncInfo->count = SOCKET_ERROR;
+ asyncInfo->error = info->ErrorCode.Value;
+ }
+ else
+ {
+ asyncInfo->count = 0;
+ }
+ completed(op);
+ });
+ }
+}
+
+void
+IceInternal::NativeInfo::queueOperation(SocketOperation op, IAsyncOperation<unsigned int>^ operation)
+{
+ AsyncInfo* info = getAsyncInfo(op);
+ if(checkIfErrorOrCompleted(op, operation))
+ {
+ info->count = static_cast<int>(operation->GetResults());
+ }
+ else
+ {
+ if(!info->completedHandler)
+ {
+ info->completedHandler = ref new AsyncOperationCompletedHandler<unsigned int>(
+ [=] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status)
+ {
+ if(status != Windows::Foundation::AsyncStatus::Completed)
+ {
+ info->count = SOCKET_ERROR;
+ info->error = operation->ErrorCode.Value;
+ }
+ else
+ {
+ info->count = static_cast<int>(operation->GetResults());
+ }
+ completed(op);
+ });
+ }
+ operation->Completed = info->completedHandler;
+ }
+}
+
+void
+IceInternal::NativeInfo::setCompletedHandler(SocketOperationCompletedHandler^ handler)
+{
+ _completedHandler = handler;
+}
+
+void
IceInternal::NativeInfo::completed(SocketOperation operation)
{
assert(_completedHandler);
_completedHandler(operation);
}
+bool
+IceInternal::NativeInfo::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info, bool connect)
+{
+ //
+ // NOTE: It's important to only check for info->Status once as it
+ // might change during the checks below (the Status can be changed
+ // by the Windows thread pool concurrently).
+ //
+ // We consider that a canceled async status is the same as an
+ // error. A canceled async status can occur if there's a timeout
+ // and the socket is closed.
+ //
+ Windows::Foundation::AsyncStatus status = info->Status;
+ if(status == Windows::Foundation::AsyncStatus::Completed)
+ {
+ _completedHandler(op);
+ return true;
+ }
+ else if (status == Windows::Foundation::AsyncStatus::Started)
+ {
+ return false;
+ }
+ else
+ {
+ if(connect) // Connect
+ {
+ checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value);
+ }
+ else
+ {
+ checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value);
+ }
+ return true; // Prevent compiler warning.
+ }
+}
+
#endif
bool
@@ -1996,6 +2096,9 @@ IceInternal::setReuseAddress(SOCKET fd, bool reuse)
#ifdef ICE_OS_WINRT
+namespace
+{
+
void
checkResultAndWait(IAsyncAction^ action)
{
@@ -2023,6 +2126,8 @@ checkResultAndWait(IAsyncAction^ action)
checkErrorCode(__FILE__, __LINE__, action->ErrorCode.Value);
}
}
+
+}
#endif
Address
@@ -2561,7 +2666,7 @@ IceInternal::createPipe(SOCKET fds[2])
#else // ICE_OS_WINRT
void
-IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, HostName^ host)
+IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr)
{
if(herr == E_ACCESSDENIED)
{
@@ -2591,11 +2696,6 @@ IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, Hos
{
DNSException ex(file, line);
ex.error = static_cast<int>(error);
- //
- // Don't need to pass a wide string converter as the wide string come from
- // Windows API.
- //
- ex.host = IceUtil::wstringToString(host->RawName->Data(), IceUtil::getProcessStringConverter());
throw ex;
}
else
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index 5d40847bdde..aae80089dbe 100644..100755
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -179,6 +179,7 @@ struct ICE_API AsyncInfo : WSAOVERLAPPED
#elif defined(ICE_OS_WINRT)
struct ICE_API AsyncInfo
{
+ Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ completedHandler;
int count;
int error;
};
@@ -221,10 +222,13 @@ public:
#if defined(ICE_USE_IOCP)
virtual AsyncInfo* getAsyncInfo(SocketOperation) = 0;
void initialize(HANDLE, ULONG_PTR);
- void completed(SocketOperation operation);
+ void completed(SocketOperation);
#elif defined(ICE_OS_WINRT)
- virtual void setCompletedHandler(SocketOperationCompletedHandler^) = 0;
- void completed(SocketOperation operation);
+ virtual AsyncInfo* getAsyncInfo(SocketOperation) = 0;
+ void queueAction(SocketOperation, Windows::Foundation::IAsyncAction^, bool = false);
+ void queueOperation(SocketOperation, Windows::Foundation::IAsyncOperation<unsigned int>^);
+ void setCompletedHandler(SocketOperationCompletedHandler^);
+ void completed(SocketOperation);
#endif
protected:
@@ -236,6 +240,7 @@ protected:
HANDLE _handle;
ULONG_PTR _key;
#elif defined(ICE_OS_WINRT)
+ bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^, bool = false);
SocketOperationCompletedHandler^ _completedHandler;
#endif
};
@@ -287,6 +292,7 @@ ICE_API void setMcastTtl(SOCKET, int, const Address&);
ICE_API void setReuseAddress(SOCKET, bool);
ICE_API Address doBind(SOCKET, const Address&);
+ICE_API void doListen(SOCKET, int);
#ifndef ICE_OS_WINRT
ICE_API bool interrupted();
@@ -301,7 +307,6 @@ ICE_API bool connectionRefused();
ICE_API bool connectInProgress();
ICE_API bool connectionLost();
-ICE_API void doListen(SOCKET, int);
ICE_API bool doConnect(SOCKET, const Address&, const Address&);
ICE_API void doFinishConnect(SOCKET);
ICE_API SOCKET doAccept(SOCKET);
@@ -312,7 +317,7 @@ ICE_API int getSocketErrno();
ICE_API Address getNumericAddress(const std::string&);
#else
-ICE_API void checkConnectErrorCode(const char*, int, HRESULT, Windows::Networking::HostName^);
+ICE_API void checkConnectErrorCode(const char*, int, HRESULT);
ICE_API void checkErrorCode(const char*, int, HRESULT);
#endif
diff --git a/cpp/src/Ice/OpaqueEndpointI.cpp b/cpp/src/Ice/OpaqueEndpointI.cpp
index 838fcc6252f..d6c8bdbf984 100644
--- a/cpp/src/Ice/OpaqueEndpointI.cpp
+++ b/cpp/src/Ice/OpaqueEndpointI.cpp
@@ -92,7 +92,7 @@ private:
//
OpaqueEndpointInfoI::OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncoding,
const Ice::ByteSeq& rawBytes) :
- Ice::OpaqueEndpointInfo(-1, false, rawEncoding, rawBytes),
+ Ice::OpaqueEndpointInfo(ICE_NULLPTR, -1, false, rawEncoding, rawBytes),
_type(type)
{
}
@@ -320,6 +320,12 @@ IceInternal::OpaqueEndpointI::operator<(const LocalObject& r) const
return false;
}
+void
+IceInternal::OpaqueEndpointI::streamWriteImpl(Ice::OutputStream*) const
+{
+ assert(false);
+}
+
bool
IceInternal::OpaqueEndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
{
diff --git a/cpp/src/Ice/OpaqueEndpointI.h b/cpp/src/Ice/OpaqueEndpointI.h
index fa4add29b16..a0ebae3a49f 100644
--- a/cpp/src/Ice/OpaqueEndpointI.h
+++ b/cpp/src/Ice/OpaqueEndpointI.h
@@ -57,6 +57,7 @@ public:
protected:
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual bool checkOption(const std::string&, const std::string&, const std::string&);
private:
diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp
index 580d51d74fe..ade367f2a40 100644
--- a/cpp/src/Ice/Selector.cpp
+++ b/cpp/src/Ice/Selector.cpp
@@ -22,12 +22,10 @@
using namespace std;
using namespace IceInternal;
-#ifdef ICE_OS_WINRT
-//using namespace Windows::Foundation;
+#if defined(ICE_OS_WINRT)
using namespace Windows::Storage::Streams;
using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;
-
#endif
#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
diff --git a/cpp/src/Ice/StreamSocket.cpp b/cpp/src/Ice/StreamSocket.cpp
index fa3761f5fa0..7d186e15dd4 100644..100755
--- a/cpp/src/Ice/StreamSocket.cpp
+++ b/cpp/src/Ice/StreamSocket.cpp
@@ -13,6 +13,14 @@
using namespace IceInternal;
+#if defined(ICE_OS_WINRT)
+
+#include <Ice/Properties.h>
+using namespace Platform;
+using namespace Windows::Foundation;
+
+#endif
+
StreamSocket::StreamSocket(const ProtocolInstancePtr& instance,
const NetworkProxyPtr& proxy,
const Address& addr,
@@ -23,13 +31,12 @@ StreamSocket::StreamSocket(const ProtocolInstancePtr& instance,
_addr(addr),
_sourceAddr(sourceAddr),
_state(StateNeedConnect)
-#ifdef ICE_USE_IOCP
- , _read(SocketOperationRead),
- _write(SocketOperationWrite)
+#if defined(ICE_USE_IOCP)
+ , _read(SocketOperationRead), _write(SocketOperationWrite)
#endif
{
init();
-#ifndef ICE_USE_IOCP
+#if !defined(ICE_USE_IOCP) && !defined(ICE_OS_WINRT)
if(doConnect(_fd, _proxy ? _proxy->getAddress() : _addr, sourceAddr))
{
_state = _proxy ? StateProxyWrite : StateConnected;
@@ -49,10 +56,11 @@ StreamSocket::StreamSocket(const ProtocolInstancePtr& instance,
StreamSocket::StreamSocket(const ProtocolInstancePtr& instance, SOCKET fd) :
NativeInfo(fd),
_instance(instance),
- _state(StateConnected)
-#ifdef ICE_USE_IOCP
- , _read(SocketOperationRead),
- _write(SocketOperationWrite)
+ _addr(),
+ _sourceAddr(),
+ _state(StateConnected)
+#if defined(ICE_USE_IOCP)
+ , _read(SocketOperationRead), _write(SocketOperationWrite)
#endif
{
init();
@@ -82,8 +90,26 @@ StreamSocket::connect(Buffer& readBuffer, Buffer& writeBuffer)
}
else if(_state <= StateConnectPending)
{
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP)
doFinishConnectAsync(_fd, _write);
+#elif defined(ICE_OS_WINRT)
+ if(_write.count == SOCKET_ERROR)
+ {
+ try
+ {
+ checkConnectErrorCode(__FILE__, __LINE__, _write.error);
+ }
+ catch(Ice::DNSException& ex)
+ {
+ //
+ // Don't need to pass a wide string converter as the wide string come from
+ // Windows API.
+ //
+ const Address& addr = _proxy ? _proxy->getAddress() : _addr;
+ ex.host = IceUtil::wstringToString(addr.host->RawName->Data(), IceUtil::getProcessStringConverter());
+ throw;
+ }
+ }
#else
doFinishConnect(_fd);
#endif
@@ -127,7 +153,7 @@ StreamSocket::isConnected()
size_t
StreamSocket::getSendPacketSize(size_t length)
{
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
return _maxSendPacketSize > 0 ? std::min(length, _maxSendPacketSize) : length;
#else
return length;
@@ -137,7 +163,7 @@ StreamSocket::getSendPacketSize(size_t length)
size_t
StreamSocket::getRecvPacketSize(size_t length)
{
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
return _maxRecvPacketSize > 0 ? std::min(length, _maxRecvPacketSize) : length;
#else
return length;
@@ -153,6 +179,7 @@ StreamSocket::setBufferSize(int rcvSize, int sndSize)
SocketOperation
StreamSocket::read(Buffer& buf)
{
+#if !defined(ICE_OS_WINRT)
if(_state == StateProxyRead)
{
while(true)
@@ -171,12 +198,14 @@ StreamSocket::read(Buffer& buf)
}
}
buf.i += read(reinterpret_cast<char*>(&*buf.i), buf.b.end() - buf.i);
+#endif
return buf.i != buf.b.end() ? SocketOperationRead : SocketOperationNone;
}
SocketOperation
StreamSocket::write(Buffer& buf)
{
+#if !defined(ICE_OS_WINRT)
if(_state == StateProxyWrite)
{
while(true)
@@ -195,9 +224,11 @@ StreamSocket::write(Buffer& buf)
}
}
buf.i += write(reinterpret_cast<const char*>(&*buf.i), buf.b.end() - buf.i);
+#endif
return buf.i != buf.b.end() ? SocketOperationWrite : SocketOperationNone;
}
+#if !defined(ICE_OS_WINRT)
ssize_t
StreamSocket::read(char* buf, size_t length)
{
@@ -278,7 +309,6 @@ StreamSocket::write(const char* buf, size_t length)
#else
size_t packetSize = length;
#endif
-
ssize_t sent = 0;
while(length > 0)
{
@@ -336,8 +366,9 @@ StreamSocket::write(const char* buf, size_t length)
}
return sent;
}
+#endif
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
AsyncInfo*
StreamSocket::getAsyncInfo(SocketOperation op)
{
@@ -352,6 +383,9 @@ StreamSocket::getAsyncInfo(SocketOperation op)
return 0;
}
}
+#endif
+
+#if defined(ICE_USE_IOCP)
bool
StreamSocket::startWrite(Buffer& buf)
@@ -489,7 +523,132 @@ StreamSocket::finishRead(Buffer& buf)
{
_state = toState(_proxy->endRead(buf));
}
+
+}
+
+#elif defined(ICE_OS_WINRT)
+
+bool
+StreamSocket::startWrite(Buffer& buf)
+{
+ if(_state == StateConnectPending)
+ {
+ const Address& addr = _proxy ? _proxy->getAddress() : _addr;
+ try
+ {
+ try
+ {
+ queueAction(SocketOperationConnect,
+ safe_cast<Windows::Networking::Sockets::StreamSocket^>(_fd)->ConnectAsync(addr.host, addr.port,
+ Windows::Networking::Sockets::SocketProtectionLevel::PlainSocket), true);
+ }
+ catch(Platform::Exception^ ex)
+ {
+ checkConnectErrorCode(__FILE__, __LINE__, ex->HResult);
+ }
+ }
+ catch(Ice::DNSException& ex)
+ {
+ //
+ // Don't need to pass a wide string converter as the wide string come from
+ // Windows API.
+ //
+ ex.host = IceUtil::wstringToString(addr.host->RawName->Data(), IceUtil::getProcessStringConverter());
+ throw;
+ }
+ return false;
+ }
+
+ assert(!buf.b.empty());
+ assert(buf.i != buf.b.end());
+
+ size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i);
+ if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize)
+ {
+ packetSize = _maxSendPacketSize;
+ }
+ assert(packetSize > 0);
+ _writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, packetSize));
+ try
+ {
+ queueOperation(SocketOperationWrite, _writer->StoreAsync());
+ }
+ catch(Platform::Exception^ ex)
+ {
+ checkErrorCode(__FILE__, __LINE__, ex->HResult);
+ }
+ return packetSize == static_cast<int>(buf.b.end() - buf.i);
}
+
+void
+StreamSocket::finishWrite(Buffer& buf)
+{
+ if(_fd == INVALID_SOCKET || (_state < StateConnected && _state != StateProxyWrite))
+ {
+ return;
+ }
+
+ if(_write.count == SOCKET_ERROR)
+ {
+ checkErrorCode(__FILE__, __LINE__, _write.error);
+ }
+
+ buf.i += _write.count;
+}
+
+void
+StreamSocket::startRead(Buffer& buf)
+{
+ size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i);
+ if(_maxRecvPacketSize > 0 && packetSize > _maxRecvPacketSize)
+ {
+ packetSize = _maxRecvPacketSize;
+ }
+ assert(!buf.b.empty() && buf.i != buf.b.end());
+
+ try
+ {
+ queueOperation(SocketOperationRead, _reader->LoadAsync(packetSize));
+ }
+ catch(Platform::Exception^ ex)
+ {
+ checkErrorCode(__FILE__, __LINE__, ex->HResult);
+ }
+}
+
+void
+StreamSocket::finishRead(Buffer& buf)
+{
+ if(_fd == INVALID_SOCKET)
+ {
+ return;
+ }
+
+ if(_read.count == SOCKET_ERROR)
+ {
+ checkErrorCode(__FILE__, __LINE__, _read.error);
+ }
+ else if(_read.count == 0)
+ {
+ Ice::ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
+ }
+
+ try
+ {
+ auto data = ref new Platform::Array<unsigned char>(_read.count);
+ _reader->ReadBytes(data);
+ memcpy(&*buf.i, data->Data, _read.count);
+ }
+ catch(Platform::Exception^ ex)
+ {
+ checkErrorCode(__FILE__, __LINE__, ex->HResult);
+ }
+
+ buf.i += _read.count;
+}
+
#endif
void
@@ -520,7 +679,7 @@ StreamSocket::init()
setBlock(_fd, false);
setTcpBufSize(_fd, _instance);
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP)
//
// For timeouts to work properly, we need to receive or send the
// data in several chunks when using IOCP WSARecv or WSASend.
@@ -530,6 +689,14 @@ StreamSocket::init()
//
_maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_fd));
_maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_fd));
+#elif defined(ICE_OS_WINRT)
+ Windows::Networking::Sockets::StreamSocket^ s = safe_cast<Windows::Networking::Sockets::StreamSocket^>(_fd);
+ _writer = ref new Windows::Storage::Streams::DataWriter(s->OutputStream);
+ _reader = ref new Windows::Storage::Streams::DataReader(s->InputStream);
+ _reader->InputStreamOptions = Windows::Storage::Streams::InputStreamOptions::Partial;
+
+ _maxSendPacketSize = std::max(static_cast<unsigned int>(512), s->Control->OutboundBufferSizeInBytes / 2);
+ _maxRecvPacketSize = _instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", 128 * 1024);
#endif
}
@@ -546,5 +713,3 @@ StreamSocket::toState(SocketOperation operation) const
return StateProxyConnected;
}
}
-
-
diff --git a/cpp/src/Ice/StreamSocket.h b/cpp/src/Ice/StreamSocket.h
index ad69b096199..3d092d20ba2 100644
--- a/cpp/src/Ice/StreamSocket.h
+++ b/cpp/src/Ice/StreamSocket.h
@@ -36,11 +36,16 @@ public:
SocketOperation read(Buffer&);
SocketOperation write(Buffer&);
+#if !defined(ICE_OS_WINRT)
ssize_t read(char*, size_t);
ssize_t write(const char*, size_t);
+#endif
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
AsyncInfo* getAsyncInfo(SocketOperation);
+#endif
+
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
bool startWrite(Buffer&);
void finishWrite(Buffer&);
void startRead(Buffer&);
@@ -73,12 +78,17 @@ private:
State _state;
std::string _desc;
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
size_t _maxSendPacketSize;
size_t _maxRecvPacketSize;
AsyncInfo _read;
AsyncInfo _write;
#endif
+
+#if defined(ICE_OS_WINRT)
+ Windows::Storage::Streams::DataReader^ _reader;
+ Windows::Storage::Streams::DataWriter^ _writer;
+#endif
};
typedef IceUtil::Handle<StreamSocket> StreamSocketPtr;
diff --git a/cpp/src/Ice/TcpAcceptor.cpp b/cpp/src/Ice/TcpAcceptor.cpp
index 8ca874cc218..e20ad639d91 100644..100755
--- a/cpp/src/Ice/TcpAcceptor.cpp
+++ b/cpp/src/Ice/TcpAcceptor.cpp
@@ -17,8 +17,21 @@
#include <Ice/StreamSocket.h>
#include <IceUtil/StringUtil.h>
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP)
# include <Mswsock.h>
+#elif defined(ICE_OS_WINRT)
+using namespace Platform;
+using namespace Windows::Foundation;
+using namespace Windows::Storage::Streams;
+using namespace Windows::Networking;
+using namespace Windows::Networking::Sockets;
+#endif
+
+//
+// Use the system default for the listen() backlog or 511 if not defined.
+//
+#ifndef SOMAXCONN
+# define SOMAXCONN 511
#endif
using namespace std;
@@ -33,22 +46,28 @@ IceInternal::TcpAcceptor::getNativeInfo()
return this;
}
-#ifdef ICE_USE_IOCP
-AsyncInfo*
-# ifndef NDEBUG
-IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation op)
-# else
-IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation)
-# endif
-{
- assert(op == SocketOperationRead);
- return &_info;
-}
-#endif
-
void
IceInternal::TcpAcceptor::close()
{
+#if defined(ICE_OS_WINRT)
+ IceUtil::Mutex::Lock lock(_mutex);
+ if(_acceptPending)
+ {
+ assert(_accepted.empty());
+ completed(SocketOperationRead);
+ _acceptPending = false;
+ }
+ else if(!_accepted.empty())
+ {
+ for(deque<Windows::Networking::Sockets::StreamSocket^>::const_iterator p = _accepted.begin();
+ p != _accepted.end(); ++p)
+ {
+ closeSocket(*p);
+ }
+ _accepted.clear();
+ }
+#endif
+
if(_fd != INVALID_SOCKET)
{
closeSocketNoThrow(_fd);
@@ -62,7 +81,9 @@ IceInternal::TcpAcceptor::listen()
try
{
const_cast<Address&>(_addr) = doBind(_fd, _addr);
+#if !defined(ICE_OS_WINRT)
doListen(_fd, _backlog);
+#endif
}
catch(...)
{
@@ -73,7 +94,14 @@ IceInternal::TcpAcceptor::listen()
return _endpoint;
}
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP)
+
+AsyncInfo*
+IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation)
+{
+ return &_info;
+}
+
void
IceInternal::TcpAcceptor::startAccept()
{
@@ -120,12 +148,9 @@ IceInternal::TcpAcceptor::finishAccept()
}
}
-#endif
-
TransceiverPtr
IceInternal::TcpAcceptor::accept()
{
-#ifdef ICE_USE_IOCP
if(_acceptFd == INVALID_SOCKET)
{
SocketException ex(__FILE__, __LINE__);
@@ -144,13 +169,82 @@ IceInternal::TcpAcceptor::accept()
SOCKET fd = _acceptFd;
_acceptFd = INVALID_SOCKET;
+ return new TcpTransceiver(_instance, new StreamSocket(_instance, fd));
+}
+
+#elif defined(ICE_OS_WINRT)
+
+AsyncInfo*
+IceInternal::TcpAcceptor::getAsyncInfo(SocketOperation)
+{
+ return 0; // Not used
+}
+
+void
+IceInternal::TcpAcceptor::startAccept()
+{
+ assert(_fd != INVALID_SOCKET);
+
+ //
+ // If there are already sockets waiting to be accepted, we just
+ // notify the selector that the acceptor is ready for acceting the
+ // new socket. Otherwise, we set the _acceptPending flag, when a
+ // new socket connection event is received, the message handler
+ // will notify the selector.
+ //
+ IceUtil::Mutex::Lock lock(_mutex);
+ assert(!_acceptPending);
+ if(!_accepted.empty())
+ {
+ completed(SocketOperationRead);
+ }
+ else
+ {
+ _acceptPending = true;
+ }
+}
+
+void
+IceInternal::TcpAcceptor::finishAccept()
+{
+ //
+ // Nothing to do, we just check there's at least one accepted
+ // socket or the acceptor was closed.
+ //
+ IceUtil::Mutex::Lock lock(_mutex);
+ assert(!_acceptPending && (!_accepted.empty() || _fd == INVALID_SOCKET));
+}
+
+TransceiverPtr
+IceInternal::TcpAcceptor::accept()
+{
+ if(_fd == INVALID_SOCKET) // Acceptor closed.
+ {
+ assert(_accepted.empty());
+ throw SocketException(__FILE__, __LINE__);
+ }
+
+ Windows::Networking::Sockets::StreamSocket^ fd;
+ {
+ IceUtil::Mutex::Lock lock(_mutex);
+ assert(!_accepted.empty());
+ fd = _accepted.front();
+ _accepted.pop_front();
+ }
+
+ return new TcpTransceiver(_instance, new StreamSocket(_instance, fd));
+}
+
#else
- SOCKET fd = doAccept(_fd);
-#endif
- return new TcpTransceiver(_instance, new StreamSocket(_instance, fd));
+TransceiverPtr
+IceInternal::TcpAcceptor::accept()
+{
+ return new TcpTransceiver(_instance, new StreamSocket(_instance, doAccept(_fd)));
}
+#endif
+
string
IceInternal::TcpAcceptor::protocol() const
{
@@ -191,23 +285,49 @@ IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint,
_instance(instance),
_addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6()))
#ifdef ICE_USE_IOCP
- , _acceptFd(INVALID_SOCKET),
- _info(SocketOperationRead)
+ , _acceptFd(INVALID_SOCKET), _info(SocketOperationRead)
#endif
{
-#ifdef SOMAXCONN
_backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN);
+
+#if defined(ICE_OS_WINRT)
+ _fd = ref new StreamSocketListener();
+ safe_cast<StreamSocketListener^>(_fd)->ConnectionReceived +=
+ ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>(
+ [=](StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^ args)
+ {
+ IceUtil::Mutex::Lock lock(_mutex);
+ if(_fd == INVALID_SOCKET) // Acceptor was closed.
+ {
+ closeSocket(args->Socket);
+ return;
+ }
+ _accepted.push_back(args->Socket);
+
+ //
+ // If the acceptor is waiting for a socket to be accepted, notify
+ // the selector that the acceptor is ready for "read". This will
+ // in turn caused finishAccept() and accept() to be called by the
+ // thread pool. If the acceptor isn't ready to accept the socket,
+ // it is just queued, when startAccept is called it will be dequed.
+ //
+ if(_acceptPending)
+ {
+ completed(SocketOperationRead);
+ _acceptPending = false;
+ }
+ });
#else
- _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);
+ _fd = createServerSocket(false, _addr, instance->protocolSupport());
#endif
- _fd = createServerSocket(false, _addr, instance->protocolSupport());
#ifdef ICE_USE_IOCP
_acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2);
#endif
setBlock(_fd, false);
setTcpBufSize(_fd, _instance);
+
#ifndef _WIN32
//
// Enable SO_REUSEADDR on Unix platforms to allow re-using the
diff --git a/cpp/src/Ice/TcpAcceptor.h b/cpp/src/Ice/TcpAcceptor.h
index c5e23428895..2d9fc24d72f 100644
--- a/cpp/src/Ice/TcpAcceptor.h
+++ b/cpp/src/Ice/TcpAcceptor.h
@@ -15,6 +15,10 @@
#include <Ice/Acceptor.h>
#include <Ice/Network.h>
+#if defined(ICE_OS_WINRT)
+#include <deque>
+#endif
+
namespace IceInternal
{
@@ -25,13 +29,13 @@ class TcpAcceptor : public Acceptor, public NativeInfo
public:
virtual NativeInfoPtr getNativeInfo();
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual AsyncInfo* getAsyncInfo(SocketOperation);
#endif
virtual void close();
virtual EndpointIPtr listen();
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual void startAccept();
virtual void finishAccept();
#endif
@@ -54,11 +58,15 @@ private:
const Address _addr;
int _backlog;
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP)
SOCKET _acceptFd;
int _acceptError;
std::vector<char> _acceptBuf;
AsyncInfo _info;
+#elif defined(ICE_OS_WINRT)
+ IceUtil::Mutex _mutex;
+ bool _acceptPending;
+ std::deque<Windows::Networking::Sockets::StreamSocket^> _accepted;
#endif
};
diff --git a/cpp/src/Ice/TcpEndpointI.cpp b/cpp/src/Ice/TcpEndpointI.cpp
index 1caadefbae2..2b2e26e924e 100644
--- a/cpp/src/Ice/TcpEndpointI.cpp
+++ b/cpp/src/Ice/TcpEndpointI.cpp
@@ -62,21 +62,19 @@ IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, Inp
s->read(const_cast<bool&>(_compress));
}
-EndpointInfoPtr
-IceInternal::TcpEndpointI::getInfo() const
+void
+IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const
{
- TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>,
- ICE_DYNAMIC_CAST(TcpEndpointI, shared_from_this()));
- fillEndpointInfo(info.get());
- return info;
+ IPEndpointI::streamWriteImpl(s);
+ s->write(_timeout);
+ s->write(_compress);
}
EndpointInfoPtr
-IceInternal::TcpEndpointI::getWSInfo(const string& resource) const
+IceInternal::TcpEndpointI::getInfo() const
{
- WSEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this());
+ TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this());
fillEndpointInfo(info.get());
- info->resource = resource;
return info;
}
@@ -254,14 +252,6 @@ IceInternal::TcpEndpointI::operator<(const LocalObject& r) const
}
void
-IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const
-{
- IPEndpointI::streamWriteImpl(s);
- s->write(_timeout);
- s->write(_compress);
-}
-
-void
IceInternal::TcpEndpointI::hashInit(Ice::Int& h) const
{
IPEndpointI::hashInit(h);
@@ -385,7 +375,7 @@ IceInternal::TcpEndpointFactory::destroy()
}
EndpointFactoryPtr
-IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance) const
+IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const
{
return new TcpEndpointFactory(instance);
}
diff --git a/cpp/src/Ice/TcpEndpointI.h b/cpp/src/Ice/TcpEndpointI.h
index ffc6743e213..f40c5c14713 100644
--- a/cpp/src/Ice/TcpEndpointI.h
+++ b/cpp/src/Ice/TcpEndpointI.h
@@ -14,12 +14,11 @@
#include <Ice/IPEndpointI.h>
#include <Ice/EndpointFactory.h>
#include <Ice/Network.h> // for IceIternal::Address
-#include <Ice/WSEndpoint.h>
namespace IceInternal
{
-class TcpEndpointI : public IPEndpointI, public WSEndpointDelegate
+class TcpEndpointI : public IPEndpointI, public Ice::EnableSharedFromThis<TcpEndpointI>
{
public:
@@ -28,8 +27,9 @@ public:
TcpEndpointI(const ProtocolInstancePtr&);
TcpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*);
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
+
virtual Ice::EndpointInfoPtr getInfo() const;
- virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const;
virtual Ice::Int timeout() const;
virtual EndpointIPtr timeout(Ice::Int) const;
@@ -51,10 +51,10 @@ public:
TcpEndpointIPtr endpoint(const TcpAcceptorPtr&) const;
using IPEndpointI::connectionId;
+ using Ice::EnableSharedFromThis<TcpEndpointI>::shared_from_this;
protected:
- virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual void hashInit(Ice::Int&) const;
virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
virtual bool checkOption(const std::string&, const std::string&, const std::string&);
@@ -84,7 +84,7 @@ public:
virtual EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const;
+ virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/Ice/TcpTransceiver.cpp b/cpp/src/Ice/TcpTransceiver.cpp
index 99898f4e2be..be280be0476 100644
--- a/cpp/src/Ice/TcpTransceiver.cpp
+++ b/cpp/src/Ice/TcpTransceiver.cpp
@@ -60,7 +60,7 @@ IceInternal::TcpTransceiver::read(Buffer& buf)
return _stream->read(buf);
}
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
bool
IceInternal::TcpTransceiver::startWrite(Buffer& buf)
{
@@ -108,16 +108,12 @@ Ice::ConnectionInfoPtr
IceInternal::TcpTransceiver::getInfo() const
{
TCPConnectionInfoPtr info = ICE_MAKE_SHARED(TCPConnectionInfo);
- fillConnectionInfo(info);
- return info;
-}
-
-Ice::ConnectionInfoPtr
-IceInternal::TcpTransceiver::getWSInfo(const Ice::HeaderDict& headers) const
-{
- WSConnectionInfoPtr info = ICE_MAKE_SHARED(WSConnectionInfo);
- fillConnectionInfo(info);
- info->headers = headers;
+ fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
+ if(_stream->fd() != INVALID_SOCKET)
+ {
+ info->rcvSize = getRecvBufferSize(_stream->fd());
+ info->sndSize = getSendBufferSize(_stream->fd());
+ }
return info;
}
@@ -141,14 +137,3 @@ IceInternal::TcpTransceiver::TcpTransceiver(const ProtocolInstancePtr& instance,
IceInternal::TcpTransceiver::~TcpTransceiver()
{
}
-
-void
-IceInternal::TcpTransceiver::fillConnectionInfo(const TCPConnectionInfoPtr& info) const
-{
- fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
- if(_stream->fd() != INVALID_SOCKET)
- {
- info->rcvSize = getRecvBufferSize(_stream->fd());
- info->sndSize = getSendBufferSize(_stream->fd());
- }
-}
diff --git a/cpp/src/Ice/TcpTransceiver.h b/cpp/src/Ice/TcpTransceiver.h
index f2890ba076c..198b4aeab77 100644
--- a/cpp/src/Ice/TcpTransceiver.h
+++ b/cpp/src/Ice/TcpTransceiver.h
@@ -14,7 +14,6 @@
#include <Ice/Transceiver.h>
#include <Ice/Network.h>
#include <Ice/StreamSocket.h>
-#include <Ice/WSTransceiver.h>
namespace IceInternal
{
@@ -22,7 +21,7 @@ namespace IceInternal
class TcpConnector;
class TcpAcceptor;
-class TcpTransceiver : public Transceiver, public WSTransceiverDelegate
+class TcpTransceiver : public Transceiver
{
public:
@@ -37,7 +36,7 @@ public:
virtual void close();
virtual SocketOperation write(Buffer&);
virtual SocketOperation read(Buffer&);
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual bool startWrite(Buffer&);
virtual void finishWrite(Buffer&);
virtual void startRead(Buffer&);
@@ -47,7 +46,6 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
virtual void checkSendSize(const Buffer&);
virtual void setBufferSize(int rcvSize, int sndSize);
@@ -56,8 +54,6 @@ private:
TcpTransceiver(const ProtocolInstancePtr&, const StreamSocketPtr&);
virtual ~TcpTransceiver();
- void fillConnectionInfo(const Ice::TCPConnectionInfoPtr&) const;
-
friend class TcpConnector;
friend class TcpAcceptor;
diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp
index f5b3e20982a..2adf5dc32cc 100644
--- a/cpp/src/Ice/UdpEndpointI.cpp
+++ b/cpp/src/Ice/UdpEndpointI.cpp
@@ -76,10 +76,24 @@ IceInternal::UdpEndpointI::UdpEndpointI(const ProtocolInstancePtr& instance, Inp
s->read(const_cast<bool&>(_compress));
}
+void
+IceInternal::UdpEndpointI::streamWriteImpl(OutputStream* s) const
+{
+ IPEndpointI::streamWriteImpl(s);
+ if(s->getEncoding() == Ice::Encoding_1_0)
+ {
+ s->write(Ice::Protocol_1_0);
+ s->write(Ice::Encoding_1_0);
+ }
+ // Not transmitted.
+ //s->write(_connect);
+ s->write(_compress);
+}
+
EndpointInfoPtr
IceInternal::UdpEndpointI::getInfo() const
{
- Ice::UDPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::UDPEndpointInfo>,
+ Ice::UDPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::UDPEndpointInfo>,
ICE_DYNAMIC_CAST(UdpEndpointI, shared_from_this()));
fillEndpointInfo(info.get());
return info;
@@ -287,20 +301,6 @@ IceInternal::UdpEndpointI::operator<(const LocalObject& r) const
}
void
-IceInternal::UdpEndpointI::streamWriteImpl(OutputStream* s) const
-{
- IPEndpointI::streamWriteImpl(s);
- if(s->getEncoding() == Ice::Encoding_1_0)
- {
- s->write(Ice::Protocol_1_0);
- s->write(Ice::Encoding_1_0);
- }
- // Not transmitted.
- //s->write(_connect);
- s->write(_compress);
-}
-
-void
IceInternal::UdpEndpointI::hashInit(Ice::Int& h) const
{
IPEndpointI::hashInit(h);
@@ -463,7 +463,7 @@ IceInternal::UdpEndpointFactory::destroy()
}
EndpointFactoryPtr
-IceInternal::UdpEndpointFactory::clone(const ProtocolInstancePtr& instance) const
+IceInternal::UdpEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const
{
return new UdpEndpointFactory(instance);
}
diff --git a/cpp/src/Ice/UdpEndpointI.h b/cpp/src/Ice/UdpEndpointI.h
index d534c52c5bb..883b725e688 100644
--- a/cpp/src/Ice/UdpEndpointI.h
+++ b/cpp/src/Ice/UdpEndpointI.h
@@ -27,6 +27,8 @@ public:
UdpEndpointI(const ProtocolInstancePtr&);
UdpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*);
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
+
virtual Ice::EndpointInfoPtr getInfo() const;
virtual Ice::Int timeout() const;
@@ -46,14 +48,13 @@ public:
virtual bool operator==(const Ice::LocalObject&) const;
virtual bool operator<(const Ice::LocalObject&) const;
#endif
-
+
UdpEndpointIPtr endpoint(const UdpTransceiverPtr&) const;
using IPEndpointI::connectionId;
protected:
- virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual void hashInit(Ice::Int&) const;
virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
virtual bool checkOption(const std::string&, const std::string&, const std::string&);
@@ -85,7 +86,7 @@ public:
virtual EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const;
+ virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index 998ba5cf58f..4c1c277829f 100644..100755
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -40,11 +40,11 @@ IceInternal::UdpTransceiver::getNativeInfo()
return this;
}
-
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
AsyncInfo*
IceInternal::UdpTransceiver::getAsyncInfo(SocketOperation status)
{
+#if defined(ICE_USE_IOCP)
switch(status)
{
case SocketOperationRead:
@@ -55,26 +55,9 @@ IceInternal::UdpTransceiver::getAsyncInfo(SocketOperation status)
assert(false);
return 0;
}
-}
#elif defined(ICE_OS_WINRT)
-void
-IceInternal::UdpTransceiver::setCompletedHandler(SocketOperationCompletedHandler^ handler)
-{
- _completedHandler = handler;
- _writeOperationCompletedHandler = ref new AsyncOperationCompletedHandler<unsigned int>(
- [=] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status)
- {
- if(status != Windows::Foundation::AsyncStatus::Completed)
- {
- _write.count = SOCKET_ERROR;
- _write.error = operation->ErrorCode.Value;
- }
- else
- {
- _write.count = static_cast<int>(operation->GetResults());
- }
- _completedHandler(SocketOperationWrite);
- });
+ return &_write;
+#endif
}
#endif
@@ -93,7 +76,15 @@ IceInternal::UdpTransceiver::initialize(Buffer& /*readBuffer*/, Buffer& /*writeB
#elif defined(ICE_OS_WINRT)
if(_write.count == SOCKET_ERROR)
{
- checkConnectErrorCode(__FILE__, __LINE__, _write.error, _addr.host);
+ try
+ {
+ checkConnectErrorCode(__FILE__, __LINE__, _write.error);
+ }
+ catch(Ice::DNSException& ex)
+ {
+ ex.host = IceUtil::wstringToString(_addr.host->RawName->Data(), IceUtil::getProcessStringConverter());
+ throw;
+ }
}
#else
doFinishConnect(_fd);
@@ -124,11 +115,10 @@ IceInternal::UdpTransceiver::close()
if(_readPending)
{
assert(_received.empty());
- _completedHandler(SocketOperationRead);
+ completed(SocketOperationRead);
_readPending = false;
}
_received.clear();
- _completedHandler = nullptr;
#endif
assert(_fd != INVALID_SOCKET);
@@ -394,7 +384,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
auto operation = safe_cast<DatagramSocket^>(_fd)->ConnectAsync(_addr.host, _addr.port);
if(!checkIfErrorOrCompleted(SocketOperationConnect, operation))
{
- SocketOperationCompletedHandler^ completed = _completedHandler;
operation->Completed = ref new AsyncActionCompletedHandler(
[=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status)
{
@@ -422,7 +411,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
auto operation = safe_cast<DatagramSocket^>(_fd)->GetOutputStreamAsync(_addr.host, _addr.port);
if(!checkIfErrorOrCompleted(SocketOperationConnect, operation))
{
- SocketOperationCompletedHandler^ completed = _completedHandler;
operation->Completed = ref new AsyncOperationCompletedHandler<IOutputStream^>(
[=] (IAsyncOperation<IOutputStream^>^ info, Windows::Foundation::AsyncStatus status)
{
@@ -456,7 +444,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
}
catch(Platform::Exception^ ex)
{
- checkConnectErrorCode(__FILE__, __LINE__, ex->HResult, _addr.host);
+ checkConnectErrorCode(__FILE__, __LINE__, ex->HResult);
}
return false;
}
@@ -464,7 +452,6 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
{
try
{
- SocketOperationCompletedHandler^ completed = _completedHandler;
DatagramSocket^ fd = safe_cast<DatagramSocket^>(_fd);
concurrency::create_task(fd->GetOutputStreamAsync(_peerAddr.host, _peerAddr.port)).then(
[=,&buf](concurrency::task<IOutputStream^> task)
@@ -474,35 +461,18 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
DataWriter^ writer = ref new DataWriter(task.get());
writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, static_cast<int>(buf.b.size())));
DataWriterStoreOperation^ operation = writer->StoreAsync();
-
- Windows::Foundation::AsyncStatus status = operation->Status;
- if(status == Windows::Foundation::AsyncStatus::Completed)
- {
- //
- // NOTE: unlike other methods, it's important to modify _write.count
- // _before_ calling checkIfErrorOrCompleted since this isn't called
- // with the connection mutex but from a Windows thread pool thread.
- // So we can't modify the _write structure after calling the
- // completed callback.
- //
- _write.count = operation->GetResults();
- completed(SocketOperationWrite);
- }
- else if(status == Windows::Foundation::AsyncStatus::Started)
- {
- operation->Completed = _writeOperationCompletedHandler;
- }
- else
- {
- if(_state < StateConnected)
- {
- checkConnectErrorCode(__FILE__, __LINE__, operation->ErrorCode.Value, _addr.host);
- }
- else
- {
- checkErrorCode(__FILE__, __LINE__, operation->ErrorCode.Value);
- }
- }
+ if(operation->Status == Windows::Foundation::AsyncStatus::Completed)
+ {
+ //
+ // NOTE: unlike other methods, it's important to modify _write.count
+ // _before_ calling checkIfErrorOrCompleted since this isn't called
+ // with the connection mutex but from a Windows thread pool thread.
+ // So we can't modify the _write structure after calling the
+ // completed callback.
+ //
+ _write.count = operation->GetResults();
+ }
+ queueOperation(SocketOperationWrite, operation);
}
catch(Platform::Exception^ pex)
{
@@ -523,15 +493,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
try
{
_writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, static_cast<int>(buf.b.size())));
- DataWriterStoreOperation^ operation = _writer->StoreAsync();
- if(checkIfErrorOrCompleted(SocketOperationWrite, operation))
- {
- _write.count = operation->GetResults();
- }
- else
- {
- operation->Completed = _writeOperationCompletedHandler;
- }
+ queueOperation(SocketOperationWrite, _writer->StoreAsync());
}
catch(Platform::Exception^ ex)
{
@@ -675,7 +637,7 @@ IceInternal::UdpTransceiver::startRead(Buffer& buf)
assert(!_readPending);
if(!_received.empty())
{
- _completedHandler(SocketOperationRead);
+ completed(SocketOperationRead);
}
else
{
@@ -1147,42 +1109,6 @@ IceInternal::UdpTransceiver::setBufSize(int rcvSize, int sndSize)
}
#ifdef ICE_OS_WINRT
-bool
-IceInternal::UdpTransceiver::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info)
-{
- //
- // NOTE: It's important to only check for info->Status once as it
- // might change during the checks below (the Status can be changed
- // by the Windows thread pool concurrently).
- //
- // We consider that a canceled async status is the same as an
- // error. A canceled async status can occur if there's a timeout
- // and the socket is closed.
- //
- Windows::Foundation::AsyncStatus status = info->Status;
- if(status == Windows::Foundation::AsyncStatus::Completed)
- {
- _completedHandler(op);
- return true;
- }
- else if(status == Windows::Foundation::AsyncStatus::Started)
- {
- return false;
- }
- else
- {
- if(_state < StateConnected)
- {
- checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value, _addr.host);
- }
- else
- {
- checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value);
- }
- return true; // Prevent compiler warning.
- }
-}
-
void
IceInternal::UdpTransceiver::appendMessage(DatagramSocketMessageReceivedEventArgs^ args)
{
@@ -1202,7 +1128,7 @@ IceInternal::UdpTransceiver::appendMessage(DatagramSocketMessageReceivedEventArg
//
if(_readPending)
{
- _completedHandler(SocketOperationRead);
+ completed(SocketOperationRead);
_readPending = false;
}
}
diff --git a/cpp/src/Ice/UdpTransceiver.h b/cpp/src/Ice/UdpTransceiver.h
index fc38da8795a..84b600d68c2 100644
--- a/cpp/src/Ice/UdpTransceiver.h
+++ b/cpp/src/Ice/UdpTransceiver.h
@@ -38,10 +38,8 @@ class UdpTransceiver : public Transceiver, public NativeInfo
public:
virtual NativeInfoPtr getNativeInfo();
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual AsyncInfo* getAsyncInfo(SocketOperation);
-#elif defined(ICE_OS_WINRT)
- virtual void setCompletedHandler(SocketOperationCompletedHandler^);
#endif
virtual SocketOperation initialize(Buffer&, Buffer&);
@@ -80,7 +78,6 @@ private:
void setBufSize(int, int);
#ifdef ICE_OS_WINRT
- bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^);
void appendMessage(Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^);
Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^ readMessage();
#endif
@@ -112,12 +109,7 @@ private:
socklen_t _readAddrLen;
#elif defined(ICE_OS_WINRT)
AsyncInfo _write;
-
Windows::Storage::Streams::DataWriter^ _writer;
-
- SocketOperationCompletedHandler^ _completedHandler;
- Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _writeOperationCompletedHandler;
-
IceUtil::Mutex _mutex;
bool _readPending;
std::deque<Windows::Networking::Sockets::DatagramSocketMessageReceivedEventArgs^> _received;
diff --git a/cpp/src/Ice/WSAcceptor.cpp b/cpp/src/Ice/WSAcceptor.cpp
index 2237d6807d7..d72414dae60 100644
--- a/cpp/src/Ice/WSAcceptor.cpp
+++ b/cpp/src/Ice/WSAcceptor.cpp
@@ -21,18 +21,12 @@ IceInternal::WSAcceptor::getNativeInfo()
return _delegate->getNativeInfo();
}
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
IceInternal::AsyncInfo*
IceInternal::WSAcceptor::getAsyncInfo(IceInternal::SocketOperation status)
{
return _delegate->getNativeInfo()->getAsyncInfo(status);
}
-#elif defined(ICE_OS_WINRT)
-void
-IceInternal::WSAcceptor::setCompletedHandler(IceInternal::SocketOperationCompletedHandler^ handler)
-{
- _delegate->getNativeInfo()->setCompletedHandler(handler);
-}
#endif
void
diff --git a/cpp/src/Ice/WSAcceptor.h b/cpp/src/Ice/WSAcceptor.h
index 8aef5a8ddff..0b389f6a210 100644
--- a/cpp/src/Ice/WSAcceptor.h
+++ b/cpp/src/Ice/WSAcceptor.h
@@ -26,10 +26,8 @@ class WSAcceptor : public Acceptor, public NativeInfo
public:
virtual NativeInfoPtr getNativeInfo();
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual AsyncInfo* getAsyncInfo(SocketOperation);
-#elif defined(ICE_OS_WINRT)
- virtual void setCompletedHandler(SocketOperationCompletedHandler^);
#endif
virtual void close();
@@ -43,8 +41,6 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
- virtual AcceptorPtr delegate() const { return _delegate; }
-
private:
WSAcceptor(const WSEndpointPtr&, const ProtocolInstancePtr&, const AcceptorPtr&);
diff --git a/cpp/src/Ice/WSConnector.cpp b/cpp/src/Ice/WSConnector.cpp
index 91e6a9a7eed..beec5f0ab70 100644
--- a/cpp/src/Ice/WSConnector.cpp
+++ b/cpp/src/Ice/WSConnector.cpp
@@ -19,7 +19,7 @@ using namespace IceInternal;
TransceiverPtr
IceInternal::WSConnector::connect()
{
- return new WSTransceiver(_instance, _delegate->connect(), _host, _port, _resource);
+ return new WSTransceiver(_instance, _delegate->connect(), _host, _resource);
}
Short
@@ -102,9 +102,9 @@ IceInternal::WSConnector::operator<(const Connector& r) const
return false;
}
-IceInternal::WSConnector::WSConnector(const ProtocolInstancePtr& instance, const ConnectorPtr& del, const string& host,
- int port, const string& resource) :
- _instance(instance), _delegate(del), _host(host), _port(port), _resource(resource)
+IceInternal::WSConnector::WSConnector(const ProtocolInstancePtr& instance, const ConnectorPtr& del, const string& host,
+ const string& resource) :
+ _instance(instance), _delegate(del), _host(host), _resource(resource)
{
}
diff --git a/cpp/src/Ice/WSConnector.h b/cpp/src/Ice/WSConnector.h
index 3c26a06ab45..176ec9d770c 100644
--- a/cpp/src/Ice/WSConnector.h
+++ b/cpp/src/Ice/WSConnector.h
@@ -34,15 +34,14 @@ public:
virtual bool operator<(const Connector&) const;
- WSConnector(const ProtocolInstancePtr&, const ConnectorPtr&, const std::string&, int, const std::string&);
+ WSConnector(const ProtocolInstancePtr&, const ConnectorPtr&, const std::string&, const std::string&);
virtual ~WSConnector();
private:
-
+
const ProtocolInstancePtr _instance;
const ConnectorPtr _delegate;
const std::string _host;
- const int _port;
const std::string _resource;
};
diff --git a/cpp/src/Ice/WSEndpoint.cpp b/cpp/src/Ice/WSEndpoint.cpp
index b42f770bc05..48a9ede3c37 100644
--- a/cpp/src/Ice/WSEndpoint.cpp
+++ b/cpp/src/Ice/WSEndpoint.cpp
@@ -22,20 +22,36 @@ using namespace std;
using namespace Ice;
using namespace IceInternal;
+namespace
+{
+
+Ice::IPEndpointInfoPtr
+getIPEndpointInfo(const Ice::EndpointInfoPtr& info)
+{
+ for(Ice::EndpointInfoPtr p = info; p; p = p->underlying)
+ {
+ Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p);
+ if(ipInfo)
+ {
+ return ipInfo;
+ }
+ }
+ return ICE_NULLPTR;
+}
+
+}
+
#ifndef ICE_CPP11_MAPPING
IceUtil::Shared* IceInternal::upCast(WSEndpoint* p) { return p; }
#endif
IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, const string& res) :
- _instance(instance),
- _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del)),
- _resource(res)
+ _instance(instance), _delegate(del), _resource(res)
{
}
IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& inst, const EndpointIPtr& del, vector<string>& args) :
- _instance(inst),
- _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del))
+ _instance(inst), _delegate(del)
{
initWithOptions(args);
@@ -46,8 +62,7 @@ IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& inst, const Endpo
}
IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const EndpointIPtr& del, InputStream* s) :
- _instance(instance),
- _delegate(ICE_DYNAMIC_CAST(IPEndpointI, del))
+ _instance(instance), _delegate(del)
{
s->read(const_cast<string&>(_resource), false);
}
@@ -55,13 +70,12 @@ IceInternal::WSEndpoint::WSEndpoint(const ProtocolInstancePtr& instance, const E
Ice::EndpointInfoPtr
IceInternal::WSEndpoint::getInfo() const
{
-#ifdef ICE_CPP11_MAPPING
- assert(dynamic_pointer_cast<WSEndpointDelegate>(_delegate));
- return dynamic_pointer_cast<WSEndpointDelegate>(_delegate)->getWSInfo(_resource);
-#else
- assert(dynamic_cast<WSEndpointDelegate*>(_delegate.get()));
- return dynamic_cast<WSEndpointDelegate*>(_delegate.get())->getWSInfo(_resource);
-#endif
+ WSEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this());
+ info->underlying = _delegate->getInfo();
+ info->compress = info->underlying->compress;
+ info->timeout = info->underlying->timeout;
+ info->resource = _resource;
+ return info;
}
Ice::Short
@@ -77,12 +91,10 @@ IceInternal::WSEndpoint::protocol() const
}
void
-IceInternal::WSEndpoint::streamWrite(OutputStream* s) const
+IceInternal::WSEndpoint::streamWriteImpl(OutputStream* s) const
{
- s->startEncapsulation();
_delegate->streamWriteImpl(s);
s->write(_resource, false);
- s->endEncapsulation();
}
Int
@@ -169,8 +181,8 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType,
public:
CallbackI(const EndpointI_connectorsPtr& callback, const ProtocolInstancePtr& instance,
- const string& host, int port, const string& resource) :
- _callback(callback), _instance(instance), _host(host), _port(port), _resource(resource)
+ const string& host, const string& resource) :
+ _callback(callback), _instance(instance), _host(host), _resource(resource)
{
}
@@ -179,7 +191,7 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType,
vector<ConnectorPtr> connectors = c;
for(vector<ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p)
{
- *p = new WSConnector(_instance, *p, _host, _port, _resource);
+ *p = new WSConnector(_instance, *p, _host, _resource);
}
_callback->connectors(connectors);
}
@@ -194,11 +206,16 @@ IceInternal::WSEndpoint::connectors_async(Ice::EndpointSelectionType selType,
const EndpointI_connectorsPtr _callback;
const ProtocolInstancePtr _instance;
const string _host;
- const int _port;
const string _resource;
};
- _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, _delegate->host(),
- _delegate->port(), _resource));
+
+ ostringstream host;
+ IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo());
+ if(info)
+ {
+ host << info->host << ":" << info->port;
+ }
+ _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, host.str(), _resource));
}
AcceptorPtr
@@ -275,12 +292,6 @@ IceInternal::WSEndpoint::options() const
return s.str();
}
-EndpointIPtr
-IceInternal::WSEndpoint::delegate() const
-{
- return ICE_DYNAMIC_CAST(EndpointI, _delegate);
-}
-
bool
#ifdef ICE_CPP11_MAPPING
IceInternal::WSEndpoint::operator==(const Endpoint& r) const
@@ -322,7 +333,7 @@ IceInternal::WSEndpoint::operator<(const Ice::LocalObject& r) const
const WSEndpoint* p = dynamic_cast<const WSEndpoint*>(&r);
if(!p)
{
- const EndpointI* e = dynamic_cast<const WSEndpoint*>(&r);
+ const EndpointI* e = dynamic_cast<const EndpointI*>(&r);
if(!e)
{
return false;
@@ -354,7 +365,6 @@ IceInternal::WSEndpoint::operator<(const Ice::LocalObject& r) const
}
return false;
-
}
bool
@@ -382,8 +392,7 @@ IceInternal::WSEndpoint::checkOption(const string& option, const string& argumen
}
IceInternal::WSEndpointFactory::WSEndpointFactory(const ProtocolInstancePtr& instance, const EndpointFactoryPtr& del) :
- _instance(instance),
- _delegate(del)
+ _instance(instance), _delegate(del)
{
}
@@ -423,8 +432,7 @@ IceInternal::WSEndpointFactory::destroy()
}
EndpointFactoryPtr
-IceInternal::WSEndpointFactory::clone(const ProtocolInstancePtr&) const
+IceInternal::WSEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr& delegate) const
{
- assert(false); // We don't support cloning this transport.
- return 0;
+ return new WSEndpointFactory(instance, delegate);
}
diff --git a/cpp/src/Ice/WSEndpoint.h b/cpp/src/Ice/WSEndpoint.h
index 8216902d3f9..a247219409d 100644
--- a/cpp/src/Ice/WSEndpoint.h
+++ b/cpp/src/Ice/WSEndpoint.h
@@ -20,17 +20,6 @@
namespace IceInternal
{
-//
-// Delegate interface implemented by TcpEndpoint or IceSSL::Endpoint or any endpoint that WS can
-// delegate to.
-//
-class ICE_API WSEndpointDelegate : public virtual IceUtil::Shared
-{
-public:
-
- virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const = 0;
-};
-
class WSEndpoint : public EndpointI, public Ice::EnableSharedFromThis<WSEndpoint>
{
public:
@@ -39,10 +28,11 @@ public:
WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, std::vector<std::string>&);
WSEndpoint(const ProtocolInstancePtr&, const EndpointIPtr&, Ice::InputStream*);
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
+
virtual Ice::EndpointInfoPtr getInfo() const;
virtual Ice::Short type() const;
virtual const std::string& protocol() const;
- virtual void streamWrite(Ice::OutputStream*) const;
virtual Ice::Int timeout() const;
virtual EndpointIPtr timeout(Ice::Int) const;
@@ -62,7 +52,6 @@ public:
virtual ::Ice::Int hash() const;
virtual std::string options() const;
- EndpointIPtr delegate() const;
WSEndpointPtr endpoint(const EndpointIPtr&) const;
#ifdef ICE_CPP11_MAPPING
@@ -83,7 +72,7 @@ private:
// All members are const, because endpoints are immutable.
//
const ProtocolInstancePtr _instance;
- const IPEndpointIPtr _delegate;
+ const EndpointIPtr _delegate;
const std::string _resource;
};
@@ -100,7 +89,7 @@ public:
virtual EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const;
+ virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&, const EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/Ice/WSTransceiver.cpp b/cpp/src/Ice/WSTransceiver.cpp
index 5c1b44491ef..24d97b89920 100644
--- a/cpp/src/Ice/WSTransceiver.cpp
+++ b/cpp/src/Ice/WSTransceiver.cpp
@@ -184,18 +184,12 @@ IceInternal::WSTransceiver::getNativeInfo()
return _delegate->getNativeInfo();
}
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
AsyncInfo*
IceInternal::WSTransceiver::getAsyncInfo(SocketOperation status)
{
return _delegate->getNativeInfo()->getAsyncInfo(status);
}
-#elif defined(ICE_OS_WINRT)
-void
-IceInternal::WSTransceiver::setCompletedHandler(IceInternal::SocketOperationCompletedHandler^ handler)
-{
- _delegate->getNativeInfo()->setCompletedHandler(handler);
-}
#endif
SocketOperation
@@ -236,7 +230,7 @@ IceInternal::WSTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer)
//
ostringstream out;
out << "GET " << _resource << " HTTP/1.1\r\n"
- << "Host: " << _host << ":" << _port << "\r\n"
+ << "Host: " << _host << "\r\n"
<< "Upgrade: websocket\r\n"
<< "Connection: Upgrade\r\n"
<< "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n"
@@ -873,8 +867,10 @@ IceInternal::WSTransceiver::toDetailedString() const
Ice::ConnectionInfoPtr
IceInternal::WSTransceiver::getInfo() const
{
- assert(dynamic_cast<WSTransceiverDelegate*>(_delegate.get()));
- return dynamic_cast<WSTransceiverDelegate*>(_delegate.get())->getWSInfo(_parser->getHeaders());
+ WSConnectionInfoPtr info = ICE_MAKE_SHARED(WSConnectionInfo);
+ info->underlying = _delegate->getInfo();
+ info->headers = _parser->getHeaders();
+ return info;
}
void
@@ -890,11 +886,10 @@ IceInternal::WSTransceiver::setBufferSize(int rcvSize, int sndSize)
}
IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del,
- const string& host, int port, const string& resource) :
+ const string& host, const string& resource) :
_instance(instance),
_delegate(del),
_host(host),
- _port(port),
_resource(resource),
_incoming(false),
_state(StateInitializeDelegate),
@@ -924,7 +919,6 @@ IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, c
IceInternal::WSTransceiver::WSTransceiver(const ProtocolInstancePtr& instance, const TransceiverPtr& del) :
_instance(instance),
_delegate(del),
- _port(-1),
_incoming(true),
_state(StateInitializeDelegate),
_parser(new HttpParser),
diff --git a/cpp/src/Ice/WSTransceiver.h b/cpp/src/Ice/WSTransceiver.h
index db01cd309b8..7b6a7ffe5e6 100644
--- a/cpp/src/Ice/WSTransceiver.h
+++ b/cpp/src/Ice/WSTransceiver.h
@@ -24,26 +24,13 @@ namespace IceInternal
class ConnectorI;
class AcceptorI;
-//
-// Delegate interface implemented by TcpTransceiver or IceSSL::Transceiver or any transport that WS can
-// delegate to.
-//
-class ICE_API WSTransceiverDelegate : public virtual IceUtil::Shared
-{
-public:
-
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const = 0;
-};
-
class WSTransceiver : public Transceiver
{
public:
virtual NativeInfoPtr getNativeInfo();
-#if defined(ICE_USE_IOCP)
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual AsyncInfo* getAsyncInfo(SocketOperation);
-#elif defined(ICE_OS_WINRT)
- virtual void setCompletedHandler(SocketOperationCompletedHandler^);
#endif
virtual SocketOperation initialize(Buffer&, Buffer&);
@@ -70,7 +57,7 @@ public:
private:
- WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&, const std::string&, int, const std::string&);
+ WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&, const std::string&, const std::string&);
WSTransceiver(const ProtocolInstancePtr&, const TransceiverPtr&);
virtual ~WSTransceiver();
@@ -92,7 +79,6 @@ private:
const ProtocolInstancePtr _instance;
const TransceiverPtr _delegate;
const std::string _host;
- const int _port;
const std::string _resource;
const bool _incoming;
diff --git a/cpp/src/Ice/ios/RegisterPluginsInit.cpp b/cpp/src/Ice/ios/RegisterPluginsInit.cpp
deleted file mode 100644
index 712f4dcc765..00000000000
--- a/cpp/src/Ice/ios/RegisterPluginsInit.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/RegisterPluginsInit.h>
-#include <Ice/CommunicatorF.h>
-#include <Ice/Initialize.h>
-
-extern "C"
-{
-
-Ice::Plugin* createIceUDP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&);
-Ice::Plugin* createIceTCP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&);
-Ice::Plugin* createIceSSL(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&);
-Ice::Plugin* createIceIAP(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&);
-
-};
-
-IceInternal::RegisterPluginsInit::RegisterPluginsInit()
-{
- Ice::registerPluginFactory("IceUDP", createIceUDP, true);
- Ice::registerPluginFactory("IceTCP", createIceTCP, true);
- Ice::registerPluginFactory("IceSSL", createIceSSL, true);
- Ice::registerPluginFactory("IceIAP", createIceIAP, true);
-}
diff --git a/cpp/src/Ice/ios/StreamEndpointI.cpp b/cpp/src/Ice/ios/StreamEndpointI.cpp
index cdc59f6a41a..78e8dab2cff 100644
--- a/cpp/src/Ice/ios/StreamEndpointI.cpp
+++ b/cpp/src/Ice/ios/StreamEndpointI.cpp
@@ -23,10 +23,7 @@
#include <Ice/HashUtil.h>
#include <Ice/NetworkProxy.h>
-#include <IceSSL/EndpointInfo.h>
-
#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
#include <fstream>
@@ -44,25 +41,10 @@ createIceTCP(const CommunicatorPtr& com, const string&, const StringSeq&)
return new EndpointFactoryPlugin(com, new IceObjC::StreamEndpointFactory(tcpInstance));
}
-Plugin*
-createIceSSL(const CommunicatorPtr& com, const string&, const StringSeq&)
-{
- IceObjC::InstancePtr sslInstance = new IceObjC::Instance(com, SSLEndpointType, "ssl", true);
- return new EndpointFactoryPlugin(com, new IceObjC::StreamEndpointFactory(sslInstance));
-}
-
}
-namespace Ice
-{
-
-void
-registerIceSSL(bool)
+namespace
{
- // Nothing to do, we always register IceSSL
-}
-
-}
inline CFStringRef
toCFString(const string& s)
@@ -70,247 +52,15 @@ toCFString(const string& s)
return CFStringCreateWithCString(NULL, s.c_str(), kCFStringEncodingUTF8);
}
-inline int
-hexValue(char c)
-{
- if(c >= '0' && c <= '9')
- {
- return c - '0';
- }
- else if(c >= 'A' && c <= 'F')
- {
- return (c - 'A') + 10;
- }
- else if(c >= 'a' && c <= 'f')
- {
- return (c - 'a') + 10;
- }
- return -1;
-}
-
-inline CFDataRef
-parseKey(const string& keyStr)
-{
- int i = 0, j = 0;
- const char* m = keyStr.c_str();
- CFMutableDataRef data = CFDataCreateMutable(0, 160);
- unsigned char buf[160];
- while(i < (int)keyStr.size())
- {
- if(isspace(m[i]) || m[i] == ':')
- {
- ++i;
- continue;
- }
- else if(i == (int)keyStr.size() - 1)
- {
- CFRelease(data);
- return 0; // Not enough bytes.
- }
-
- int vh = hexValue(m[i++]);
- int vl = hexValue(m[i++]);
- if(vh < 0 || vl < 0)
- {
- CFRelease(data);
- return 0;
- }
- buf[j] = vh << 4;
- buf[j++] += vl;
-
- if(j == sizeof(buf))
- {
- CFDataAppendBytes(data, (UInt8*)buf, j);
- j = 0;
- }
- }
-
- if(j > 0)
- {
- CFDataAppendBytes(data, buf, j);
- }
-
- return data;
-}
-
-namespace
-{
-
-CFDataRef
-readCert(const string& defaultDir, const string& certFile)
-{
- string path;
- CFURLRef url = 0;
- CFBundleRef bundle = CFBundleGetMainBundle();
- if(bundle)
- {
- CFStringRef resourceName = toCFString(certFile);
- CFStringRef subDirName = toCFString(defaultDir);
- url = CFBundleCopyResourceURL(bundle, resourceName, 0, subDirName);
- CFRelease(resourceName);
- CFRelease(subDirName);
-
- UInt8 filePath[PATH_MAX];
- if(CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath)))
- {
- path = string(reinterpret_cast<char*>(filePath));
- }
- }
-
- if(!url || path.empty())
- {
- path = defaultDir.empty() ? certFile : defaultDir + "/" + certFile;
- }
-
- FILE *file = fopen(path.c_str(), "rb");
- if(!file)
- {
- ostringstream os;
- os << "IceSSL: unable to open file " << certFile << " (error = " << IceUtilInternal::lastErrorToString() << ")";
- throw InitializationException(__FILE__, __LINE__, os.str());
- }
-
- fseek(file, 0, SEEK_END);
- unsigned long size = ftell(file);
- fseek(file, 0, SEEK_SET);
- CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, size);
- CFDataSetLength(data, size);
- if(fread(CFDataGetMutableBytePtr(data), 1, size, file) != size)
- {
- CFRelease(data);
- ostringstream os;
- os << "IceSSL: error while reading file " << certFile;
- throw InitializationException(__FILE__, __LINE__, os.str());
- }
- fclose(file);
- return data;
-}
-
}
IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const string& protocol, bool secure) :
ProtocolInstance(com, type, protocol, secure),
_voip(com->getProperties()->getPropertyAsIntWithDefault("Ice.Voip", 0) > 0),
_communicator(com),
- _serverSettings(0),
- _clientSettings(0),
- _proxySettings(0),
- _certificateAuthorities(0),
- _trustOnlyKeyID(0)
+ _proxySettings(0)
{
const Ice::PropertiesPtr properties = com->getProperties();
- if(secure)
- {
- _clientSettings = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- string defaultDir = properties->getProperty("IceSSL.DefaultDir");
- string certAuthFile = properties->getProperty("IceSSL.CAs");
- if(certAuthFile.empty())
- {
- certAuthFile = properties->getProperty("IceSSL.CertAuthFile");
- }
- string certFile = properties->getProperty("IceSSL.CertFile");
-
- OSStatus err;
- if(!certAuthFile.empty())
- {
- CFDataRef cert = readCert(defaultDir, certAuthFile);
- if(!cert)
- {
- InitializationException ex(__FILE__, __LINE__);
- ex.reason = "IceSSL: unable to open file " + certAuthFile;
- throw ex;
- }
-
- SecCertificateRef result = SecCertificateCreateWithData(0, cert);
- CFRelease(cert);
- if(!result)
- {
- InitializationException ex(__FILE__, __LINE__);
- ex.reason = "IceSSL: certificate " + certAuthFile + " is not a valid DER-encoded certificate";
- throw ex;
- }
-
- SecCertificateRef certs[] = { result };
- _certificateAuthorities = CFArrayCreate(0, (const void**)certs, 1, &kCFTypeArrayCallBacks);
- CFRelease(result);
-
- // The root CA will be validated by the transceiver.
- // NOTE: on the iPhone, setting kCFStreamSSLAllowsAnyRoot = true isn't enough.
- //CFDictionarySetValue(_clientSettings, kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
- CFDictionarySetValue(_clientSettings, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
- }
- else if(properties->getPropertyAsInt("IceSSL.UsePlatformCAs") <= 0)
- {
- // Setup an empty list of Root CAs to not use the system root CAs.
- _certificateAuthorities = CFArrayCreate(0, 0, 0, 0);
- }
-
- if(!certFile.empty())
- {
- CFDataRef cert = readCert(defaultDir, certFile);
- if(!cert)
- {
- InitializationException ex(__FILE__, __LINE__);
- ex.reason = "IceSSL: unable to open file " + certFile;
- throw ex;
- }
-
- CFMutableDictionaryRef settings = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFStringRef password = toCFString(properties->getProperty("IceSSL.Password"));
- CFDictionarySetValue(settings, kSecImportExportPassphrase, password);
- CFRelease(password);
-
- CFArrayRef items = 0;
- err = SecPKCS12Import(cert, settings, &items);
- CFRelease(cert);
- CFRelease(settings);
- if(err != noErr)
- {
- ostringstream os;
- os << "IceSSL: unable to import certificate from file " << certFile << " (error = " << err << ")";
- throw InitializationException(__FILE__, __LINE__, os.str());
- }
-
- SecIdentityRef identity = 0;
- if(CFArrayGetCount(items) > 0)
- {
- identity = (SecIdentityRef)CFDictionaryGetValue((CFDictionaryRef)CFArrayGetValueAtIndex(items, 0),
- kSecImportItemIdentity);
- }
- if(identity == 0)
- {
- ostringstream os;
- os << "IceSSL: couldn't find identity in file " << certFile << " (error = " << err << ")";
- throw InitializationException(__FILE__, __LINE__, os.str());
- }
- CFRetain(identity);
- CFRelease(items);
-
- SecIdentityRef identities[] = { identity };
- items = CFArrayCreate(0, (const void**)identities, 1, &kCFTypeArrayCallBacks);
- CFDictionarySetValue(_clientSettings, kCFStreamSSLCertificates, items);
- CFRelease(identity);
- CFRelease(items);
- }
-
- string trustOnly = properties->getProperty("IceSSL.TrustOnly.Client");
- if(!trustOnly.empty())
- {
- _trustOnlyKeyID = parseKey(trustOnly);
- if(!_trustOnlyKeyID)
- {
- ostringstream os;
- os << "IceSSL: invalid `IceSSL.TrustOnly.Client' property value";
- throw InitializationException(__FILE__, __LINE__, os.str());
- }
- }
-
- _serverSettings = CFDictionaryCreateMutableCopy(0, 0, _clientSettings);
- CFDictionarySetValue(_serverSettings, kCFStreamSSLIsServer, kCFBooleanTrue);
- }
//
// Proxy settings
@@ -340,22 +90,6 @@ IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const s
IceObjC::Instance::~Instance()
{
- if(_trustOnlyKeyID)
- {
- CFRelease(_trustOnlyKeyID);
- }
- if(_serverSettings)
- {
- CFRelease(_serverSettings);
- }
- if(_clientSettings)
- {
- CFRelease(_clientSettings);
- }
- if(_certificateAuthorities)
- {
- CFRelease(_certificateAuthorities);
- }
if(_proxySettings)
{
CFRelease(_proxySettings);
@@ -387,40 +121,6 @@ IceObjC::Instance::setupStreams(CFReadStreamRef readStream,
throw Ice::SyscallException(__FILE__, __LINE__);
}
}
-
- if(secure())
- {
- CFDictionaryRef settings = server ? _serverSettings : _clientSettings;
-
- if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySocketSecurityLevel,
- kCFStreamSocketSecurityLevelNegotiatedSSL) ||
- !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySocketSecurityLevel,
- kCFStreamSocketSecurityLevelNegotiatedSSL))
- {
- throw Ice::SecurityException(__FILE__, __LINE__, "couldn't set security level");
- }
-
- if(!server && properties()->getPropertyAsIntWithDefault("IceSSL.CheckCertName", 1))
- {
- settings = CFDictionaryCreateMutableCopy(0, 0, settings);
-
- CFStringRef h = toCFString(host);
- CFDictionarySetValue((CFMutableDictionaryRef)settings, kCFStreamSSLPeerName, h);
- CFRelease(h);
- }
- else
- {
- CFRetain(settings);
- }
-
- if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, settings) ||
- !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, settings))
- {
- CFRelease(settings);
- throw Ice::SecurityException(__FILE__, __LINE__, "couldn't set security options");
- }
- CFRelease(settings);
- }
}
IceObjC::Instance*
@@ -459,38 +159,10 @@ IceObjC::StreamEndpointI::StreamEndpointI(const InstancePtr& instance, Ice::Inpu
EndpointInfoPtr
IceObjC::StreamEndpointI::getInfo() const
{
- IPEndpointInfoPtr info;
- if(_instance->secure())
- {
- info = ICE_MAKE_SHARED(InfoI<IceSSL::EndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()));
- }
- else
- {
- info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()));
- }
- fillEndpointInfo(info.get());
- return info;
-}
-
-EndpointInfoPtr
-IceObjC::StreamEndpointI::getWSInfo(const string& resource) const
-{
- IPEndpointInfoPtr info;
- if(_instance->secure())
- {
- IceSSL::WSSEndpointInfoPtr i;
- i = ICE_MAKE_SHARED(InfoI<IceSSL::WSSEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()));
- i->resource = resource;
- info = i;
- }
- else
- {
- Ice::WSEndpointInfoPtr i;
- i = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()));
- i->resource = resource;
- info = i;
- }
- fillEndpointInfo(info.get());
+ TCPEndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this());
+ IPEndpointI::fillEndpointInfo(info.get());
+ info->timeout = _timeout;
+ info->compress = _compress;
return info;
}
@@ -561,7 +233,7 @@ IceObjC::StreamEndpointI::transceiver() const
AcceptorPtr
IceObjC::StreamEndpointI::acceptor(const string&) const
{
- return new StreamAcceptor(ICE_DYNAMIC_CAST(StreamEndpointI, shared_from_this()), _instance, _host, _port);
+ return new StreamAcceptor(shared_from_this(), _instance, _host, _port);
}
IceObjC::StreamEndpointIPtr
@@ -698,14 +370,6 @@ IceObjC::StreamEndpointI::hashInit(Ice::Int& h) const
hashAdd(h, _compress);
}
-void
-IceObjC::StreamEndpointI::fillEndpointInfo(IPEndpointInfo* info) const
-{
- IPEndpointI::fillEndpointInfo(info);
- info->timeout = _timeout;
- info->compress = _compress;
-}
-
bool
IceObjC::StreamEndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
{
@@ -815,7 +479,7 @@ IceObjC::StreamEndpointFactory::destroy()
}
EndpointFactoryPtr
-IceObjC::StreamEndpointFactory::clone(const ProtocolInstancePtr& instance) const
+IceObjC::StreamEndpointFactory::clone(const ProtocolInstancePtr& instance, const EndpointFactoryPtr&) const
{
return new StreamEndpointFactory(_instance->clone(instance));
}
diff --git a/cpp/src/Ice/ios/StreamEndpointI.h b/cpp/src/Ice/ios/StreamEndpointI.h
index 51d3ab75d78..3dd90551199 100644
--- a/cpp/src/Ice/ios/StreamEndpointI.h
+++ b/cpp/src/Ice/ios/StreamEndpointI.h
@@ -37,16 +37,6 @@ public:
Instance(const Ice::CommunicatorPtr&, Ice::Short, const std::string&, bool);
virtual ~Instance();
- CFArrayRef certificateAuthorities() const
- {
- return _certificateAuthorities;
- }
-
- CFDataRef trustOnlyKeyID() const
- {
- return _trustOnlyKeyID;
- }
-
const std::string& proxyHost() const
{
return _proxyHost;
@@ -65,12 +55,7 @@ private:
const bool _voip;
const Ice::CommunicatorPtr _communicator;
- CFMutableDictionaryRef _serverSettings;
- CFMutableDictionaryRef _clientSettings;
CFMutableDictionaryRef _proxySettings;
- CFArrayRef _certificateAuthorities;
- CFDataRef _trustOnlyKeyID;
-
std::string _proxyHost;
int _proxyPort;
};
@@ -86,7 +71,7 @@ typedef ::std::shared_ptr<StreamEndpointI> StreamEndpointIPtr;
typedef IceUtil::Handle<StreamEndpointI> StreamEndpointIPtr;
#endif
-class StreamEndpointI : public IceInternal::IPEndpointI, public IceInternal::WSEndpointDelegate
+class StreamEndpointI : public IceInternal::IPEndpointI, public Ice::EnableSharedFromThis<StreamEndpointI>
{
public:
@@ -96,7 +81,6 @@ public:
StreamEndpointI(const InstancePtr&, Ice::InputStream*);
virtual Ice::EndpointInfoPtr getInfo() const;
- virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const;
virtual Ice::Int timeout() const;
virtual IceInternal::EndpointIPtr timeout(Ice::Int) const;
@@ -121,12 +105,12 @@ public:
StreamEndpointIPtr endpoint(const StreamAcceptorPtr&) const;
using IPEndpointI::connectionId;
+ using Ice::EnableSharedFromThis<StreamEndpointI>::shared_from_this;
protected:
virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual void hashInit(Ice::Int&) const;
- virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
virtual bool checkOption(const std::string&, const std::string&, const std::string&);
virtual IceInternal::ConnectorPtr createConnector(const IceInternal::Address&,
@@ -158,7 +142,8 @@ public:
virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const;
+ virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&,
+ const IceInternal::EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/Ice/ios/StreamTransceiver.cpp b/cpp/src/Ice/ios/StreamTransceiver.cpp
index bc76ffcd059..4fcbec4f400 100644
--- a/cpp/src/Ice/ios/StreamTransceiver.cpp
+++ b/cpp/src/Ice/ios/StreamTransceiver.cpp
@@ -19,7 +19,6 @@
#include <IceSSL/ConnectionInfo.h>
#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
using namespace std;
using namespace Ice;
@@ -292,13 +291,6 @@ IceObjC::StreamTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer)
setBlock(_fd, false);
setTcpBufSize(_fd, _instance);
-
- //
- // Limit the size of packets passed to SSLWrite/SSLRead to avoid
- // blocking and holding too much memory.
- //
- _maxSendPacketSize = std::max(512, getSendBufferSize(_fd));
- _maxRecvPacketSize = std::max(512, getRecvBufferSize(_fd));
}
assert(_state == StateConnected);
return SocketOperationNone;
@@ -345,7 +337,7 @@ IceObjC::StreamTransceiver::write(Buffer& buf)
}
// Its impossible for the packetSize to be more than an Int.
- size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxSendPacketSize);
+ size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i);
while(buf.i != buf.b.end())
{
if(!CFWriteStreamCanAcceptBytes(_writeStream))
@@ -353,12 +345,6 @@ IceObjC::StreamTransceiver::write(Buffer& buf)
return SocketOperationWrite;
}
- if(_checkCertificates)
- {
- _checkCertificates = false;
- checkCertificates();
- }
-
assert(_fd != INVALID_SOCKET);
CFIndex ret = CFWriteStreamWrite(_writeStream, reinterpret_cast<const UInt8*>(&*buf.i), packetSize);
@@ -401,7 +387,7 @@ IceObjC::StreamTransceiver::read(Buffer& buf)
}
// Its impossible for the packetSize to be more than an Int.
- size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxRecvPacketSize);
+ size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i);
while(buf.i != buf.b.end())
{
if(!CFReadStreamHasBytesAvailable(_readStream))
@@ -409,12 +395,6 @@ IceObjC::StreamTransceiver::read(Buffer& buf)
return SocketOperationRead;
}
- if(_checkCertificates)
- {
- _checkCertificates = false;
- checkCertificates();
- }
-
assert(_fd != INVALID_SOCKET);
CFIndex ret = CFReadStreamRead(_readStream, reinterpret_cast<UInt8*>(&*buf.i), packetSize);
@@ -475,39 +455,11 @@ IceObjC::StreamTransceiver::toDetailedString() const
Ice::ConnectionInfoPtr
IceObjC::StreamTransceiver::getInfo() const
{
- if(_instance->secure())
- {
- IceSSL::ConnectionInfoPtr info = ICE_MAKE_SHARED(IceSSL::ConnectionInfo);
- fillConnectionInfo(info);
- info->verified = _state == StateConnected;
- return info;
- }
- else
- {
- Ice::TCPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo);
- fillConnectionInfo(info);
- return info;
- }
-}
-
-Ice::ConnectionInfoPtr
-IceObjC::StreamTransceiver::getWSInfo(const Ice::HeaderDict& headers) const
-{
- if(_instance->secure())
- {
- IceSSL::WSSConnectionInfoPtr info = ICE_MAKE_SHARED(IceSSL::WSSConnectionInfo);
- fillConnectionInfo(info);
- info->verified = _state == StateConnected;
- info->headers = headers;
- return info;
- }
- else
- {
- Ice::WSConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::WSConnectionInfo);
- fillConnectionInfo(info);
- info->headers = headers;
- return info;
- }
+ Ice::TCPConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo);
+ fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
+ info->rcvSize = getRecvBufferSize(_fd);
+ info->sndSize = getSendBufferSize(_fd);
+ return info;
}
void
@@ -535,7 +487,6 @@ IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance,
_readStreamRegistered(false),
_writeStreamRegistered(false),
_opening(false),
- _checkCertificates(instance->secure()),
_error(false),
_state(StateNeedConnect)
{
@@ -562,7 +513,6 @@ IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance,
_readStreamRegistered(false),
_writeStreamRegistered(false),
_opening(false),
- _checkCertificates(false),
_error(false),
_state(StateNeedConnect),
_desc(fdToString(fd))
@@ -577,144 +527,6 @@ IceObjC::StreamTransceiver::~StreamTransceiver()
}
void
-IceObjC::StreamTransceiver::checkCertificates()
-{
- SecTrustRef trust = (SecTrustRef)CFWriteStreamCopyProperty(_writeStream, kCFStreamPropertySSLPeerTrust);
- if(!trust)
- {
- throw Ice::SecurityException(__FILE__, __LINE__, "unable to obtain trust object");
- }
-
- try
- {
- SecPolicyRef policy = 0;
- if(_host.empty() || _instance->properties()->getPropertyAsIntWithDefault("IceSSL.CheckCertName", 1) == 0)
- {
- policy = SecPolicyCreateBasicX509();
- }
- else
- {
- CFStringRef h = CFStringCreateWithCString(NULL, _host.c_str(), kCFStringEncodingUTF8);
- policy = SecPolicyCreateSSL(false, h);
- CFRelease(h);
- }
-
- OSStatus err = SecTrustSetPolicies(trust, policy);
- CFRelease(policy);
- if(err != noErr)
- {
- ostringstream os;
- os << "unable to set trust object policy (error = " << err << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
-
- //
- // If IceSSL.CertAuthFile is set, we use the certificate authorities from this file
- // instead of the ones from the keychain.
- //
- if((err = SecTrustSetAnchorCertificates(trust, _instance->certificateAuthorities())) != noErr)
- {
- ostringstream os;
- os << "couldn't set root CA certificates with trust object (error = " << err << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
-
- SecTrustResultType result = kSecTrustResultInvalid;
- if((err = SecTrustEvaluate(trust, &result)) != noErr)
- {
- ostringstream os;
- os << "unable to evaluate the peer certificate trust (error = " << err << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
-
- //
- // The kSecTrustResultUnspecified result indicates that the user didn't set any trust
- // settings for the root CA. This is expected if the root CA is provided by the user
- // with IceSSL.CertAuthFile or if the user didn't explicitly set any trust settings
- // for the certificate.
- //
- if(result != kSecTrustResultProceed && result != kSecTrustResultUnspecified)
- {
- ostringstream os;
- os << "certificate validation failed (result = " << result << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
-
- if(_instance->trustOnlyKeyID())
- {
- if(SecTrustGetCertificateCount(trust) < 0)
- {
- throw Ice::SecurityException(__FILE__, __LINE__, "unable to obtain peer certificate");
- }
-
- SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
-
- //
- // To check the subject key ID, we add the peer certificate to the keychain with SetItemAdd,
- // then we lookup for the cert using the kSecAttrSubjectKeyID. Then we remove the cert from
- // the keychain. NOTE: according to the Apple documentation, it should in theory be possible
- // to not add/remove the item to the keychain by specifying the kSecMatchItemList key (or
- // kSecUseItemList?) when calling SecItemCopyMatching. Unfortunately this doesn't appear to
- // work. Similarly, it should be possible to get back the attributes of the certificate
- // once it added by setting kSecReturnAttributes in the add query, again this doesn't seem
- // to work.
- //
- CFMutableDictionaryRef query;
- query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
- CFDictionarySetValue(query, kSecValueRef, cert);
- err = SecItemAdd(query, 0);
- if(err != noErr && err != errSecDuplicateItem)
- {
- CFRelease(query);
- ostringstream os;
- os << "unable to add peer certificate to keychain (error = " << err << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
- CFRelease(query);
-
- query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
- CFDictionarySetValue(query, kSecValueRef, cert);
- CFDictionarySetValue(query, kSecAttrSubjectKeyID, _instance->trustOnlyKeyID());
- err = SecItemCopyMatching(query, 0);
- OSStatus foundErr = err;
- CFRelease(query);
-
- query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
- CFDictionarySetValue(query, kSecValueRef, cert);
- err = SecItemDelete(query);
- if(err != noErr)
- {
- CFRelease(query);
- ostringstream os;
- os << "unable to remove peer certificate from keychain (error = " << err << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
- CFRelease(query);
-
- if(foundErr != noErr)
- {
- ostringstream os;
- os << "the certificate subject key ID doesn't match the `IceSSL.TrustOnly.Client' property ";
- os << "(error = " << foundErr << ")";
- throw Ice::SecurityException(__FILE__, __LINE__, os.str());
- }
- }
- CFRelease(trust);
- }
- catch(...)
- {
- if(trust)
- {
- CFRelease(trust);
- }
- throw;
- }
-}
-
-void
IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int line)
{
assert(err);
@@ -783,11 +595,3 @@ IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int lin
CFRelease(err);
throw ex;
}
-
-void
-IceObjC::StreamTransceiver::fillConnectionInfo(const Ice::IPConnectionInfoPtr& info) const
-{
- fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
- info->rcvSize = getRecvBufferSize(_fd);
- info->sndSize = getSendBufferSize(_fd);
-}
diff --git a/cpp/src/Ice/ios/StreamTransceiver.h b/cpp/src/Ice/ios/StreamTransceiver.h
index 97578f094d0..e38285451f8 100644
--- a/cpp/src/Ice/ios/StreamTransceiver.h
+++ b/cpp/src/Ice/ios/StreamTransceiver.h
@@ -29,8 +29,7 @@ namespace IceObjC
class Instance;
typedef IceUtil::Handle<Instance> InstancePtr;
-class StreamTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo,
- public IceInternal::WSTransceiverDelegate
+class StreamTransceiver : public IceInternal::Transceiver, public IceInternal::StreamNativeInfo
{
enum State
{
@@ -67,15 +66,12 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
virtual void checkSendSize(const IceInternal::Buffer&);
virtual void setBufferSize(int, int);
private:
- void checkCertificates();
void checkError(CFErrorRef, const char*, int);
- void fillConnectionInfo(const Ice::IPConnectionInfoPtr&) const;
const InstancePtr _instance;
const std::string _host;
@@ -85,16 +81,12 @@ private:
bool _readStreamRegistered;
bool _writeStreamRegistered;
bool _opening;
- bool _checkCertificates;
IceUtil::Mutex _mutex;
bool _error;
State _state;
std::string _desc;
-
- size_t _maxSendPacketSize;
- size_t _maxRecvPacketSize;
};
}
diff --git a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj
index c6fe7a4255b..68b41ffea80 100644
--- a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj
+++ b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
@@ -147,6 +147,7 @@
<ClCompile Include="..\..\..\IceUtil\Shared.cpp" />
<ClCompile Include="..\..\..\IceUtil\StringConverter.cpp" />
<ClCompile Include="..\..\..\IceUtil\StringUtil.cpp" />
+ <ClCompile Include="..\..\StreamSocket.cpp" />
<ClCompile Include="..\..\Thread.cpp" />
<ClCompile Include="..\..\..\IceUtil\ThreadException.cpp" />
<ClCompile Include="..\..\..\IceUtil\Time.cpp" />
@@ -232,10 +233,10 @@
<ClCompile Include="..\..\UdpConnector.cpp" />
<ClCompile Include="..\..\UdpEndpointI.cpp" />
<ClCompile Include="..\..\UdpTransceiver.cpp" />
- <ClCompile Include="..\..\uwp\TcpAcceptor.cpp" />
- <ClCompile Include="..\..\uwp\TcpConnector.cpp" />
- <ClCompile Include="..\..\uwp\TcpEndpointI.cpp" />
- <ClCompile Include="..\..\uwp\TcpTransceiver.cpp" />
+ <ClCompile Include="..\..\TcpAcceptor.cpp" />
+ <ClCompile Include="..\..\TcpConnector.cpp" />
+ <ClCompile Include="..\..\TcpEndpointI.cpp" />
+ <ClCompile Include="..\..\TcpTransceiver.cpp" />
<ClCompile Include="..\..\Value.cpp" />
<ClCompile Include="..\..\ValueFactoryManagerI.cpp" />
<ClCompile Include="..\..\WSAcceptor.cpp" />
@@ -3566,4 +3567,4 @@
<Import Project="$(IceBuilderCppTargets)" Condition="Exists('$(IceBuilderCppTargets)')" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters
index f6d97e7170b..4a33c8ded78 100644
--- a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters
+++ b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
@@ -319,18 +319,6 @@
<ClCompile Include="..\..\UdpTransceiver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\uwp\TcpAcceptor.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\TcpConnector.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\TcpEndpointI.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\TcpTransceiver.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\RegisterPluginsInit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -1102,6 +1090,19 @@
<ClCompile Include="..\..\Timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\TcpEndpointI.cpp" />
+ <ClCompile Include="..\..\TcpAcceptor.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\TcpConnector.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\TcpTransceiver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\StreamSocket.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<IceBuilder Include="..\..\..\..\..\slice\Ice\BuiltinSequences.ice">
@@ -1926,4 +1927,4 @@
<Filter>Header Files\x64\Release</Filter>
</ClInclude>
</ItemGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/cpp/src/Ice/uwp/RegisterPluginsInit.cpp b/cpp/src/Ice/uwp/RegisterPluginsInit.cpp
deleted file mode 100644
index c8294ee7033..00000000000
--- a/cpp/src/Ice/uwp/RegisterPluginsInit.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/Initialize.h>
-#include <Ice/RegisterPluginsInit.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-extern "C"
-{
-
-Plugin* createIceUDP(const CommunicatorPtr&, const string&, const StringSeq&);
-Plugin* createIceTCP(const CommunicatorPtr&, const string&, const StringSeq&);
-Plugin* createIceSSL(const CommunicatorPtr&, const string&, const StringSeq&);
-Plugin* createIceDiscovery(const CommunicatorPtr&, const string&, const StringSeq&);
-Plugin* createIceLocatorDiscovery(const CommunicatorPtr&, const string&, const StringSeq&);
-
-}
-
-namespace Ice
-{
-
-void
-registerIceSSL(bool)
-{
- // Nothing to do, IceSSL is always registered by the static initializer.
-}
-
-}
-
-RegisterPluginsInit::RegisterPluginsInit()
-{
- registerPluginFactory("IceUDP", createIceUDP, true);
- registerPluginFactory("IceTCP", createIceTCP, true);
- registerPluginFactory("IceSSL", createIceSSL, true);
- registerPluginFactory("IceDiscovery", createIceDiscovery, false);
- registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, false);
-}
diff --git a/cpp/src/Ice/uwp/TcpAcceptor.cpp b/cpp/src/Ice/uwp/TcpAcceptor.cpp
deleted file mode 100644
index f97aa28c434..00000000000
--- a/cpp/src/Ice/uwp/TcpAcceptor.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/uwp/TcpAcceptor.h>
-#include <Ice/uwp/TcpTransceiver.h>
-#include <Ice/uwp/TcpEndpointI.h>
-
-#include <Ice/ProtocolInstance.h>
-#include <Ice/LocalException.h>
-#include <Ice/LoggerUtil.h>
-#include <Ice/Exception.h>
-#include <Ice/Properties.h>
-#include <IceUtil/StringUtil.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-using namespace Platform;
-using namespace Windows::Foundation;
-using namespace Windows::Storage::Streams;
-using namespace Windows::Networking;
-using namespace Windows::Networking::Sockets;
-
-IceUtil::Shared* IceInternal::upCast(TcpAcceptor* p) { return p; }
-
-NativeInfoPtr
-IceInternal::TcpAcceptor::getNativeInfo()
-{
- return this;
-}
-
-void
-IceInternal::TcpAcceptor::setCompletedHandler(SocketOperationCompletedHandler^ handler)
-{
- _completedHandler = handler;
-}
-
-void
-IceInternal::TcpAcceptor::close()
-{
- IceUtil::Mutex::Lock lock(_mutex);
- if(_acceptPending)
- {
- assert(_accepted.empty());
- _completedHandler(SocketOperationRead);
- _acceptPending = false;
- }
- else if(!_accepted.empty())
- {
- for(deque<StreamSocket^>::const_iterator p = _accepted.begin(); p != _accepted.end(); ++p)
- {
- closeSocket(*p);
- }
- _accepted.clear();
- }
-
- if(_fd != INVALID_SOCKET)
- {
- closeSocketNoThrow(_fd);
- _fd = INVALID_SOCKET;
- }
-}
-
-EndpointIPtr
-IceInternal::TcpAcceptor::listen()
-{
- try
- {
- const_cast<Address&>(_addr) = doBind(_fd, _addr);
- }
- catch(...)
- {
- _fd = INVALID_SOCKET;
- throw;
- }
- _endpoint = _endpoint->endpoint(this);
- return _endpoint;
-}
-
-void
-IceInternal::TcpAcceptor::startAccept()
-{
- assert(_fd != INVALID_SOCKET);
-
- //
- // If there are already sockets waiting to be accepted, we just
- // notify the selector that the acceptor is ready for acceting the
- // new socket. Otherwise, we set the _acceptPending flag, when a
- // new socket connection event is received, the message handler
- // will notify the selector.
- //
- IceUtil::Mutex::Lock lock(_mutex);
- assert(!_acceptPending);
- if(!_accepted.empty())
- {
- _completedHandler(SocketOperationRead);
- }
- else
- {
- _acceptPending = true;
- }
-}
-
-void
-IceInternal::TcpAcceptor::finishAccept()
-{
- //
- // Nothing to do, we just check there's at least one accepted
- // socket or the acceptor was closed.
- //
- IceUtil::Mutex::Lock lock(_mutex);
- assert(!_acceptPending && (!_accepted.empty() || _fd == INVALID_SOCKET));
-}
-
-TransceiverPtr
-IceInternal::TcpAcceptor::accept()
-{
- if(_fd == INVALID_SOCKET) // Acceptor closed.
- {
- assert(_accepted.empty());
- throw SocketException(__FILE__, __LINE__);
- }
-
- StreamSocket^ fd;
- {
- IceUtil::Mutex::Lock lock(_mutex);
- assert(!_accepted.empty());
- fd = _accepted.front();
- _accepted.pop_front();
- }
-
- return new TcpTransceiver(_instance, fd, true);
-}
-
-string
-IceInternal::TcpAcceptor::protocol() const
-{
- return _instance->protocol();
-}
-
-string
-IceInternal::TcpAcceptor::toString() const
-{
- return addrToString(_addr);
-}
-
-string
-IceInternal::TcpAcceptor::toDetailedString() const
-{
- ostringstream os;
- os << "local address = " << toString();
- vector<string> intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true);
- if(!intfs.empty())
- {
- os << "\nlocal interfaces = ";
- os << IceUtilInternal::joinString(intfs, ", ");
- }
- return os.str();
-}
-
-int
-IceInternal::TcpAcceptor::effectivePort() const
-{
- return getPort(_addr);
-}
-
-IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint,
- const ProtocolInstancePtr& instance,
- const string& host,
- int port) :
- _endpoint(endpoint),
- _instance(instance),
- _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6())),
- _acceptPending(false)
-{
- _fd = ref new StreamSocketListener();
-
- safe_cast<StreamSocketListener^>(_fd)->ConnectionReceived +=
- ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>(
- [=](StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^ args)
- {
- queueAcceptedSocket(args->Socket);
- });
-}
-
-IceInternal::TcpAcceptor::~TcpAcceptor()
-{
- assert(_fd == INVALID_SOCKET);
-}
-
-void
-IceInternal::TcpAcceptor::queueAcceptedSocket(StreamSocket^ socket)
-{
- IceUtil::Mutex::Lock lock(_mutex);
- if(_fd == INVALID_SOCKET) // Acceptor was closed.
- {
- closeSocket(socket);
- return;
- }
- _accepted.push_back(socket);
-
- //
- // If the acceptor is waiting for a socket to be accepted, notify
- // the selector that the acceptor is ready for "read". This will
- // in turn caused finishAccept() and accept() to be called by the
- // thread pool. If the acceptor isn't ready to accept the socket,
- // it is just queued, when startAccept is called it will be dequed.
- //
- if(_acceptPending)
- {
- _completedHandler(SocketOperationRead);
- _acceptPending = false;
- }
-}
diff --git a/cpp/src/Ice/uwp/TcpAcceptor.h b/cpp/src/Ice/uwp/TcpAcceptor.h
deleted file mode 100644
index bfef0da2712..00000000000
--- a/cpp/src/Ice/uwp/TcpAcceptor.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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.
-//
-// **********************************************************************
-
-#ifndef ICE_UWP_TCP_ACCEPTOR_H
-#define ICE_UWP_TCP_ACCEPTOR_H
-
-#include <Ice/TransceiverF.h>
-#include <Ice/ProtocolInstanceF.h>
-#include <Ice/Acceptor.h>
-#include <Ice/Network.h>
-#include <Ice/uwp/TransceiverF.h>
-
-#include <IceUtil/Mutex.h>
-
-#include <deque>
-
-namespace IceInternal
-{
-
-class TcpAcceptor : public Acceptor, public NativeInfo
-{
-public:
-
- virtual NativeInfoPtr getNativeInfo();
- virtual void setCompletedHandler(SocketOperationCompletedHandler^);
-
- virtual void close();
- virtual EndpointIPtr listen();
-
- virtual void startAccept();
- virtual void finishAccept();
-
- virtual TransceiverPtr accept();
- virtual std::string protocol() const;
- virtual std::string toString() const;
- virtual std::string toDetailedString() const;
-
- int effectivePort() const;
-
-private:
-
- TcpAcceptor(const TcpEndpointIPtr&, const ProtocolInstancePtr&, const std::string&, int);
- virtual ~TcpAcceptor();
- friend class TcpEndpointI;
-
- virtual void queueAcceptedSocket(Windows::Networking::Sockets::StreamSocket^);
-
- TcpEndpointIPtr _endpoint;
- const ProtocolInstancePtr _instance;
- const Address _addr;
-
- IceUtil::Mutex _mutex;
- bool _acceptPending;
- SocketOperationCompletedHandler^ _completedHandler;
- std::deque<Windows::Networking::Sockets::StreamSocket^> _accepted;
-};
-
-}
-#endif
diff --git a/cpp/src/Ice/uwp/TcpConnector.cpp b/cpp/src/Ice/uwp/TcpConnector.cpp
deleted file mode 100644
index cba0245497e..00000000000
--- a/cpp/src/Ice/uwp/TcpConnector.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/uwp/TcpConnector.h>
-#include <Ice/uwp/TcpTransceiver.h>
-#include <Ice/uwp/TcpEndpointI.h>
-
-#include <Ice/ProtocolInstance.h>
-#include <Ice/LoggerUtil.h>
-#include <Ice/Network.h>
-#include <Ice/Exception.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-TransceiverPtr
-IceInternal::TcpConnector::connect()
-{
- TransceiverPtr transceiver = new TcpTransceiver(_instance, createSocket(false, _addr), false);
- dynamic_cast<TcpTransceiver*>(transceiver.get())->connect(_addr);
- return transceiver;
-}
-
-Short
-IceInternal::TcpConnector::type() const
-{
- return _instance->type();
-}
-
-string
-IceInternal::TcpConnector::toString() const
-{
- return addrToString(_addr);
-}
-
-bool
-IceInternal::TcpConnector::operator==(const Connector& r) const
-{
- const TcpConnector* p = dynamic_cast<const TcpConnector*>(&r);
- if(!p)
- {
- return false;
- }
-
- if(type() != p->type())
- {
- return false;
- }
-
- if(compareAddress(_addr, p->_addr) != 0)
- {
- return false;
- }
-
- if(_timeout != p->_timeout)
- {
- return false;
- }
-
- if(_connectionId != p->_connectionId)
- {
- return false;
- }
-
- return true;
-}
-
-bool
-IceInternal::TcpConnector::operator!=(const Connector& r) const
-{
- return !operator==(r);
-}
-
-bool
-IceInternal::TcpConnector::operator<(const Connector& r) const
-{
- const TcpConnector* p = dynamic_cast<const TcpConnector*>(&r);
- if(!p)
- {
- return type() < r.type();
- }
-
- if(type() < p->type())
- {
- return true;
- }
- else if(p->type() < type())
- {
- return false;
- }
-
- if(_timeout < p->_timeout)
- {
- return true;
- }
- else if(p->_timeout < _timeout)
- {
- return false;
- }
-
- if(_connectionId < p->_connectionId)
- {
- return true;
- }
- else if(p->_connectionId < _connectionId)
- {
- return false;
- }
- return compareAddress(_addr, p->_addr) < 0;
-}
-
-IceInternal::TcpConnector::TcpConnector(const ProtocolInstancePtr& instance, const Address& addr,
- Ice::Int timeout, const string& connectionId) :
- _instance(instance),
- _addr(addr),
- _timeout(timeout),
- _connectionId(connectionId)
-{
-}
diff --git a/cpp/src/Ice/uwp/TcpConnector.h b/cpp/src/Ice/uwp/TcpConnector.h
deleted file mode 100644
index 96f005de7d0..00000000000
--- a/cpp/src/Ice/uwp/TcpConnector.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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.
-//
-// **********************************************************************
-
-#ifndef ICE_UWP_TCP_CONNECTOR_H
-#define ICE_UWP_TCP_CONNECTOR_H
-
-#include <Ice/TransceiverF.h>
-#include <Ice/ProtocolInstanceF.h>
-#include <Ice/Connector.h>
-#include <Ice/Network.h>
-
-namespace IceInternal
-{
-
-class TcpConnector : public Connector
-{
-public:
-
- virtual TransceiverPtr connect();
-
- virtual Ice::Short type() const;
- virtual std::string toString() const;
-
- virtual bool operator==(const Connector&) const;
- virtual bool operator!=(const Connector&) const;
- virtual bool operator<(const Connector&) const;
-
-private:
-
- TcpConnector(const ProtocolInstancePtr&, const Address&, Ice::Int, const std::string&);
- friend class TcpEndpointI;
-
- const ProtocolInstancePtr _instance;
- const Address _addr;
- const Ice::Int _timeout;
- const std::string _connectionId;
-};
-
-}
-
-#endif
diff --git a/cpp/src/Ice/uwp/TcpEndpointI.cpp b/cpp/src/Ice/uwp/TcpEndpointI.cpp
deleted file mode 100644
index 020d7283b6f..00000000000
--- a/cpp/src/Ice/uwp/TcpEndpointI.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/uwp/TcpEndpointI.h>
-#include <Ice/uwp/TcpAcceptor.h>
-#include <Ice/uwp/TcpConnector.h>
-#include <Ice/uwp/TcpTransceiver.h>
-
-#include <Ice/Network.h>
-#include <Ice/OutputStream.h>
-#include <Ice/InputStream.h>
-#include <Ice/LocalException.h>
-#include <Ice/ProtocolInstance.h>
-#include <Ice/DefaultsAndOverrides.h>
-#include <Ice/HashUtil.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-extern "C"
-{
-
-Plugin*
-createIceTCP(const CommunicatorPtr& com, const string&, const StringSeq&)
-{
- ProtocolInstancePtr instance = new ProtocolInstance(com, TCPEndpointType, "tcp", false);
- return new EndpointFactoryPlugin(com, new TcpEndpointFactory(instance));
-}
-
-}
-
-#ifndef ICE_CPP11_MAPPING
-IceUtil::Shared* IceInternal::upCast(TcpEndpointI* p) { return p; }
-#endif
-
-IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, const string& ho, Int po, Int ti,
- const string& conId, bool co) :
- IPEndpointI(instance, ho, po, Address(), conId),
- _timeout(ti),
- _compress(co)
-{
-}
-
-IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance) :
- IPEndpointI(instance),
- _timeout(-2),
- _compress(false)
-{
-}
-
-IceInternal::TcpEndpointI::TcpEndpointI(const ProtocolInstancePtr& instance, InputStream* s) :
- IPEndpointI(instance, s),
- _timeout(-1),
- _compress(false)
-{
- s->read(const_cast<Int&>(_timeout));
- s->read(const_cast<bool&>(_compress));
-}
-
-EndpointInfoPtr
-IceInternal::TcpEndpointI::getInfo() const
-{
- IPEndpointInfoPtr info;
- info = ICE_MAKE_SHARED(InfoI<Ice::TCPEndpointInfo>, shared_from_this());
- fillEndpointInfo(info.get());
- return info;
-}
-
-EndpointInfoPtr
-IceInternal::TcpEndpointI::getWSInfo(const string& resource) const
-{
- IPEndpointInfoPtr info;
- Ice::WSEndpointInfoPtr i = ICE_MAKE_SHARED(InfoI<Ice::WSEndpointInfo>, shared_from_this());
- i->resource = resource;
- info = i;
- fillEndpointInfo(info.get());
- return info;
-}
-
-Int
-IceInternal::TcpEndpointI::timeout() const
-{
- return _timeout;
-}
-
-EndpointIPtr
-IceInternal::TcpEndpointI::timeout(Int timeout) const
-{
- if(timeout == _timeout)
- {
- return shared_from_this();
- }
- else
- {
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, timeout, _connectionId, _compress);
- }
-}
-
-EndpointIPtr
-IceInternal::TcpEndpointI::connectionId(const string& connectionId) const
-{
- if(connectionId == _connectionId)
- {
- return shared_from_this();
- }
- else
- {
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _timeout, connectionId, _compress);
- }
-}
-
-bool
-IceInternal::TcpEndpointI::compress() const
-{
- return _compress;
-}
-
-EndpointIPtr
-IceInternal::TcpEndpointI::compress(bool compress) const
-{
- if(compress == _compress)
- {
- return shared_from_this();
- }
- else
- {
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, _port, _timeout, _connectionId, compress);
- }
-}
-
-bool
-IceInternal::TcpEndpointI::datagram() const
-{
- return false;
-}
-
-bool
-IceInternal::TcpEndpointI::secure() const
-{
- return false;
-}
-
-TransceiverPtr
-IceInternal::TcpEndpointI::transceiver() const
-{
- return 0;
-}
-
-AcceptorPtr
-IceInternal::TcpEndpointI::acceptor(const string&) const
-{
- return new TcpAcceptor(ICE_DYNAMIC_CAST(TcpEndpointI, shared_from_this()), _instance, _host, _port);
-}
-
-TcpEndpointIPtr
-IceInternal::TcpEndpointI::endpoint(const TcpAcceptorPtr& acceptor) const
-{
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, _host, acceptor->effectivePort(), _timeout, _connectionId, _compress);
-}
-
-string
-IceInternal::TcpEndpointI::options() const
-{
- //
- // WARNING: Certain features, such as proxy validation in Glacier2,
- // depend on the format of proxy strings. Changes to toString() and
- // methods called to generate parts of the reference string could break
- // these features. Please review for all features that depend on the
- // format of proxyToString() before changing this and related code.
- //
- ostringstream s;
-
- s << IPEndpointI::options();
-
- if(_timeout == -1)
- {
- s << " -t infinite";
- }
- else
- {
- s << " -t " << _timeout;
- }
-
- if(_compress)
- {
- s << " -z";
- }
-
- return s.str();
-}
-
-bool
-#ifdef ICE_CPP11_MAPPING
-IceInternal::TcpEndpointI::operator==(const Endpoint& r) const
-#else
-IceInternal::TcpEndpointI::operator==(const LocalObject& r) const
-#endif
-{
- if(!IPEndpointI::operator==(r))
- {
- return false;
- }
-
- const TcpEndpointI* p = dynamic_cast<const TcpEndpointI*>(&r);
- if(!p)
- {
- return false;
- }
-
- if(this == p)
- {
- return true;
- }
-
- if(_timeout != p->_timeout)
- {
- return false;
- }
-
- if(_compress != p->_compress)
- {
- return false;
- }
-
- return true;
-}
-
-bool
-#ifdef ICE_CPP11_MAPPING
-IceInternal::TcpEndpointI::operator<(const Endpoint& r) const
-#else
-IceInternal::TcpEndpointI::operator<(const LocalObject& r) const
-#endif
-{
- const TcpEndpointI* p = dynamic_cast<const TcpEndpointI*>(&r);
- if(!p)
- {
- const EndpointI* e = dynamic_cast<const EndpointI*>(&r);
- if(!e)
- {
- return false;
- }
- return type() < e->type();
- }
-
- if(this == p)
- {
- return false;
- }
-
- if(_timeout < p->_timeout)
- {
- return true;
- }
- else if(p->_timeout < _timeout)
- {
- return false;
- }
-
- if(!_compress && p->_compress)
- {
- return true;
- }
- else if(p->_compress < _compress)
- {
- return false;
- }
-
- return IPEndpointI::operator<(r);
-}
-
-void
-IceInternal::TcpEndpointI::streamWriteImpl(OutputStream* s) const
-{
- IPEndpointI::streamWriteImpl(s);
- s->write(_timeout);
- s->write(_compress);
-}
-
-void
-IceInternal::TcpEndpointI::hashInit(Ice::Int& h) const
-{
- IPEndpointI::hashInit(h);
- hashAdd(h, _timeout);
- hashAdd(h, _compress);
-}
-
-void
-IceInternal::TcpEndpointI::fillEndpointInfo(IPEndpointInfo* info) const
-{
- IPEndpointI::fillEndpointInfo(info);
- info->timeout = _timeout;
- info->compress = _compress;
-}
-
-void
-IceInternal::TcpEndpointI::initWithOptions(vector<string>& args, bool oaEndpoint)
-{
- IPEndpointI::initWithOptions(args, oaEndpoint);
-
- if(_timeout == -2)
- {
- const_cast<Int&>(_timeout) = _instance->defaultTimeout();
- }
-}
-
-bool
-IceInternal::TcpEndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
-{
- if(IPEndpointI::checkOption(option, argument, endpoint))
- {
- return true;
- }
-
- switch(option[1])
- {
- case 't':
- {
- if(argument.empty())
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "no argument provided for -t option in endpoint " + endpoint;
- throw ex;
- }
-
- if(argument == "infinite")
- {
- const_cast<Int&>(_timeout) = -1;
- }
- else
- {
- istringstream t(argument);
- if(!(t >> const_cast<Int&>(_timeout)) || !t.eof() || _timeout < 1)
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint;
- throw ex;
- }
- }
- return true;
- }
-
- case 'z':
- {
- if(!argument.empty())
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint;
- throw ex;
- }
- const_cast<bool&>(_compress) = true;
- return true;
- }
-
- default:
- {
- return false;
- }
- }
-}
-
-ConnectorPtr
-IceInternal::TcpEndpointI::createConnector(const Address& address, const NetworkProxyPtr& proxy) const
-{
- // TODO: Add support for network proxies?
- return new TcpConnector(_instance, address, _timeout, _connectionId);
-}
-
-IPEndpointIPtr
-IceInternal::TcpEndpointI::createEndpoint(const string& host, int port, const string& connectionId) const
-{
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, host, port, _timeout, connectionId, _compress);
-}
-
-IceInternal::TcpEndpointFactory::TcpEndpointFactory(const ProtocolInstancePtr& instance) : _instance(instance)
-{
-}
-
-IceInternal::TcpEndpointFactory::~TcpEndpointFactory()
-{
-}
-
-Short
-IceInternal::TcpEndpointFactory::type() const
-{
- return _instance->type();
-}
-
-string
-IceInternal::TcpEndpointFactory::protocol() const
-{
- return _instance->protocol();
-}
-
-EndpointIPtr
-IceInternal::TcpEndpointFactory::create(vector<string>& args, bool oaEndpoint) const
-{
- IPEndpointIPtr endpt = ICE_MAKE_SHARED(TcpEndpointI, _instance);
- endpt->initWithOptions(args, oaEndpoint);
- return endpt;
-}
-
-EndpointIPtr
-IceInternal::TcpEndpointFactory::read(InputStream* s) const
-{
- return ICE_MAKE_SHARED(TcpEndpointI, _instance, s);
-}
-
-void
-IceInternal::TcpEndpointFactory::destroy()
-{
- _instance = 0;
-}
-
-EndpointFactoryPtr
-IceInternal::TcpEndpointFactory::clone(const ProtocolInstancePtr& instance) const
-{
- return new TcpEndpointFactory(instance);
-}
diff --git a/cpp/src/Ice/uwp/TcpEndpointI.h b/cpp/src/Ice/uwp/TcpEndpointI.h
deleted file mode 100644
index 19a40eac4e5..00000000000
--- a/cpp/src/Ice/uwp/TcpEndpointI.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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.
-//
-// **********************************************************************
-
-#ifndef ICE_UWP_TCP_ENDPOINT_I_H
-#define ICE_UWP_TCP_ENDPOINT_I_H
-
-#include <IceUtil/Config.h>
-#include <Ice/IPEndpointI.h>
-#include <Ice/EndpointFactory.h>
-#include <Ice/WSEndpoint.h>
-#include <Ice/Network.h> // for IceIternal::Address
-#include <Ice/uwp/TransceiverF.h>
-
-namespace IceInternal
-{
-
-class TcpEndpointI : public IPEndpointI, public WSEndpointDelegate
-{
-public:
-
- TcpEndpointI(const ProtocolInstancePtr&, const std::string&, Ice::Int, Ice::Int, const std::string&, bool);
- TcpEndpointI(const ProtocolInstancePtr&);
- TcpEndpointI(const ProtocolInstancePtr&, Ice::InputStream*);
-
- virtual Ice::EndpointInfoPtr getInfo() const;
- virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const;
-
- virtual Ice::Int timeout() const;
- virtual EndpointIPtr timeout(Ice::Int) const;
- virtual EndpointIPtr connectionId(const ::std::string&) const;
- virtual bool compress() const;
- virtual EndpointIPtr compress(bool) const;
- virtual bool datagram() const;
- virtual bool secure() const;
-
- virtual TransceiverPtr transceiver() const;
- virtual AcceptorPtr acceptor(const std::string&) const;
- virtual std::string options() const;
-
-#ifdef ICE_CPP11_MAPPING
- virtual bool operator==(const Ice::Endpoint&) const;
- virtual bool operator<(const Ice::Endpoint&) const;
-#else
- virtual bool operator==(const Ice::LocalObject&) const;
- virtual bool operator<(const Ice::LocalObject&) const;
-#endif
-
- TcpEndpointIPtr endpoint(const TcpAcceptorPtr&) const;
-
- using IPEndpointI::connectionId;
-
-protected:
-
- virtual void streamWriteImpl(Ice::OutputStream*) const;
- virtual void hashInit(Ice::Int&) const;
- virtual void initWithOptions(std::vector<std::string>&, bool);
- virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
- virtual bool checkOption(const std::string&, const std::string&, const std::string&);
-
- virtual ConnectorPtr createConnector(const Address&, const NetworkProxyPtr&) const;
- virtual IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const;
-
-private:
-
- //
- // All members are const, because endpoints are immutable.
- //
- const Ice::Int _timeout;
- const bool _compress;
-};
-
-class TcpEndpointFactory : public EndpointFactory
-{
-public:
-
- TcpEndpointFactory(const ProtocolInstancePtr&);
- virtual ~TcpEndpointFactory();
-
- virtual Ice::Short type() const;
- virtual std::string protocol() const;
- virtual EndpointIPtr create(std::vector<std::string>&, bool) const;
- virtual EndpointIPtr read(Ice::InputStream*) const;
- virtual void destroy();
-
- virtual EndpointFactoryPtr clone(const ProtocolInstancePtr&) const;
-
-private:
-
- ProtocolInstancePtr _instance;
-};
-
-}
-
-#endif
diff --git a/cpp/src/Ice/uwp/TcpTransceiver.cpp b/cpp/src/Ice/uwp/TcpTransceiver.cpp
deleted file mode 100644
index de400168fa3..00000000000
--- a/cpp/src/Ice/uwp/TcpTransceiver.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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/uwp/TcpTransceiver.h>
-#include <Ice/Connection.h>
-#include <Ice/ProtocolInstance.h>
-#include <Ice/LoggerUtil.h>
-#include <Ice/Buffer.h>
-#include <Ice/LocalException.h>
-#include <Ice/Properties.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-using namespace Platform;
-using namespace Windows::Foundation;
-using namespace Windows::Storage::Streams;
-using namespace Windows::Networking;
-using namespace Windows::Networking::Sockets;
-
-namespace
-{
-
-AsyncOperationCompletedHandler<unsigned int>^
-createAsyncOperationCompletedHandler(SocketOperationCompletedHandler^ cb, SocketOperation op, AsyncInfo& info)
-{
- return ref new AsyncOperationCompletedHandler<unsigned int>(
- [=,&info] (IAsyncOperation<unsigned int>^ operation, Windows::Foundation::AsyncStatus status)
- {
- if(status != Windows::Foundation::AsyncStatus::Completed)
- {
- info.count = SOCKET_ERROR;
- info.error = operation->ErrorCode.Value;
- }
- else
- {
- info.count = static_cast<int>(operation->GetResults());
- }
- cb(op);
- });
-}
-
-}
-
-NativeInfoPtr
-IceInternal::TcpTransceiver::getNativeInfo()
-{
- return this;
-}
-
-void
-IceInternal::TcpTransceiver::setCompletedHandler(SocketOperationCompletedHandler^ handler)
-{
- _completedHandler = handler;
- _readOperationCompletedHandler = createAsyncOperationCompletedHandler(handler, SocketOperationRead, _read);
- _writeOperationCompletedHandler = createAsyncOperationCompletedHandler(handler, SocketOperationWrite, _write);
-}
-
-SocketOperation
-IceInternal::TcpTransceiver::initialize(Buffer&, Buffer&)
-{
- if(_state == StateNeedConnect)
- {
- _state = StateConnectPending;
- return SocketOperationConnect;
- }
- else if(_state <= StateConnectPending)
- {
- if(_write.count == SOCKET_ERROR)
- {
- checkConnectErrorCode(__FILE__, __LINE__, _write.error, _connectAddr.host);
- }
- _state = StateConnected;
- _desc = fdToString(_fd);
- }
- assert(_state == StateConnected);
- return SocketOperationNone;
-}
-
-SocketOperation
-#ifdef ICE_CPP11_MAPPING
-IceInternal::TcpTransceiver::closing(bool initiator, exception_ptr)
-#else
-IceInternal::TcpTransceiver::closing(bool initiator, const Ice::LocalException&)
-#endif
-{
- // If we are initiating the connection closure, wait for the peer
- // to close the TCP/IP connection. Otherwise, close immediately.
- return initiator ? SocketOperationRead : SocketOperationNone;
-}
-
-void
-IceInternal::TcpTransceiver::close()
-{
- assert(_fd != INVALID_SOCKET);
-
- _completedHandler = nullptr;
- _readOperationCompletedHandler = nullptr;
- _writeOperationCompletedHandler = nullptr;
-
- try
- {
- closeSocket(_fd);
- _fd = INVALID_SOCKET;
- }
- catch(const SocketException&)
- {
- _fd = INVALID_SOCKET;
- throw;
- }
-}
-
-SocketOperation
-IceInternal::TcpTransceiver::write(Buffer& buf)
-{
- return buf.i == buf.b.end() ? SocketOperationNone : SocketOperationWrite;
-}
-
-SocketOperation
-IceInternal::TcpTransceiver::read(Buffer& buf)
-{
- return buf.i == buf.b.end() ? SocketOperationNone : SocketOperationRead;
-}
-
-bool
-IceInternal::TcpTransceiver::startWrite(Buffer& buf)
-{
- if(_state < StateConnected)
- {
- try
- {
- IAsyncAction^ action = safe_cast<StreamSocket^>(_fd)->ConnectAsync(
- _connectAddr.host,
- _connectAddr.port,
- SocketProtectionLevel::PlainSocket);
-
- if(!checkIfErrorOrCompleted(SocketOperationConnect, action))
- {
- SocketOperationCompletedHandler^ completed = _completedHandler;
- action->Completed = ref new AsyncActionCompletedHandler(
- [=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status)
- {
- if(status != Windows::Foundation::AsyncStatus::Completed)
- {
- _write.count = SOCKET_ERROR;
- _write.error = info->ErrorCode.Value;
- }
- else
- {
- _write.count = 0;
- }
- completed(SocketOperationConnect);
- });
- }
- }
- catch(Platform::Exception^ ex)
- {
- checkConnectErrorCode(__FILE__, __LINE__, ex->HResult, _connectAddr.host);
- }
- return false;
- }
-
- assert(!buf.b.empty());
- assert(buf.i != buf.b.end());
-
- int packetSize = static_cast<int>(buf.b.end() - buf.i);
- if(_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize)
- {
- packetSize = _maxSendPacketSize;
- }
- assert(packetSize > 0);
- _writer->WriteBytes(ref new Array<unsigned char>(&*buf.i, packetSize));
- try
- {
- DataWriterStoreOperation^ operation = _writer->StoreAsync();
- if(checkIfErrorOrCompleted(SocketOperationWrite, operation))
- {
- _write.count = operation->GetResults();
- }
- else
- {
- operation->Completed = _writeOperationCompletedHandler;
- }
- }
- catch(Platform::Exception^ ex)
- {
- checkErrorCode(__FILE__, __LINE__, ex->HResult);
- }
- return packetSize == static_cast<int>(buf.b.end() - buf.i);
-}
-
-void
-IceInternal::TcpTransceiver::finishWrite(Buffer& buf)
-{
- if(_state < StateConnected)
- {
- if(_write.count == SOCKET_ERROR)
- {
- checkConnectErrorCode(__FILE__, __LINE__, _write.error, _connectAddr.host);
- }
- _verified = true;
- return;
- }
-
- if(_write.count == SOCKET_ERROR)
- {
- checkErrorCode(__FILE__, __LINE__, _write.error);
- }
-
- buf.i += _write.count;
-}
-
-void
-IceInternal::TcpTransceiver::startRead(Buffer& buf)
-{
- int packetSize = static_cast<int>(buf.b.end() - buf.i);
- if(_maxReceivePacketSize > 0 && packetSize > _maxReceivePacketSize)
- {
- packetSize = _maxReceivePacketSize;
- }
- assert(!buf.b.empty() && buf.i != buf.b.end());
-
- try
- {
- DataReaderLoadOperation^ operation = _reader->LoadAsync(packetSize);
- if(checkIfErrorOrCompleted(SocketOperationRead, operation))
- {
- _read.count = operation->GetResults();
- }
- else
- {
- operation->Completed = _readOperationCompletedHandler;
- }
- }
- catch(Platform::Exception^ ex)
- {
- checkErrorCode(__FILE__, __LINE__, ex->HResult);
- }
-}
-
-void
-IceInternal::TcpTransceiver::finishRead(Buffer& buf)
-{
- if(_read.count == SOCKET_ERROR)
- {
- checkErrorCode(__FILE__, __LINE__, _read.error);
- }
- else if(_read.count == 0)
- {
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = 0;
- throw ex;
- }
-
- try
- {
- auto data = ref new Platform::Array<unsigned char>(_read.count);
- _reader->ReadBytes(data);
- memcpy(&*buf.i, data->Data, _read.count);
- }
- catch(Platform::Exception^ ex)
- {
- checkErrorCode(__FILE__, __LINE__, ex->HResult);
- }
-
- buf.i += _read.count;
-}
-
-string
-IceInternal::TcpTransceiver::protocol() const
-{
- return _instance->protocol();
-}
-
-string
-IceInternal::TcpTransceiver::toString() const
-{
- return _desc;
-}
-
-string
-IceInternal::TcpTransceiver::toDetailedString() const
-{
- return toString();
-}
-
-Ice::ConnectionInfoPtr
-IceInternal::TcpTransceiver::getInfo() const
-{
- Ice::IPConnectionInfoPtr info;
- info = ICE_MAKE_SHARED(Ice::TCPConnectionInfo);
- fillConnectionInfo(info);
- return info;
-}
-
-Ice::ConnectionInfoPtr
-IceInternal::TcpTransceiver::getWSInfo(const Ice::HeaderDict& headers) const
-{
- Ice::WSConnectionInfoPtr info = ICE_MAKE_SHARED(Ice::WSConnectionInfo);
- fillConnectionInfo(info);
- info->headers = headers;
- return info;
-}
-
-void
-IceInternal::TcpTransceiver::checkSendSize(const Buffer&)
-{
-}
-
- void
- IceInternal::TcpTransceiver::setBufferSize(int rcvSize, int sndSize)
- {
- setTcpBufSize(_fd, rcvSize, sndSize, _instance);
- }
-
-IceInternal::TcpTransceiver::TcpTransceiver(const ProtocolInstancePtr& instance, SOCKET fd, bool connected) :
- NativeInfo(fd),
- _instance(instance),
- _state(connected ? StateConnected : StateNeedConnect),
- _desc(connected ? fdToString(_fd) : string()),
- _verified(false)
-{
- StreamSocket^ streamSocket = safe_cast<StreamSocket^>(_fd);
- _writer = ref new DataWriter(streamSocket->OutputStream);
- _reader = ref new DataReader(streamSocket->InputStream);
- _reader->InputStreamOptions = InputStreamOptions::Partial;
-
- setTcpBufSize(_fd, _instance);
-
- _maxSendPacketSize = streamSocket->Control->OutboundBufferSizeInBytes / 2;
- if(_maxSendPacketSize < 512)
- {
- _maxSendPacketSize = 0;
- }
-
- _maxReceivePacketSize = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", 128 * 1024);
-}
-
-IceInternal::TcpTransceiver::~TcpTransceiver()
-{
- assert(_fd == INVALID_SOCKET);
-}
-
-void
-IceInternal::TcpTransceiver::connect(const Address& addr)
-{
- _connectAddr = addr;
-}
-
-bool
-IceInternal::TcpTransceiver::checkIfErrorOrCompleted(SocketOperation op, IAsyncInfo^ info, int count)
-{
- //
- // NOTE: It's important to only check for info->Status once as it
- // might change during the checks below (the Status can be changed
- // by the Windows thread pool concurrently).
- //
- // We consider that a canceled async status is the same as an
- // error. A canceled async status can occur if there's a timeout
- // and the socket is closed.
- //
- Windows::Foundation::AsyncStatus status = info->Status;
- if(status == Windows::Foundation::AsyncStatus::Completed)
- {
- _completedHandler(op);
- return true;
- }
- else if (status == Windows::Foundation::AsyncStatus::Started)
- {
- return false;
- }
- else
- {
- if(_state < StateConnected)
- {
- checkConnectErrorCode(__FILE__, __LINE__, info->ErrorCode.Value, _connectAddr.host);
- }
- else
- {
- checkErrorCode(__FILE__, __LINE__, info->ErrorCode.Value);
- }
- return true; // Prevent compiler warning.
- }
-}
-
-void
-IceInternal::TcpTransceiver::fillConnectionInfo(const Ice::IPConnectionInfoPtr& info) const
-{
- fdToAddressAndPort(_fd, info->localAddress, info->localPort, info->remoteAddress, info->remotePort);
- info->rcvSize = getRecvBufferSize(_fd);
- info->sndSize = getSendBufferSize(_fd);
-}
diff --git a/cpp/src/Ice/uwp/TcpTransceiver.h b/cpp/src/Ice/uwp/TcpTransceiver.h
deleted file mode 100644
index 433da311100..00000000000
--- a/cpp/src/Ice/uwp/TcpTransceiver.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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.
-//
-// **********************************************************************
-
-#ifndef ICE_UWP_TCP_TRANSCEIVER_H
-#define ICE_UWP_TCP_TRANSCEIVER_H
-
-#include <Ice/ProtocolInstanceF.h>
-#include <Ice/Transceiver.h>
-#include <Ice/Network.h>
-#include <Ice/WSTransceiver.h>
-
-namespace IceInternal
-{
-
-class StreamConnector;
-class StreamAcceptor;
-
-class TcpTransceiver : public Transceiver, public NativeInfo, public WSTransceiverDelegate
-{
- enum State
- {
- StateNeedConnect,
- StateConnectPending,
- StateConnected
- };
-
-public:
-
- virtual NativeInfoPtr getNativeInfo();
- virtual void setCompletedHandler(SocketOperationCompletedHandler^);
-
- virtual SocketOperation initialize(Buffer&, Buffer&);
-#ifdef ICE_CPP11_MAPPING
- virtual SocketOperation closing(bool, std::exception_ptr);
-#else
- virtual SocketOperation closing(bool, const Ice::LocalException&);
-#endif
- virtual void close();
- virtual SocketOperation write(Buffer&);
- virtual SocketOperation read(Buffer&);
-
- virtual bool startWrite(Buffer&);
- virtual void finishWrite(Buffer&);
- virtual void startRead(Buffer&);
- virtual void finishRead(Buffer&);
-
- virtual std::string protocol() const;
- virtual std::string toString() const;
- virtual std::string toDetailedString() const;
- virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
- virtual void checkSendSize(const Buffer&);
- virtual void setBufferSize(int rcvSize, int sndSize);
-
-private:
-
- TcpTransceiver(const ProtocolInstancePtr&, SOCKET, bool);
- virtual ~TcpTransceiver();
-
- void connect(const Address&);
- bool checkIfErrorOrCompleted(SocketOperation, Windows::Foundation::IAsyncInfo^, int = 0);
- void fillConnectionInfo(const Ice::IPConnectionInfoPtr&) const;
-
- friend class TcpConnector;
- friend class TcpAcceptor;
-
- const ProtocolInstancePtr _instance;
-
- State _state;
- std::string _desc;
- bool _verified;
- Address _connectAddr;
-
- AsyncInfo _read;
- AsyncInfo _write;
- int _maxSendPacketSize;
- int _maxReceivePacketSize;
-
- Windows::Storage::Streams::DataReader^ _reader;
- Windows::Storage::Streams::DataWriter^ _writer;
-
- Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _readOperationCompletedHandler;
- Windows::Foundation::AsyncOperationCompletedHandler<unsigned int>^ _writeOperationCompletedHandler;
-};
-
-}
-
-#endif
diff --git a/cpp/src/Ice/uwp/TransceiverF.h b/cpp/src/Ice/uwp/TransceiverF.h
deleted file mode 100644
index 76572a71a66..00000000000
--- a/cpp/src/Ice/uwp/TransceiverF.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2016 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.
-//
-// **********************************************************************
-
-#ifndef ICE_UWP_TRANSCEIVER_F_H
-#define ICE_UWP_TRANSCEIVER_F_H
-
-#include <IceUtil/Shared.h>
-#include <Ice/Handle.h>
-
-namespace IceInternal
-{
-
-class TcpEndpointI;
-#ifndef ICE_CPP11_MAPPING
-ICE_API IceUtil::Shared* upCast(TcpEndpointI*);
-#endif
-ICE_DEFINE_PTR(TcpEndpointIPtr, TcpEndpointI);
-
-class TcpAcceptor;
-ICE_API IceUtil::Shared* upCast(TcpAcceptor*);
-typedef IceInternal::Handle<TcpAcceptor> TcpAcceptorPtr;
-
-}
-
-#endif
diff --git a/cpp/src/IceBT/EndpointI.cpp b/cpp/src/IceBT/EndpointI.cpp
index 1f4ab9a99da..5c0d31cc8ef 100644
--- a/cpp/src/IceBT/EndpointI.cpp
+++ b/cpp/src/IceBT/EndpointI.cpp
@@ -92,17 +92,15 @@ IceBT::EndpointI::EndpointI(const InstancePtr& instance, InputStream* s) :
}
void
-IceBT::EndpointI::streamWrite(OutputStream* s) const
+IceBT::EndpointI::streamWriteImpl(OutputStream* s) const
{
//
// _name and _channel are not marshaled.
//
- s->startEncapsulation();
s->write(_addr, false);
s->write(_uuid, false);
s->write(_timeout);
s->write(_compress);
- s->endEncapsulation();
}
Ice::Short
@@ -758,7 +756,8 @@ IceBT::EndpointFactoryI::destroy()
}
IceInternal::EndpointFactoryPtr
-IceBT::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance) const
+IceBT::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance,
+ const IceInternal::EndpointFactoryPtr&) const
{
return new EndpointFactoryI(new Instance(_instance->engine(), instance->type(), instance->protocol()));
}
diff --git a/cpp/src/IceBT/EndpointI.h b/cpp/src/IceBT/EndpointI.h
index d3034413567..f0d2433d122 100644
--- a/cpp/src/IceBT/EndpointI.h
+++ b/cpp/src/IceBT/EndpointI.h
@@ -30,7 +30,7 @@ public:
EndpointI(const InstancePtr&);
EndpointI(const InstancePtr&, Ice::InputStream*);
- virtual void streamWrite(Ice::OutputStream*) const;
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual Ice::Short type() const;
virtual const std::string& protocol() const;
virtual Ice::Int timeout() const;
@@ -49,7 +49,7 @@ public:
#ifdef ICE_CPP11_MAPPING
virtual bool operator==(const Ice::Endpoint&) const;
- virtual bool operator<(const Ice::Endpoint&) const;
+ virtual bool operator<(const Ice::Endpoint&) const;
#else
virtual bool operator==(const Ice::LocalObject&) const;
virtual bool operator<(const Ice::LocalObject&) const;
@@ -140,7 +140,8 @@ public:
virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const;
+ virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&,
+ const IceInternal::EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/IceBT/PluginI.cpp b/cpp/src/IceBT/PluginI.cpp
index 07a6fb67c42..c8f2882bbfb 100644
--- a/cpp/src/IceBT/PluginI.cpp
+++ b/cpp/src/IceBT/PluginI.cpp
@@ -59,13 +59,21 @@ registerIceBT(bool loadOnInitialize)
IceBT::PluginI::PluginI(const Ice::CommunicatorPtr& com) :
_engine(new Engine(com))
{
+ IceInternal::ProtocolPluginFacadePtr pluginFacade = IceInternal::getProtocolPluginFacade(com);
+
//
// Register the endpoint factory. We have to do this now, rather
// than in initialize, because the communicator may need to
// interpret proxies before the plug-in is fully initialized.
//
- IceInternal::EndpointFactoryPtr btFactory = new EndpointFactoryI(new Instance(_engine, EndpointType, "bt"));
- IceInternal::getProtocolPluginFacade(com)->addEndpointFactory(btFactory);
+ pluginFacade->addEndpointFactory(new EndpointFactoryI(new Instance(_engine, BTEndpointType, "bt")));
+
+ IceInternal::EndpointFactoryPtr sslFactory = pluginFacade->getEndpointFactory(SSLEndpointType);
+ if(sslFactory)
+ {
+ InstancePtr instance = new Instance(_engine, BTSEndpointType, "bts");
+ pluginFacade->addEndpointFactory(sslFactory->clone(instance, new EndpointFactoryI(instance)));
+ }
}
void
diff --git a/cpp/src/IceBT/StreamSocket.cpp b/cpp/src/IceBT/StreamSocket.cpp
index 7c398fbed6f..ba4b27ca57f 100644
--- a/cpp/src/IceBT/StreamSocket.cpp
+++ b/cpp/src/IceBT/StreamSocket.cpp
@@ -104,12 +104,12 @@ IceBT::StreamSocket::setBufferSize(int rcvSize, int sndSize)
// Warn if the size that was set is less than the requested size and
// we have not already warned.
//
- IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(EndpointType);
+ IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(BTEndpointType);
if(!winfo.rcvWarn || rcvSize != winfo.rcvSize)
{
Ice::Warning out(_instance->logger());
out << "BT receive buffer size: requested size of " << rcvSize << " adjusted to " << size;
- _instance->setRcvBufSizeWarn(EndpointType, rcvSize);
+ _instance->setRcvBufSizeWarn(BTEndpointType, rcvSize);
}
}
}
@@ -127,12 +127,12 @@ IceBT::StreamSocket::setBufferSize(int rcvSize, int sndSize)
{
// Warn if the size that was set is less than the requested size and
// we have not already warned.
- IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(EndpointType);
+ IceInternal::BufSizeWarnInfo winfo = _instance->getBufSizeWarn(BTEndpointType);
if(!winfo.sndWarn || sndSize != winfo.sndSize)
{
Ice::Warning out(_instance->logger());
out << "BT send buffer size: requested size of " << sndSize << " adjusted to " << size;
- _instance->setSndBufSizeWarn(EndpointType, sndSize);
+ _instance->setSndBufSizeWarn(BTEndpointType, sndSize);
}
}
}
diff --git a/cpp/src/IceBT/TransceiverI.cpp b/cpp/src/IceBT/TransceiverI.cpp
index fc4c878f35a..4a3f4005803 100644
--- a/cpp/src/IceBT/TransceiverI.cpp
+++ b/cpp/src/IceBT/TransceiverI.cpp
@@ -90,6 +90,11 @@ IceBT::TransceiverI::getInfo() const
IceBT::ConnectionInfoPtr info = ICE_MAKE_SHARED(IceBT::ConnectionInfo);
fdToAddressAndChannel(_stream->fd(), info->localAddress, info->localChannel, info->remoteAddress,
info->remoteChannel);
+ if(_stream->fd() != INVALID_SOCKET)
+ {
+ info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd());
+ info->sndSize = IceInternal::getSendBufferSize(_stream->fd());
+ }
info->uuid = _uuid;
return info;
}
diff --git a/cpp/src/IceDiscovery/PluginI.cpp b/cpp/src/IceDiscovery/PluginI.cpp
index 5360dc14d31..615e0eeec96 100644
--- a/cpp/src/IceDiscovery/PluginI.cpp
+++ b/cpp/src/IceDiscovery/PluginI.cpp
@@ -28,17 +28,12 @@ using namespace IceDiscovery;
//
// Plugin factory function.
//
-extern "C"
-{
-
-ICE_DISCOVERY_API Ice::Plugin*
+extern "C" ICE_DISCOVERY_API Ice::Plugin*
createIceDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
{
return new PluginI(communicator);
}
-}
-
namespace Ice
{
@@ -50,6 +45,15 @@ registerIceDiscovery(bool loadOnInitialize)
}
+//
+// Objective-C function to allow Objective-C programs to register plugin.
+//
+extern "C" ICE_DISCOVERY_API void
+ICEregisterIceDiscovery(bool loadOnInitialize)
+{
+ Ice::registerIceDiscovery(loadOnInitialize);
+}
+
PluginI::PluginI(const Ice::CommunicatorPtr& communicator) : _communicator(communicator)
{
}
diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp
index fb31d8d588b..d246b26dd9c 100644
--- a/cpp/src/IceGrid/RegistryI.cpp
+++ b/cpp/src/IceGrid/RegistryI.cpp
@@ -118,6 +118,19 @@ private:
ProcessPtr _origProcess;
};
+Ice::IPConnectionInfoPtr
+getIPConnectionInfo(const Ice::ConnectionInfoPtr& info)
+{
+ for(Ice::ConnectionInfoPtr p = info; p; p = p->underlying)
+ {
+ Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(p);
+ if(ipInfo)
+ {
+ return ipInfo;
+ }
+ }
+ return ICE_NULLPTR;
+}
ProcessI::ProcessI(const RegistryIPtr& registry, const ProcessPtr& origProcess) :
_registry(registry),
@@ -1338,10 +1351,11 @@ RegistryI::getSSLInfo(const ConnectionPtr& connection, string& userDN)
throw exc;
}
- sslinfo.remotePort = info->remotePort;
- sslinfo.remoteHost = info->remoteAddress;
- sslinfo.localPort = info->localPort;
- sslinfo.localHost = info->localAddress;
+ Ice::IPConnectionInfoPtr ipInfo = getIPConnectionInfo(info);
+ sslinfo.remotePort = ipInfo->remotePort;
+ sslinfo.remoteHost = ipInfo->remoteAddress;
+ sslinfo.localPort = ipInfo->localPort;
+ sslinfo.localHost = ipInfo->localAddress;
sslinfo.cipher = info->cipher;
sslinfo.certs = info->certs;
if(info->certs.size() > 0)
diff --git a/cpp/src/Ice/ios/iAPConnector.h b/cpp/src/IceIAP/Connector.h
index f2bd4281d95..f2bd4281d95 100644
--- a/cpp/src/Ice/ios/iAPConnector.h
+++ b/cpp/src/IceIAP/Connector.h
diff --git a/cpp/src/Ice/ios/iAPConnector.mm b/cpp/src/IceIAP/Connector.mm
index 935858b9c6f..b7c57ddb31b 100644
--- a/cpp/src/Ice/ios/iAPConnector.mm
+++ b/cpp/src/IceIAP/Connector.mm
@@ -7,9 +7,9 @@
//
// **********************************************************************
-#include "iAPTransceiver.h"
-#include "iAPEndpointI.h"
-#include "iAPConnector.h"
+#include "Transceiver.h"
+#include "EndpointI.h"
+#include "Connector.h"
#include <Ice/ProtocolInstance.h>
#include <Ice/Exception.h>
diff --git a/cpp/src/Ice/ios/iAPEndpointI.h b/cpp/src/IceIAP/EndpointI.h
index dc85e085bf7..c4016073453 100644
--- a/cpp/src/Ice/ios/iAPEndpointI.h
+++ b/cpp/src/IceIAP/EndpointI.h
@@ -33,7 +33,7 @@ public:
iAPEndpointI(const IceInternal::ProtocolInstancePtr&);
iAPEndpointI(const IceInternal::ProtocolInstancePtr&, Ice::InputStream*);
- virtual void streamWrite(Ice::OutputStream*) const;
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual Ice::EndpointInfoPtr getInfo() const;
virtual Ice::Short type() const;
@@ -97,7 +97,8 @@ public:
virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const;
+ virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&,
+ const IceInternal::EndpointFactoryPtr&) const;
private:
diff --git a/cpp/src/Ice/ios/iAPEndpointI.mm b/cpp/src/IceIAP/EndpointI.mm
index 86ca8060fbc..44a0526d9ab 100644
--- a/cpp/src/Ice/ios/iAPEndpointI.mm
+++ b/cpp/src/IceIAP/EndpointI.mm
@@ -7,8 +7,10 @@
//
// **********************************************************************
-#include "iAPEndpointI.h"
-#include "iAPConnector.h"
+#include "EndpointI.h"
+#include "Connector.h"
+
+#include <IceIAP/EndpointInfo.h>
#include <Ice/Network.h>
#include <Ice/InputStream.h>
@@ -20,6 +22,8 @@
#include <Ice/EndpointFactoryManager.h>
#include <Ice/Properties.h>
#include <Ice/HashUtil.h>
+#include <Ice/ProtocolPluginFacade.h>
+#include <Ice/RegisterPlugins.h>
#include <CoreFoundation/CoreFoundation.h>
@@ -29,18 +33,62 @@ using namespace std;
using namespace Ice;
using namespace IceInternal;
-extern "C"
+namespace
+{
+
+class iAPEndpointFactoryPlugin : public Ice::Plugin
{
+public:
+
+ iAPEndpointFactoryPlugin(const Ice::CommunicatorPtr& com)
+ {
+ ProtocolPluginFacadePtr pluginFacade = getProtocolPluginFacade(com);
+
+ // iAP transport
+ ProtocolInstancePtr instance = new ProtocolInstance(com, iAPEndpointType, "iap", false);
+ pluginFacade->addEndpointFactory(new IceObjC::iAPEndpointFactory(instance));
+
+ // SSL based on iAP transport
+ EndpointFactoryPtr ssl = pluginFacade->getEndpointFactory(SSLEndpointType);
+ if(ssl)
+ {
+ ProtocolInstancePtr sslinstance = new ProtocolInstance(com, iAPSEndpointType, "iaps", true);
+ pluginFacade->addEndpointFactory(ssl->clone(sslinstance, new IceObjC::iAPEndpointFactory(sslinstance)));
+ }
+ }
-Plugin*
+ virtual void initialize() {}
+ virtual void destroy() {}
+};
+
+}
+
+extern "C" ICE_IAP_API Plugin*
createIceIAP(const CommunicatorPtr& com, const string&, const StringSeq&)
{
- ProtocolInstancePtr instance = new ProtocolInstance(com, iAPEndpointType, "iap", false);
- return new EndpointFactoryPlugin(com, new IceObjC::iAPEndpointFactory(instance));
+ return new iAPEndpointFactoryPlugin(com);
+}
+
+namespace Ice
+{
+
+ICE_IAP_API void
+registerIceIAP(bool loadOnInitialize)
+{
+ Ice::registerPluginFactory("IceIAP", createIceIAP, loadOnInitialize);
}
}
+//
+// Objective-C function to allow Objective-C programs to register plugin.
+//
+extern "C" ICE_IAP_API void
+ICEregisterIceIAP(bool loadOnInitialize)
+{
+ Ice::registerIceIAP(loadOnInitialize);
+}
+
IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, const string& m,
const string& o, const string& n, const string& p, Int ti,
const string& conId, bool co) :
@@ -70,26 +118,33 @@ IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, InputSt
s->read(const_cast<string&>(_manufacturer), false);
s->read(const_cast<string&>(_modelNumber), false);
s->read(const_cast<string&>(_name), false);
+ s->read(const_cast<string&>(_protocol), false);
s->read(const_cast<Int&>(_timeout));
s->read(const_cast<bool&>(_compress));
}
void
-IceObjC::iAPEndpointI::streamWrite(OutputStream* s) const
+IceObjC::iAPEndpointI::streamWriteImpl(OutputStream* s) const
{
- s->startEncapsulation();
s->write(_manufacturer, false);
s->write(_modelNumber, false);
s->write(_name, false);
+ s->write(_protocol, false);
s->write(_timeout);
s->write(_compress);
- s->endEncapsulation();
}
EndpointInfoPtr
IceObjC::iAPEndpointI::getInfo() const
{
- return 0;
+ IceIAP::EndpointInfoPtr info = ICE_MAKE_SHARED(InfoI<IceIAP::EndpointInfo>, shared_from_this());
+ info->timeout = _timeout;
+ info->compress = _compress;
+ info->manufacturer = _manufacturer;
+ info->modelNumber = _modelNumber;
+ info->name = _name;
+ info->protocol = _protocol;
+ return info;
}
Short
@@ -131,7 +186,8 @@ IceObjC::iAPEndpointI::timeout(Int t) const
}
else
{
- return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId, _compress);
+ return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId,
+ _compress);
}
}
@@ -150,7 +206,8 @@ IceObjC::iAPEndpointI::connectionId(const string& cId) const
}
else
{
- return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId, _compress);
+ return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId,
+ _compress);
}
}
@@ -169,7 +226,8 @@ IceObjC::iAPEndpointI::compress(bool c) const
}
else
{
- return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, _connectionId, c);
+ return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout,
+ _connectionId, c);
}
}
@@ -197,37 +255,28 @@ IceObjC::iAPEndpointI::connectors_async(Ice::EndpointSelectionType selType,
NSArray* array = [manager connectedAccessories];
NSEnumerator* enumerator = [array objectEnumerator];
EAAccessory* accessory = nil;
- int lastError = 0;
while((accessory = [enumerator nextObject]))
{
if(!accessory.connected)
{
- lastError = 1;
continue;
}
-
if(!_manufacturer.empty() && _manufacturer != [accessory.manufacturer UTF8String])
{
- lastError = 2;
continue;
}
if(!_modelNumber.empty() && _modelNumber != [accessory.modelNumber UTF8String])
{
- lastError = 3;
continue;
}
if(!_name.empty() && _name != [accessory.name UTF8String])
{
- lastError = 4;
continue;
}
-
if(![accessory.protocolStrings containsObject:protocol])
{
- lastError = 5;
continue;
}
-
c.push_back(new iAPConnector(_instance, _timeout, _connectionId, protocol, accessory));
}
[protocol release];
@@ -268,7 +317,8 @@ IceObjC::iAPEndpointI::equivalent(const EndpointIPtr& endpoint) const
}
return endpointI->_manufacturer == _manufacturer &&
endpointI->_modelNumber == _modelNumber &&
- endpointI->_name == _name;
+ endpointI->_name == _name &&
+ endpointI->_protocol == _protocol;
}
bool
@@ -304,6 +354,11 @@ IceObjC::iAPEndpointI::operator==(const Ice::LocalObject& r) const
return false;
}
+ if(_protocol != p->_protocol)
+ {
+ return false;
+ }
+
if(_timeout != p->_timeout)
{
return false;
@@ -372,6 +427,15 @@ IceObjC::iAPEndpointI::operator<(const Ice::LocalObject& r) const
return false;
}
+ if(_protocol < p->_protocol)
+ {
+ return true;
+ }
+ else if(p->_protocol < _protocol)
+ {
+ return false;
+ }
+
if(_timeout < p->_timeout)
{
return true;
@@ -477,6 +541,7 @@ IceObjC::iAPEndpointI::options() const
{
s << " -t " << _timeout;
}
+
if(_compress)
{
s << " -z";
@@ -491,6 +556,7 @@ IceObjC::iAPEndpointI::hash() const
hashAdd(h, _manufacturer);
hashAdd(h, _modelNumber);
hashAdd(h, _name);
+ hashAdd(h, _protocol);
hashAdd(h, _timeout);
hashAdd(h, _connectionId);
return h;
@@ -634,7 +700,7 @@ IceObjC::iAPEndpointFactory::destroy()
}
EndpointFactoryPtr
-IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance) const
+IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance, const IceInternal::EndpointFactoryPtr&) const
{
return new iAPEndpointFactory(instance);
}
diff --git a/cpp/src/IceIAP/Makefile.mk b/cpp/src/IceIAP/Makefile.mk
new file mode 100644
index 00000000000..daeffbead19
--- /dev/null
+++ b/cpp/src/IceIAP/Makefile.mk
@@ -0,0 +1,20 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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.
+#
+# **********************************************************************
+
+$(project)_libraries = IceIAP
+
+IceIAP_configs := xcodesdk cpp11-xcodesdk
+IceIAP_platforms := iphoneos iphonesimulator
+
+IceIAP_targetdir := $(libdir)
+IceIAP_dependencies := Ice
+IceIAP_sliceflags := --include-dir IceIAP --dll-export ICE_IAP_API
+IceIAP_cppflags := -DICE_IAP_API_EXPORTS
+
+projects += $(project)
diff --git a/cpp/src/Ice/ios/iAPTransceiver.h b/cpp/src/IceIAP/Transceiver.h
index 6aaeb731241..b82ed27c395 100644
--- a/cpp/src/Ice/ios/iAPTransceiver.h
+++ b/cpp/src/IceIAP/Transceiver.h
@@ -66,6 +66,7 @@ private:
void checkError(NSError*, const char*, int);
IceInternal::ProtocolInstancePtr _instance;
+ EASession* _session;
NSInputStream* _readStream;
NSOutputStream* _writeStream;
iAPTransceiverCallback* _callback;
diff --git a/cpp/src/Ice/ios/iAPTransceiver.mm b/cpp/src/IceIAP/Transceiver.mm
index 3139b8f608e..a9a57dbf407 100644
--- a/cpp/src/Ice/ios/iAPTransceiver.mm
+++ b/cpp/src/IceIAP/Transceiver.mm
@@ -7,8 +7,10 @@
//
// **********************************************************************
-#include "iAPTransceiver.h"
-#include "iAPEndpointI.h"
+#include "Transceiver.h"
+#include "EndpointI.h"
+
+#include <IceIAP/ConnectionInfo.h>
#include <Ice/LocalException.h>
#include <Ice/ProtocolInstance.h>
@@ -62,8 +64,7 @@ using namespace IceInternal;
callback->readyCallback(static_cast<SocketOperation>(SocketOperationConnect | SocketOperationWrite));
}
break;
- case NSStreamEventEndEncountered:
- case NSStreamEventErrorOccurred:
+ default:
if([[stream class] isSubclassOfClass:[NSInputStream class]])
{
callback->readyCallback(SocketOperationRead, -1); // Error
@@ -88,7 +89,6 @@ SocketOperation
IceObjC::iAPTransceiver::registerWithRunLoop(SocketOperation op)
{
IceUtil::Mutex::Lock sync(_mutex);
-
SocketOperation readyOp = SocketOperationNone;
if(op & SocketOperationConnect)
{
@@ -236,39 +236,16 @@ IceObjC::iAPTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer)
{
if(_error)
{
- assert([_writeStream streamStatus] == NSStreamStatusError);
- NSError* err = [_writeStream streamError];
- NSString* domain = [err domain];
- if([domain compare:NSPOSIXErrorDomain] == NSOrderedSame)
+ NSError* err = nil;
+ if([_writeStream streamStatus] == NSStreamStatusError)
{
- errno = [err code];
- [err release];
- if(connectionRefused())
- {
- ConnectionRefusedException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- else if(connectFailed())
- {
- ConnectFailedException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
- else
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
- }
+ err = [_writeStream streamError];
}
-
- // Otherwise throw a generic exception.
- CFNetworkException ex(__FILE__, __LINE__);
- ex.domain = [domain UTF8String];
- ex.error = [err code];
- [err release];
- throw ex;
+ if([_readStream streamStatus] == NSStreamStatusError)
+ {
+ err = [_readStream streamError];
+ }
+ checkError(err, __FILE__, __LINE__);
}
_state = StateConnected;
}
@@ -296,7 +273,7 @@ IceObjC::iAPTransceiver::close()
SocketOperation
IceObjC::iAPTransceiver::write(Buffer& buf)
{
- IceUtil::Mutex::Lock sync(_mutex);
+ IceUtil::Mutex::Lock sync(_mutex);
if(_error)
{
assert([_writeStream streamStatus] == NSStreamStatusError);
@@ -421,7 +398,14 @@ IceObjC::iAPTransceiver::toDetailedString() const
Ice::ConnectionInfoPtr
IceObjC::iAPTransceiver::getInfo() const
{
- return 0;
+ IceIAP::ConnectionInfoPtr info = new IceIAP::ConnectionInfo();
+ info->manufacturer = [_session.accessory.manufacturer UTF8String];
+ info->name = [_session.accessory.name UTF8String];
+ info->modelNumber = [_session.accessory.modelNumber UTF8String];
+ info->firmwareRevision = [_session.accessory.firmwareRevision UTF8String];
+ info->hardwareRevision = [_session.accessory.hardwareRevision UTF8String];
+ info->protocol = [_session.protocolString UTF8String];
+ return info;
}
void
@@ -437,20 +421,23 @@ IceObjC::iAPTransceiver::setBufferSize(int, int)
IceObjC::iAPTransceiver::iAPTransceiver(const ProtocolInstancePtr& instance, EASession* session) :
StreamNativeInfo(INVALID_SOCKET),
_instance(instance),
- _readStream([[session inputStream] retain]),
- _writeStream([[session outputStream] retain]),
+ _session([session retain]),
+ _readStream([session inputStream]),
+ _writeStream([session outputStream]),
_readStreamRegistered(false),
_writeStreamRegistered(false),
_error(false),
_state(StateNeedConnect)
{
- _desc = string("name = ") + [session.accessory.name UTF8String];
+ ostringstream os;
+ os << "name = " << [session.accessory.name UTF8String] << "\n";
+ os << "protocol = " << [session.protocolString UTF8String];
+ _desc = os.str();
}
IceObjC::iAPTransceiver::~iAPTransceiver()
{
- [_readStream release];
- [_writeStream release];
+ [_session release];
}
void
diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp
index 4851e98bfcc..ee1e79d9c99 100644
--- a/cpp/src/IceLocatorDiscovery/PluginI.cpp
+++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp
@@ -27,17 +27,12 @@ using namespace IceLocatorDiscovery;
//
// Plugin factory function.
//
-extern "C"
-{
-
-ICE_LOCATOR_DISCOVERY_API Ice::Plugin*
+extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin*
createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
{
return new PluginI(communicator);
}
-}
-
namespace Ice
{
@@ -49,6 +44,15 @@ registerIceLocatorDiscovery(bool loadOnInitialize)
}
+//
+// Objective-C function to allow Objective-C programs to register plugin.
+//
+extern "C" ICE_LOCATOR_DISCOVERY_API void
+ICEregisterIceLocatorDiscovery(bool loadOnInitialize)
+{
+ Ice::registerIceLocatorDiscovery(loadOnInitialize);
+}
+
namespace
{
diff --git a/cpp/src/IcePatch2/Server.cpp b/cpp/src/IcePatch2/Server.cpp
index f0d0dc21b32..b559a091796 100644
--- a/cpp/src/IcePatch2/Server.cpp
+++ b/cpp/src/IcePatch2/Server.cpp
@@ -53,7 +53,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status)
IceUtilInternal::Options opts;
opts.addOpt("h", "help");
opts.addOpt("v", "version");
-
+
vector<string> args;
try
{
@@ -109,7 +109,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status)
{
throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString();
}
-
+
dataDir = cwd + '/' + dataDir;
}
@@ -125,7 +125,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[], int& status)
error(ex);
return false;
}
-
+
const string endpointsProperty = "IcePatch2.Endpoints";
string endpoints = properties->getProperty(endpointsProperty);
if(endpoints.empty())
diff --git a/cpp/src/IceSSL/AcceptorI.cpp b/cpp/src/IceSSL/AcceptorI.cpp
index 7f8c70341ed..8042fb8d195 100644
--- a/cpp/src/IceSSL/AcceptorI.cpp
+++ b/cpp/src/IceSSL/AcceptorI.cpp
@@ -11,23 +11,15 @@
#include <IceSSL/EndpointI.h>
#include <IceSSL/Instance.h>
+
#include <IceSSL/OpenSSLTransceiverI.h>
#include <IceSSL/SecureTransportTransceiverI.h>
#include <IceSSL/SChannelTransceiverI.h>
+#include <IceSSL/WinRTTransceiverI.h>
#include <IceSSL/Util.h>
-#include <Ice/Communicator.h>
-#include <Ice/Exception.h>
#include <Ice/LocalException.h>
-#include <Ice/LoggerUtil.h>
-#include <Ice/Properties.h>
-#include <Ice/StreamSocket.h>
-#include <IceUtil/StringUtil.h>
-
-#ifdef ICE_USE_IOCP
-# include <Mswsock.h>
-#endif
using namespace std;
using namespace Ice;
@@ -38,90 +30,43 @@ IceUtil::Shared* IceSSL::upCast(AcceptorI* p) { return p; }
IceInternal::NativeInfoPtr
IceSSL::AcceptorI::getNativeInfo()
{
- return this;
+ return _delegate->getNativeInfo();
}
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
IceInternal::AsyncInfo*
-IceSSL::AcceptorI::getAsyncInfo(IceInternal::SocketOperation)
+IceSSL::AcceptorI::getAsyncInfo(IceInternal::SocketOperation status)
{
- return &_info;
+ return _delegate->getNativeInfo()->getAsyncInfo(status);
}
#endif
void
IceSSL::AcceptorI::close()
{
- if(_fd != INVALID_SOCKET)
- {
- IceInternal::closeSocketNoThrow(_fd);
- _fd = INVALID_SOCKET;
- }
+ _delegate->close();
}
IceInternal::EndpointIPtr
IceSSL::AcceptorI::listen()
{
- try
- {
- const_cast<IceInternal::Address&>(_addr) = IceInternal::doBind(_fd, _addr);
- IceInternal::doListen(_fd, _backlog);
- }
- catch(...)
- {
- _fd = INVALID_SOCKET;
- throw;
- }
- _endpoint = _endpoint->endpoint(this);
+ _endpoint = _endpoint->endpoint(_delegate->listen());
return _endpoint;
}
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
void
IceSSL::AcceptorI::startAccept()
{
- LPFN_ACCEPTEX AcceptEx = NULL; // a pointer to the 'AcceptEx()' function
- GUID GuidAcceptEx = WSAID_ACCEPTEX; // The Guid
- DWORD dwBytes;
- if(WSAIoctl(_fd,
- SIO_GET_EXTENSION_FUNCTION_POINTER,
- &GuidAcceptEx,
- sizeof(GuidAcceptEx),
- &AcceptEx,
- sizeof(AcceptEx),
- &dwBytes,
- NULL,
- NULL) == SOCKET_ERROR)
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = IceInternal::getSocketErrno();
- throw ex;
- }
+ _delegate->startAccept();
- assert(_acceptFd == INVALID_SOCKET);
- _acceptFd = IceInternal::createSocket(false, _addr);
- const int sz = static_cast<int>(_acceptBuf.size() / 2);
- if(!AcceptEx(_fd, _acceptFd, &_acceptBuf[0], 0, sz, sz, &_info.count, &_info))
- {
- if(!IceInternal::wouldBlock())
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = IceInternal::getSocketErrno();
- throw ex;
- }
- }
}
void
IceSSL::AcceptorI::finishAccept()
{
- if(static_cast<int>(_info.count) == SOCKET_ERROR || _fd == INVALID_SOCKET)
- {
- IceInternal::closeSocketNoThrow(_acceptFd);
- _acceptFd = INVALID_SOCKET;
- _acceptError = _info.error;
- }
+ _delegate->finishAccept();
}
#endif
@@ -138,121 +83,36 @@ IceSSL::AcceptorI::accept()
throw ex;
}
-#ifndef ICE_USE_IOCP
- SOCKET fd = IceInternal::doAccept(_fd);
-#else
- if(_acceptFd == INVALID_SOCKET)
- {
- SocketException ex(__FILE__, __LINE__);
- ex.error = _acceptError;
- throw ex;
- }
-
- if(setsockopt(_acceptFd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&_acceptFd, sizeof(_acceptFd)) ==
- SOCKET_ERROR)
- {
- IceInternal::closeSocketNoThrow(_acceptFd);
- _acceptFd = INVALID_SOCKET;
- SocketException ex(__FILE__, __LINE__);
- ex.error = IceInternal::getSocketErrno();
- throw ex;
- }
-
- SOCKET fd = _acceptFd;
- _acceptFd = INVALID_SOCKET;
-#endif
-
- //
- // SSL handshaking is performed in TransceiverI::initialize, since
- // accept must not block.
- //
- return new TransceiverI(_instance, new IceInternal::StreamSocket(_instance, fd), _adapterName, true);
+ return new TransceiverI(_instance, _delegate->accept(), _adapterName, true);
}
string
IceSSL::AcceptorI::protocol() const
{
- return _instance->protocol();
+ return _delegate->protocol();
}
string
IceSSL::AcceptorI::toString() const
{
- return IceInternal::addrToString(_addr);
+ return _delegate->toString();
}
string
IceSSL::AcceptorI::toDetailedString() const
{
- ostringstream os;
- os << "local address = " << toString();
- vector<string> intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true);
- if(!intfs.empty())
- {
- os << "\nlocal interfaces = ";
- os << IceUtilInternal::joinString(intfs, ", ");
- }
- return os.str();
+ return _delegate->toDetailedString();
}
-int
-IceSSL::AcceptorI::effectivePort() const
-{
- if(_addr.saStorage.ss_family == AF_INET)
- {
- return ntohs(_addr.saIn.sin_port);
- }
- else
- {
- return ntohs(_addr.saIn6.sin6_port);
- }
-}
-
-IceSSL::AcceptorI::AcceptorI(const EndpointIPtr& endpoint, const InstancePtr& instance, const string& adapterName,
- const string& host, int port) :
+IceSSL::AcceptorI::AcceptorI(const EndpointIPtr& endpoint, const InstancePtr& instance,
+ const IceInternal::AcceptorPtr& del, const string& adapterName) :
_endpoint(endpoint),
_instance(instance),
- _adapterName(adapterName),
- _addr(IceInternal::getAddressForServer(host, port, instance->protocolSupport(), instance->preferIPv6()))
-#ifdef ICE_USE_IOCP
- , _acceptFd(INVALID_SOCKET),
- _info(IceInternal::SocketOperationRead)
-#endif
+ _delegate(del),
+ _adapterName(adapterName)
{
-#ifdef SOMAXCONN
- _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN);
-#else
- _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);
-#endif
-
- IceInternal::ProtocolSupport protocol = instance->protocolSupport();
- _fd = IceInternal::createServerSocket(false, _addr, protocol);
-#ifdef ICE_USE_IOCP
- _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2);
-#endif
- IceInternal::setBlock(_fd, false);
- IceInternal::setTcpBufSize(_fd, _instance);
-#ifndef _WIN32
- //
- // Enable SO_REUSEADDR on Unix platforms to allow re-using the
- // socket even if it's in the TIME_WAIT state. On Windows,
- // this doesn't appear to be necessary and enabling
- // SO_REUSEADDR would actually not be a good thing since it
- // allows a second process to bind to an address even it's
- // already bound by another process.
- //
- // TODO: using SO_EXCLUSIVEADDRUSE on Windows would probably
- // be better but it's only supported by recent Windows
- // versions (XP SP2, Windows Server 2003).
- //
- IceInternal::setReuseAddress(_fd, true);
-#endif
}
IceSSL::AcceptorI::~AcceptorI()
{
- assert(_fd == INVALID_SOCKET);
-#ifdef ICE_USE_IOCP
- assert(_acceptFd == INVALID_SOCKET);
-#endif
}
diff --git a/cpp/src/IceSSL/AcceptorI.h b/cpp/src/IceSSL/AcceptorI.h
index 465878a24c2..3ee5d5d2d4c 100644
--- a/cpp/src/IceSSL/AcceptorI.h
+++ b/cpp/src/IceSSL/AcceptorI.h
@@ -25,13 +25,13 @@ class AcceptorI : public IceInternal::Acceptor, public IceInternal::NativeInfo
public:
virtual IceInternal::NativeInfoPtr getNativeInfo();
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual IceInternal::AsyncInfo* getAsyncInfo(IceInternal::SocketOperation);
#endif
virtual void close();
virtual IceInternal::EndpointIPtr listen();
-#ifdef ICE_USE_IOCP
+#if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
virtual void startAccept();
virtual void finishAccept();
#endif
@@ -40,25 +40,16 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
- int effectivePort() const;
-
private:
- AcceptorI(const EndpointIPtr&, const InstancePtr&, const std::string&, const std::string&, int);
+ AcceptorI(const EndpointIPtr&, const InstancePtr&, const IceInternal::AcceptorPtr&, const std::string&);
virtual ~AcceptorI();
friend class EndpointI;
EndpointIPtr _endpoint;
const InstancePtr _instance;
+ const IceInternal::AcceptorPtr _delegate;
const std::string _adapterName;
- const IceInternal::Address _addr;
- int _backlog;
-#ifdef ICE_USE_IOCP
- SOCKET _acceptFd;
- int _acceptError;
- std::vector<char> _acceptBuf;
- IceInternal::AsyncInfo _info;
-#endif
};
}
diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp
index 61597bdd0fe..5429a96b2e9 100644..100755
--- a/cpp/src/IceSSL/Certificate.cpp
+++ b/cpp/src/IceSSL/Certificate.cpp
@@ -15,6 +15,7 @@
#include <IceSSL/Util.h>
#include <IceSSL/RFC2253.h>
#include <Ice/Object.h>
+#include <Ice/Base64.h>
#if defined(ICE_USE_OPENSSL)
# include <openssl/x509v3.h>
@@ -42,12 +43,12 @@ extern "C" typedef void (*FreeFunc)(void*);
#endif
-
using namespace std;
using namespace Ice;
using namespace IceSSL;
#if defined(ICE_USE_SECURE_TRANSPORT) || defined(ICE_USE_SCHANNEL)
+
//
// Map a certificate OID to its alias
//
@@ -80,7 +81,6 @@ const int certificateOIDSSize = sizeof(certificateOIDS) / sizeof(CertificateOID)
#endif
-
#if defined(ICE_USE_SECURE_TRANSPORT)
string
@@ -98,29 +98,6 @@ certificateOIDAlias(const string& name)
return name;
}
-//
-// Map alternative name alias to its types.
-//
-const char* certificateAlternativeNameTypes[] = {"", "Email Address", "DNS Name", "", "Directory Name", "", "URI",
- "IP Address"};
-const int certificateAlternativeNameTypesSize = sizeof(certificateAlternativeNameTypes) / sizeof(char*);
-
-int
-certificateAlternativeNameType(const string& alias)
-{
- if(!alias.empty())
- {
- for(int i = 0; i < certificateAlternativeNameTypesSize; ++i)
- {
- if(alias == certificateAlternativeNameTypes[i])
- {
- return i;
- }
- }
- }
- return -1; // Not supported
-}
-
string
escapeX509Name(const string& name)
{
@@ -149,6 +126,31 @@ escapeX509Name(const string& name)
return os.str();
}
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
+
+//
+// Map alternative name alias to its types.
+//
+const char* certificateAlternativeNameTypes[] = {"", "Email Address", "DNS Name", "", "Directory Name", "", "URI",
+ "IP Address"};
+const int certificateAlternativeNameTypesSize = sizeof(certificateAlternativeNameTypes) / sizeof(char*);
+
+int
+certificateAlternativeNameType(const string& alias)
+{
+ if(!alias.empty())
+ {
+ for(int i = 0; i < certificateAlternativeNameTypesSize; ++i)
+ {
+ if(alias == certificateAlternativeNameTypes[i])
+ {
+ return i;
+ }
+ }
+ }
+ return -1; // Not supported
+}
+
DistinguishedName
getX509Name(SecCertificateRef cert, CFTypeRef key)
{
@@ -256,8 +258,158 @@ getX509String(SecCertificateRef cert, CFTypeRef key)
return value;
}
-#elif defined(ICE_USE_SCHANNEL)
+#else // IOS
+
+//
+// ASN1Parser to pase the subject/issuer ASN.1 DER encoded attributes on iOS.
+//
+class ASN1Parser
+{
+public:
+
+ ASN1Parser(CFDataRef data) : _data(CFDataGetBytePtr(data)), _length(CFDataGetLength(data)), _p(_data), _next(0)
+ {
+ }
+
+ list<pair<string, string> >
+ parse()
+ {
+ list<pair<string, string> > rdns;
+ while(_p < _data + _length)
+ {
+ switch(parseByte())
+ {
+ case 0x06: // OID
+ {
+ _rdn.first = parseOID();
+ break;
+ }
+ case 0x12: // NumericString
+ case 0x13: // PrintableString
+ case 0x0C: // UTF8String
+ case 0x16: // IA5String
+ {
+ _rdn.second = escapeX509Name(parseUTF8String());
+ break;
+ }
+ case 0x30: // SEQUENCE
+ case 0x31: // SET
+ {
+ int length = parseLength(0);
+ _next = _p + length;
+ if(_next > _data + _length)
+ {
+ throw CertificateEncodingException(__FILE__, __LINE__, "invalid length");
+ }
+ break;
+ }
+ default:
+ {
+ // Unsupported tag, skip the SET.
+ if(!_next)
+ {
+ return rdns;
+ }
+ _p = _next;
+ _next = 0;
+ break;
+ }
+ }
+ if(_p == _next)
+ {
+ rdns.push_back(_rdn);
+ }
+ }
+ return rdns;
+ }
+
+ string
+ parseOID()
+ {
+ int length = parseLength(1);
+ ostringstream oid;
+ unsigned char c = parseByte();
+ oid << c / 40 << "." << c % 40;
+ while(--length > 0)
+ {
+ if((*_p & 0x80) == 0)
+ {
+ oid << "." << static_cast<int>(parseByte());
+ }
+ else
+ {
+ uint64_t result = (uint64_t)(*_p & 127);
+ while(parseByte() & 128)
+ {
+ result = (result << 7) | (uint64_t)(*_p & 127);
+ --length;
+ }
+ oid << "." << result;
+ }
+ }
+ return certificateOIDAlias(oid.str());
+ }
+
+ string
+ parseUTF8String()
+ {
+ int length = parseLength(0);
+ string v(reinterpret_cast<const char*>(_p), length);
+ _p += length;
+ return v;
+ }
+ int
+ parseLength(int required)
+ {
+ int length = 0;
+ if((*_p & 0x80) == 0)
+ {
+ length = static_cast<int>(parseByte());
+ }
+ else
+ {
+ int nbytes = static_cast<int>(parseByte());
+ for(int i = 0; i < nbytes; ++i)
+ {
+ length = length * 256 + parseByte();
+ }
+ }
+ if((required > 0 && length < required) || (_p + length > _data + _length))
+ {
+ throw CertificateEncodingException(__FILE__, __LINE__, "invalid length");
+ }
+ return length;
+ }
+
+ unsigned char
+ parseByte()
+ {
+ if(_p >= _data + _length)
+ {
+ throw CertificateEncodingException(__FILE__, __LINE__, "invalid length");
+ }
+ unsigned char b = *_p++;
+ return b;
+ }
+
+private:
+
+ const unsigned char* _data;
+ const size_t _length;
+ const unsigned char* _p;
+ const unsigned char* _next;
+ pair<string, string> _rdn;
+ list<pair<string, string> > _rdns;
+};
+#endif
+
+#elif defined(ICE_USE_SCHANNEL) || defined(ICE_OS_WINRT)
+
+const Ice::Long TICKS_PER_MSECOND = 10000LL;
+const Ice::Long MSECS_TO_EPOCH = 11644473600000LL;
+
+#if defined(ICE_USE_SCHANNEL)
void
loadCertificate(PCERT_SIGNED_CONTENT_INFO* cert, const char* buffer, DWORD length)
{
@@ -294,9 +446,6 @@ loadCertificate(PCERT_SIGNED_CONTENT_INFO* cert, const string& file)
loadCertificate(cert, &buffer[0], static_cast<DWORD>(buffer.size()));
}
-const Ice::Long TICKS_PER_MSECOND = 10000LL;
-const Ice::Long MSECS_TO_EPOCH = 11644473600000LL;
-
IceUtil::Time
filetimeToTime(FILETIME ftime)
{
@@ -419,6 +568,32 @@ certificateAltNames(CERT_INFO* certInfo, LPCSTR altNameOID)
}
return altNames;
}
+#else
+
+vector<pair<int, string> >
+certificateAltNames(Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ subAltNames)
+{
+ vector<pair<int, string> > altNames;
+ for (auto iter = subAltNames->EmailName->First(); iter->HasCurrent; iter->MoveNext())
+ {
+ altNames.push_back(make_pair(AltNameEmail, IceUtil::wstringToString(iter->Current->Data())));
+ }
+ for (auto iter = subAltNames->DnsName->First(); iter->HasCurrent; iter->MoveNext())
+ {
+ altNames.push_back(make_pair(AltNameDNS, IceUtil::wstringToString(iter->Current->Data())));
+ }
+ for (auto iter = subAltNames->Url->First(); iter->HasCurrent; iter->MoveNext())
+ {
+ altNames.push_back(make_pair(AltNameURL, IceUtil::wstringToString(iter->Current->Data())));
+ }
+ for (auto iter = subAltNames->IPAddress->First(); iter->HasCurrent; iter->MoveNext())
+ {
+ altNames.push_back(make_pair(AltNAmeIP, IceUtil::wstringToString(iter->Current->Data())));
+ }
+ return altNames;
+}
+#endif
+
#endif
CertificateReadException::CertificateReadException(const char* file, int line, const string& r) :
@@ -700,21 +875,25 @@ ParseException::ice_throw() const
}
#ifdef ICE_USE_OPENSSL
-DistinguishedName::DistinguishedName(X509NAME* name) :
- _rdns(RFC2253::parseStrict(convertX509NameToString(name)))
+DistinguishedName::DistinguishedName(X509NAME* name) : _rdns(RFC2253::parseStrict(convertX509NameToString(name)))
{
unescape();
}
#endif
-DistinguishedName::DistinguishedName(const string& dn) :
- _rdns(RFC2253::parseStrict(dn))
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+DistinguishedName::DistinguishedName(CFDataRef data) : _rdns(ASN1Parser(data).parse())
{
unescape();
}
+#endif
-DistinguishedName::DistinguishedName(const list<pair<string, string> >& rdns) :
- _rdns(rdns)
+DistinguishedName::DistinguishedName(const string& dn) : _rdns(RFC2253::parseStrict(dn))
+{
+ unescape();
+}
+
+DistinguishedName::DistinguishedName(const list<pair<string, string> >& rdns) : _rdns(rdns)
{
unescape();
}
@@ -810,7 +989,7 @@ PublicKey::~PublicKey()
{
# if defined(ICE_USE_SECURE_TRANSPORT)
CFRelease(_key);
-# else
+# elif defined(ICE_USE_OPENSSL)
EVP_PKEY_free(_key);
# endif
}
@@ -827,9 +1006,6 @@ PublicKey::key() const
// The caller is responsible for incrementing the reference count.
//
Certificate::Certificate(X509CertificateRef cert) : _cert(cert)
-#ifdef ICE_USE_SCHANNEL
- , _certInfo(0)
-#endif
{
if(!_cert)
{
@@ -837,6 +1013,7 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert)
}
#ifdef ICE_USE_SCHANNEL
+ _certInfo = 0;
try
{
//
@@ -856,13 +1033,28 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert)
throw;
}
#endif
+
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ _subject = NULL;
+ _issuer = NULL;
+#endif
}
Certificate::~Certificate()
{
if(_cert)
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ if(_subject)
+ {
+ CFRelease(_subject);
+ }
+ if(_issuer)
+ {
+ CFRelease(_issuer);
+ }
+ CFRelease(_cert);
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
CFRelease(_cert);
#elif defined(ICE_USE_SCHANNEL)
LocalFree(_cert);
@@ -870,7 +1062,7 @@ Certificate::~Certificate()
{
LocalFree(_certInfo);
}
-#else
+#elif defined(ICE_USE_OPENSSL)
X509_free(_cert);
#endif
}
@@ -880,12 +1072,20 @@ CertificatePtr
Certificate::load(const string& file)
{
#if defined(ICE_USE_SECURE_TRANSPORT)
- return ICE_MAKE_SHARED(Certificate, loadCertificate(file));
+ string resolved;
+ if(checkPath(file, "", false, resolved))
+ {
+ return ICE_MAKE_SHARED(Certificate, loadCertificate(resolved));
+ }
+ else
+ {
+ throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file);
+ }
#elif defined(ICE_USE_SCHANNEL)
CERT_SIGNED_CONTENT_INFO* cert;
loadCertificate(&cert, file);
return ICE_MAKE_SHARED(Certificate, cert);
-#else
+#elif defined(ICE_USE_OPENSSL)
BIO *cert = BIO_new(BIO_s_file());
if(BIO_read_filename(cert, file.c_str()) <= 0)
{
@@ -901,16 +1101,45 @@ Certificate::load(const string& file)
}
BIO_free(cert);
return ICE_MAKE_SHARED(Certificate, x);
+#elif defined(ICE_OS_WINRT)
+ // TODO
+ return ICE_NULLPTR;
+#else
+# error "Unknown platform"
#endif
}
CertificatePtr
Certificate::decode(const string& encoding)
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ string::size_type size, startpos, endpos = 0;
+ startpos = encoding.find("-----BEGIN CERTIFICATE-----", endpos);
+ if(startpos != string::npos)
+ {
+ startpos += sizeof("-----BEGIN CERTIFICATE-----");
+ endpos = encoding.find("-----END CERTIFICATE-----", startpos);
+ size = endpos - startpos;
+ }
+ else
+ {
+ startpos = 0;
+ endpos = string::npos;
+ size = encoding.size();
+ }
+
+ vector<unsigned char> data(IceInternal::Base64::decode(string(&encoding[startpos], size)));
+ UniqueRef<CFDataRef> certdata(CFDataCreate(kCFAllocatorDefault, &data[0], data.size()));
+ SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get());
+ if(!cert)
+ {
+ assert(false);
+ throw CertificateEncodingException(__FILE__, __LINE__, "certificate is not a valid PEM-encoded certificate");
+ }
+ return ICE_MAKE_SHARED(Certificate, cert);
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(encoding.c_str()),
encoding.size(), kCFAllocatorNull);
-
SecExternalFormat format = kSecFormatUnknown;
SecExternalItemType type = kSecItemTypeCertificate;
@@ -929,14 +1158,13 @@ Certificate::decode(const string& encoding)
SecKeychainItemRef item = (SecKeychainItemRef)CFArrayGetValueAtIndex(items, 0);
CFRetain(item);
CFRelease(items);
-
assert(SecCertificateGetTypeID() == CFGetTypeID(item));
return ICE_MAKE_SHARED(Certificate, (SecCertificateRef)item);
#elif defined(ICE_USE_SCHANNEL)
CERT_SIGNED_CONTENT_INFO* cert;
loadCertificate(&cert, encoding.c_str(), static_cast<DWORD>(encoding.size()));
return ICE_MAKE_SHARED(Certificate, cert);
-#else
+#elif defined(ICE_USE_OPENSSL)
BIO *cert = BIO_new_mem_buf(static_cast<void*>(const_cast<char*>(&encoding[0])), static_cast<int>(encoding.size()));
X509CertificateRef x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
if(x == NULL)
@@ -946,6 +1174,11 @@ Certificate::decode(const string& encoding)
}
BIO_free(cert);
return ICE_MAKE_SHARED(Certificate, x);
+#elif defined(ICE_OS_WINRT)
+ // TODO
+ return ICE_NULLPTR;
+#else
+# error "Unknown platform"
#endif
}
@@ -956,27 +1189,27 @@ Certificate::operator==(const Certificate& other) const
return CFEqual(_cert, other._cert);
#elif defined(ICE_USE_SCHANNEL)
return CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, _certInfo, other._certInfo);
-#else
+#elif defined(ICE_USE_OPENSSL)
return X509_cmp(_cert, other._cert) == 0;
+#elif defined(ICE_OS_WINRT)
+ return _cert->Equals(other._cert);
+#else
+# error "Unknown platform"
#endif
}
bool
Certificate::operator!=(const Certificate& other) const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
- return !CFEqual(_cert, other._cert);
-#elif defined(ICE_USE_SCHANNEL)
- return !CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, _certInfo, other._certInfo);
-#else
- return X509_cmp(_cert, other._cert) != 0;
-#endif
+ return !operator==(other);
}
PublicKeyPtr
Certificate::getPublicKey() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ return ICE_NULLPTR; // Not supported
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
SecKeyRef key;
OSStatus err = SecCertificateCopyPublicKey(_cert, &key);
if(err)
@@ -986,8 +1219,12 @@ Certificate::getPublicKey() const
return ICE_MAKE_SHARED(PublicKey, shared_from_this(), key);
#elif defined(ICE_USE_SCHANNEL)
return ICE_MAKE_SHARED(PublicKey, shared_from_this(), &_certInfo->SubjectPublicKeyInfo);
-#else
+#elif defined(ICE_USE_OPENSSL)
return ICE_MAKE_SHARED(PublicKey, shared_from_this(), X509_get_pubkey(_cert));
+#elif defined(ICE_OS_WINRT)
+ return ICE_NULLPTR; // Not supported
+#else
+# error "Unknown platform"
#endif
}
@@ -996,17 +1233,20 @@ Certificate::verify(const CertificatePtr& cert) const
{
#if defined(ICE_USE_SECURE_TRANSPORT)
//
- // We first check if the given certificate subject match
- // our certificate issuer. Otherwhise when use SecTrustEvaluate
- // and check a certificate against itself will always return
- // that is valid.
+ // We first check if the given certificate subject match our certificate
+ // issuer. Otherwhise when checking a certificate against itself
+ // SecTrustEvaluate always returns it is valid.
//
bool valid = false;
- CFErrorRef error = 0;
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ initializeAttributes();
+ cert->initializeAttributes();
+ valid = CFEqual(_issuer, cert->_subject);
+#else
CFDataRef issuer = 0;
CFDataRef subject = 0;
-
+ CFErrorRef error = 0;
try
{
issuer = SecCertificateCopyNormalizedIssuerContent(_cert, &error);
@@ -1042,7 +1282,7 @@ Certificate::verify(const CertificatePtr& cert) const
CFRelease(issuer);
CFRelease(subject);
-
+#endif
if(valid)
{
SecPolicyRef policy = 0;
@@ -1107,8 +1347,12 @@ Certificate::verify(const CertificatePtr& cert) const
bool result = CryptVerifyCertificateSignature(0, X509_ASN_ENCODING, buffer, length, cert->getPublicKey()->key());
LocalFree(buffer);
return result;
-#else
+#elif defined(ICE_USE_OPENSSL)
return X509_verify(_cert, cert->getPublicKey()->key()) > 0;
+#elif defined(ICE_OS_WINRT)
+ return false;
+#else
+# error "Unknown platform"
#endif
}
@@ -1123,7 +1367,15 @@ Certificate::verify(const PublicKeyPtr& key) const
string
Certificate::encode() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ UniqueRef<CFDataRef> c(SecCertificateCopyData(_cert));
+ vector<unsigned char> data(CFDataGetBytePtr(c.get()), CFDataGetBytePtr(c.get()) + CFDataGetLength(c.get()));
+ ostringstream os;
+ os << "-----BEGIN CERTIFICATE-----\n";
+ os << IceInternal::Base64::encode(data);
+ os << "-----END CERTIFICATE-----\n";
+ return os.str();
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
CFDataRef exported;
OSStatus err = SecItemExport(_cert, kSecFormatPEMSequence, kSecItemPemArmour, 0, &exported);
if(err != noErr)
@@ -1170,7 +1422,7 @@ Certificate::encode() const
throw;
}
return s;
-#else
+#elif defined(ICE_USE_OPENSSL)
BIO* out = BIO_new(BIO_s_mem());
int i = PEM_write_bio_X509_AUX(out, _cert);
if(i <= 0)
@@ -1183,9 +1435,25 @@ Certificate::encode() const
string result = string(p->data, p->length);
BIO_free(out);
return result;
+#elif defined(ICE_OS_WINRT)
+ auto reader = Windows::Storage::Streams::DataReader::FromBuffer(_cert->GetCertificateBlob());
+ std::vector<unsigned char> data(reader->UnconsumedBufferLength);
+ if (!data.empty())
+ {
+ reader->ReadBytes(Platform::ArrayReference<unsigned char>(&data[0], data.size()));
+ }
+ ostringstream os;
+ os << "-----BEGIN CERTIFICATE-----\n";
+ os << IceInternal::Base64::encode(data);
+ os << "-----END CERTIFICATE-----\n";
+ return os.str();
+#else
+# error "Unknown platform"
#endif
}
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
+
bool
Certificate::checkValidity() const
{
@@ -1206,8 +1474,13 @@ Certificate::getNotAfter() const
return getX509Date(_cert, kSecOIDX509V1ValidityNotAfter);
#elif defined(ICE_USE_SCHANNEL)
return filetimeToTime(_certInfo->NotAfter);
-#else
+#elif defined(ICE_USE_OPENSSL)
return ASMUtcTimeToIceUtilTime(X509_get_notAfter(_cert));
+#elif defined(ICE_OS_WINRT)
+ // Convert 100ns time from January 1, 1601 to ms from January 1, 1970
+ return IceUtil::Time::milliSeconds(_cert->ValidTo.UniversalTime / TICKS_PER_MSECOND - MSECS_TO_EPOCH);
+#else
+# error "Unknown platform"
#endif
}
@@ -1218,15 +1491,25 @@ Certificate::getNotBefore() const
return getX509Date(_cert, kSecOIDX509V1ValidityNotBefore);
#elif defined(ICE_USE_SCHANNEL)
return filetimeToTime(_certInfo->NotBefore);
-#else
+#elif defined(ICE_USE_OPENSSL)
return ASMUtcTimeToIceUtilTime(X509_get_notBefore(_cert));
+#elif defined(ICE_OS_WINRT)
+ // Convert 100ns time from January 1, 1601 to ms from January 1, 1970
+ return IceUtil::Time::milliSeconds(_cert->ValidFrom.UniversalTime / TICKS_PER_MSECOND - MSECS_TO_EPOCH);
+#else
+# error "Unknown platform"
#endif
}
+#endif
+
string
Certificate::getSerialNumber() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ initializeAttributes();
+ return _serial;
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
return getX509String(_cert, kSecOIDX509V1SerialNumber);
#elif defined(ICE_USE_SCHANNEL)
ostringstream os;
@@ -1235,14 +1518,14 @@ Certificate::getSerialNumber() const
unsigned char c = _certInfo->SerialNumber.pbData[i];
os.fill('0');
os.width(2);
- os << hex << (int)c;
+ os << hex << static_cast<int>(c);
if(i)
{
os << ' ';
}
}
return IceUtilInternal::toUpper(os.str());
-#else
+#elif defined(ICE_USE_OPENSSL)
BIGNUM* bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(_cert), 0);
char* dec = BN_bn2dec(bn);
string result = dec;
@@ -1250,31 +1533,40 @@ Certificate::getSerialNumber() const
BN_free(bn);
return result;
+#elif defined(ICE_OS_WINRT)
+ ostringstream os;
+ os.fill(0);
+ os.width(2);
+ for (unsigned int i = 0; i < _cert->SerialNumber->Length; i++)
+ {
+ os << hex << static_cast<int>(_cert->SerialNumber[i]);
+ }
+ return IceUtilInternal::toUpper(os.str());
+#else
+# error "Unknown platform"
#endif
}
-//string
-//Certificate::getSigAlgName() const
-//{
-//}
-
-//string
-//Certificate::getSigAlgOID() const
-//{
-//}
-
DistinguishedName
Certificate::getIssuerDN() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ initializeAttributes();
+ return _issuer ? DistinguishedName(_issuer) : DistinguishedName("");
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
return getX509Name(_cert, kSecOIDX509V1IssuerName);
#elif defined(ICE_USE_SCHANNEL)
return DistinguishedName(certNameToString(&_certInfo->Issuer));
-#else
+#elif defined(ICE_USE_OPENSSL)
return DistinguishedName(RFC2253::parseStrict(convertX509NameToString(X509_get_issuer_name(_cert))));
+#elif defined(ICE_OS_WINRT)
+ return DistinguishedName(IceUtil::wstringToString(_cert->Issuer->Data()));
+#else
+# error "Unknown platform"
#endif
}
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
vector<pair<int, string> >
Certificate::getIssuerAlternativeNames()
{
@@ -1282,23 +1574,45 @@ Certificate::getIssuerAlternativeNames()
return getX509AltName(_cert, kSecOIDIssuerAltName);
#elif defined(ICE_USE_SCHANNEL)
return certificateAltNames(_certInfo, szOID_ISSUER_ALT_NAME2);
-#else
+#elif defined(ICE_USE_OPENSSL)
return convertGeneralNames(reinterpret_cast<GENERAL_NAMES*>(X509_get_ext_d2i(_cert, NID_issuer_alt_name, 0, 0)));
+#elif defined(ICE_OS_WINRT)
+ return vector<pair<int, string> >(); // Not supported
+#else
+# error "Unknown platform"
#endif
}
+#endif
DistinguishedName
Certificate::getSubjectDN() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ initializeAttributes();
+ if(_subject)
+ {
+ return DistinguishedName(_subject);
+ }
+ else
+ {
+ string s = "CN=";
+ s += fromCFString(UniqueRef<CFStringRef>(SecCertificateCopySubjectSummary(_cert)).get());
+ return DistinguishedName(s);
+ }
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
return getX509Name(_cert, kSecOIDX509V1SubjectName);
#elif defined(ICE_USE_SCHANNEL)
return DistinguishedName(certNameToString(&_certInfo->Subject));
-#else
+#elif defined(ICE_USE_OPENSSL)
return DistinguishedName(RFC2253::parseStrict(convertX509NameToString(X509_get_subject_name(_cert))));
+#elif defined(ICE_OS_WINRT)
+ return DistinguishedName(IceUtil::wstringToString(_cert->Subject->Data()));
+#else
+# error "Unknown platform"
#endif
}
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
vector<pair<int, string> >
Certificate::getSubjectAlternativeNames()
{
@@ -1306,20 +1620,32 @@ Certificate::getSubjectAlternativeNames()
return getX509AltName(_cert, kSecOIDSubjectAltName);
#elif defined(ICE_USE_SCHANNEL)
return certificateAltNames(_certInfo, szOID_SUBJECT_ALT_NAME2);
-#else
+#elif defined(ICE_USE_OPENSSL)
return convertGeneralNames(reinterpret_cast<GENERAL_NAMES*>(X509_get_ext_d2i(_cert, NID_subject_alt_name, 0, 0)));
+#elif defined(ICE_OS_WINRT)
+ return certificateAltNames(_cert->SubjectAlternativeName);
+#else
+# error "Unknown platform"
#endif
}
+#endif
int
Certificate::getVersion() const
{
-#if defined(ICE_USE_SECURE_TRANSPORT)
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ initializeAttributes();
+ return _version;
+#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS)
return atoi(getX509String(_cert, kSecOIDX509V1Version).c_str()) - 1;
#elif defined(ICE_USE_SCHANNEL)
return _certInfo->dwVersion;
-#else
+#elif defined(ICE_USE_OPENSSL)
return static_cast<int>(X509_get_version(_cert));
+#elif defined(ICE_OS_WINRT)
+ return -1; // Not supported
+#else
+# error "Unknown platform"
#endif
}
@@ -1330,8 +1656,10 @@ Certificate::toString() const
os << "serial: " << getSerialNumber() << "\n";
os << "issuer: " << string(getIssuerDN()) << "\n";
os << "subject: " << string(getSubjectDN()) << "\n";
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
os << "notBefore: " << getNotBefore().toDateTime() << "\n";
os << "notAfter: " << getNotAfter().toDateTime();
+#endif
return os.str();
}
@@ -1340,3 +1668,101 @@ Certificate::getCert() const
{
return _cert;
}
+
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+
+namespace
+{
+
+IceUtil::Mutex* globalMutex = 0;
+
+class Init
+{
+public:
+
+ Init()
+ {
+ globalMutex = new IceUtil::Mutex;
+ }
+
+ ~Init()
+ {
+ delete globalMutex;
+ globalMutex = 0;
+ }
+};
+
+Init init;
+
+}
+
+void
+Certificate::initializeAttributes() const
+{
+ if(_subject)
+ {
+ return;
+ }
+
+ //
+ // We need to temporarily add the certificate to the keychain in order to
+ // retrieve its attributes. Unfortunately kSecMatchItemList doesn't work
+ // on iOS. We make sure only one thread adds/removes a cert at a time here.
+ //
+ IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex);
+
+ CFMutableDictionaryRef query;
+
+ query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(query, kSecValueRef, _cert);
+ CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
+ CFDictionaryRef attributes;
+ OSStatus err;
+ if((err = SecItemAdd(query, (CFTypeRef*)&attributes)) == errSecDuplicateItem)
+ {
+ CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
+ err = SecItemCopyMatching(query, (CFTypeRef*)&attributes);
+ }
+ else
+ {
+ CFRelease(query);
+ query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
+ CFDictionarySetValue(query, kSecValueRef, _cert);
+ err = SecItemDelete(query);
+ }
+ CFRelease(query);
+ if(err != noErr)
+ {
+ _subject = 0;
+ _issuer = 0;
+ return;
+ }
+
+ _subject = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSubject);
+ _issuer = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrIssuer);
+ CFDataRef serial = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSerialNumber);
+ ostringstream os;
+ for(int i = 0; i < CFDataGetLength(serial); ++i)
+ {
+ int c = static_cast<int>(CFDataGetBytePtr(serial)[i]);
+ if(i)
+ {
+ os << ' ';
+ }
+ os.fill('0');
+ os.width(2);
+ os << hex << c;
+ }
+ _serial = os.str();
+ CFNumberRef version = (CFNumberRef)CFDictionaryGetValue(attributes, kSecAttrCertificateType);
+ if(!CFNumberGetValue(version, kCFNumberIntType, &_version))
+ {
+ _version = -1;
+ }
+ CFRetain(_subject);
+ CFRetain(_issuer);
+
+ CFRelease(attributes);
+}
+#endif \ No newline at end of file
diff --git a/cpp/src/IceSSL/ConnectorI.cpp b/cpp/src/IceSSL/ConnectorI.cpp
index 51a79e1929f..532847ec0ed 100644
--- a/cpp/src/IceSSL/ConnectorI.cpp
+++ b/cpp/src/IceSSL/ConnectorI.cpp
@@ -13,6 +13,7 @@
#include <IceSSL/OpenSSLTransceiverI.h>
#include <IceSSL/SecureTransportTransceiverI.h>
#include <IceSSL/SChannelTransceiverI.h>
+#include <IceSSL/WinRTTransceiverI.h>
#include <IceSSL/EndpointI.h>
#include <IceSSL/Util.h>
@@ -39,20 +40,19 @@ IceSSL::ConnectorI::connect()
throw ex;
}
- IceInternal::StreamSocketPtr stream = new IceInternal::StreamSocket(_instance, _proxy, _addr, _sourceAddr);
- return new TransceiverI(_instance, stream, _host, false);
+ return new TransceiverI(_instance, _delegate->connect(), _host, false);
}
Short
IceSSL::ConnectorI::type() const
{
- return _instance->type();
+ return _delegate->type();
}
string
IceSSL::ConnectorI::toString() const
{
- return IceInternal::addrToString(!_proxy ? _addr : _proxy->getAddress());
+ return _delegate->toString();
}
bool
@@ -64,22 +64,12 @@ IceSSL::ConnectorI::operator==(const IceInternal::Connector& r) const
return false;
}
- if(IceInternal::compareAddress(_addr, p->_addr) != 0)
+ if(this == p)
{
- return false;
- }
-
- if(_timeout != p->_timeout)
- {
- return false;
- }
-
- if(IceInternal::compareAddress(_sourceAddr, p->_sourceAddr) != 0)
- {
- return false;
+ return true;
}
- if(_connectionId != p->_connectionId)
+ if(_delegate != p->_delegate)
{
return false;
}
@@ -102,47 +92,25 @@ IceSSL::ConnectorI::operator<(const IceInternal::Connector& r) const
return type() < r.type();
}
- if(_timeout < p->_timeout)
- {
- return true;
- }
- else if(p->_timeout < _timeout)
- {
- return false;
- }
-
- int rc = compareAddress(_sourceAddr, p->_sourceAddr);
- if(rc < 0)
- {
- return true;
- }
- else if(rc > 0)
+ if(this == p)
{
return false;
}
- if(_connectionId < p->_connectionId)
+ if(_delegate < p->_delegate)
{
return true;
}
- else if(p->_connectionId < _connectionId)
+ else if(p->_delegate < _delegate)
{
return false;
}
- return IceInternal::compareAddress(_addr, p->_addr) == -1;
+ return false;
}
-IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const string& host, const IceInternal::Address& addr,
- const IceInternal::NetworkProxyPtr& proxy, const IceInternal::Address& sourceAddr,
- Ice::Int timeout, const string& connectionId) :
- _instance(instance),
- _host(host),
- _addr(addr),
- _proxy(proxy),
- _sourceAddr(sourceAddr),
- _timeout(timeout),
- _connectionId(connectionId)
+IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const IceInternal::ConnectorPtr& del, const string& h) :
+ _instance(instance), _delegate(del), _host(h)
{
}
diff --git a/cpp/src/IceSSL/ConnectorI.h b/cpp/src/IceSSL/ConnectorI.h
index 48a80fdebcc..e1434d97d1b 100644
--- a/cpp/src/IceSSL/ConnectorI.h
+++ b/cpp/src/IceSSL/ConnectorI.h
@@ -36,19 +36,13 @@ public:
private:
- ConnectorI(const InstancePtr&, const std::string&, const IceInternal::Address&,
- const IceInternal::NetworkProxyPtr&, const IceInternal::Address&,
- Ice::Int, const std::string&);
+ ConnectorI(const InstancePtr&, const IceInternal::ConnectorPtr&, const std::string&);
virtual ~ConnectorI();
friend class EndpointI;
const InstancePtr _instance;
+ const IceInternal::ConnectorPtr _delegate;
const std::string _host;
- const IceInternal::Address _addr;
- const IceInternal::NetworkProxyPtr _proxy;
- const IceInternal::Address _sourceAddr;
- const Ice::Int _timeout;
- const std::string _connectionId;
};
}
diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp
index 0038cf9717f..1615b12d05d 100644
--- a/cpp/src/IceSSL/EndpointI.cpp
+++ b/cpp/src/IceSSL/EndpointI.cpp
@@ -17,101 +17,135 @@
#include <Ice/DefaultsAndOverrides.h>
#include <Ice/Object.h>
#include <Ice/HashUtil.h>
+#include <Ice/Comparable.h>
using namespace std;
using namespace Ice;
using namespace IceSSL;
-#ifndef ICE_CPP11_MAPPING
-IceUtil::Shared* IceSSL::upCast(EndpointI* p) { return p; }
-#endif
+namespace
+{
-IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const string& ho, Int po,
- const IceInternal::Address& sourceAddr, Int ti, const string& conId, bool co) :
- IceInternal::IPEndpointI(instance, ho, po, sourceAddr, conId),
- _instance(instance),
- _timeout(ti),
- _compress(co)
+Ice::IPEndpointInfoPtr
+getIPEndpointInfo(const Ice::EndpointInfoPtr& info)
{
+ for(Ice::EndpointInfoPtr p = info; p; p = p->underlying)
+ {
+ Ice::IPEndpointInfoPtr ipInfo = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, p);
+ if(ipInfo)
+ {
+ return ipInfo;
+ }
+ }
+ return ICE_NULLPTR;
}
-IceSSL::EndpointI::EndpointI(const InstancePtr& instance) :
- IceInternal::IPEndpointI(instance),
- _instance(instance),
- _timeout(instance->defaultTimeout()),
- _compress(false)
+}
+
+#ifndef ICE_CPP11_MAPPING
+IceUtil::Shared* IceSSL::upCast(EndpointI* p) { return p; }
+#endif
+
+IceSSL::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del) :
+ _instance(instance), _delegate(del)
{
}
-IceSSL::EndpointI::EndpointI(const InstancePtr& instance, Ice::InputStream* s) :
- IPEndpointI(instance, s),
- _instance(instance),
- _timeout(-1),
- _compress(false)
+void
+IceSSL::EndpointI::streamWriteImpl(Ice::OutputStream* stream) const
{
- s->read(const_cast<Int&>(_timeout));
- s->read(const_cast<bool&>(_compress));
+ _delegate->streamWriteImpl(stream);
}
Ice::EndpointInfoPtr
IceSSL::EndpointI::getInfo() const
{
EndpointInfoPtr info = ICE_MAKE_SHARED(IceInternal::InfoI<EndpointInfo>, shared_from_this());
- fillEndpointInfo(info.get());
+ info->underlying = _delegate->getInfo();
+ info->compress = info->underlying->compress;
+ info->timeout = info->underlying->timeout;
return info;
}
-Ice::EndpointInfoPtr
-IceSSL::EndpointI::getWSInfo(const string& resource) const
+Ice::Short
+IceSSL::EndpointI::type() const
{
- WSSEndpointInfoPtr info = ICE_MAKE_SHARED(IceInternal::InfoI<WSSEndpointInfo>, shared_from_this());
- fillEndpointInfo(info.get());
- info->resource = resource;
- return info;
+ return _delegate->type();
+}
+
+const std::string&
+IceSSL::EndpointI::protocol() const
+{
+ return _delegate->protocol();
}
Int
IceSSL::EndpointI::timeout() const
{
- return _timeout;
+ return _delegate->timeout();
}
IceInternal::EndpointIPtr
IceSSL::EndpointI::timeout(Int timeout) const
{
- if(timeout == _timeout)
+ if(timeout == _delegate->timeout())
{
return shared_from_this();
}
else
{
- return ICE_MAKE_SHARED(EndpointI, _instance, _host, _port, _sourceAddr, timeout, _connectionId, _compress);
+ return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->timeout(timeout));
+ }
+}
+
+const string&
+IceSSL::EndpointI::connectionId() const
+{
+ return _delegate->connectionId();
+}
+
+IceInternal::EndpointIPtr
+IceSSL::EndpointI::connectionId(const string& connectionId) const
+{
+ if(connectionId == _delegate->connectionId())
+ {
+ return shared_from_this();
+ }
+ else
+ {
+ return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->connectionId(connectionId));
}
}
bool
IceSSL::EndpointI::compress() const
{
- return _compress;
+ return _delegate->compress();
}
IceInternal::EndpointIPtr
IceSSL::EndpointI::compress(bool compress) const
{
- if(compress == _compress)
+ if(compress == _delegate->compress())
{
return shared_from_this();
}
else
{
- return ICE_MAKE_SHARED(EndpointI, _instance, _host, _port, _sourceAddr, _timeout, _connectionId, compress);
+ return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->compress(compress));
}
}
bool
IceSSL::EndpointI::datagram() const
{
- return false;
+ return _delegate->datagram();
+}
+
+bool
+IceSSL::EndpointI::secure() const
+{
+ return _delegate->secure();
}
IceInternal::TransceiverPtr
@@ -120,46 +154,90 @@ IceSSL::EndpointI::transceiver() const
return 0;
}
+void
+IceSSL::EndpointI::connectors_async(Ice::EndpointSelectionType selType,
+ const IceInternal::EndpointI_connectorsPtr& callback) const
+{
+ class CallbackI : public IceInternal::EndpointI_connectors
+ {
+ public:
+
+ CallbackI(const IceInternal::EndpointI_connectorsPtr& callback, const InstancePtr& instance,
+ const string& host) :
+ _callback(callback), _instance(instance), _host(host)
+ {
+ }
+
+ virtual void connectors(const vector<IceInternal::ConnectorPtr>& c)
+ {
+ vector<IceInternal::ConnectorPtr> connectors = c;
+ for(vector<IceInternal::ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p)
+ {
+ *p = new ConnectorI(_instance, *p, _host);
+ }
+ _callback->connectors(connectors);
+ }
+
+ virtual void exception(const Ice::LocalException& ex)
+ {
+ _callback->exception(ex);
+ }
+
+ private:
+
+ const IceInternal::EndpointI_connectorsPtr _callback;
+ const InstancePtr _instance;
+ const string _host;
+ };
+
+ IPEndpointInfoPtr info = getIPEndpointInfo(_delegate->getInfo());
+ _delegate->connectors_async(selType, ICE_MAKE_SHARED(CallbackI, callback, _instance, info ? info->host : string()));
+}
+
IceInternal::AcceptorPtr
IceSSL::EndpointI::acceptor(const string& adapterName) const
{
- return new AcceptorI(ICE_DYNAMIC_CAST(IceSSL::EndpointI, shared_from_this()), _instance, adapterName, _host, _port);
+ return new AcceptorI(shared_from_this(), _instance, _delegate->acceptor(adapterName), adapterName);
}
EndpointIPtr
-IceSSL::EndpointI::endpoint(const AcceptorIPtr& acceptor) const
+IceSSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const
{
- return ICE_MAKE_SHARED(EndpointI, _instance, _host, acceptor->effectivePort(), _sourceAddr, _timeout, _connectionId, _compress);
+ return ICE_MAKE_SHARED(EndpointI, _instance, delEndp);
}
-string
-IceSSL::EndpointI::options() const
+vector<IceInternal::EndpointIPtr>
+IceSSL::EndpointI::expand() const
{
- //
- // WARNING: Certain features, such as proxy validation in Glacier2,
- // depend on the format of proxy strings. Changes to toString() and
- // methods called to generate parts of the reference string could break
- // these features. Please review for all features that depend on the
- // format of proxyToString() before changing this and related code.
- //
- ostringstream s;
- s << IPEndpointI::options();
-
- if(_timeout == -1)
+ vector<IceInternal::EndpointIPtr> endps = _delegate->expand();
+ for(vector<IceInternal::EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p)
{
- s << " -t infinite";
- }
- else
- {
- s << " -t " << _timeout;
+ *p = p->get() == _delegate.get() ? shared_from_this() : ICE_MAKE_SHARED(EndpointI, _instance, *p);
}
+ return endps;
+}
- if(_compress)
+bool
+IceSSL::EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const
+{
+ const EndpointI* endpointI = dynamic_cast<const EndpointI*>(endpoint.get());
+ if(!endpointI)
{
- s << " -z";
+ return false;
}
+ return _delegate->equivalent(endpointI->_delegate);
+}
+
+Ice::Int
+IceSSL::EndpointI::hash() const
+{
+ return _delegate->hash();
+}
- return s.str();
+string
+IceSSL::EndpointI::options() const
+{
+ return _delegate->options();
}
bool
@@ -169,11 +247,6 @@ IceSSL::EndpointI::operator==(const Ice::Endpoint& r) const
IceSSL::EndpointI::operator==(const Ice::LocalObject& r) const
#endif
{
- if(!IPEndpointI::operator==(r))
- {
- return false;
- }
-
const EndpointI* p = dynamic_cast<const EndpointI*>(&r);
if(!p)
{
@@ -185,12 +258,7 @@ IceSSL::EndpointI::operator==(const Ice::LocalObject& r) const
return true;
}
- if(_timeout != p->_timeout)
- {
- return false;
- }
-
- if(_compress != p->_compress)
+ if(!Ice::targetEquals(_delegate, p->_delegate))
{
return false;
}
@@ -221,119 +289,27 @@ IceSSL::EndpointI::operator<(const Ice::LocalObject& r) const
return false;
}
- if(_timeout < p->_timeout)
- {
- return true;
- }
- else if(p->_timeout < _timeout)
- {
- return false;
- }
-
- if(!_compress && p->_compress)
+ if(Ice::targetLess(_delegate, p->_delegate))
{
return true;
}
- else if(p->_compress < _compress)
+ else if (Ice::targetLess(p->_delegate, _delegate))
{
return false;
}
- return IPEndpointI::operator<(r);
-}
-
-void
-IceSSL::EndpointI::streamWriteImpl(Ice::OutputStream* s) const
-{
- IPEndpointI::streamWriteImpl(s);
- s->write(_timeout);
- s->write(_compress);
-}
-
-void
-IceSSL::EndpointI::hashInit(Ice::Int& h) const
-{
- IPEndpointI::hashInit(h);
- IceInternal::hashAdd(h, _timeout);
- IceInternal::hashAdd(h, _compress);
-}
-
-void
-IceSSL::EndpointI::fillEndpointInfo(IPEndpointInfo* info) const
-{
- IPEndpointI::fillEndpointInfo(info);
- info->timeout = _timeout;
- info->compress = _compress;
+ return false;
}
bool
IceSSL::EndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
{
- if(IPEndpointI::checkOption(option, argument, endpoint))
- {
- return true;
- }
-
- switch(option[1])
- {
- case 't':
- {
- if(argument.empty())
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "no argument provided for -t option in endpoint " + endpoint;
- throw ex;
- }
-
- if(argument == "infinite")
- {
- const_cast<Int&>(_timeout) = -1;
- }
- else
- {
- istringstream t(argument);
- if(!(t >> const_cast<Int&>(_timeout)) || !t.eof() || _timeout < 1)
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint;
- throw ex;
- }
- }
- return true;
- }
-
- case 'z':
- {
- if(!argument.empty())
- {
- EndpointParseException ex(__FILE__, __LINE__);
- ex.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint;
- throw ex;
- }
- const_cast<bool&>(_compress) = true;
- return true;
- }
-
- default:
- {
- return false;
- }
- }
-}
-
-IceInternal::ConnectorPtr
-IceSSL::EndpointI::createConnector(const IceInternal::Address& address, const IceInternal::NetworkProxyPtr& proxy) const
-{
- return new ConnectorI(_instance, _host, address, proxy, _sourceAddr, _timeout, _connectionId);
-}
-
-IceInternal::IPEndpointIPtr
-IceSSL::EndpointI::createEndpoint(const string& host, int port, const string& connectionId) const
-{
- return ICE_MAKE_SHARED(EndpointI, _instance, host, port, _sourceAddr, _timeout, connectionId, _compress);
+ return false;
}
-IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance) : _instance(instance)
+IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance,
+ const IceInternal::EndpointFactoryPtr& delegate) :
+ _instance(instance), _delegate(delegate)
{
}
@@ -356,25 +332,26 @@ IceSSL::EndpointFactoryI::protocol() const
IceInternal::EndpointIPtr
IceSSL::EndpointFactoryI::create(vector<string>& args, bool oaEndpoint) const
{
- IceInternal::IPEndpointIPtr endpt = ICE_MAKE_SHARED(EndpointI, _instance);
- endpt->initWithOptions(args, oaEndpoint);
- return endpt;
+ return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->create(args, oaEndpoint));
}
IceInternal::EndpointIPtr
IceSSL::EndpointFactoryI::read(Ice::InputStream* s) const
{
- return ICE_MAKE_SHARED(EndpointI, _instance, s);
+ return ICE_MAKE_SHARED(EndpointI, _instance, _delegate->read(s));
}
void
IceSSL::EndpointFactoryI::destroy()
{
+ _delegate->destroy();
_instance = 0;
}
IceInternal::EndpointFactoryPtr
-IceSSL::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& instance) const
+IceSSL::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr& inst,
+ const IceInternal::EndpointFactoryPtr& delegate) const
{
- return new EndpointFactoryI(new Instance(_instance->engine(), instance->type(), instance->protocol()));
+ InstancePtr instance = new Instance(_instance->engine(), inst->type(), inst->protocol());
+ return new EndpointFactoryI(instance, delegate ? delegate : _delegate->clone(instance, 0));
}
diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h
index 0aec468f9c7..fd122d7b146 100644
--- a/cpp/src/IceSSL/EndpointI.h
+++ b/cpp/src/IceSSL/EndpointI.h
@@ -13,7 +13,6 @@
#include <Ice/EndpointI.h>
#include <Ice/IPEndpointI.h>
#include <Ice/EndpointFactory.h>
-#include <Ice/WSEndpoint.h>
#include <IceSSL/InstanceF.h>
#include <IceSSL/EndpointInfo.h>
#include <Ice/Network.h>
@@ -21,28 +20,38 @@
namespace IceSSL
{
-class EndpointI : public IceInternal::IPEndpointI, public IceInternal::WSEndpointDelegate
+class EndpointI : public IceInternal::EndpointI, public Ice::EnableSharedFromThis<EndpointI>
{
public:
- EndpointI(const InstancePtr&, const std::string&, Ice::Int, const IceInternal::Address&, Ice::Int,
- const std::string&, bool);
- EndpointI(const InstancePtr&);
- EndpointI(const InstancePtr&, Ice::InputStream*);
+ EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&);
+
+ virtual void streamWriteImpl(Ice::OutputStream*) const;
virtual Ice::EndpointInfoPtr getInfo() const;
- virtual Ice::EndpointInfoPtr getWSInfo(const std::string&) const;
+ virtual Ice::Short type() const;
+ virtual const std::string& protocol() const;
virtual Ice::Int timeout() const;
virtual IceInternal::EndpointIPtr timeout(Ice::Int) const;
+ virtual const std::string& connectionId() const;
+ virtual IceInternal::EndpointIPtr connectionId(const ::std::string&) const;
virtual bool compress() const;
virtual IceInternal::EndpointIPtr compress(bool) const;
virtual bool datagram() const;
+ virtual bool secure() const;
virtual IceInternal::TransceiverPtr transceiver() const;
+ virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const;
virtual IceInternal::AcceptorPtr acceptor(const std::string&) const;
+
+ virtual std::vector<IceInternal::EndpointIPtr> expand() const;
+ virtual bool equivalent(const IceInternal::EndpointIPtr&) const;
+ virtual ::Ice::Int hash() const;
virtual std::string options() const;
+ EndpointIPtr endpoint(const IceInternal::EndpointIPtr&) const;
+
#ifdef ICE_CPP11_MAPPING
virtual bool operator==(const Ice::Endpoint&) const;
virtual bool operator<(const Ice::Endpoint&) const;
@@ -51,29 +60,17 @@ public:
virtual bool operator<(const Ice::LocalObject&) const;
#endif
- virtual EndpointIPtr endpoint(const AcceptorIPtr&) const;
-
- using IceInternal::IPEndpointI::connectionId;
-
protected:
- virtual void streamWriteImpl(Ice::OutputStream*) const;
- virtual void hashInit(Ice::Int&) const;
- virtual void fillEndpointInfo(Ice::IPEndpointInfo*) const;
virtual bool checkOption(const std::string&, const std::string&, const std::string&);
- virtual IceInternal::ConnectorPtr createConnector(const IceInternal::Address&,
- const IceInternal::NetworkProxyPtr&) const;
- virtual IceInternal::IPEndpointIPtr createEndpoint(const std::string&, int, const std::string&) const;
-
private:
//
// All members are const, because endpoints are immutable.
//
const InstancePtr _instance;
- const Ice::Int _timeout;
- const bool _compress;
+ const IceInternal::EndpointIPtr _delegate;
};
class EndpointFactoryI : public IceInternal::EndpointFactory
@@ -88,14 +85,16 @@ public:
virtual IceInternal::EndpointIPtr read(Ice::InputStream*) const;
virtual void destroy();
- virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const;
+ virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&,
+ const IceInternal::EndpointFactoryPtr&) const;
private:
- EndpointFactoryI(const InstancePtr&);
+ EndpointFactoryI(const InstancePtr&, const IceInternal::EndpointFactoryPtr&);
friend class PluginI;
InstancePtr _instance;
+ const IceInternal::EndpointFactoryPtr _delegate;
};
}
diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp
index b7f9ce3fdf4..e37ab14a967 100644
--- a/cpp/src/IceSSL/Instance.cpp
+++ b/cpp/src/IceSSL/Instance.cpp
@@ -7,13 +7,8 @@
//
// **********************************************************************
-#include <IceUtil/Config.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#endif
#include <IceSSL/Instance.h>
#include <IceSSL/SSLEngine.h>
-#include <Ice/Properties.h>
using namespace std;
using namespace Ice;
diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h
index 6a4514de52b..d9a25482eb0 100644
--- a/cpp/src/IceSSL/Instance.h
+++ b/cpp/src/IceSSL/Instance.h
@@ -10,8 +10,8 @@
#ifndef ICE_SSL_INSTANCE_H
#define ICE_SSL_INSTANCE_H
-#include <IceSSL/InstanceF.h>
#include <Ice/ProtocolInstance.h>
+#include <IceSSL/InstanceF.h>
#include <IceSSL/SSLEngineF.h>
namespace IceSSL
@@ -24,12 +24,12 @@ public:
Instance(const SSLEnginePtr&, Ice::Short, const std::string&);
virtual ~Instance();
- SSLEnginePtr
+ SSLEnginePtr
engine() const
{
return _engine;
}
-
+
bool initialized() const;
private:
diff --git a/cpp/src/IceSSL/Makefile.mk b/cpp/src/IceSSL/Makefile.mk
index 3a6988f4879..0e2e3d00e94 100644
--- a/cpp/src/IceSSL/Makefile.mk
+++ b/cpp/src/IceSSL/Makefile.mk
@@ -11,10 +11,7 @@ $(project)_libraries := IceSSL
IceSSL_targetdir := $(libdir)
IceSSL_dependencies := Ice
-IceSSL_cppflags := -DICESSL_API_EXPORTS
-IceSSL_sliceflags := --include-dir IceSSL --dll-export ICESSL_API
-
-IceSSL[iphoneos]_excludes := $(wildcard $(addprefix $(currentdir)/,*.cpp))
-IceSSL[iphonesimulator]_excludes = $(IceSSL[iphoneos]_excludes)
+IceSSL_cppflags := -DICE_SSL_API_EXPORTS
+IceSSL_sliceflags := --include-dir IceSSL --dll-export ICE_SSL_API
projects += $(project)
diff --git a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp
index 2178c292ea0..de7fbb3ade6 100644
--- a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp
+++ b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp
@@ -79,16 +79,20 @@ IceSSL_opensslVerifyCallback(int ok, X509_STORE_CTX* ctx)
IceInternal::NativeInfoPtr
IceSSL::TransceiverI::getNativeInfo()
{
- return _stream;
+ return _delegate->getNativeInfo();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer)
{
- IceInternal::SocketOperation status = _stream->connect(readBuffer, writeBuffer);
- if(status != IceInternal::SocketOperationNone)
+ if(!_connected)
{
- return status;
+ IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer);
+ if(status != IceInternal::SocketOperationNone)
+ {
+ return status;
+ }
+ _connected = true;
}
if(!_ssl)
@@ -96,7 +100,9 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
//
// This static_cast is necessary due to 64bit windows. There SOCKET is a non-int type.
//
- BIO* bio = BIO_new_socket(static_cast<int>(_stream->fd()), 0);
+ SOCKET fd = _delegate->getNativeInfo()->fd();
+ assert(fd != INVALID_SOCKET); // Underlying transport must be SOCKET based.
+ BIO* bio = BIO_new_socket(static_cast<int>(fd), 0);
if(!bio)
{
SecurityException ex(__FILE__, __LINE__);
@@ -231,15 +237,9 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
}
case SSL_ERROR_SSL:
{
- IceInternal::Address remoteAddr;
- string desc = "<not available>";
- if(IceInternal::fdToRemoteAddress(_stream->fd(), remoteAddr))
- {
- desc = IceInternal::addrToString(remoteAddr);
- }
ostringstream ostr;
ostr << "SSL error occurred for new " << (_incoming ? "incoming" : "outgoing")
- << " connection:\nremote address = " << desc << "\n" << _engine->sslErrors();
+ << " connection:\nremote address = " << _delegate->toString() << "\n" << _engine->sslErrors();
ProtocolException ex(__FILE__, __LINE__);
ex.reason = ostr.str();
throw ex;
@@ -278,12 +278,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
{
_verified = true;
}
-
-#ifdef ICE_CPP11_MAPPING
- _engine->verifyPeer(_stream->fd(), _host, dynamic_pointer_cast<NativeConnectionInfo>(getInfo()));
-#else
- _engine->verifyPeer(_stream->fd(), _host, NativeConnectionInfoPtr::dynamicCast(getInfo()));
-#endif
+ _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString());
if(_engine->securityTraceLevel() >= 1)
{
@@ -342,15 +337,15 @@ IceSSL::TransceiverI::close()
_ssl = 0;
}
- _stream->close();
+ _delegate->close();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->write(buf);
+ return _delegate->write(buf);
}
if(buf.i == buf.b.end())
@@ -450,9 +445,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
IceInternal::SocketOperation
IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->read(buf);
+ return _delegate->read(buf);
}
//
@@ -466,7 +461,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
return IceInternal::SocketOperationNone;
}
- _stream->ready(IceInternal::SocketOperationRead, false);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
//
// It's impossible for packetSize to be more than an Int.
@@ -560,7 +555,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
//
// Check if there's still buffered data to read, set the read ready status.
//
- _stream->ready(IceInternal::SocketOperationRead, SSL_pending(_ssl) > 0);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, SSL_pending(_ssl) > 0);
return IceInternal::SocketOperationNone;
}
@@ -574,7 +569,7 @@ IceSSL::TransceiverI::protocol() const
string
IceSSL::TransceiverI::toString() const
{
- return _stream->toString();
+ return _delegate->toString();
}
string
@@ -587,16 +582,19 @@ Ice::ConnectionInfoPtr
IceSSL::TransceiverI::getInfo() const
{
NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- return info;
-}
-
-Ice::ConnectionInfoPtr
-IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const
-{
- WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- info->headers = headers;
+ info->underlying = _delegate->getInfo();
+ info->incoming = _incoming;
+ info->adapterName = _adapterName;
+ info->verified = _verified;
+ info->nativeCerts = _nativeCerts;
+ for(vector<CertificatePtr>::const_iterator p = _nativeCerts.begin(); p != _nativeCerts.end(); ++p)
+ {
+ info->certs.push_back((*p)->encode());
+ }
+ if(_ssl != 0)
+ {
+ info->cipher = SSL_get_cipher_name(_ssl); // Nothing needs to be free'd.
+ }
return info;
}
@@ -608,7 +606,7 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
void
IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
{
- _stream->setBufferSize(rcvSize, sndSize);
+ _delegate->setBufferSize(rcvSize, sndSize);
}
int
@@ -656,14 +654,15 @@ IceSSL::TransceiverI::verifyCallback(int ok, X509_STORE_CTX* c)
return 1;
}
-IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, const IceInternal::StreamSocketPtr& stream,
+IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, const IceInternal::TransceiverPtr& delegate,
const string& hostOrAdapterName, bool incoming) :
_instance(instance),
_engine(OpenSSLEnginePtr::dynamicCast(instance->engine())),
_host(incoming ? "" : hostOrAdapterName),
_adapterName(incoming ? hostOrAdapterName : ""),
_incoming(incoming),
- _stream(stream),
+ _delegate(delegate),
+ _connected(false),
_verified(false),
_ssl(0)
{
@@ -673,30 +672,4 @@ IceSSL::TransceiverI::~TransceiverI()
{
}
-void
-IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, std::vector<CertificatePtr>& nativeCerts) const
-{
- IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress,
- info->remotePort);
- if(_stream->fd() != INVALID_SOCKET)
- {
- info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd());
- info->sndSize = IceInternal::getSendBufferSize(_stream->fd());
- }
- info->adapterName = _adapterName;
- info->incoming = _incoming;
- info->verified = _verified;
- nativeCerts = _nativeCerts;
- for(vector<CertificatePtr>::const_iterator p = _nativeCerts.begin(); p != _nativeCerts.end(); ++p)
- {
- info->certs.push_back((*p)->encode());
- }
- if(_ssl != 0)
- {
- info->cipher = SSL_get_cipher_name(_ssl); // Nothing needs to be free'd.
- }
- info->adapterName = _adapterName;
- info->incoming = _incoming;
-}
-
#endif
diff --git a/cpp/src/IceSSL/OpenSSLTransceiverI.h b/cpp/src/IceSSL/OpenSSLTransceiverI.h
index 8451db86b69..58459e804b9 100644
--- a/cpp/src/IceSSL/OpenSSLTransceiverI.h
+++ b/cpp/src/IceSSL/OpenSSLTransceiverI.h
@@ -32,7 +32,7 @@ namespace IceSSL
class ConnectorI;
class AcceptorI;
-class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate
+class TransceiverI : public IceInternal::Transceiver
{
public:
@@ -51,7 +51,6 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
virtual void checkSendSize(const IceInternal::Buffer&);
virtual void setBufferSize(int rcvSize, int sndSize);
@@ -59,11 +58,9 @@ public:
private:
- TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool);
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool);
virtual ~TransceiverI();
- void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const;
-
friend class ConnectorI;
friend class AcceptorI;
@@ -72,7 +69,8 @@ private:
const std::string _host;
const std::string _adapterName;
const bool _incoming;
- const IceInternal::StreamSocketPtr _stream;
+ const IceInternal::TransceiverPtr _delegate;
+ bool _connected;
bool _verified;
std::vector<CertificatePtr> _nativeCerts;
diff --git a/cpp/src/IceSSL/PluginI.cpp b/cpp/src/IceSSL/PluginI.cpp
index 7e9fb283783..cd6bbab1f53 100644..100755
--- a/cpp/src/IceSSL/PluginI.cpp
+++ b/cpp/src/IceSSL/PluginI.cpp
@@ -15,6 +15,7 @@
#include <Ice/ProtocolPluginFacade.h>
#include <Ice/ProtocolInstance.h>
#include <Ice/LocalException.h>
+#include <Ice/RegisterPlugins.h>
using namespace std;
using namespace Ice;
@@ -23,17 +24,12 @@ using namespace IceSSL;
//
// Plug-in factory function.
//
-extern "C"
-{
-
-ICE_SSL_API Ice::Plugin*
+extern "C" ICE_SSL_API Ice::Plugin*
createIceSSL(const CommunicatorPtr& communicator, const string& /*name*/, const StringSeq& /*args*/)
{
return new PluginI(communicator);
}
-}
-
namespace Ice
{
@@ -46,6 +42,15 @@ registerIceSSL(bool loadOnInitialize)
}
//
+// Objective-C function to allow Objective-C programs to register plugin.
+//
+extern "C" ICE_SSL_API void
+ICEregisterIceSSL(bool loadOnInitialize)
+{
+ Ice::registerIceSSL(loadOnInitialize);
+}
+
+//
// Plugin implementation.
//
IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com)
@@ -54,6 +59,8 @@ IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com)
_engine = new SecureTransportEngine(com);
#elif defined(ICE_USE_SCHANNEL)
_engine = new SChannelEngine(com);
+#elif defined(ICE_OS_WINRT)
+ _engine = new WinRTEngine(com);
#else
_engine = new OpenSSLEngine(com);
#endif
@@ -63,8 +70,31 @@ IceSSL::PluginI::PluginI(const Ice::CommunicatorPtr& com)
// than in initialize, because the communicator may need to
// interpret proxies before the plug-in is fully initialized.
//
- IceInternal::EndpointFactoryPtr sslFactory = new EndpointFactoryI(new Instance(_engine, EndpointType, "ssl"));
- IceInternal::getProtocolPluginFacade(com)->addEndpointFactory(sslFactory);
+ IceInternal::ProtocolPluginFacadePtr pluginFacade = IceInternal::getProtocolPluginFacade(com);
+
+ // SSL based on TCP
+ IceInternal::EndpointFactoryPtr tcp = pluginFacade->getEndpointFactory(TCPEndpointType);
+ if(tcp)
+ {
+ InstancePtr instance = new Instance(_engine, SSLEndpointType, "ssl");
+ pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, tcp->clone(instance, 0)));
+ }
+
+ // SSL based on Bluetooth
+ IceInternal::EndpointFactoryPtr bluetooth = pluginFacade->getEndpointFactory(BTEndpointType);
+ if(bluetooth)
+ {
+ InstancePtr instance = new Instance(_engine, BTSEndpointType, "bts");
+ pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, bluetooth->clone(instance, 0)));
+ }
+
+ // SSL based on iAP
+ IceInternal::EndpointFactoryPtr iap = pluginFacade->getEndpointFactory(iAPEndpointType);
+ if(iap)
+ {
+ InstancePtr instance = new Instance(_engine, iAPSEndpointType, "iaps");
+ pluginFacade->addEndpointFactory(new EndpointFactoryI(instance, iap->clone(instance, 0)));
+ }
}
void
diff --git a/cpp/src/IceSSL/PluginI.h b/cpp/src/IceSSL/PluginI.h
index e0c5a48120b..ea0cf344ab4 100644
--- a/cpp/src/IceSSL/PluginI.h
+++ b/cpp/src/IceSSL/PluginI.h
@@ -46,6 +46,8 @@ private:
SecureTransportEnginePtr _engine;
#elif defined(ICE_USE_SCHANNEL)
SChannelEnginePtr _engine;
+#elif defined(ICE_OS_WINRT)
+ WinRTEnginePtr _engine;
#else
OpenSSLEnginePtr _engine;
#endif
diff --git a/cpp/src/IceSSL/RFC2253.cpp b/cpp/src/IceSSL/RFC2253.cpp
index 7b46682f3c2..e4c57add13a 100644
--- a/cpp/src/IceSSL/RFC2253.cpp
+++ b/cpp/src/IceSSL/RFC2253.cpp
@@ -271,7 +271,7 @@ parseAttributeType(const string& data, size_t& pos)
//
// Here we must also check for "oid." and "OID." before parsing
// according to the ALPHA KEYCHAR* rule.
- //
+ //
// First the OID case.
//
if(IceUtilInternal::isDigit(data[pos]) ||
@@ -318,7 +318,7 @@ parseAttributeType(const string& data, size_t& pos)
result += data[pos];
++pos;
// 1* KEYCHAR
- while(pos < data.size() &&
+ while(pos < data.size() &&
(IceUtilInternal::isAlpha(data[pos]) || IceUtilInternal::isDigit(data[pos]) || data[pos] == '-'))
{
result += data[pos];
@@ -448,7 +448,7 @@ parsePair(const string& data, size_t& pos)
}
return parseHexPair(data, pos, false);
}
-
+
//
// RFC 2253
// hexpair = hexchar hexchar
diff --git a/cpp/src/IceSSL/SChannelTransceiverI.cpp b/cpp/src/IceSSL/SChannelTransceiverI.cpp
index b5eca20d632..d7555d545a9 100644
--- a/cpp/src/IceSSL/SChannelTransceiverI.cpp
+++ b/cpp/src/IceSSL/SChannelTransceiverI.cpp
@@ -208,7 +208,7 @@ getSecBufferWithType(const SecBufferDesc& desc, ULONG bufferType)
IceInternal::NativeInfoPtr
IceSSL::TransceiverI::getNativeInfo()
{
- return _stream;
+ return _delegate->getNativeInfo();
}
IceInternal::SocketOperation
@@ -624,13 +624,17 @@ IceSSL::TransceiverI::encryptMessage(IceInternal::Buffer& buffer)
IceInternal::SocketOperation
IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer)
{
- IceInternal::SocketOperation op = _stream->connect(readBuffer, writeBuffer);
- if(op != IceInternal::SocketOperationNone)
+ if(_state == StateNotInitialized)
{
- return op;
+ IceInternal::SocketOperation op = _delegate->initialize(readBuffer, writeBuffer);
+ if(op != IceInternal::SocketOperationNone)
+ {
+ return op;
+ }
+ _state = StateHandshakeNotStarted;
}
- op = sslHandshake();
+ IceInternal::SocketOperation op = sslHandshake();
if(op != IceInternal::SocketOperationNone)
{
return op;
@@ -715,7 +719,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
}
}
- _engine->verifyPeer(_stream->fd(), _host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()));
+ _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString());
_state = StateHandshakeComplete;
if(_instance->engine()->securityTraceLevel() >= 1)
@@ -746,8 +750,8 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
}
out << toString();
}
- _stream->ready(IceInternal::SocketOperationRead,
- !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead,
+ !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
return IceInternal::SocketOperationNone;
}
@@ -778,7 +782,7 @@ IceSSL::TransceiverI::close()
_credentialsInitialized = false;
}
- _stream->close();
+ _delegate->close();
//
// Clear the buffers now instead of waiting for destruction.
@@ -791,9 +795,9 @@ IceSSL::TransceiverI::close()
IceInternal::SocketOperation
IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- return _stream->write(buf);
+ return _delegate->write(buf);
}
if(buf.i == buf.b.end())
@@ -826,9 +830,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
IceInternal::SocketOperation
IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- return _stream->read(buf);
+ return _delegate->read(buf);
}
if(buf.i == buf.b.end())
@@ -837,7 +841,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
}
assert(_state == StateHandshakeComplete);
- _stream->ready(IceInternal::SocketOperationRead, false);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
while(buf.i != buf.b.end())
{
if(_readUnprocessed.b.empty() && _readBuffer.i == _readBuffer.b.begin() && !readRaw(_readBuffer))
@@ -857,8 +861,8 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
buf.i += decrypted;
}
- _stream->ready(IceInternal::SocketOperationRead,
- !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead,
+ !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
return IceInternal::SocketOperationNone;
}
@@ -867,9 +871,9 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
bool
IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buffer)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- return _stream->startWrite(buffer);
+ return _delegate->startWrite(buffer);
}
if(_state == StateHandshakeComplete && _bufferedW == 0)
@@ -878,19 +882,19 @@ IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buffer)
_bufferedW = encryptMessage(buffer);
}
- return _stream->startWrite(_writeBuffer);
+ return _delegate->startWrite(_writeBuffer) && _bufferedW == (buffer.b.end() - buffer.i);
}
void
IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- _stream->finishWrite(buf);
+ _delegate->finishWrite(buf);
return;
}
- _stream->finishWrite(_writeBuffer);
+ _delegate->finishWrite(_writeBuffer);
if(_writeBuffer.i != _writeBuffer.b.end())
{
return; // We're not finished yet with writing the write buffer.
@@ -906,36 +910,36 @@ IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf)
void
IceSSL::TransceiverI::startRead(IceInternal::Buffer& buffer)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- _stream->startRead(buffer);
+ _delegate->startRead(buffer);
return;
}
- _stream->startRead(_readBuffer);
+ _delegate->startRead(_readBuffer);
}
void
IceSSL::TransceiverI::finishRead(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(_state == StateNotInitialized)
{
- _stream->finishRead(buf);
+ _delegate->finishRead(buf);
return;
}
- _stream->finishRead(_readBuffer);
+ _delegate->finishRead(_readBuffer);
if(_state == StateHandshakeComplete)
{
size_t decrypted = decryptMessage(buf);
if(decrypted > 0)
{
buf.i += decrypted;
- _stream->ready(IceInternal::SocketOperationRead,
- !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead,
+ !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
}
else
{
- _stream->ready(IceInternal::SocketOperationRead, false);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
}
}
}
@@ -950,7 +954,7 @@ IceSSL::TransceiverI::protocol() const
string
IceSSL::TransceiverI::toString() const
{
- return _stream->toString();
+ return _delegate->toString();
}
string
@@ -963,65 +967,10 @@ Ice::ConnectionInfoPtr
IceSSL::TransceiverI::getInfo() const
{
NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- return info;
-}
-
-Ice::ConnectionInfoPtr
-IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const
-{
- WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- info->headers = headers;
- return info;
-}
-
-void
-IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
-{
-}
-
-void
-IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
-{
- _stream->setBufferSize(rcvSize, sndSize);
-}
-
-IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
- const IceInternal::StreamSocketPtr& stream,
- const string& hostOrAdapterName,
- bool incoming) :
- _instance(instance),
- _engine(SChannelEnginePtr::dynamicCast(instance->engine())),
- _host(incoming ? "" : hostOrAdapterName),
- _adapterName(incoming ? hostOrAdapterName : ""),
- _incoming(incoming),
- _stream(stream),
- _state(StateHandshakeNotStarted),
- _bufferedW(0),
- _sslInitialized(false),
- _credentialsInitialized(false),
- _verified(false)
-{
-}
-
-IceSSL::TransceiverI::~TransceiverI()
-{
-}
-
-void
-IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<CertificatePtr>& nativeCerts) const
-{
- IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress,
- info->remotePort);
- if(_stream->fd() != INVALID_SOCKET)
- {
- info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd());
- info->sndSize = IceInternal::getSendBufferSize(_stream->fd());
- }
-
+ info->underlying = _delegate->getInfo();
+ info->incoming = _incoming;
+ info->adapterName = _adapterName;
info->verified = _verified;
-
if(_sslInitialized)
{
CtxtHandle* ssl = const_cast<CtxtHandle*>(&_ssl);
@@ -1056,7 +1005,7 @@ IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<C
}
CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cc);
- nativeCerts.push_back(certificate);
+ info->nativeCerts.push_back(certificate);
info->certs.push_back(certificate->encode());
}
CertFreeCertificateChain(certChain);
@@ -1080,24 +1029,53 @@ IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, vector<C
IceUtilInternal::lastErrorToString());
}
}
+ return info;
+}
- info->adapterName = _adapterName;
- info->incoming = _incoming;
+void
+IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
+{
+}
+
+void
+IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
+{
+ _delegate->setBufferSize(rcvSize, sndSize);
+}
+
+IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
+ const IceInternal::TransceiverPtr& delegate,
+ const string& hostOrAdapterName,
+ bool incoming) :
+ _instance(instance),
+ _engine(SChannelEnginePtr::dynamicCast(instance->engine())),
+ _host(incoming ? "" : hostOrAdapterName),
+ _adapterName(incoming ? hostOrAdapterName : ""),
+ _incoming(incoming),
+ _delegate(delegate),
+ _state(StateNotInitialized),
+ _bufferedW(0),
+ _sslInitialized(false),
+ _credentialsInitialized(false),
+ _verified(false)
+{
+}
+IceSSL::TransceiverI::~TransceiverI()
+{
}
bool
IceSSL::TransceiverI::writeRaw(IceInternal::Buffer& buf)
{
- ssize_t ret = _stream->write(reinterpret_cast<const char*>(&*buf.i), buf.b.end() - buf.i);
- buf.i += ret;
+ _delegate->write(buf);
return buf.i == buf.b.end();
}
bool
IceSSL::TransceiverI::readRaw(IceInternal::Buffer& buf)
{
- ssize_t ret = _stream->read(reinterpret_cast<char*>(&*buf.i), buf.b.end() - buf.i);
- buf.i += ret;
- return ret > 0;
+ IceInternal::Buffer::Container::iterator p = buf.i;
+ _delegate->read(buf);
+ return buf.i != p;
}
#endif
diff --git a/cpp/src/IceSSL/SChannelTransceiverI.h b/cpp/src/IceSSL/SChannelTransceiverI.h
index b9d96b47eea..dc9d8030b61 100644
--- a/cpp/src/IceSSL/SChannelTransceiverI.h
+++ b/cpp/src/IceSSL/SChannelTransceiverI.h
@@ -43,7 +43,7 @@ namespace IceSSL
class ConnectorI;
class AcceptorI;
-class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate
+class TransceiverI : public IceInternal::Transceiver
{
public:
@@ -68,17 +68,14 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
virtual void checkSendSize(const IceInternal::Buffer&);
virtual void setBufferSize(int rcvSize, int sndSize);
private:
- TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool);
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool);
virtual ~TransceiverI();
- void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const;
-
IceInternal::SocketOperation sslHandshake();
size_t decryptMessage(IceInternal::Buffer&);
@@ -92,6 +89,7 @@ private:
enum State
{
+ StateNotInitialized,
StateHandshakeNotStarted,
StateHandshakeReadContinue,
StateHandshakeWriteContinue,
@@ -103,7 +101,7 @@ private:
const std::string _host;
const std::string _adapterName;
const bool _incoming;
- const IceInternal::StreamSocketPtr _stream;
+ const IceInternal::TransceiverPtr _delegate;
State _state;
//
diff --git a/cpp/src/IceSSL/SSLEngine.cpp b/cpp/src/IceSSL/SSLEngine.cpp
index 31bc4d54e3d..ed286df2b5b 100644
--- a/cpp/src/IceSSL/SSLEngine.cpp
+++ b/cpp/src/IceSSL/SSLEngine.cpp
@@ -115,23 +115,24 @@ IceSSL::SSLEngine::initialize()
// VerifyPeer determines whether certificate validation failures abort a connection.
//
_verifyPeer = properties->getPropertyAsIntWithDefault(propPrefix + "VerifyPeer", 2);
-
+
if(_verifyPeer < 0 || _verifyPeer > 2)
{
PluginInitializationException ex(__FILE__, __LINE__);
ex.reason = "IceSSL: invalid value for " + propPrefix + "VerifyPeer";
throw ex;
}
-
+
_securityTraceLevel = properties->getPropertyAsInt("IceSSL.Trace.Security");
_securityTraceCategory = "Security";
}
void
-IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConnectionInfoPtr& info)
+IceSSL::SSLEngine::verifyPeer(const string& address, const NativeConnectionInfoPtr& info, const string& desc)
{
const CertificateVerifierPtr verifier = getCertificateVerifier();
-
+
+#if !defined(ICE_USE_SECURE_TRANSPORT_IOS)
//
// For an outgoing connection, we compare the proxy address (if any) against
// fields in the server's certificate (if any).
@@ -248,6 +249,7 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn
}
}
}
+#endif
if(_verifyDepthMax > 0 && static_cast<int>(info->certs.size()) > _verifyDepthMax)
{
@@ -258,19 +260,19 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn
string msg = ostr.str();
if(_securityTraceLevel >= 1)
{
- _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd));
+ _logger->trace(_securityTraceCategory, msg + "\n" + desc);
}
SecurityException ex(__FILE__, __LINE__);
ex.reason = msg;
throw ex;
}
- if(!_trustManager->verify(info))
+ if(!_trustManager->verify(info, desc))
{
string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by trust manager";
if(_securityTraceLevel >= 1)
{
- _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd));
+ _logger->trace(_securityTraceCategory, msg + "\n" + desc);
}
SecurityException ex(__FILE__, __LINE__);
ex.reason = msg;
@@ -282,7 +284,7 @@ IceSSL::SSLEngine::verifyPeer(SOCKET fd, const string& address, const NativeConn
string msg = string(info->incoming ? "incoming" : "outgoing") + " connection rejected by certificate verifier";
if(_securityTraceLevel >= 1)
{
- _logger->trace(_securityTraceCategory, msg + "\n" + IceInternal::fdToString(fd));
+ _logger->trace(_securityTraceCategory, msg + "\n" + desc);
}
SecurityException ex(__FILE__, __LINE__);
ex.reason = msg;
diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h
index 08b79e85bd5..25748c71c78 100644
--- a/cpp/src/IceSSL/SSLEngine.h
+++ b/cpp/src/IceSSL/SSLEngine.h
@@ -22,6 +22,7 @@
#if defined(ICE_USE_SECURE_TRANSPORT)
# include <Security/Security.h>
+# include <Security/SecureTransport.h>
#elif defined(ICE_USE_SCHANNEL)
//
@@ -72,7 +73,7 @@ public:
//
// Verify peer certificate
//
- void verifyPeer(SOCKET, const std::string&, const NativeConnectionInfoPtr&);
+ void verifyPeer(const std::string&, const NativeConnectionInfoPtr&, const std::string&);
CertificateVerifierPtr getCertificateVerifier() const;
PasswordPromptPtr getPasswordPrompt() const;
@@ -80,6 +81,7 @@ public:
std::string getPassword() const;
void setPassword(const std::string& password);
+ bool getCheckCertName() const { return _checkCertName; }
int getVerifyPeer() const { return _verifyPeer; }
int securityTraceLevel() const { return _securityTraceLevel; }
std::string securityTraceCategory() const { return _securityTraceCategory; }
@@ -120,7 +122,6 @@ public:
private:
void parseCiphers(const std::string&);
- SecKeychainRef openKeychain();
bool _initialized;
UniqueRef<CFArrayRef> _certificateAuthorities;
@@ -131,8 +132,9 @@ private:
std::string _defaultDir;
+#if TARGET_OS_IPHONE==0
std::vector<char> _dhParams;
-
+#endif
std::vector<SSLCipherSuite> _ciphers;
IceUtil::Mutex _mutex;
};
@@ -179,6 +181,7 @@ private:
# endif
#endif
+
class SChannelEngine : public SSLEngine
{
public:
@@ -219,7 +222,22 @@ private:
HCERTCHAINENGINE _chainEngine;
std::vector<ALG_ID> _ciphers;
};
+
+#elif defined(ICE_OS_WINRT)
+
+class WinRTEngine : public SSLEngine
+{
+public:
+
+ WinRTEngine(const Ice::CommunicatorPtr&);
+
+ virtual void initialize();
+ virtual bool initialized() const;
+ virtual void destroy();
+};
+
#else // OpenSSL
+
class OpenSSLEngine : public SSLEngine
{
public:
diff --git a/cpp/src/IceSSL/SSLEngineF.h b/cpp/src/IceSSL/SSLEngineF.h
index 6d9c7a1e284..61656a11d2a 100644
--- a/cpp/src/IceSSL/SSLEngineF.h
+++ b/cpp/src/IceSSL/SSLEngineF.h
@@ -19,20 +19,24 @@ namespace IceSSL
{
class SSLEngine;
-ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SSLEngine*);
+ICE_SSL_API IceUtil::Shared* upCast(SSLEngine*);
typedef IceInternal::Handle<SSLEngine> SSLEnginePtr;
#if defined(ICE_USE_SECURE_TRANSPORT)
class SecureTransportEngine;
-ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SecureTransportEngine*);
+ICE_SSL_API IceUtil::Shared* upCast(SecureTransportEngine*);
typedef IceInternal::Handle<SecureTransportEngine> SecureTransportEnginePtr;
#elif defined(ICE_USE_SCHANNEL)
class SChannelEngine;
-ICE_SSL_API IceUtil::Shared* upCast(IceSSL::SChannelEngine*);
+ICE_SSL_API IceUtil::Shared* upCast(SChannelEngine*);
typedef IceInternal::Handle<SChannelEngine> SChannelEnginePtr;
+#elif defined(ICE_OS_WINRT)
+class WinRTEngine;
+ICE_SSL_API IceUtil::Shared* upCast(WinRTEngine*);
+typedef IceInternal::Handle<WinRTEngine> WinRTEnginePtr;
#else // OpenSSL
class OpenSSLEngine;
-ICE_SSL_API IceUtil::Shared* upCast(IceSSL::OpenSSLEngine*);
+ICE_SSL_API IceUtil::Shared* upCast(OpenSSLEngine*);
typedef IceInternal::Handle<OpenSSLEngine> OpenSSLEnginePtr;
#endif
diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp
index 00cb59d4c83..1876477794c 100644
--- a/cpp/src/IceSSL/SecureTransportEngine.cpp
+++ b/cpp/src/IceSSL/SecureTransportEngine.cpp
@@ -858,6 +858,9 @@ IceSSL::SecureTransportEngine::initialize()
string certFile = properties->getProperty("IceSSL.CertFile");
string keyFile = properties->getProperty("IceSSL.KeyFile");
string findCert = properties->getProperty("IceSSL.FindCert");
+ string keychain = properties->getProperty("IceSSL.Keychain");
+ string keychainPassword = properties->getProperty("IceSSL.KeychainPassword");
+
if(!certFile.empty())
{
vector<string> files;
@@ -903,10 +906,10 @@ IceSSL::SecureTransportEngine::initialize()
keyFile = resolved;
}
- UniqueRef<SecKeychainRef> kc(openKeychain());
try
{
- _chain.reset(loadCertificateChain(file, keyFile, kc.get(), password, passwordPrompt, passwordRetryMax));
+ _chain.reset(loadCertificateChain(file, keyFile, keychain, keychainPassword, password, passwordPrompt,
+ passwordRetryMax));
break;
}
catch(const CertificateReadException& ce)
@@ -924,57 +927,13 @@ IceSSL::SecureTransportEngine::initialize()
}
else if(!findCert.empty())
{
- UniqueRef<SecKeychainRef> kc(openKeychain());
- UniqueRef<SecCertificateRef> cert(findCertificate(kc.get(), findCert));
-
- //
- // Retrieve the certificate chain
- //
- UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0));
- SecTrustRef trust = 0;
- OSStatus err = SecTrustCreateWithCertificates((CFArrayRef)cert.get(), policy.get(), &trust);
- if(err || !trust)
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error creating trust object" +
- (err ? ":\n" + errorToString(err) : ""));
- }
- UniqueRef<SecTrustRef> v(trust);
-
- SecTrustResultType trustResult;
- if((err = SecTrustEvaluate(trust, &trustResult)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error evaluating trust:\n" + errorToString(err));
- }
-
- int chainLength = SecTrustGetCertificateCount(trust);
- CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks);
- for(int i = 0; i < chainLength; ++i)
- {
- CFArrayAppendValue(items, SecTrustGetCertificateAtIndex(trust, i));
- }
-
- //
- // Replace the first certificate in the chain with the
- // identity.
- //
- SecIdentityRef identity;
- err = SecIdentityCreateWithCertificate(kc.get(), cert.get(), &identity);
- if(err != noErr)
- {
- ostringstream os;
- os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err);
- throw PluginInitializationException(__FILE__, __LINE__, os.str());
- }
- CFArraySetValueAtIndex(items, 0, identity);
- CFRelease(identity);
- _chain.reset(items);
+ _chain.reset(findCertificateChain(keychain, keychainPassword, findCert));
}
//
// DiffieHellmanParams in DER format.
//
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
string dhFile = properties->getProperty("IceSSL.DHParams");
if(!dhFile.empty())
{
@@ -986,6 +945,7 @@ IceSSL::SecureTransportEngine::initialize()
readFile(resolved, _dhParams);
}
+#endif
//
// Establish the cipher list.
@@ -1086,6 +1046,7 @@ IceSSL::SecureTransportEngine::newContext(bool incoming)
}
}
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
if(!_dhParams.empty())
{
if((err = SSLSetDiffieHellmanParams(ssl, &_dhParams[0], _dhParams.size())))
@@ -1094,6 +1055,7 @@ IceSSL::SecureTransportEngine::newContext(bool incoming)
"IceSSL: unable to create the trust object:\n" + errorToString(err));
}
}
+#endif
}
if(_chain && (err = SSLSetCertificate(ssl, _chain.get())))
@@ -1318,92 +1280,5 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers)
}
}
-SecKeychainRef
-SecureTransportEngine::openKeychain()
-{
- const PropertiesPtr properties = communicator()->getProperties();
-
- //
- // Open the application KeyChain or create it if the keychain doesn't exists
- //
- string keychainPath = properties->getProperty("IceSSL.Keychain");
- string keychainPassword = properties->getProperty("IceSSL.KeychainPassword");
-
- SecKeychainRef keychain = 0;
- OSStatus err = 0;
- if(keychainPath.empty())
- {
- if((err = SecKeychainCopyDefault(&keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to retrieve default keychain:\n" + errorToString(err));
- }
- }
- else
- {
- //
- // KeyChain path is relative to the current working directory.
- //
- if(!IceUtilInternal::isAbsolutePath(keychainPath))
- {
- string cwd;
- if(IceUtilInternal::getcwd(cwd) == 0)
- {
- keychainPath = string(cwd) + '/' + keychainPath;
- }
- }
-
- if((err = SecKeychainOpen(keychainPath.c_str(), &keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" +
- keychainPath + "'\n" + errorToString(err));
- }
- }
-
- UniqueRef<SecKeychainRef> k(keychain);
-
- SecKeychainStatus status;
- err = SecKeychainGetStatus(keychain, &status);
- if(err == noErr)
- {
- const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
- if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to unlock keychain:\n" + errorToString(err));
- }
- }
- else if(err == errSecNoSuchKeychain)
- {
- const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
- if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to create keychain:\n" + errorToString(err));
- }
- k.reset(keychain);
- }
- else
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to open keychain:\n" + errorToString(err));
- }
-
- //
- // Set keychain settings to avoid keychain lock.
- //
- SecKeychainSettings settings;
- settings.version = SEC_KEYCHAIN_SETTINGS_VERS1;
- settings.lockOnSleep = FALSE;
- settings.useLockInterval = FALSE;
- settings.lockInterval = INT_MAX;
- if((err = SecKeychainSetSettings(keychain, &settings)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error setting keychain settings:\n" + errorToString(err));
- }
-
- return k.release();
-}
#endif
diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
index b043ef19713..f407e008913 100644
--- a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
+++ b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
@@ -96,7 +96,8 @@ socketRead(SSLConnectionRef connection, void* data, size_t* length)
}
bool
-checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const InstancePtr& instance)
+checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const InstancePtr& instance,
+ const string& host)
{
OSStatus err = noErr;
SecTrustResultType trustResult = kSecTrustResultOtherError;
@@ -115,6 +116,28 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons
throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
}
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ if(engine->getCheckCertName() && !host.empty())
+ {
+ //
+ // Add SSL trust policy if we need to check the certificate name.
+ //
+ UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(false, toCFString(host)));
+ CFArrayRef policies;
+ if((err = SecTrustCopyPolicies(trust, &policies)))
+ {
+ throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
+ }
+ UniqueRef<CFMutableArrayRef> newPolicies(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, policies));
+ CFRelease(policies);
+ CFArrayAppendValue(newPolicies.get(), policy.release());
+ if((err = SecTrustSetPolicies(trust, newPolicies.release())))
+ {
+ throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
+ }
+ }
+#endif
+
//
// Evaluate the trust
//
@@ -171,18 +194,29 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons
IceInternal::NativeInfoPtr
IceSSL::TransceiverI::getNativeInfo()
{
- return _stream;
+ return _delegate->getNativeInfo();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer)
{
- IceInternal::SocketOperation status = _stream->connect(readBuffer, writeBuffer);
- if(status != IceInternal::SocketOperationNone)
+ if(!_connected)
{
- return status;
+ IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer);
+ if(status != IceInternal::SocketOperationNone)
+ {
+ return status;
+ }
+ _connected = true;
}
+ //
+ // Limit the size of packets passed to SSLWrite/SSLRead to avoid
+ // blocking and holding too much memory.
+ //
+ _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_delegate->getNativeInfo()->fd()));
+ _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_delegate->getNativeInfo()->fd()));
+
OSStatus err = 0;
if(!_ssl)
{
@@ -237,7 +271,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
}
if(err == noErr)
{
- _verified = checkTrustResult(_trust, _engine, _instance);
+ _verified = checkTrustResult(_trust, _engine, _instance, _host);
continue; // Call SSLHandshake to resume the handsake.
}
// Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error.
@@ -247,18 +281,12 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
throw ConnectionLostException(__FILE__, __LINE__, 0);
}
- IceInternal::Address remoteAddr;
- string desc = "<not available>";
- if(IceInternal::fdToRemoteAddress(_stream->fd(), remoteAddr))
- {
- desc = IceInternal::addrToString(remoteAddr);
- }
ostringstream os;
os << "IceSSL: ssl error occurred for new " << (_incoming ? "incoming" : "outgoing") << " connection:\n"
- << "remote address = " << desc << "\n" << errorToString(err);
+ << _delegate->toString() << "\n" << errorToString(err);
throw ProtocolException(__FILE__, __LINE__, os.str());
}
- _engine->verifyPeer(_stream->fd(), _host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()));
+ _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString());
if(_instance->engine()->securityTraceLevel() >= 1)
{
@@ -317,15 +345,15 @@ IceSSL::TransceiverI::close()
_ssl = 0;
}
- _stream->close();
+ _delegate->close();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->write(buf);
+ return _delegate->write(buf);
}
if(buf.i == buf.b.end())
@@ -402,9 +430,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
IceInternal::SocketOperation
IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->read(buf);
+ return _delegate->read(buf);
}
if(buf.i == buf.b.end())
@@ -412,7 +440,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
return IceInternal::SocketOperationNone;
}
- _stream->ready(IceInternal::SocketOperationRead, false);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxRecvPacketSize);
while(buf.i != buf.b.end())
@@ -471,7 +499,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
errno = err;
throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno());
}
- _stream->ready(IceInternal::SocketOperationRead, buffered > 0);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, buffered > 0);
return IceInternal::SocketOperationNone;
}
@@ -484,7 +512,7 @@ IceSSL::TransceiverI::protocol() const
string
IceSSL::TransceiverI::toString() const
{
- return _stream->toString();
+ return _delegate->toString();
}
string
@@ -497,16 +525,30 @@ Ice::ConnectionInfoPtr
IceSSL::TransceiverI::getInfo() const
{
NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- return info;
-}
+ info->underlying = _delegate->getInfo();
+ info->incoming = _incoming;
+ info->adapterName = _adapterName;
+ if(_ssl)
+ {
+ for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i)
+ {
+ SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i);
+ CFRetain(cert);
-Ice::ConnectionInfoPtr
-IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const
-{
- WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- info->headers = headers;
+ CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert);
+ info->nativeCerts.push_back(certificate);
+ info->certs.push_back(certificate->encode());
+ }
+
+ SSLCipherSuite cipher;
+ SSLGetNegotiatedCipher(_ssl, &cipher);
+ info->cipher = _engine->getCipherName(cipher);
+ info->verified = _verified;
+ }
+ else
+ {
+ info->verified = false;
+ }
return info;
}
@@ -518,11 +560,11 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
void
IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
{
- _stream->setBufferSize(rcvSize, sndSize);
+ _delegate->setBufferSize(rcvSize, sndSize);
}
IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
- const IceInternal::StreamSocketPtr& stream,
+ const IceInternal::TransceiverPtr& delegate,
const string& hostOrAdapterName,
bool incoming) :
_instance(instance),
@@ -530,61 +572,19 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
_host(incoming ? "" : hostOrAdapterName),
_adapterName(incoming ? hostOrAdapterName : ""),
_incoming(incoming),
- _stream(stream),
+ _delegate(delegate),
_ssl(0),
_trust(0),
+ _connected(false),
_verified(false),
_buffered(0)
{
- //
- // Limit the size of packets passed to SSLWrite/SSLRead to avoid
- // blocking and holding too much memory.
- //
- _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_stream->fd()));
- _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_stream->fd()));
}
IceSSL::TransceiverI::~TransceiverI()
{
}
-void
-IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, std::vector<CertificatePtr>& nativeCerts) const
-{
- IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress,
- info->remotePort);
- if(_stream->fd() != INVALID_SOCKET)
- {
- info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd());
- info->sndSize = IceInternal::getSendBufferSize(_stream->fd());
- }
-
- if(_ssl)
- {
- for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i)
- {
- SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i);
- CFRetain(cert);
-
- CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert);
- nativeCerts.push_back(certificate);
- info->certs.push_back(certificate->encode());
- }
-
- SSLCipherSuite cipher;
- SSLGetNegotiatedCipher(_ssl, &cipher);
- info->cipher = _engine->getCipherName(cipher);
- info->verified = _verified;
- }
- else
- {
- info->verified = false;
- }
-
- info->adapterName = _adapterName;
- info->incoming = _incoming;
-}
-
OSStatus
IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const
{
@@ -592,13 +592,15 @@ IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const
try
{
- ssize_t ret = _stream->write(data, *length);
- if(ret < *length)
+ IceInternal::Buffer buf(reinterpret_cast<const Ice::Byte*>(data), reinterpret_cast<const Ice::Byte*>(data) + *length);
+ IceInternal::SocketOperation op = _delegate->write(buf);
+ if(op == IceInternal::SocketOperationWrite)
{
- *length = static_cast<size_t>(ret);
+ *length = buf.i - buf.b.begin();
_flags |= SSLWantWrite;
return errSSLWouldBlock;
}
+ assert(op == IceInternal::SocketOperationNone);
}
catch(const Ice::ConnectionLostException&)
{
@@ -623,13 +625,15 @@ IceSSL::TransceiverI::readRaw(char* data, size_t* length) const
try
{
- ssize_t ret = _stream->read(data, *length);
- if(ret < *length)
+ IceInternal::Buffer buf(reinterpret_cast<Ice::Byte*>(data), reinterpret_cast<Ice::Byte*>(data) + *length);
+ IceInternal::SocketOperation op = _delegate->read(buf);
+ if(op == IceInternal::SocketOperationRead)
{
- *length = static_cast<size_t>(ret);
+ *length = buf.i - buf.b.begin();
_flags |= SSLWantRead;
return errSSLWouldBlock;
}
+ assert(op == IceInternal::SocketOperationNone);
}
catch(const Ice::ConnectionLostException&)
{
diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.h b/cpp/src/IceSSL/SecureTransportTransceiverI.h
index 68b0a677783..71a2a6c5f34 100644
--- a/cpp/src/IceSSL/SecureTransportTransceiverI.h
+++ b/cpp/src/IceSSL/SecureTransportTransceiverI.h
@@ -17,12 +17,11 @@
#include <Ice/Transceiver.h>
#include <Ice/Network.h>
-#include <Ice/StreamSocket.h>
-#include <Ice/WSTransceiver.h>
#ifdef ICE_USE_SECURE_TRANSPORT
#include <Security/Security.h>
+#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
namespace IceSSL
@@ -31,7 +30,7 @@ namespace IceSSL
class ConnectorI;
class AcceptorI;
-class TransceiverI : public IceInternal::Transceiver, public IceInternal::WSTransceiverDelegate
+class TransceiverI : public IceInternal::Transceiver
{
public:
@@ -51,7 +50,6 @@ public:
virtual std::string toString() const;
virtual std::string toDetailedString() const;
virtual Ice::ConnectionInfoPtr getInfo() const;
- virtual Ice::ConnectionInfoPtr getWSInfo(const Ice::HeaderDict&) const;
virtual void checkSendSize(const IceInternal::Buffer&);
virtual void setBufferSize(int rcvSize, int sndSize);
@@ -60,11 +58,9 @@ public:
private:
- TransceiverI(const InstancePtr&, const IceInternal::StreamSocketPtr&, const std::string&, bool);
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool);
virtual ~TransceiverI();
- void fillConnectionInfo(const ConnectionInfoPtr&, std::vector<CertificatePtr>&) const;
-
friend class ConnectorI;
friend class AcceptorI;
@@ -73,10 +69,11 @@ private:
const std::string _host;
const std::string _adapterName;
const bool _incoming;
- const IceInternal::StreamSocketPtr _stream;
+ const IceInternal::TransceiverPtr _delegate;
SSLContextRef _ssl;
SecTrustRef _trust;
+ bool _connected;
bool _verified;
size_t _buffered;
diff --git a/cpp/src/IceSSL/TrustManager.cpp b/cpp/src/IceSSL/TrustManager.cpp
index 0e60abb5a82..31b42291db3 100644
--- a/cpp/src/IceSSL/TrustManager.cpp
+++ b/cpp/src/IceSSL/TrustManager.cpp
@@ -62,7 +62,7 @@ TrustManager::TrustManager(const Ice::CommunicatorPtr& communicator) :
}
bool
-TrustManager::verify(const NativeConnectionInfoPtr& info)
+TrustManager::verify(const NativeConnectionInfoPtr& info, const std::string& desc)
{
list<list<DistinguishedName> > reject, accept;
@@ -139,19 +139,14 @@ TrustManager::verify(const NativeConnectionInfoPtr& info)
Ice::Trace trace(_communicator->getLogger(), "Security");
if(info->incoming)
{
- trace << "trust manager evaluating client:\n"
- << "subject = " << string(subject) << '\n'
- << "adapter = " << info->adapterName << '\n'
- << "local addr = " << info->localAddress << ":" << info->localPort << '\n'
- << "remote addr = " << info->remoteAddress << ":" << info->remotePort;
+ trace << "trust manager evaluating client:\n" << "subject = " << string(subject) << '\n'
+ << "adapter = " << info->adapterName << '\n';
}
else
{
- trace << "trust manager evaluating server:\n"
- << "subject = " << string(subject) << '\n'
- << "local addr = " << info->localAddress << ":" << info->localPort << '\n'
- << "remote addr = " << info->remoteAddress << ":" << info->remotePort;
+ trace << "trust manager evaluating server:\n" << "subject = " << string(subject) << '\n';
}
+ trace << desc;
}
//
diff --git a/cpp/src/IceSSL/TrustManager.h b/cpp/src/IceSSL/TrustManager.h
index a03c5d2a694..a99363baf05 100644
--- a/cpp/src/IceSSL/TrustManager.h
+++ b/cpp/src/IceSSL/TrustManager.h
@@ -25,7 +25,7 @@ public:
TrustManager(const Ice::CommunicatorPtr&);
- bool verify(const NativeConnectionInfoPtr&);
+ bool verify(const NativeConnectionInfoPtr&, const std::string&);
private:
diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp
index b55ca494233..9a5f6bce50e 100644..100755
--- a/cpp/src/IceSSL/Util.cpp
+++ b/cpp/src/IceSSL/Util.cpp
@@ -8,7 +8,7 @@
// **********************************************************************
#include <IceUtil/Config.h>
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(ICE_OS_WINRT)
# include <winsock2.h>
#endif
@@ -16,6 +16,7 @@
#include <IceUtil/FileUtil.h>
#include <IceUtil/StringUtil.h>
+#include <Ice/Base64.h>
#include <Ice/LocalException.h>
#include <Ice/Network.h>
#include <Ice/Object.h>
@@ -33,30 +34,7 @@ using namespace Ice;
using namespace IceUtil;
using namespace IceSSL;
-void
-IceSSL::readFile(const string& file, vector<char>& buffer)
-{
- IceUtilInternal::ifstream is(file, ios::in | ios::binary);
- if(!is.good())
- {
- throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file);
- }
-
- is.seekg(0, is.end);
- buffer.resize(static_cast<int>(is.tellg()));
- is.seekg(0, is.beg);
-
- if(!buffer.empty())
- {
- is.read(&buffer[0], buffer.size());
- if(!is.good())
- {
- throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file);
- }
- }
-}
-
-#ifndef ICE_USE_OPENSSL
+#if !defined(ICE_USE_OPENSSL)
namespace
{
@@ -423,12 +401,14 @@ IceSSL::errorToString(OSStatus status)
{
ostringstream os;
os << "(error: " << status;
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
CFStringRef s = SecCopyErrorMessageString(status, 0);
if(s)
{
os << " description: " << fromCFString(s);
CFRelease(s);
}
+#endif
os << ")";
return os.str();
}
@@ -448,6 +428,7 @@ IceSSL::fromCFString(CFStringRef v)
return s;
}
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
CFDictionaryRef
IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key)
{
@@ -471,10 +452,36 @@ IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key)
CFRelease(values);
return property;
}
+#endif
namespace
{
+CFDataRef
+readCertFile(const string& file)
+{
+ IceUtilInternal::ifstream is(file, ios::in | ios::binary);
+ if(!is.good())
+ {
+ throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file);
+ }
+
+ is.seekg(0, is.end);
+ size_t size = is.tellg();
+ is.seekg(0, is.beg);
+
+ CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, size);
+ CFDataSetLength(data, size);
+ is.read(reinterpret_cast<char*>(CFDataGetMutableBytePtr(data)), size);
+ if(!is.good())
+ {
+ CFRelease(data);
+ throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file);
+ }
+ return data;
+}
+
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
//
// Check the certificate basic constraints to check if the certificate is marked as a CA.
//
@@ -506,12 +513,7 @@ CFArrayRef
loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef keychain, const string& passphrase,
const PasswordPromptPtr& prompt, int retryMax)
{
- vector<char> buffer;
- readFile(file, buffer);
- UniqueRef<CFDataRef> data(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
- reinterpret_cast<const UInt8*>(&buffer[0]),
- buffer.size(),
- kCFAllocatorNull));
+ UniqueRef<CFDataRef> data(readCertFile(file));
SecItemImportExportKeyParameters params;
memset(&params, 0, sizeof(params));
@@ -591,14 +593,93 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k
return items;
}
+SecKeychainRef
+openKeychain(const std::string& path, const std::string& keychainPassword)
+{
+ string keychainPath = path;
+ SecKeychainRef keychain = 0;
+ OSStatus err = 0;
+ if(keychainPath.empty())
+ {
+ if((err = SecKeychainCopyDefault(&keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to retrieve default keychain:\n" + errorToString(err));
+ }
+ }
+ else
+ {
+ //
+ // KeyChain path is relative to the current working directory.
+ //
+ if(!IceUtilInternal::isAbsolutePath(keychainPath))
+ {
+ string cwd;
+ if(IceUtilInternal::getcwd(cwd) == 0)
+ {
+ keychainPath = string(cwd) + '/' + keychainPath;
+ }
+ }
+
+ if((err = SecKeychainOpen(keychainPath.c_str(), &keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" +
+ keychainPath + "'\n" + errorToString(err));
+ }
+ }
+
+ UniqueRef<SecKeychainRef> k(keychain);
+
+ SecKeychainStatus status;
+ err = SecKeychainGetStatus(keychain, &status);
+ if(err == noErr)
+ {
+ const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
+ if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to unlock keychain:\n" + errorToString(err));
+ }
+ }
+ else if(err == errSecNoSuchKeychain)
+ {
+ const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
+ if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to create keychain:\n" + errorToString(err));
+ }
+ k.reset(keychain);
+ }
+ else
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to open keychain:\n" + errorToString(err));
+ }
+
+ //
+ // Set keychain settings to avoid keychain lock.
+ //
+ SecKeychainSettings settings;
+ settings.version = SEC_KEYCHAIN_SETTINGS_VERS1;
+ settings.lockOnSleep = FALSE;
+ settings.useLockInterval = FALSE;
+ settings.lockInterval = INT_MAX;
+ if((err = SecKeychainSetSettings(keychain, &settings)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: error setting keychain settings:\n" + errorToString(err));
+ }
+
+ return k.release();
}
//
// Imports a certificate private key and optionally add it to a keychain.
//
SecIdentityRef
-IceSSL::loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password,
- const PasswordPromptPtr& prompt, int retryMax)
+loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keychain, const string& password,
+ const PasswordPromptPtr& prompt, int retryMax)
{
//
// Check if we already imported the certificate
@@ -751,17 +832,139 @@ IceSSL::loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRe
}
return identity;
}
+#else
+
+CFArrayRef
+loadCerts(const string& file)
+{
+ UniqueRef<CFMutableArrayRef> certs(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
+ if(file.find(".pem") != string::npos)
+ {
+ vector<char> buffer;
+ readFile(file, buffer);
+ string strbuf(buffer.begin(), buffer.end());
+ string::size_type size, startpos, endpos = 0;
+ bool first = true;
+ while(true)
+ {
+ startpos = strbuf.find("-----BEGIN CERTIFICATE-----", endpos);
+ if(startpos != string::npos)
+ {
+ startpos += sizeof("-----BEGIN CERTIFICATE-----");
+ endpos = strbuf.find("-----END CERTIFICATE-----", startpos);
+ if(endpos == string::npos)
+ {
+ InitializationException ex(__FILE__, __LINE__);
+ ex.reason = "IceSSL: certificate " + file + " is not a valid PEM-encoded certificate";
+ throw ex;
+ }
+ size = endpos - startpos;
+ }
+ else if(first)
+ {
+ startpos = 0;
+ endpos = string::npos;
+ size = strbuf.size();
+ }
+ else
+ {
+ break;
+ }
+
+ vector<unsigned char> data(IceInternal::Base64::decode(string(&buffer[startpos], size)));
+ UniqueRef<CFDataRef> certdata(CFDataCreate(kCFAllocatorDefault, &data[0], data.size()));
+ SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get());
+ if(!cert)
+ {
+ InitializationException ex(__FILE__, __LINE__);
+ ex.reason = "IceSSL: certificate " + file + " is not a valid PEM-encoded certificate";
+ throw ex;
+ }
+ CFArrayAppendValue(certs.get(), cert);
+ CFRelease(cert);
+ first = false;
+ }
+ }
+ else
+ {
+ UniqueRef<CFDataRef> data(readCertFile(file));
+ SecCertificateRef cert = SecCertificateCreateWithData(0, data.get());
+ if(!cert)
+ {
+ InitializationException ex(__FILE__, __LINE__);
+ ex.reason = "IceSSL: certificate " + file + " is not a valid DER-encoded certificate";
+ throw ex;
+ }
+ CFArrayAppendValue(certs.get(), cert);
+ CFRelease(cert);
+ }
+ return certs.release();
+}
+#endif
+
+}
//
// Imports a certificate (it might contain an identity or certificate depending on the format).
//
CFArrayRef
-IceSSL::loadCertificateChain(const string& file, const string& keyFile, SecKeychainRef keychain,
- const string& password, const PasswordPromptPtr& prompt, int retryMax)
+IceSSL::loadCertificateChain(const string& file, const string& keyFile, const std::string& keychainPath,
+ const string& keychainPassword, const string& password, const PasswordPromptPtr& prompt,
+ int retryMax)
{
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ UniqueRef<CFDataRef> cert(readCertFile(file));
+
+ UniqueRef<CFMutableDictionaryRef> settings(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ CFArrayRef items = 0;
+ OSStatus err;
+ if(password.empty() && prompt)
+ {
+ int count = 0;
+ do
+ {
+ UniqueRef<CFStringRef> pass(toCFString(prompt->getPassword()));
+ CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get());
+ err = SecPKCS12Import(cert.get(), settings.get(), &items);
+ ++count;
+ }
+ while(err == errSecAuthFailed && count < retryMax);
+ }
+ else
+ {
+ UniqueRef<CFStringRef> pass(toCFString(password));
+ CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get());
+ err = SecPKCS12Import(cert.get(), settings.get(), &items);
+ }
+ if(err != noErr)
+ {
+ ostringstream os;
+ os << "IceSSL: unable to import certificate from file " << file << " (error = " << err << ")";
+ throw InitializationException(__FILE__, __LINE__, os.str());
+ }
+
+ UniqueRef<CFArrayRef> itemsHolder(items);;
+ for(int i = 0; i < CFArrayGetCount(items); ++i)
+ {
+ CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(items, i);
+ SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(dict, kSecImportItemIdentity);
+ if(identity)
+ {
+ CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(dict, kSecImportItemCertChain);
+ CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs);
+ CFArraySetValueAtIndex(a, 0, identity);
+ return a;
+ }
+ }
+ ostringstream os;
+ os << "IceSSL: couldn't find identity in file " << file;
+ throw InitializationException(__FILE__, __LINE__, os.str());
+#else
+ UniqueRef<SecKeychainRef> keychain(openKeychain(keychainPath, keychainPassword));
if(keyFile.empty())
{
- return loadKeychainItems(file, kSecItemTypeUnknown, keychain, password, prompt, retryMax);
+ return loadKeychainItems(file, kSecItemTypeUnknown, keychain.get(), password, prompt, retryMax);
}
else
{
@@ -783,26 +986,37 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, SecKeych
// add the certificate/key to the keychain if they aren't
// already present in the keychain.
//
- UniqueRef<SecIdentityRef> identity(loadPrivateKey(keyFile, cert, keychain, password, prompt, retryMax));
+ UniqueRef<SecIdentityRef> identity(loadPrivateKey(keyFile, cert, keychain.get(), password, prompt, retryMax));
CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, items.get());
CFArraySetValueAtIndex(a, 0, identity.get());
return a;
}
+#endif
}
SecCertificateRef
IceSSL::loadCertificate(const string& file)
{
- CFArrayRef items = loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0);
- SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items, 0);
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ UniqueRef<CFArrayRef> certs(loadCerts(file));
+ assert(CFArrayGetCount(certs.get()) > 0);
+ SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0);
+ CFRetain(cert);
+ return cert;
+#else
+ UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0));
+ SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0);
CFRetain(cert);
- CFRelease(items);
return cert;
+#endif
}
CFArrayRef
IceSSL::loadCACertificates(const string& file)
{
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ return loadCerts(file);
+#else
UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0));
CFMutableArrayRef certificateAuthorities = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
int count = CFArrayGetCount(items.get());
@@ -816,10 +1030,11 @@ IceSSL::loadCACertificates(const string& file)
}
}
return certificateAuthorities;
+#endif
}
-SecCertificateRef
-IceSSL::findCertificate(SecKeychainRef keychain, const string& value)
+CFArrayRef
+IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& keychainPassword, const string& value)
{
//
// Search the keychain using key:value pairs. The following keys are supported:
@@ -836,17 +1051,20 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value)
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
- const void* values[] = { keychain };
+#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
+ UniqueRef<SecKeychainRef> keychain(openKeychain(keychainPath, keychainPassword));
+ const void* values[] = { keychain.get() };
UniqueRef<CFArrayRef> searchList(CFArrayCreate(kCFAllocatorDefault, values, 1, &kCFTypeArrayCallBacks));
-
- CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne);
CFDictionarySetValue(query.get(), kSecMatchSearchList, searchList.get());
+#endif
+ CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne);
CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate);
CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue);
CFDictionarySetValue(query.get(), kSecMatchCaseInsensitive, kCFBooleanTrue);
size_t start = 0;
size_t pos;
+ bool valid = false;
while((pos = value.find(':', start)) != string::npos)
{
string field = IceUtilInternal::toUpper(IceUtilInternal::trim(value.substr(start, pos - start)));
@@ -906,6 +1124,7 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value)
{
UniqueRef<CFStringRef> v(toCFString(arg));
CFDictionarySetValue(query.get(), field == "LABEL" ? kSecAttrLabel : kSecMatchSubjectContains, v.get());
+ valid = true;
}
else if(field == "SUBJECTKEYID" || field == "SERIAL")
{
@@ -917,10 +1136,11 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value)
UniqueRef<CFDataRef> v(CFDataCreate(kCFAllocatorDefault, &buffer[0], buffer.size()));
CFDictionarySetValue(query.get(), field == "SUBJECTKEYID" ? kSecAttrSubjectKeyID : kSecAttrSerialNumber,
v.get());
+ valid = true;
}
}
- if(CFDictionaryGetCount(query.get()) == 5)
+ if(!valid)
{
throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value `" + value + "'");
}
@@ -932,7 +1152,92 @@ IceSSL::findCertificate(SecKeychainRef keychain, const string& value)
throw PluginInitializationException(__FILE__, __LINE__,
"IceSSL: find certificate `" + value + "' failed:\n" + errorToString(err));
}
- return cert;
+
+ UniqueRef<SecCertificateRef> certHolder(cert);
+
+ //
+ // Retrieve the certificate chain
+ //
+ UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0));
+ SecTrustRef trust = 0;
+ err = SecTrustCreateWithCertificates((CFArrayRef)cert, policy.get(), &trust);
+ if(err || !trust)
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: error creating trust object" +
+ (err ? ":\n" + errorToString(err) : ""));
+ }
+ UniqueRef<SecTrustRef> v(trust);
+
+ SecTrustResultType trustResult;
+ if((err = SecTrustEvaluate(trust, &trustResult)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: error evaluating trust:\n" + errorToString(err));
+ }
+
+ int chainLength = SecTrustGetCertificateCount(trust);
+ CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks);
+ UniqueRef<CFMutableArrayRef> itemsHolder(items);
+ for(int i = 0; i < chainLength; ++i)
+ {
+ CFArrayAppendValue(items, SecTrustGetCertificateAtIndex(trust, i));
+ }
+
+ //
+ // Replace the first certificate in the chain with the
+ // identity.
+ //
+ SecIdentityRef identity;
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+
+ //
+ // SecIdentityCreateWithCertificate isn't supported on iOS so we lookup the identity
+ // using the certicate label. If the user added the identity with SecItemAdd the
+ // identity has the same label as the certificate.
+ //
+ query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate);
+ CFDictionarySetValue(query.get(), kSecValueRef, cert);
+ CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue);
+ CFDictionaryRef attributes;
+ err = SecItemCopyMatching(query.get(), (CFTypeRef*)&attributes);
+ if(err != noErr)
+ {
+ ostringstream os;
+ os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err);
+ throw PluginInitializationException(__FILE__, __LINE__, os.str());
+ }
+ UniqueRef<CFDictionaryRef> attributesHolder(attributes);
+
+ // Now lookup the identity with the label
+ query.reset(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne);
+ CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity);
+ CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrLabel));
+ CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue);
+ err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity);
+ if(err == noErr)
+ {
+ SecCertificateRef cert2 = NULL;
+ if((err = SecIdentityCopyCertificate(identity, &cert2)) == noErr)
+ {
+ err = CFEqual(cert2, cert) ? noErr : errSecItemNotFound;
+ CFRelease(cert2);
+ }
+ }
+#else
+ err = SecIdentityCreateWithCertificate(keychain.get(), cert, &identity);
+#endif
+ if(err != noErr)
+ {
+ ostringstream os;
+ os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err);
+ throw PluginInitializationException(__FILE__, __LINE__, os.str());
+ }
+ CFArraySetValueAtIndex(items, 0, identity);
+ CFRelease(identity);
+ return itemsHolder.release();
}
#elif defined(ICE_USE_SCHANNEL)
@@ -1195,9 +1500,55 @@ IceSSL::findCertificates(const string& location, const string& name, const strin
}
#endif
+void
+IceSSL::readFile(const string& file, vector<char>& buffer)
+{
+ IceUtilInternal::ifstream is(file, ios::in | ios::binary);
+ if(!is.good())
+ {
+ throw CertificateReadException(__FILE__, __LINE__, "error opening file " + file);
+ }
+
+ is.seekg(0, is.end);
+ buffer.resize(static_cast<int>(is.tellg()));
+ is.seekg(0, is.beg);
+
+ if(!buffer.empty())
+ {
+ is.read(&buffer[0], buffer.size());
+ if(!is.good())
+ {
+ throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file);
+ }
+ }
+}
+
bool
IceSSL::checkPath(const string& path, const string& defaultDir, bool dir, string& resolved)
{
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ CFURLRef url = 0;
+ CFBundleRef bundle = CFBundleGetMainBundle();
+ if(bundle)
+ {
+ CFStringRef resourceName = toCFString(path);
+ CFStringRef subDirName = toCFString(defaultDir);
+ url = CFBundleCopyResourceURL(bundle, resourceName, 0, subDirName);
+ CFRelease(resourceName);
+ CFRelease(subDirName);
+
+ UInt8 filePath[PATH_MAX];
+ if(CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath)))
+ {
+ string tmp = string(reinterpret_cast<char*>(filePath));
+ if((dir && IceUtilInternal::directoryExists(tmp)) || (!dir && IceUtilInternal::fileExists(tmp)))
+ {
+ resolved = tmp;
+ return true;
+ }
+ }
+ }
+#endif
if(IceUtilInternal::isAbsolutePath(path))
{
if((dir && IceUtilInternal::directoryExists(path)) || (!dir && IceUtilInternal::fileExists(path)))
diff --git a/cpp/src/IceSSL/Util.h b/cpp/src/IceSSL/Util.h
index 855e0ac71b8..3e98050ee35 100644
--- a/cpp/src/IceSSL/Util.h
+++ b/cpp/src/IceSSL/Util.h
@@ -150,27 +150,23 @@ toCFString(const std::string& s)
std::string errorToString(CFErrorRef);
std::string errorToString(OSStatus);
+#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0
//
// Retrieve a certificate property
//
CFDictionaryRef getCertificateProperty(SecCertificateRef, CFTypeRef);
-
-//
-// Read a private key from an file and associate it to the given certificate.
-//
-SecIdentityRef loadPrivateKey(const std::string&, SecCertificateRef, SecKeychainRef, const std::string&,
- const PasswordPromptPtr&, int);
+#endif
//
// Read certificate from a file.
//
-CFArrayRef loadCertificateChain(const std::string&, const std::string&, SecKeychainRef, const std::string&,
- const PasswordPromptPtr&, int);
+CFArrayRef loadCertificateChain(const std::string&, const std::string&, const std::string&, const std::string&,
+ const std::string&, const PasswordPromptPtr&, int);
SecCertificateRef loadCertificate(const std::string&);
CFArrayRef loadCACertificates(const std::string&);
-SecCertificateRef findCertificate(SecKeychainRef, const std::string&);
+CFArrayRef findCertificateChain(const std::string&, const std::string&, const std::string&);
#elif defined(ICE_USE_SCHANNEL)
std::vector<PCCERT_CONTEXT>
diff --git a/cpp/src/IceSSL/WinRTEngine.cpp b/cpp/src/IceSSL/WinRTEngine.cpp
new file mode 100755
index 00000000000..7eb59f922a7
--- /dev/null
+++ b/cpp/src/IceSSL/WinRTEngine.cpp
@@ -0,0 +1,43 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <IceSSL/Config.h>
+
+#ifdef ICE_OS_WINRT
+
+#include <IceSSL/SSLEngine.h>
+#include <IceUtil/Shared.h>
+
+IceUtil::Shared* IceSSL::upCast(IceSSL::WinRTEngine* p) { return p; }
+
+using namespace IceSSL;
+
+WinRTEngine::WinRTEngine(const Ice::CommunicatorPtr& communicator) : SSLEngine(communicator)
+{
+
+}
+
+void
+WinRTEngine::initialize()
+{
+}
+
+bool
+WinRTEngine::initialized() const
+{
+ return true;
+}
+
+void
+WinRTEngine::destroy()
+{
+}
+
+#endif
+
diff --git a/cpp/src/IceSSL/WinRTTransceiverI.cpp b/cpp/src/IceSSL/WinRTTransceiverI.cpp
new file mode 100755
index 00000000000..be0d632eaf8
--- /dev/null
+++ b/cpp/src/IceSSL/WinRTTransceiverI.cpp
@@ -0,0 +1,199 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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 <IceSSL/Config.h>
+
+#ifdef ICE_OS_WINRT
+
+#include <IceSSL/WinRTTransceiverI.h>
+#include <IceSSL/Instance.h>
+#include <IceSSL/SSLEngine.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceSSL;
+
+using namespace Platform;
+using namespace Windows::Networking;
+using namespace Windows::Networking::Sockets;
+
+IceInternal::NativeInfoPtr
+IceSSL::TransceiverI::getNativeInfo()
+{
+ return _delegate->getNativeInfo();
+}
+
+IceInternal::SocketOperation
+IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer)
+{
+ if(!_connected)
+ {
+ IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer);
+ if(status != IceInternal::SocketOperationNone)
+ {
+ return status;
+ }
+ _connected = true;
+
+ //
+ // Continue connecting, this will call startWrite/finishWrite to upgrade the stream
+ // to SSL.
+ //
+ return IceInternal::SocketOperationConnect;
+ }
+ else if(!_upgraded)
+ {
+ _upgraded = true;
+ }
+ return IceInternal::SocketOperationNone;
+}
+
+IceInternal::SocketOperation
+#ifdef ICE_CPP11_MAPPING
+IceSSL::TransceiverI::closing(bool initiator, exception_ptr ex)
+#else
+IceSSL::TransceiverI::closing(bool initiator, const Ice::LocalException& ex)
+#endif
+{
+ return _delegate->closing(initiator, ex);
+}
+
+void
+IceSSL::TransceiverI::close()
+{
+ _delegate->close();
+}
+
+IceInternal::SocketOperation
+IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
+{
+ return _delegate->write(buf);
+}
+
+IceInternal::SocketOperation
+IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
+{
+ return _delegate->read(buf);
+}
+
+bool
+IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buf)
+{
+ if(_connected && !_upgraded)
+ {
+ StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd());
+ HostName^ host = ref new HostName(ref new String(IceUtil::stringToWstring(_host).c_str()));
+ try
+ {
+ Windows::Foundation::IAsyncAction^ action = stream->UpgradeToSslAsync(SocketProtectionLevel::Tls12, host);
+ getNativeInfo()->queueAction(IceInternal::SocketOperationWrite, action);
+ }
+ catch(Platform::Exception^ ex)
+ {
+ IceInternal::checkErrorCode(__FILE__, __LINE__, ex->HResult);
+ }
+ return true;
+ }
+ return _delegate->startWrite(buf);
+}
+
+void
+IceSSL::TransceiverI::finishWrite(IceInternal::Buffer& buf)
+{
+ if(_connected && !_upgraded)
+ {
+ IceInternal::AsyncInfo* asyncInfo = getNativeInfo()->getAsyncInfo(IceInternal::SocketOperationWrite);
+ if(asyncInfo->count == SOCKET_ERROR)
+ {
+ IceInternal::checkErrorCode(__FILE__, __LINE__, asyncInfo->error);
+ }
+ return;
+ }
+ _delegate->finishWrite(buf);
+}
+
+void
+IceSSL::TransceiverI::startRead(IceInternal::Buffer& buf)
+{
+ _delegate->startRead(buf);
+}
+
+void
+IceSSL::TransceiverI::finishRead(IceInternal::Buffer& buf)
+{
+ _delegate->finishRead(buf);
+}
+
+string
+IceSSL::TransceiverI::protocol() const
+{
+ return _instance->protocol();
+}
+
+string
+IceSSL::TransceiverI::toString() const
+{
+ return _delegate->toString();
+}
+
+string
+IceSSL::TransceiverI::toDetailedString() const
+{
+ return toString();
+}
+
+Ice::ConnectionInfoPtr
+IceSSL::TransceiverI::getInfo() const
+{
+ NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo);
+ StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd());
+ info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, stream->Information->ServerCertificate));
+ info->certs.push_back(info->nativeCerts.back()->encode());
+ for(auto iter = stream->Information->ServerIntermediateCertificates->First(); iter->HasCurrent; iter->MoveNext())
+ {
+ info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, iter->Current));
+ info->certs.push_back(info->nativeCerts.back()->encode());
+ }
+ info->adapterName = _adapterName;
+ info->incoming = _incoming;
+ info->underlying = _delegate->getInfo();
+ return info;
+}
+
+void
+IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
+{
+}
+
+void
+IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
+{
+ _delegate->setBufferSize(rcvSize, sndSize);
+}
+
+IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
+ const IceInternal::TransceiverPtr& delegate,
+ const string& hostOrAdapterName,
+ bool incoming) :
+ _instance(instance),
+ _engine(WinRTEnginePtr::dynamicCast(instance->engine())),
+ _host(incoming ? "" : hostOrAdapterName),
+ _adapterName(incoming ? hostOrAdapterName : ""),
+ _incoming(incoming),
+ _delegate(delegate),
+ _connected(false),
+ _upgraded(false)
+{
+}
+
+IceSSL::TransceiverI::~TransceiverI()
+{
+}
+
+#endif
diff --git a/cpp/src/IceSSL/WinRTTransceiverI.h b/cpp/src/IceSSL/WinRTTransceiverI.h
new file mode 100755
index 00000000000..d3994eb359a
--- /dev/null
+++ b/cpp/src/IceSSL/WinRTTransceiverI.h
@@ -0,0 +1,81 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 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.
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_WINRT_TRANSCEIVER_I_H
+#define ICE_SSL_WINRT_TRANSCEIVER_I_H
+
+#include <IceSSL/Config.h>
+
+#ifdef ICE_OS_WINRT
+
+#include <IceSSL/InstanceF.h>
+#include <IceSSL/SSLEngineF.h>
+#include <IceSSL/Plugin.h>
+
+#include <Ice/Transceiver.h>
+#include <Ice/Network.h>
+
+namespace IceSSL
+{
+
+class ConnectorI;
+class AcceptorI;
+
+class TransceiverI : public IceInternal::Transceiver
+{
+public:
+
+ virtual IceInternal::NativeInfoPtr getNativeInfo();
+
+ virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&);
+#ifdef ICE_CPP11_MAPPING
+ virtual IceInternal::SocketOperation closing(bool, std::exception_ptr);
+#else
+ virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&);
+#endif
+ virtual void close();
+ virtual IceInternal::SocketOperation write(IceInternal::Buffer&);
+ virtual IceInternal::SocketOperation read(IceInternal::Buffer&);
+ virtual bool startWrite(IceInternal::Buffer&);
+ virtual void finishWrite(IceInternal::Buffer&);
+ virtual void startRead(IceInternal::Buffer&);
+ virtual void finishRead(IceInternal::Buffer&);
+
+ virtual std::string protocol() const;
+ virtual std::string toString() const;
+ virtual std::string toDetailedString() const;
+ virtual Ice::ConnectionInfoPtr getInfo() const;
+ virtual void checkSendSize(const IceInternal::Buffer&);
+ virtual void setBufferSize(int rcvSize, int sndSize);
+
+private:
+
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, bool);
+ virtual ~TransceiverI();
+
+ friend class ConnectorI;
+ friend class AcceptorI;
+
+ const InstancePtr _instance;
+ const WinRTEnginePtr _engine;
+ const std::string _host;
+ const std::string _adapterName;
+ const bool _incoming;
+ const IceInternal::TransceiverPtr _delegate;
+
+ bool _connected;
+ bool _upgraded;
+};
+typedef IceUtil::Handle<TransceiverI> TransceiverIPtr;
+
+}
+
+#endif
+
+#endif
diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj
index 2b35204da8a..6b376e66034 100644
--- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj
+++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj
@@ -136,10 +136,18 @@
<IceBuilder Include="..\..\..\..\..\slice\IceSSL\EndpointInfo.ice" />
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\..\uwp\AcceptorI.cpp" />
- <ClCompile Include="..\..\uwp\ConnectorI.cpp" />
- <ClCompile Include="..\..\uwp\EndpointI.cpp" />
- <ClCompile Include="..\..\uwp\TransceiverI.cpp" />
+ <ClCompile Include="..\..\AcceptorI.cpp" />
+ <ClCompile Include="..\..\Certificate.cpp" />
+ <ClCompile Include="..\..\ConnectorI.cpp" />
+ <ClCompile Include="..\..\EndpointI.cpp" />
+ <ClCompile Include="..\..\Instance.cpp" />
+ <ClCompile Include="..\..\PluginI.cpp" />
+ <ClCompile Include="..\..\RFC2253.cpp" />
+ <ClCompile Include="..\..\SSLEngine.cpp" />
+ <ClCompile Include="..\..\TrustManager.cpp" />
+ <ClCompile Include="..\..\Util.cpp" />
+ <ClCompile Include="..\..\WinRTEngine.cpp" />
+ <ClCompile Include="..\..\WinRTTransceiverI.cpp" />
<ClCompile Include="ARM\Debug\ConnectionInfo.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters
index 7d141e0bffd..17f262f778e 100644
--- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters
+++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters
@@ -75,18 +75,6 @@
</IceBuilder>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\..\uwp\AcceptorI.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\ConnectorI.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\EndpointI.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\uwp\TransceiverI.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="Win32\Debug\ConnectionInfo.cpp">
<Filter>Source Files\Win32\Debug</Filter>
</ClCompile>
@@ -123,6 +111,40 @@
<ClCompile Include="x64\Release\EndpointInfo.cpp">
<Filter>Source Files\x64\Release</Filter>
</ClCompile>
+ <ClCompile Include="..\..\ConnectorI.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\AcceptorI.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\EndpointI.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\Instance.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\SSLEngine.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\TrustManager.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\WinRTTransceiverI.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\PluginI.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\Certificate.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\Util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\WinRTEngine.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\RFC2253.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\uwp\AcceptorI.h">
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 81c335ad2dc..5fe808581fa 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -2527,7 +2527,7 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p)
}
bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
- bool override = p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic());
+ bool override = !p->isLocal() && p->canBeCyclic() && (!hasBaseClass || !bases.front()->canBeCyclic());
bool hasGCObjectBaseClass = basePreserved || override || preserved;
if(!basePreserved && (override || preserved))
{