-
Notifications
You must be signed in to change notification settings - Fork 12
Refactor handshake #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 8 commits
eab1d14
66a435c
4ba64de
88ce93c
b437f7a
9971739
0d8b104
c6bb0b0
fd3aea5
7243bad
12aec4a
269342b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,17 +18,16 @@ namespace boost { | |||||
namespace wintls { | ||||||
namespace detail { | ||||||
|
||||||
template <typename NextLayer> | ||||||
template<typename NextLayer> | ||||||
struct async_handshake : boost::asio::coroutine { | ||||||
async_handshake(NextLayer& next_layer, detail::sspi_handshake& handshake, handshake_type type) | ||||||
: next_layer_(next_layer) | ||||||
, handshake_(handshake) | ||||||
, entry_count_(0) | ||||||
, state_(state::idle) { | ||||||
: next_layer_(next_layer) | ||||||
, handshake_(handshake) | ||||||
, entry_count_(0) { | ||||||
handshake_(type); | ||||||
} | ||||||
|
||||||
template <typename Self> | ||||||
template<typename Self> | ||||||
void operator()(Self& self, boost::system::error_code ec = {}, std::size_t length = 0) { | ||||||
if (ec) { | ||||||
self.complete(ec); | ||||||
|
@@ -40,94 +39,54 @@ struct async_handshake : boost::asio::coroutine { | |||||
return entry_count_ > 1; | ||||||
}; | ||||||
|
||||||
switch(state_) { | ||||||
case state::reading: | ||||||
handshake_.size_read(length); | ||||||
state_ = state::idle; | ||||||
break; | ||||||
case state::writing: | ||||||
handshake_.size_written(length); | ||||||
state_ = state::idle; | ||||||
break; | ||||||
case state::idle: | ||||||
break; | ||||||
} | ||||||
|
||||||
detail::sspi_handshake::state handshake_state; | ||||||
sspi_handshake::state handshake_state; | ||||||
BOOST_ASIO_CORO_REENTER(*this) { | ||||||
while((handshake_state = handshake_()) != detail::sspi_handshake::state::done) { | ||||||
if (handshake_state == detail::sspi_handshake::state::data_needed) { | ||||||
while (true) { | ||||||
handshake_state = handshake_(); | ||||||
if (handshake_state == sspi_handshake::state::data_needed) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
state_ = state::reading; | ||||||
next_layer_.async_read_some(handshake_.in_buffer(), std::move(self)); | ||||||
} | ||||||
handshake_.size_read(length); | ||||||
continue; | ||||||
} | ||||||
|
||||||
if (handshake_state == detail::sspi_handshake::state::data_available) { | ||||||
if (handshake_state == sspi_handshake::state::data_available) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
state_ = state::writing; | ||||||
net::async_write(next_layer_, handshake_.out_buffer(), std::move(self)); | ||||||
} | ||||||
handshake_.size_written(length); | ||||||
continue; | ||||||
} | ||||||
|
||||||
if (handshake_state == detail::sspi_handshake::state::error) { | ||||||
if (!is_continuation()) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
auto e = self.get_executor(); | ||||||
net::post(e, [self = std::move(self), ec, length]() mutable { self(ec, length); }); | ||||||
} | ||||||
} | ||||||
self.complete(handshake_.last_error()); | ||||||
return; | ||||||
} | ||||||
|
||||||
if (handshake_state == detail::sspi_handshake::state::done_with_data) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
state_ = state::writing; | ||||||
net::async_write(next_layer_, handshake_.out_buffer(), std::move(self)); | ||||||
} | ||||||
if (handshake_state == sspi_handshake::state::error) { | ||||||
break; | ||||||
} | ||||||
|
||||||
if (handshake_state == detail::sspi_handshake::state::error_with_data) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
state_ = state::writing; | ||||||
net::async_write(next_layer_, handshake_.out_buffer(), std::move(self)); | ||||||
} | ||||||
if (!is_continuation()) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
auto e = self.get_executor(); | ||||||
net::post(e, [self = std::move(self), ec, length]() mutable { self(ec, length); }); | ||||||
} | ||||||
} | ||||||
self.complete(handshake_.last_error()); | ||||||
return; | ||||||
if (handshake_state == sspi_handshake::state::done) { | ||||||
BOOST_ASSERT(!handshake_.last_error()); | ||||||
handshake_.manual_auth(); | ||||||
break; | ||||||
} | ||||||
} | ||||||
|
||||||
// If this is the first call to this function, it would cause the completion handler | ||||||
// (invoked by self.complete()) to be executed on the wrong executor. | ||||||
// Ensure that doesn't happen by posting the completion handler instead of calling it directly. | ||||||
if (!is_continuation()) { | ||||||
BOOST_ASIO_CORO_YIELD { | ||||||
auto e = self.get_executor(); | ||||||
net::post(e, [self = std::move(self), ec, length]() mutable { self(ec, length); }); | ||||||
|
net::post(e, [self = std::move(self), ec, length]() mutable { self(ec, length); }); | |
net::post(self.get_io_executor(), asio::append(std::move(self), ec, length)); |
This is bad because you lose the assocated executor, allocator & cancellation slot. Use append instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint!
asio::append
is available since boost 1.80 and from your blog post you linked above, i gather that self.get_io_executor()
is available since boost 1.81.
Currently wintls tests against older boost versions also and i think it is reasonable to support older versions for now, to keep the potential testing audience larger.
Hm, so maybe we should add a distinction based on BOOST_VERSION for now? @laudrup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this supposed to return
void
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a small lambda that returns bool.
Although i do not know why this is a lambda and not a simple bool variable. Technically, even the entry_count_ member could be a bool i suppose.
Then again, looking into the source of asio::detail::composed_op, it seems that it keeps track of its invocations itself and that we could access that via
asio::asio_handler_is_continuation(&self)
. Is that how it should be done?