What is the proper way to securely disconnect an asio SSL socket?

给你一囗甜甜゛ 提交于 2019-11-27 04:54:47
Tanner Sansbury

To securely disconnect, perform a shutdown operation and then close the underlying transport once shutdown has complete. Hence, the method you are currently using will perform a secure disconnect:

boost::system::error_code ec;
ssl_socket.cancel(ec);
ssl_socket.async_shutdown([](...) { ssl_socket.close(); };

Be aware that the current async_shutdown operation will be considered complete when either:

  • A close_notify has been received by the remote peer.
  • The remote peer closes the socket.
  • The operation has been cancelled.

Hence, if resources are bound to the lifetime of the socket or connection, then these resources will remain alive waiting for the remote peer to take action or until the operation is cancelled locally. However, waiting for a close_notify response is not required for a secure shutdown. If resources are bound to the connection, and locally the connection is considered dead upon sending a shutdown, then it may be worthwhile to not wait for the remote peer to take action:

ssl_socket.async_shutdown(...);
const char buffer[] = "";
async_write(ssl_socket, boost::asio::buffer(buffer),
    [](...) { ssl_socket.close(); })

When a client sends a close_notify message, the client guarantees that the client will not send additional data across the secure connection. In essence, the async_write() is being used to detect when the client has sent a close_notify, and within the completion handler, will close the underlying transport, causing the async_shutdown() to complete with boost::asio::error::operation_aborted. As noted in the linked answer, the async_write() operation is expected to fail.

... as the write side of PartyA's SSL stream has closed, the async_write() operation will fail with an SSL error indicating the protocol has been shutdown.

if ((error.category() == boost::asio::error::get_ssl_category())
     && (SSL_R_PROTOCOL_IS_SHUTDOWN == ERR_GET_REASON(error.value())))
{
  ssl_stream.lowest_layer().close();
}

The failed async_write() operation will then explicitly close the underlying transport, causing the async_shutdown() operation that is waiting for PartyB's close_notify to be cancelled.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!