【问题标题】:need to call ssl::stream::shutdown when closing boost asio ssl socket?关闭 boost asio ssl 套接字时需要调用 ssl::stream::shutdown 吗?
【发布时间】:2013-02-25 01:45:25
【问题描述】:

我的代码如下:

declaration: boost::asio::ssl::stream<boost::asio::ip::tcp::socket> m_remote_socket;

m_remote_socket.shutdown(ec);
if (ec)
{      
    cdbug<<"id: "<<m_id<<", error when ssl shutdown: "    <<boost::system::system_category().message(ec.value()).c_str(); 
}
m_remote_socket.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
if (ec)
{
    cdbug<<"id: "<<m_id<<", error when tcp shutdown: "<<boost::system::system_category().message(ec.value()).c_str(); 
}

每次调用m_remote_socket.shutdown,都会报错。这种未知错误,错误值非常大。

但是不调用m_remote_socket.shutdown直接调用m_remote_socket.lowest_layer().shutdown()也可以。

谁能告诉我如何关闭 ssl 流式套接字?

【问题讨论】:

  • 关机失败时的错误代码和信息是什么?

标签: c++ sockets boost ssl boost-asio


【解决方案1】:

ssl::stream 及其lowest_layer() 上进行shutdown() 调用是最干净的。第一个ends the SSL connection 和第二个ends the TCP connection。如果您在 SSL 关闭时遇到错误,则可能是对方在结束连接时没有那么优雅。

【讨论】:

  • 这不正确。 SSL 连接底层的 TCP 连接半关闭是不合法的。请参阅 RFC 2246。
  • @EJP,我不确定我理解你的意思。 SSL 连接应该在较低的协议层之前关闭这一事实并不能阻止您与之通信的一方关闭或丢弃 TCP。我只是想解释一下为什么在尝试关闭 SSL 时可能会出错。
  • @rashimodo 没有半封闭的 SSL 连接。一旦一侧收到 close_notify,它必须关闭连接。我很惊讶正在讨论的库甚至提供了 SSL 关闭,但如果它确实有效并且它工作,结果必须是一个完全关闭的连接。关闭底层 TCP 连接的一侧会使 SSL 处于无效状态。这个答案不正确。
  • 谢谢,终于知道为什么会报错了:还有未完成的io操作挂起
  • 套接字。并且在我将关闭操作移至析构函数后,错误消失了
【解决方案2】:

我强烈建议您不要使用关闭方法并且不要尊重 SSL 层 + TCP 层(lowest_layer)。安全起见,将 tcp 最低层关闭为

m_remote_socket.lowest_layer().close(ec);

我面临的问题是,当您尊重 SSL 或 TCP 时,应用程序资源(套接字处理程序)将存储在内存中,直到服务器端发送关闭会话确认。

【讨论】:

    【解决方案3】:

    只需调用 close()。关闭 SSL 套接字是不合法的:在 SSL 中没有半关闭这样的事情。请参阅 RFC 2246,关于 close_notify 的讨论。

    【讨论】:

    • 你对“关机”的定义是什么?我认为我们中的一个人存在语义误解。 OpenSSL concept of shutdown 正在发送 close_notify,这就是 boost::asio 调用的内容。
    • TCP 的关闭概念是半关闭:向一个方向发送 FIN,同时保持另一方向打开。这就是 'shutdown(SHUT_WR)' 的作用。 close_notify 的 SSL 概念是完全关闭。 '当前打开的会话被视为关闭'。它们是不可调和的。
    • 这就是为什么我的回答说要在ssl::stream 上致电shutdown()。那发送 FIN 并结束 TCP 连接;它调用 OpenSSL SSL_shutdown 发送 close_notifyssl::stream::shutdown() == close_notfifySSL_shutdown() != TCP FIN。
    • 你上面的评论说“你不应该同时关闭 TCP”和“如果这个关闭方法没有半关闭,那么它的名字就大错特错了”。这对我来说暗示你是说如果你在 SSL 层调用shutdown(),那么你不需要在 TCP 层调用close()。如果你想回到你的答案,只调用close()是不正确的。 close()boost::asio::ip::tcp::socket() 上的一个方法,在 SSL/TLS 层什么都不做。
    • 看起来你忽略了我评论的上下文,首先引用你的评论,你说“你不应该同时关闭 TCP”,这与你原来的答案相矛盾。看起来您的问题与 boost::asio API 设计有关。也许您也不熟悉 OpenSSL API,因为那里的关闭概念是相同的(正如我的第一条评论指出的那样)。即使您不喜欢该 API,您的回答也不会发送 close_notify。
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多