From 5a74f69819a895b7e7f684bb18f4d1d9990391b4 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 8 Nov 2015 21:23:04 +0100 Subject: [PATCH] Fix memory leak for JSON-RPC/HTTP connections fixes #10517 --- lib/base/fifo.hpp | 2 +- lib/base/networkstream.cpp | 2 ++ lib/base/stdiostream.cpp | 2 ++ lib/base/stream.cpp | 5 +++++ lib/base/stream.hpp | 2 +- lib/base/tlsstream.cpp | 42 ++++++++++++++++++++------------------ 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/lib/base/fifo.hpp b/lib/base/fifo.hpp index db552c4b3..60a3e4c62 100644 --- a/lib/base/fifo.hpp +++ b/lib/base/fifo.hpp @@ -36,7 +36,7 @@ class I2_BASE_API FIFO : public Stream public: DECLARE_PTR_TYPEDEFS(FIFO); - static const size_t BlockSize = 16 * 1024; + static const size_t BlockSize = 512; FIFO(void); ~FIFO(void); diff --git a/lib/base/networkstream.cpp b/lib/base/networkstream.cpp index b732a02d2..47b0fd1c2 100644 --- a/lib/base/networkstream.cpp +++ b/lib/base/networkstream.cpp @@ -27,6 +27,8 @@ NetworkStream::NetworkStream(const Socket::Ptr& socket) void NetworkStream::Close(void) { + Stream::Close(); + m_Socket->Close(); } diff --git a/lib/base/stdiostream.cpp b/lib/base/stdiostream.cpp index 356e64361..f178aee75 100644 --- a/lib/base/stdiostream.cpp +++ b/lib/base/stdiostream.cpp @@ -55,6 +55,8 @@ void StdioStream::Write(const void *buffer, size_t size) void StdioStream::Close(void) { + Stream::Close(); + if (m_OwnsStream) { delete m_InnerStream; m_OwnsStream = false; diff --git a/lib/base/stream.cpp b/lib/base/stream.cpp index cfcdf0bb0..f14b7a664 100644 --- a/lib/base/stream.cpp +++ b/lib/base/stream.cpp @@ -76,6 +76,11 @@ bool Stream::WaitForData(int timeout) return IsDataAvailable() || IsEof(); } +void Stream::Close(void) +{ + OnDataAvailable.disconnect_all_slots(); +} + StreamReadStatus Stream::ReadLine(String *line, StreamReadContext& context, bool may_wait) { if (context.Eof) diff --git a/lib/base/stream.hpp b/lib/base/stream.hpp index 32ed4bb8d..7928a51e6 100644 --- a/lib/base/stream.hpp +++ b/lib/base/stream.hpp @@ -113,7 +113,7 @@ public: /** * Closes the stream and releases resources. */ - virtual void Close(void) = 0; + virtual void Close(void); /** * Checks whether we've reached the end-of-file condition. diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp index d68d82fed..eba8375f5 100644 --- a/lib/base/tlsstream.cpp +++ b/lib/base/tlsstream.cpp @@ -85,7 +85,7 @@ TlsStream::TlsStream(const Socket::Ptr& socket, const String& hostname, Connecti TlsStream::~TlsStream(void) { - SocketEvents::Unregister(); + Close(); } int TlsStream::ValidateCertificate(int preverify_ok, X509_STORE_CTX *ctx) @@ -216,33 +216,31 @@ void TlsStream::OnEvent(int revents) break; case SSL_ERROR_ZERO_RETURN: - SocketEvents::Unregister(); - - m_SSL.reset(); - m_Socket->Close(); - m_Socket.reset(); + lock.unlock(); - m_Eof = true; + if (IsHandlingEvents()) + SignalDataAvailable(); - m_CV.notify_all(); + Close(); break; default: - SocketEvents::Unregister(); - - m_SSL.reset(); - m_Socket->Close(); - m_Socket.reset(); - - m_Eof = true; - m_ErrorCode = ERR_peek_error(); m_ErrorOccurred = true; - Log(LogWarning, "TlsStream") - << "OpenSSL error: " << ERR_error_string(m_ErrorCode, NULL); + if (m_ErrorCode != 0) { + Log(LogWarning, "TlsStream") + << "OpenSSL error: " << ERR_error_string(m_ErrorCode, NULL); + } else { + Log(LogWarning, "TlsStream", "TLS stream was disconnected."); + } + + lock.unlock(); + + if (IsHandlingEvents()) + SignalDataAvailable(); - m_CV.notify_all(); + Close(); break; } @@ -318,6 +316,8 @@ void TlsStream::Shutdown(void) */ void TlsStream::Close(void) { + Stream::Close(); + SocketEvents::Unregister(); boost::mutex::scoped_lock lock(m_Mutex); @@ -327,11 +327,13 @@ void TlsStream::Close(void) if (!m_SSL) return; - (void) SSL_shutdown(m_SSL.get()); + (void)SSL_shutdown(m_SSL.get()); m_SSL.reset(); m_Socket->Close(); m_Socket.reset(); + + m_CV.notify_all(); } bool TlsStream::IsEof(void) const -- 2.40.0