diff options
author | Benoit Foucher <benoit@zeroc.com> | 2016-06-27 17:54:30 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2016-06-27 17:54:30 +0200 |
commit | c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7 (patch) | |
tree | 5cb64dfe155e5d2349efb6c7dc4b0f5b5284d44a /cpp/src/Ice/StreamSocket.cpp | |
parent | Fix Windows php build to restore nuget packages (diff) | |
download | ice-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/Ice/StreamSocket.cpp')
-rwxr-xr-x[-rw-r--r--] | cpp/src/Ice/StreamSocket.cpp | 197 |
1 files changed, 181 insertions, 16 deletions
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; } } - - |