boost asio set_verify_callback leaks shared_ptr

boost asio set_verify_callback leaks shared_ptr

本文关键字:leaks shared ptr callback verify asio set boost      更新时间:2023-10-16

在ssl套接字上使用set_verify_callback时,我看到了一个泄漏。我有一个类"CClientLock",成员为"boost::asio::ssl::stream m_socket;"

我的CClientLock类派生自'enable_shared_from_this

类CClientLock:public-boost::enable_shared_from_this

如果我打电话:

m_socket.set_verify_callback(boost::bind(&CClientLock::verify_certificate,shared_from_this(),_1,_2) );

那么我的CClientLock实例永远不会被破坏。

如果我不调用"m_socket.set_verify_callback",则我的CClientLock实例将正确销毁。

代码如下:

void CClientLock::StartPoll(){m_socket.set_verify_mode(boost::asio::ssl::verify_peer|boost::asio::ssl::verify_fail_if_no_peer_cert);m_socket.set_verify_callback(boost::bind(&CClientLock::verify_certificate,shared_from_this(),_1,_2) );boost::asio::ip::tcp::解析器::迭代器endpoint_iterator;endpoint_iterator=解析地址("xxx.xxx.xxx.xxx",nPort);boost::asio::async_connect(m_socket.loest_layer(),endpoint_iterator,boost::bind(&CClientLock::handle_connect,shared_from_this(),boost::asio::占位符::error);}bool CClientLock::verify_certificate(bool预验证,boost::asio::ssl::verify_context&ctx){char subject_name[256];X509*cert=X509_STORE_TX_get_current_cert(CTX.native_handle());X509_NAME_oneline(X509_get_subject_NAME(cert),subject_NAME,256);SYSTEMTIME st;GetLocalTime(&st);C字符串;s.Format("%02d SSL验证:%s",m_nId,subject_name);LogMsg(m_dwThreadId,&st,s,0,NULL);退货预先验证;}

是否必须在"set_verify_callback"中执行某些操作才能发布引用?

通过在验证回调中保留shared_ptr<CClientSock>,可以获得循环引用。上下文维护一个boost::asio::ssl::detail::verify_callback成员,其中包含您的共享指针。要打破循环,请使用带lambda 的弱指针

std::weak_ptr<CClientSock> weak( shared_from_this() );
m_socket.set_verify_callback([weak](bool p, boost::asio::ssl::verify_context& context) {
    std::shared_ptr<CClientSock> strong( weak );
    if ( strong ) {
        strong->verify_certificate( p, context );
    }
});

在sehe和Sam Miller的回复后,我开始工作了。我最终使用了Sam展示的大部分代码,使用了sehe首次发布的"共享指针循环"想法。

我修改了lambda表达式以使用"by value"捕获子句([=])。这告诉编译器如何处理weak_ptr变量。然后,我修改了返回布尔值的函数的表达式。我最终得到了这个,它确实允许对象实例被销毁。

boost::weak_ptr weak(shared_from_this());m_socket.set_verify_callback([=](bool p,boost::asio::ssl::verifycontext&context)->bool{boost::shared_ptr强(弱);if(strong){p=strong->verify_certificate(p,context);}返回p;});

我有预感SSL上下文可能会被重新使用。

在这种情况下,您可以显式地管理上下文,这样您就知道它何时被破坏:

  • http://www.boost.org/doc/libs/1_56_0/doc/html/boost_asio/reference/ssl__context/set_verify_callback.html

或者,可以有一个共享指针循环,由上下文保持套接字创建,这样上下文或处理程序都不会被释放。(在这种情况下,您应该会看到更多的问题)。尝试通过显式释放处理程序来打破循环:

s.set_verify_callback([](bool p, verify_context&) { return p; });