diff options
author | Tim Oesterreich <[email protected]> | 2019-03-06 14:50:46 +0100 |
---|---|---|
committer | Hannes Rantzsch <[email protected]> | 2019-04-16 10:48:13 +0200 |
commit | e2ed1d7af6302d2d4f5da9460be85e2f99f7b6d0 (patch) | |
tree | 0ddfb94c3f062d251d0a2ad8262d59b6d157995e /src/lib/tls | |
parent | 8956112490dffbd418f01d3608268d9cce5b3cef (diff) |
do not call completion_handler directly; allow async ops to be constructed with optional error_code
Diffstat (limited to 'src/lib/tls')
-rw-r--r-- | src/lib/tls/asio/asio_async_handshake_op.h | 17 | ||||
-rw-r--r-- | src/lib/tls/asio/asio_async_read_op.h | 21 | ||||
-rw-r--r-- | src/lib/tls/asio/asio_async_write_op.h | 14 | ||||
-rw-r--r-- | src/lib/tls/asio/asio_stream.h | 8 |
4 files changed, 35 insertions, 25 deletions
diff --git a/src/lib/tls/asio/asio_async_handshake_op.h b/src/lib/tls/asio/asio_async_handshake_op.h index 0a3ee2ffa..eee553424 100644 --- a/src/lib/tls/asio/asio_async_handshake_op.h +++ b/src/lib/tls/asio/asio_async_handshake_op.h @@ -32,12 +32,14 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec AsyncHandshakeOperation( HandlerT&& handler, Stream& stream, - StreamCore& core) + StreamCore& core, + const boost::system::error_code& ec = {}) : AsyncBase<Handler, typename Stream::executor_type, Allocator>( std::forward<HandlerT>(handler), stream.get_executor()) , m_stream(stream) , m_core(core) + , m_ec(ec) { } @@ -50,6 +52,7 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec { reenter(this) { + if(ec) { m_ec = ec; } // process tls packets from socket first if(bytesTransferred > 0) { @@ -60,12 +63,12 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec } catch(const std::exception&) { - ec = convertException(); + m_ec = convertException(); } } // send tls packets - if(m_core.hasDataToSend() && !ec) + if(m_core.hasDataToSend() && !m_ec) { // \note: we construct `AsyncWriteOperation` with 0 as its last parameter (`plainBytesTransferred`). // This operation will eventually call `*this` as its own handler, passing the 0 back to this call @@ -81,7 +84,7 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec } // we need more tls data from the socket - if(!m_stream.native_handle()->is_active() && !ec) + if(!m_stream.native_handle()->is_active() && !m_ec) { m_stream.next_layer().async_read_some(m_core.input_buffer, std::move(*this)); return; @@ -92,12 +95,10 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec // this 0 byte read completes immediately. `yield` causes the coroutine to reenter the function after // this read, enabling us to call the handler, while respecting asios guarantee that the handler will not // be called without an intermediate initiating function - m_ec_store = ec; yield m_stream.next_layer().async_read_some(boost::asio::mutable_buffer(), std::move(*this)); - ec = m_ec_store; } - this->invoke_now(ec); + this->invoke_now(m_ec); } } @@ -105,7 +106,7 @@ struct AsyncHandshakeOperation : public AsyncBase<Handler, typename Stream::exec Stream& m_stream; StreamCore& m_core; - boost::system::error_code m_ec_store; + boost::system::error_code m_ec; }; } // namespace TLS diff --git a/src/lib/tls/asio/asio_async_read_op.h b/src/lib/tls/asio/asio_async_read_op.h index d849c6994..eaaf8ea33 100644 --- a/src/lib/tls/asio/asio_async_read_op.h +++ b/src/lib/tls/asio/asio_async_read_op.h @@ -32,7 +32,8 @@ struct AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_ AsyncReadOperation(HandlerT&& handler, Stream& stream, StreamCore& core, - const MutableBufferSequence& buffers) + const MutableBufferSequence& buffers, + const boost::system::error_code& ec = {}) : AsyncBase<Handler, typename Stream::executor_type, Allocator>( std::forward<HandlerT>(handler), stream.get_executor()) @@ -40,6 +41,7 @@ struct AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_ , m_core(core) , m_buffers(buffers) , m_decodedBytes(0) + , m_ec(ec) { } @@ -52,7 +54,8 @@ struct AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_ { reenter(this) { - if(bytes_transferred > 0 && !ec) + if(ec) { m_ec = ec; } + if(bytes_transferred > 0 && !m_ec) { boost::asio::const_buffer read_buffer{m_core.input_buffer.data(), bytes_transferred}; try @@ -62,31 +65,29 @@ struct AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_ } catch(const std::exception&) { - ec = convertException(); + m_ec = convertException(); } } - if(!m_core.hasReceivedData() && !ec) + if(!m_core.hasReceivedData() && !m_ec) { // we need more tls packets from the socket m_stream.next_layer().async_read_some(m_core.input_buffer, std::move(*this)); return; } - if(m_core.hasReceivedData() && !ec) + if(m_core.hasReceivedData() && !m_ec) { m_decodedBytes = m_core.copyReceivedData(m_buffers); - ec = {}; + m_ec = {}; } if(!isContinuation) { - m_ec_store = ec; yield m_stream.next_layer().async_read_some(boost::asio::mutable_buffer(), std::move(*this)); - ec = m_ec_store; } - this->invoke_now(ec, m_decodedBytes); + this->invoke_now(m_ec, m_decodedBytes); } } @@ -95,8 +96,8 @@ struct AsyncReadOperation : public AsyncBase<Handler, typename Stream::executor_ StreamCore& m_core; MutableBufferSequence m_buffers; - boost::system::error_code m_ec_store; size_t m_decodedBytes; + boost::system::error_code m_ec; }; } // namespace TLS diff --git a/src/lib/tls/asio/asio_async_write_op.h b/src/lib/tls/asio/asio_async_write_op.h index df1cb9a9a..e8cda3e76 100644 --- a/src/lib/tls/asio/asio_async_write_op.h +++ b/src/lib/tls/asio/asio_async_write_op.h @@ -31,13 +31,15 @@ struct AsyncWriteOperation : public AsyncBase<Handler, typename Stream::executor AsyncWriteOperation(HandlerT&& handler, Stream& stream, StreamCore& core, - std::size_t plainBytesTransferred) + std::size_t plainBytesTransferred, + const boost::system::error_code& ec = {}) : AsyncBase<Handler, typename Stream::executor_type, Allocator>( std::forward<HandlerT>(handler), stream.get_executor()) , m_stream(stream) , m_core(core) , m_plainBytesTransferred(plainBytesTransferred) + , m_ec(ec) { } @@ -52,24 +54,24 @@ struct AsyncWriteOperation : public AsyncBase<Handler, typename Stream::executor { m_core.consumeSendBuffer(bytes_transferred); + if(ec) { m_ec = ec; } + if(!isContinuation) { - m_ec_store = ec; yield m_stream.next_layer().async_write_some(boost::asio::const_buffer(), std::move(*this)); - ec = m_ec_store; } // the size of the sent TLS record can differ from the size of the payload due to TLS encryption. We need to tell // the handler how many bytes of the original data we already processed. - this->invoke_now(ec, ec ? 0 : m_plainBytesTransferred); + this->invoke_now(m_ec, m_ec ? 0 : m_plainBytesTransferred); } } Stream& m_stream; StreamCore& m_core; - std::size_t m_plainBytesTransferred; - boost::system::error_code m_ec_store; + std::size_t m_plainBytesTransferred; + boost::system::error_code m_ec; }; } // namespace TLS diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h index 224bf5fa7..7a77844a7 100644 --- a/src/lib/tls/asio/asio_stream.h +++ b/src/lib/tls/asio/asio_stream.h @@ -380,7 +380,13 @@ class Stream : public StreamBase<Channel> } catch(const std::exception&) { - init.completion_handler(Botan::TLS::convertException(), std::size_t(0)); + Botan::TLS::AsyncWriteOperation<typename std::decay<WriteHandler>::type, Stream> + op{std::move(init.completion_handler), + *this, + this->m_core, + std::size_t(0), + Botan::TLS::convertException()}; + boost::asio::async_write(m_nextLayer, this->m_core.sendBuffer(), std::move(op)); return init.result.get(); } |