• <tfoot id='X0mEt'></tfoot>
    • <bdo id='X0mEt'></bdo><ul id='X0mEt'></ul>

  • <i id='X0mEt'><tr id='X0mEt'><dt id='X0mEt'><q id='X0mEt'><span id='X0mEt'><b id='X0mEt'><form id='X0mEt'><ins id='X0mEt'></ins><ul id='X0mEt'></ul><sub id='X0mEt'></sub></form><legend id='X0mEt'></legend><bdo id='X0mEt'><pre id='X0mEt'><center id='X0mEt'></center></pre></bdo></b><th id='X0mEt'></th></span></q></dt></tr></i><div id='X0mEt'><tfoot id='X0mEt'></tfoot><dl id='X0mEt'><fieldset id='X0mEt'></fieldset></dl></div>
  • <small id='X0mEt'></small><noframes id='X0mEt'>

      1. <legend id='X0mEt'><style id='X0mEt'><dir id='X0mEt'><q id='X0mEt'></q></dir></style></legend>

        如何优雅地关闭 boost asio ssl 客户端?

        时间:2024-08-14
          <bdo id='Lins7'></bdo><ul id='Lins7'></ul>

            • <i id='Lins7'><tr id='Lins7'><dt id='Lins7'><q id='Lins7'><span id='Lins7'><b id='Lins7'><form id='Lins7'><ins id='Lins7'></ins><ul id='Lins7'></ul><sub id='Lins7'></sub></form><legend id='Lins7'></legend><bdo id='Lins7'><pre id='Lins7'><center id='Lins7'></center></pre></bdo></b><th id='Lins7'></th></span></q></dt></tr></i><div id='Lins7'><tfoot id='Lins7'></tfoot><dl id='Lins7'><fieldset id='Lins7'></fieldset></dl></div>
            • <tfoot id='Lins7'></tfoot>

              1. <small id='Lins7'></small><noframes id='Lins7'>

                <legend id='Lins7'><style id='Lins7'><dir id='Lins7'><q id='Lins7'></q></dir></style></legend>
                  <tbody id='Lins7'></tbody>
                  本文介绍了如何优雅地关闭 boost asio ssl 客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  客户端执行一些 ssl::stream::async_read_some()/ssl::stream::async_write() 调用和一些点需要退出,即需要关闭连接.

                  调用 ssl::stream<tcp_socket>::lowest_layer().close() 有效,但是(正如预期的那样)服务器(一个 openssl s_server -state ... 命令)在关闭连接时报告错误.

                  查看 API 的正确方法似乎是调用 ssl::stream::async_shutdown().

                  现在基本上有两种情况需要关机:

                  1) 客户端在 async_read_some() 回调中并对来自服务器的退出"命令做出反应.从那里调用 async_shutdown() 会在关闭回调中产生短读"错误.

                  这令人惊讶,但在谷歌搜索之后这似乎是正常行为 - 人们似乎必须检查它是否是一个真正的错误或不是这样的:

                  //const boost::system::error_code &ecif (ec.category() == asio::error::get_ssl_category() &&ec.value() == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) {//->不是真正的错误,只是正常的 TLS 关闭}

                  TLS 服务器似乎很高兴,不过 - 它报告:

                  完成关闭 SSL连接已关闭

                  2) async_read_some() 处于活动状态 - 但用户决定退出客户端(例如,通过来自 stdin 的命令).当从该上下文调用 async_shutdown() 时,会发生以下情况:

                  • async_read_some() 回调执行时带有短读"错误代码 - 现在是预期的
                  • async_shutdown() 回调执行时带有解密失败或记录错误 mac 错误代码 - 这是意外的

                  服务端不报错.

                  因此我的问题是如何使用 boost asio 正确关闭 TLS 客户端.

                  解决方案

                  解决第二个上下文中解密失败或错误记录 mac"错误代码的一种方法是:

                  a) 来自 stdin 处理程序调用:

                  ssl::stream::lowest_layer()::shutdown(tcp::socket::shutdown_receive)

                  b) 这导致 async_read_some() 回调以短读"错误"代码执行

                  c) 在那个错误"条件下的回调中 async_shutdown() 被调用:

                  //const boost::system::error_code &ecif (ec.category() == asio::error::get_ssl_category() &&ec.value() == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) {//->不是真正的错误:do_ssl_async_shutdown();}

                  d) async_shutdown() 回调执行时带有一个短读"错误代码,我们最终从这里调用:

                  <前>ssl::stream::lowest_layer()::close()

                  这些步骤导致连接关闭,客户端或服务器端没有任何奇怪的错误消息.

                  例如,当使用 openssl s_server -state ... 作为服务器时,它会报告 sutdown:

                  <前>SSL3 警报读取:警告:关闭通知完毕关闭 SSL连接已关闭接受

                  (最后一行是因为该命令接受新连接)

                  替代方案

                  代替lowest_layer()::shutdown(tcp::socket::shutdown_receive) 我们也可以调用

                  ssl::stream::lowest_layer()::cancel()

                  启动适当的关闭.它具有相同的效果,即它产生预定的 async_read_some() 回调的执行(但带有 operation_aborted 错误代码).因此,可以从那里调用 async_shutdown():

                  if (ec.value() == asio::error::operation_aborted) {cout<<"(不是真正的错误)
                  ";do_async_ssl_shutdown();}

                  The client does some ssl::stream<tcp_socket>::async_read_some()/ssl::stream<tcp_socket>::async_write() calls and at some point needs to exit, i.e. it needs to shutdown the connection.

                  Calling ssl::stream<tcp_socket>::lowest_layer().close() works, but (as it is expected) the server (a openssl s_server -state ... command) reports an error on closing the connection.

                  Looking at the API the right way seems to be to call ssl::stream<tcp_socket>::async_shutdown().

                  Now there are basically 2 situation where a shutdown is needed:

                  1) Client is in the async_read_some() callback and reacts on a 'quit' command from the server. Calling from there async_shutdown() yields a 'short read' error in the shutdown callback.

                  This is surprising but after googling around this seems to be normal behaviour - one seem to have to check if it is a real error or not like this:

                  // 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, just a normal TLS shutdown
                  }
                  

                  The TLS server seems to be happy, though - it reports:

                  DONE
                  shutting down SSL
                  CONNECTION CLOSED
                  

                  2) A async_read_some() is active - but a user decides to exit the client (e.g. via a command from stdin). When calling async_shutdown() from that context following happens:

                  • the async_read_some() callback is executed with a 'short read' error code - kind of expected now
                  • the async_shutdown() callback is executed with a decryption failed or bad record mac error code - this is unexpected

                  The server side does not report an error.

                  Thus my question how to properly shutdown a TLS client with boost asio.

                  解决方案

                  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)
                  ";
                    do_async_ssl_shutdown();
                  }
                  

                  这篇关于如何优雅地关闭 boost asio ssl 客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何使用 openssl 从 PKCS7.p7b 证书文件中读取证书文件? 下一篇:从 RSA 密钥对变量中分离公钥和私钥

                  相关文章

                  <i id='ZqTDs'><tr id='ZqTDs'><dt id='ZqTDs'><q id='ZqTDs'><span id='ZqTDs'><b id='ZqTDs'><form id='ZqTDs'><ins id='ZqTDs'></ins><ul id='ZqTDs'></ul><sub id='ZqTDs'></sub></form><legend id='ZqTDs'></legend><bdo id='ZqTDs'><pre id='ZqTDs'><center id='ZqTDs'></center></pre></bdo></b><th id='ZqTDs'></th></span></q></dt></tr></i><div id='ZqTDs'><tfoot id='ZqTDs'></tfoot><dl id='ZqTDs'><fieldset id='ZqTDs'></fieldset></dl></div>

                    <legend id='ZqTDs'><style id='ZqTDs'><dir id='ZqTDs'><q id='ZqTDs'></q></dir></style></legend>

                    <tfoot id='ZqTDs'></tfoot>
                      <bdo id='ZqTDs'></bdo><ul id='ZqTDs'></ul>

                    <small id='ZqTDs'></small><noframes id='ZqTDs'>