diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index 794b6e18d..2e1bb3a0e 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -205,7 +206,13 @@ std::shared_ptr ApiListener::RenewCert(const std::shared_ptr& 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 lock (m_SSLContextMutex); + + m_SSLContext = std::move(ctx); + } for (const Endpoint::Ptr& endpoint : ConfigType::GetObjectsByType()) { 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::Ptr& server, const Shared::Ptr& sslContext) +void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Shared::Ptr& server) { namespace asio = boost::asio; @@ -485,7 +492,10 @@ void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Sha } } - auto sslConn (Shared::Make(io, *sslContext)); + boost::shared_lock lock (m_SSLContextMutex); + auto sslConn (Shared::Make(io, *m_SSLContext)); + + lock.unlock(); sslConn->lowest_layer() = std::move(socket); auto strand (Shared::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 lock (m_SSLContextMutex); auto sslConn (Shared::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") diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index d5e6ffe8c..1be29522f 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,7 @@ protected: private: Shared::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::Ptr& strand, const Shared::Ptr& client, const String& hostname, ConnectionRole role ); - void ListenerCoroutineProc(boost::asio::yield_context yc, const Shared::Ptr& server, const Shared::Ptr& sslContext); + void ListenerCoroutineProc(boost::asio::yield_context yc, const Shared::Ptr& server); WorkQueue m_RelayQueue; WorkQueue m_SyncQueue{0, 4};