Protect ApiListener#m_SSLContext with a mutex

This commit is contained in:
Alexander A. Klimov 2022-04-04 13:26:55 +02:00
parent e490883577
commit c9e4c016e0
2 changed files with 20 additions and 5 deletions

View File

@ -32,6 +32,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/locks.hpp>
#include <climits>
#include <cstdint>
#include <fstream>
@ -205,7 +206,13 @@ std::shared_ptr<X509> ApiListener::RenewCert(const std::shared_ptr<X509>& cert)
void ApiListener::UpdateSSLContext()
{
m_SSLContext = SetupSslContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath(), GetCrlPath(), GetCipherList(), GetTlsProtocolmin(), GetDebugInfo());
auto ctx (SetupSslContext(GetDefaultCertPath(), GetDefaultKeyPath(), GetDefaultCaPath(), GetCrlPath(), GetCipherList(), GetTlsProtocolmin(), GetDebugInfo()));
{
boost::unique_lock<decltype(m_SSLContextMutex)> lock (m_SSLContextMutex);
m_SSLContext = std::move(ctx);
}
for (const Endpoint::Ptr& endpoint : ConfigType::GetObjectsByType<Endpoint>()) {
for (const JsonRpcConnection::Ptr& client : endpoint->GetClients()) {
@ -449,14 +456,14 @@ bool ApiListener::AddListener(const String& node, const String& service)
Log(LogInformation, "ApiListener")
<< "Started new listener on '[" << localEndpoint.address() << "]:" << localEndpoint.port() << "'";
IoEngine::SpawnCoroutine(io, [this, acceptor](asio::yield_context yc) { ListenerCoroutineProc(yc, acceptor, m_SSLContext); });
IoEngine::SpawnCoroutine(io, [this, acceptor](asio::yield_context yc) { ListenerCoroutineProc(yc, acceptor); });
UpdateStatusFile(localEndpoint);
return true;
}
void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Shared<boost::asio::ip::tcp::acceptor>::Ptr& server, const Shared<boost::asio::ssl::context>::Ptr& sslContext)
void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Shared<boost::asio::ip::tcp::acceptor>::Ptr& server)
{
namespace asio = boost::asio;
@ -485,7 +492,10 @@ void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Sha
}
}
auto sslConn (Shared<AsioTlsStream>::Make(io, *sslContext));
boost::shared_lock<decltype(m_SSLContextMutex)> lock (m_SSLContextMutex);
auto sslConn (Shared<AsioTlsStream>::Make(io, *m_SSLContext));
lock.unlock();
sslConn->lowest_layer() = std::move(socket);
auto strand (Shared<asio::io_context::strand>::Make(io));
@ -538,8 +548,11 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint)
<< "Reconnecting to endpoint '" << endpoint->GetName() << "' via host '" << host << "' and port '" << port << "'";
try {
boost::shared_lock<decltype(m_SSLContextMutex)> lock (m_SSLContextMutex);
auto sslConn (Shared<AsioTlsStream>::Make(io, *m_SSLContext, endpoint->GetName()));
lock.unlock();
Timeout::Ptr timeout(new Timeout(strand->context(), *strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)),
[sslConn, endpoint, host, port](asio::yield_context yc) {
Log(LogCritical, "ApiListener")

View File

@ -21,6 +21,7 @@
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <cstdint>
#include <mutex>
#include <set>
@ -160,6 +161,7 @@ protected:
private:
Shared<boost::asio::ssl::context>::Ptr m_SSLContext;
boost::shared_mutex m_SSLContextMutex;
mutable std::mutex m_AnonymousClientsLock;
mutable std::mutex m_HttpClientsLock;
@ -194,7 +196,7 @@ private:
boost::asio::yield_context yc, const Shared<boost::asio::io_context::strand>::Ptr& strand,
const Shared<AsioTlsStream>::Ptr& client, const String& hostname, ConnectionRole role
);
void ListenerCoroutineProc(boost::asio::yield_context yc, const Shared<boost::asio::ip::tcp::acceptor>::Ptr& server, const Shared<boost::asio::ssl::context>::Ptr& sslContext);
void ListenerCoroutineProc(boost::asio::yield_context yc, const Shared<boost::asio::ip::tcp::acceptor>::Ptr& server);
WorkQueue m_RelayQueue;
WorkQueue m_SyncQueue{0, 4};