C++ boost asio ssl异步\u关闭是否总是以错误结束?
我有一个用boost 1.55 asio编程的小型ssl客户端,我正在试图弄清楚为什么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::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连接,在关机过程中会出现以下错误代码:
- 一方启动关闭,远程方关闭或已经关闭基础传输,但未关闭协议:
- 启动器的
操作将失败,并出现SSL短读错误shutdown()
- 启动器的
- 一方启动关闭并等待远程方关闭协议:
- 启动器的关闭操作将完成,错误值为
boost::asio::error::eof
- 远程方的
操作成功完成shutdown()
- 启动器的关闭操作将完成,错误值为
- 一方启动关闭,然后关闭基础协议,而无需等待远程方关闭协议:
- 启动器的
操作将被取消,导致错误shutdown()
。这是以下详细信息中说明的解决方法的结果boost::asio::error::operation\u被中止。
- 远程方的
操作成功完成shutdown()
- 启动器的
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() );
}
}