How to gracefully shutdown a boost asio ssl client?

旧时模样 提交于 2019-11-29 03:35:45
maxschlepzig

One way to resolve the 'decryption failed or bad record mac' error code from the 2nd context is:

a) from inside the stdin handler call:

ssl::stream<tcp_socket>::lowest_layer()::shutdown(tcp::socket::shutdown_receive)

b) this results in the async_read_some() callback getting executed with a 'short read' 'error' code

c) in that callback under that 'error' condition async_shutdown() is called:

// const boost::system::error_code &ec
if (ec.category() == asio::error::get_ssl_category() &&
    ec.value()    == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) {
  // -> not a real error:
  do_ssl_async_shutdown();
}

d) the async_shutdown() callback is executed with a 'short read' error code, from where we finally call:

ssl::stream::lowest_layer()::close()

These steps result in a connection shutdown without any weird error messages on the client or server side.

For example, when using openssl s_server -state ... as server it reports on sutdown:

SSL3 alert read:warning:close notify
DONE
shutting down SSL
CONNECTION CLOSED
ACCEPT

(the last line is because the command accepts new connections)

Alternative

Instead of lowest_layer()::shutdown(tcp::socket::shutdown_receive) we can also call

ssl::stream<tcp_socket>::lowest_layer()::cancel()

to initiate a proper shutdown. It has the same effect, i.e. it yields the execution of the scheduled async_read_some() callback (but with operation_aborted error code). Thus, one can call async_shutdown() from there:

if (ec.value() == asio::error::operation_aborted) {
  cout << "(not really an error)\n";
  do_async_ssl_shutdown();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!