C++ boost asio ssl异步\u关闭是否总是以错误结束?

C++ boost asio ssl异步\u关闭是否总是以错误结束?,c++,ssl,boost,openssl,boost-asio,C++,Ssl,Boost,Openssl,Boost Asio,我有一个用boost 1.55 asio编程的小型ssl客户端,我正在试图弄清楚为什么boost::asio::ssl::stream::async_shutdown()总是失败。该客户端与boost文档中的ssl客户端示例非常相似(几乎完全相同),因为它经历了一个boost::asio::ip::tcp::resolver::async_resolve()->boost::asio::ssl::stream::async_connect()->boost::asio::ssl::stream:

我有一个用boost 1.55 asio编程的小型ssl客户端,我正在试图弄清楚为什么
boost::asio::ssl::stream::async_shutdown()
总是失败。该客户端与boost文档中的ssl客户端示例非常相似(几乎完全相同),因为它经历了一个
boost::asio::ip::tcp::resolver::async_resolve()
->
boost::asio::ssl::stream::async_connect()
->
boost::asio::ssl::stream::async_握手()
回调序列。所有这些都按预期工作,并且
async\u handshake()
回调得到一个完全清除的
boost::system::error\u code

async\u handshake()
回调中,我调用
async\u shutdown()
(我不传输任何数据-此对象更多用于测试握手):

然后调用
handle\u shutdown\u success()
,但总是出错?错误为
asio.misc
中的值=2,即“文件结束”。我曾在各种ssl服务器上尝试过这一点,但我似乎总是遇到这个
asio.misc
错误。这不是一个潜在的openssl错误,这表明我可能在某种程度上滥用了asio


有人知道为什么会这样吗?我觉得用
async_shutdown()
关闭连接是正确的做法,但我想我可以调用
boost::asio::ssl::stream.lowestlayer().close()
从openssl下关闭套接字,如果这是预期的方法的话(事实上,asio ssl示例似乎表明这是正确的关机方式)。

对于加密安全关机,双方必须通过调用
shutdown()
async\u shutdown()在上执行关机操作
并运行
io_服务
。如果操作完成时出现
错误_code
,并且在部分关闭之前未取消,则连接已安全关闭,底层传输可重复使用或关闭。只需关闭最低层,会话可能会失败对一个公司来说是可行的


协议和Boost.asioapi 在标准化协议和非标准化协议中,安全关机涉及各方交换
close\u notify
消息。就Boost.Asio API而言,任何一方都可以通过调用
shutdown()
async\u shutdown()来启动关机
,导致向另一方发送
close\u notify
消息,通知收件人启动器将不会在SSL连接上发送更多消息。根据规范,收件人必须响应
close\u notify
消息。Boost.Asio不会自动执行此行为,并且需要reci允许显式调用
shutdown()
async\u shutdown()

规范允许关机的发起人在收到
close\u notify
响应之前关闭其连接的读取端。这用于应用程序协议不希望重用基础协议的情况。遗憾的是,Boost.Asio当前没有(1.56)为该功能提供直接支持。在Boost.Asio中,如果出现错误或当一方已发送和接收到
close\u notify
消息,则认为
shutdown()
操作已完成。一旦操作完成,应用程序可重用基础协议或将其关闭

场景和错误代码 一旦建立SSL连接,在关机过程中会出现以下错误代码:

  • 一方启动关闭,远程方关闭或已经关闭基础传输,但未关闭协议:
    • 启动器的
      shutdown()
      操作将失败,并出现SSL短读错误
  • 一方启动关闭并等待远程方关闭协议:
    • 启动器的关闭操作将完成,错误值为
      boost::asio::error::eof
    • 远程方的
      shutdown()
      操作成功完成
  • 一方启动关闭,然后关闭基础协议,而无需等待远程方关闭协议:
    • 启动器的
      shutdown()
      操作将被取消,导致错误
      boost::asio::error::operation\u被中止。
      。这是以下详细信息中说明的解决方法的结果
    • 远程方的
      shutdown()
      操作成功完成
下面详细介绍了这些不同的场景。每个场景都用一个类似游动线的图表进行了说明,表明了各方在同一时间点上正在做什么

PartyB关闭连接而不协商关闭后,PartyA调用
shutdown()
。 在此场景中,PartyB在未首先调用流上的
shutdown()
的情况下关闭底层传输,从而违反了关闭过程。一旦底层传输关闭,PartyA将尝试启动
shutdown()

PartyA | PartyB
-------------------------------------+----------------------------------------
ssl_流。握手(…);| ssl_流。握手(…);
…| ssl_流。最低层().close();
ssl_stream.shutdown()|
PartyA将尝试发送
close\u notify
消息,但对基础传输的写入将失败,并出现
boost::asio::error::eof
.boost。由于PartyB违反了SSL关闭过程,asio将基础传输的
eof
错误转换为SSL短读错误

if((error.category()==boost::a
void ClientCertificateFinder::handle_handshake(const boost::system::error_code& e)
{
    if ( !e )
    {
        m_socket.async_shutdown( boost::bind( &ClientCertificateFinder::handle_shutdown_after_success, 
            this, 
            boost::asio::placeholders::error ) );
    }
    else
    {
        m_handler( e, IssuerNameList() );
    }
}