diff options
Diffstat (limited to 'cpp/src/IceSSL/OpenSSLTransceiverI.cpp')
-rw-r--r-- | cpp/src/IceSSL/OpenSSLTransceiverI.cpp | 256 |
1 files changed, 124 insertions, 132 deletions
diff --git a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp index 9c0b260d9ac..9de9a9f53ea 100644 --- a/cpp/src/IceSSL/OpenSSLTransceiverI.cpp +++ b/cpp/src/IceSSL/OpenSSLTransceiverI.cpp @@ -94,30 +94,35 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal:: if(!_ssl) { SOCKET fd = _delegate->getNativeInfo()->fd(); - if(fd == INVALID_SOCKET) - { - // - // The delegate has finished its initialization but may not have a file descriptor yet (e.g., Bluetooth). - // The underlying transport must (eventually) be socket-based. - // - return IceInternal::SocketOperationRead; - } - -#ifdef ICE_USE_IOCP + BIO* bio = 0; + #ifdef ICE_USE_IOCP _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(fd)); _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(fd)); - BIO* bio; _sentBytes = 0; - if(!BIO_new_bio_pair(&bio, _maxSendPacketSize, &_iocpBio, _maxRecvPacketSize)) + if(!BIO_new_bio_pair(&bio, _maxSendPacketSize, &_memBio, _maxRecvPacketSize)) { bio = 0; - _iocpBio = 0; + _memBio = 0; } #else - // - // This static_cast is necessary due to 64bit windows. There SOCKET is a non-int type. - // - BIO* bio = BIO_new_socket(static_cast<int>(fd), 0); + if(fd == INVALID_SOCKET) + { + assert(_sentBytes == 0); + _maxSendPacketSize = 128 * 1024; // 128KB + _maxRecvPacketSize = 128 * 1024; // 128KB + if(!BIO_new_bio_pair(&bio, _maxSendPacketSize, &_memBio, _maxRecvPacketSize)) + { + bio = 0; + _memBio = 0; + } + } + else + { + // + // This static_cast is necessary due to 64bit windows. There SOCKET is a non-int type. + // + bio = BIO_new_socket(static_cast<int>(fd), 0); + } #endif if(!bio) @@ -129,10 +134,11 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal:: if(!_ssl) { BIO_free(bio); -#ifdef ICE_USE_IOCP - BIO_free(_iocpBio); - _iocpBio = 0; -#endif + if(_memBio) + { + BIO_free(_memBio); + _memBio = 0; + } throw SecurityException(__FILE__, __LINE__, "openssl failure"); } SSL_set_bio(_ssl, bio, bio); @@ -208,8 +214,7 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal:: sync.release(); #endif -#ifdef ICE_USE_IOCP - if(BIO_ctrl_pending(_iocpBio)) + if(_memBio && BIO_ctrl_pending(_memBio)) { if(!send()) { @@ -217,7 +222,6 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal:: } continue; } -#endif if(ret <= 0) { @@ -234,51 +238,48 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal:: } case SSL_ERROR_WANT_READ: { -#ifdef ICE_USE_IOCP - if(receive()) + if(_memBio && receive()) { continue; } -#endif return IceInternal::SocketOperationRead; } case SSL_ERROR_WANT_WRITE: { -#ifdef ICE_USE_IOCP - if(send()) + if(_memBio && send()) { continue; } -#endif return IceInternal::SocketOperationWrite; } case SSL_ERROR_SYSCALL: { -#ifndef ICE_USE_IOCP - if(IceInternal::interrupted()) + if(!_memBio) { - break; - } - - if(IceInternal::wouldBlock()) - { - if(SSL_want_read(_ssl)) + if(IceInternal::interrupted()) { - return IceInternal::SocketOperationRead; + break; } - else if(SSL_want_write(_ssl)) + + if(IceInternal::wouldBlock()) { - return IceInternal::SocketOperationWrite; + if(SSL_want_read(_ssl)) + { + return IceInternal::SocketOperationRead; + } + else if(SSL_want_write(_ssl)) + { + return IceInternal::SocketOperationWrite; + } + + break; } - break; - } - - if(IceInternal::connectionLost() || IceInternal::getSocketErrno() == 0) - { - throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + if(IceInternal::connectionLost() || IceInternal::getSocketErrno() == 0) + { + throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); + } } -#endif throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno()); } case SSL_ERROR_SSL: @@ -377,13 +378,11 @@ OpenSSL::TransceiverI::close() _ssl = 0; } -#ifdef ICE_USE_IOCP - if(_iocpBio) + if(_memBio) { - BIO_free(_iocpBio); - _iocpBio = 0; + BIO_free(_memBio); + _memBio = 0; } -#endif _delegate->close(); } @@ -396,15 +395,13 @@ OpenSSL::TransceiverI::write(IceInternal::Buffer& buf) return _delegate->write(buf); } -#ifdef ICE_USE_IOCP - if(_writeBuffer.i != _writeBuffer.b.end()) + if(_memBio && _writeBuffer.i != _writeBuffer.b.end()) { if(!send()) { return IceInternal::SocketOperationWrite; } } -#endif if(buf.i == buf.b.end()) { @@ -414,37 +411,39 @@ OpenSSL::TransceiverI::write(IceInternal::Buffer& buf) // // It's impossible for packetSize to be more than an Int. // - int packetSize = -#ifdef ICE_USE_IOCP - std::min(static_cast<int>(_maxSendPacketSize), static_cast<int>(buf.b.end() - buf.i)); -#else + int packetSize = _memBio ? + std::min(static_cast<int>(_maxSendPacketSize), static_cast<int>(buf.b.end() - buf.i)) : static_cast<int>(buf.b.end() - buf.i); -#endif + while(buf.i != buf.b.end()) { ERR_clear_error(); // Clear any spurious errors. -#ifdef ICE_USE_IOCP int ret; - if(_sentBytes) + if(_memBio) { - ret = _sentBytes; - _sentBytes = 0; - } - else - { - ret = SSL_write(_ssl, reinterpret_cast<const void*>(&*buf.i), packetSize); - if(ret > 0) + if(_sentBytes) { - if(!send()) + ret = _sentBytes; + _sentBytes = 0; + } + else + { + ret = SSL_write(_ssl, reinterpret_cast<const void*>(&*buf.i), packetSize); + if(ret > 0) { - _sentBytes = ret; - return IceInternal::SocketOperationWrite; + if(!send()) + { + _sentBytes = ret; + return IceInternal::SocketOperationWrite; + } } } } -#else - int ret = SSL_write(_ssl, reinterpret_cast<const void*>(&*buf.i), packetSize); -#endif + else + { + ret = SSL_write(_ssl, reinterpret_cast<const void*>(&*buf.i), packetSize); + } + if(ret <= 0) { switch(SSL_get_error(_ssl, ret)) @@ -463,35 +462,34 @@ OpenSSL::TransceiverI::write(IceInternal::Buffer& buf) } case SSL_ERROR_WANT_WRITE: { -#ifdef ICE_USE_IOCP - if(send()) + if(_memBio && send()) { continue; } -#endif return IceInternal::SocketOperationWrite; } case SSL_ERROR_SYSCALL: { -#ifndef ICE_USE_IOCP - - if(IceInternal::interrupted()) + if(!_memBio) { - continue; - } + if(IceInternal::interrupted()) + { + continue; + } - if(IceInternal::noBuffers() && packetSize > 1024) - { - packetSize /= 2; - continue; - } + if(IceInternal::noBuffers() && packetSize > 1024) + { + packetSize /= 2; + continue; + } - if(IceInternal::wouldBlock()) - { - assert(SSL_want_write(_ssl)); - return IceInternal::SocketOperationWrite; + if(IceInternal::wouldBlock()) + { + assert(SSL_want_write(_ssl)); + return IceInternal::SocketOperationWrite; + } } -#endif + if(IceInternal::connectionLost() || IceInternal::getSocketErrno() == 0) { throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); @@ -527,15 +525,13 @@ OpenSSL::TransceiverI::read(IceInternal::Buffer& buf) return _delegate->read(buf); } -#ifdef ICE_USE_IOCP - if(_readBuffer.i != _readBuffer.b.end()) + if(_memBio && _readBuffer.i != _readBuffer.b.end()) { if(!receive()) { return IceInternal::SocketOperationRead; } } -#endif // // Note: We assume that OpenSSL doesn't read more SSL records than @@ -573,12 +569,10 @@ OpenSSL::TransceiverI::read(IceInternal::Buffer& buf) } case SSL_ERROR_WANT_READ: { -#ifdef ICE_USE_IOCP - if(receive()) + if(_memBio && receive()) { continue; } -#endif return IceInternal::SocketOperationRead; } case SSL_ERROR_WANT_WRITE: @@ -588,24 +582,26 @@ OpenSSL::TransceiverI::read(IceInternal::Buffer& buf) } case SSL_ERROR_SYSCALL: { -#ifndef ICE_USE_IOCP - if(IceInternal::interrupted()) + if(!_memBio) { - continue; - } + if(IceInternal::interrupted()) + { + continue; + } - if(IceInternal::noBuffers() && packetSize > 1024) - { - packetSize /= 2; - continue; - } + if(IceInternal::noBuffers() && packetSize > 1024) + { + packetSize /= 2; + continue; + } - if(IceInternal::wouldBlock()) - { - assert(SSL_want_read(_ssl)); - return IceInternal::SocketOperationRead; + if(IceInternal::wouldBlock()) + { + assert(SSL_want_read(_ssl)); + return IceInternal::SocketOperationRead; + } } -#endif + if(IceInternal::connectionLost() || IceInternal::getSocketErrno() == 0) { throw ConnectionLostException(__FILE__, __LINE__, IceInternal::getSocketErrno()); @@ -655,10 +651,10 @@ OpenSSL::TransceiverI::startWrite(IceInternal::Buffer& buffer) int packetSize = std::min(static_cast<int>(_maxSendPacketSize), static_cast<int>(buffer.b.end() - buffer.i)); _sentBytes = SSL_write(_ssl, reinterpret_cast<void*>(&*buffer.i), packetSize); - assert(BIO_ctrl_pending(_iocpBio)); - _writeBuffer.b.resize( BIO_ctrl_pending(_iocpBio)); + assert(BIO_ctrl_pending(_memBio)); + _writeBuffer.b.resize( BIO_ctrl_pending(_memBio)); _writeBuffer.i = _writeBuffer.b.begin(); - BIO_read(_iocpBio, _writeBuffer.i, static_cast<int>(_writeBuffer.b.size())); + BIO_read(_memBio, _writeBuffer.i, static_cast<int>(_writeBuffer.b.size())); } return _delegate->startWrite(_writeBuffer) && buffer.i == buffer.b.end(); @@ -700,8 +696,8 @@ OpenSSL::TransceiverI::startRead(IceInternal::Buffer& buffer) SSL_read(_ssl, reinterpret_cast<void*>(&*buffer.i), static_cast<int>(buffer.b.end() - buffer.i)); assert(ret <= 0 && SSL_get_error(_ssl, ret) == SSL_ERROR_WANT_READ); - assert(BIO_ctrl_get_read_request(_iocpBio)); - _readBuffer.b.resize(BIO_ctrl_get_read_request(_iocpBio)); + assert(BIO_ctrl_get_read_request(_memBio)); + _readBuffer.b.resize(BIO_ctrl_get_read_request(_memBio)); _readBuffer.i = _readBuffer.b.begin(); } @@ -722,7 +718,7 @@ OpenSSL::TransceiverI::finishRead(IceInternal::Buffer& buffer) _delegate->finishRead(_readBuffer); if(_readBuffer.i == _readBuffer.b.end()) { - int n = BIO_write(_iocpBio, _readBuffer.b.begin(), static_cast<int>(_readBuffer.b.size())); + int n = BIO_write(_memBio, _readBuffer.b.begin(), static_cast<int>(_readBuffer.b.size())); if(n < 0) // Expected if the transceiver was closed. { throw SecurityException(__FILE__, __LINE__, "SSL bio write failed"); @@ -872,13 +868,11 @@ OpenSSL::TransceiverI::TransceiverI(const InstancePtr& instance, _delegate(delegate), _connected(false), _verified(false), - _ssl(0) -#ifdef ICE_USE_IOCP - , _iocpBio(0), + _ssl(0), + _memBio(0), _sentBytes(0), _maxSendPacketSize(0), _maxRecvPacketSize(0) -#endif { } @@ -886,14 +880,13 @@ OpenSSL::TransceiverI::~TransceiverI() { } -#ifdef ICE_USE_IOCP bool OpenSSL::TransceiverI::receive() { if(_readBuffer.i == _readBuffer.b.end()) { - assert(BIO_ctrl_get_read_request(_iocpBio)); - _readBuffer.b.resize(BIO_ctrl_get_read_request(_iocpBio)); + assert(BIO_ctrl_get_read_request(_memBio)); + _readBuffer.b.resize(BIO_ctrl_get_read_request(_memBio)); _readBuffer.i = _readBuffer.b.begin(); } @@ -910,7 +903,7 @@ OpenSSL::TransceiverI::receive() #ifndef NDEBUG int n = #endif - BIO_write(_iocpBio, &_readBuffer.b[0], static_cast<int>(_readBuffer.b.end() - _readBuffer.b.begin())); + BIO_write(_memBio, &_readBuffer.b[0], static_cast<int>(_readBuffer.b.end() - _readBuffer.b.begin())); assert(n == static_cast<int>(_readBuffer.b.end() - _readBuffer.b.begin())); @@ -922,10 +915,10 @@ OpenSSL::TransceiverI::send() { if(_writeBuffer.i == _writeBuffer.b.end()) { - assert(BIO_ctrl_pending(_iocpBio)); - _writeBuffer.b.resize( BIO_ctrl_pending(_iocpBio)); + assert(BIO_ctrl_pending(_memBio)); + _writeBuffer.b.resize( BIO_ctrl_pending(_memBio)); _writeBuffer.i = _writeBuffer.b.begin(); - BIO_read(_iocpBio, _writeBuffer.i, static_cast<int>(_writeBuffer.b.size())); + BIO_read(_memBio, _writeBuffer.i, static_cast<int>(_writeBuffer.b.size())); } if(_writeBuffer.i != _writeBuffer.b.end()) @@ -937,4 +930,3 @@ OpenSSL::TransceiverI::send() } return _writeBuffer.i == _writeBuffer.b.end(); } -#endif |