aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls
diff options
context:
space:
mode:
authorTim Oesterreich <[email protected]>2019-03-06 14:50:46 +0100
committerHannes Rantzsch <[email protected]>2019-04-16 10:48:13 +0200
commite2ed1d7af6302d2d4f5da9460be85e2f99f7b6d0 (patch)
tree0ddfb94c3f062d251d0a2ad8262d59b6d157995e /src/lib/tls
parent8956112490dffbd418f01d3608268d9cce5b3cef (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.h17
-rw-r--r--src/lib/tls/asio/asio_async_read_op.h21
-rw-r--r--src/lib/tls/asio/asio_async_write_op.h14
-rw-r--r--src/lib/tls/asio/asio_stream.h8
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();
}