From 2efe44517a1d08b59ca16dfd235ac433c6c7b1a1 Mon Sep 17 00:00:00 2001 From: Christian Flach Date: Thu, 30 Jan 2020 10:57:47 +0100 Subject: [PATCH] Fix 'Bad Address' error when sending large messages --- server/control_session_tcp.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/server/control_session_tcp.cpp b/server/control_session_tcp.cpp index 3a057c78..410ebb14 100644 --- a/server/control_session_tcp.cpp +++ b/server/control_session_tcp.cpp @@ -105,8 +105,20 @@ void ControlSessionTcp::sendAsync(const std::string& message) void ControlSessionTcp::send_next() { - auto message = messages_.front(); - boost::asio::async_write(socket_, boost::asio::buffer(message + "\r\n"), + // We cannot simply do boost::asio::buffer(message + "\r\n"), because 'message + "\r\n"' becomes invalid + // after leaving this method, leading to a 'Bad address' error. + // Instead, we need to mutate the string before passing it to boost::asio::buffer. + // + // From the boost reference: + // + // A buffer object does not have any ownership of the memory it refers to. It is the responsibility of + // the application to ensure the memory region remains valid until it is no longer required for an I/O + // operation. When the memory is no longer available, the buffer is said to have been invalidated. + // https://www.boost.org/doc/libs/1_72_0/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.buffer_invalidation + + string& message = messages_.front(); + message += "\r\n"; + boost::asio::async_write(socket_, boost::asio::buffer(message), boost::asio::bind_executor(strand_, [ this, self = shared_from_this() ](std::error_code ec, std::size_t length) { messages_.pop_front(); if (ec)