How to gracefully shutdown a boost asio ssl client?

后端 未结 1 1671
被撕碎了的回忆
被撕碎了的回忆 2020-12-15 21:24

The client does some ssl::stream::async_read_some()/ssl::stream::async_write() calls and at some point needs to

相关标签:
1条回答
  • 2020-12-15 21:38

    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();
    }
    
    0 讨论(0)
提交回复
热议问题