From 4f001e2a3426176c221e23d0743d95d65ecce0f2 Mon Sep 17 00:00:00 2001 From: Ariel Abreu Date: Fri, 24 Jun 2022 01:39:04 -0400 Subject: [PATCH] Add reply-push synchronization This is used to avoid the server reading incorrect/corrupted reply contents for pushed replies. This was happening because clients were sending the push-reply call with the pointer to the message contents, but they were immediately returning after sending it. This led to a race condition in which the server would sometimes read the data after the client had already overwritten/discarded said data. --- src/call.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/call.cpp b/src/call.cpp index 6f941a7..dd2185f 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -133,6 +133,14 @@ std::shared_ptr DarlingServer::Call::callFromMessage(Messag auto pushReplyCall = reinterpret_cast(requestMessage.data().data()); Message replyToSave(pushReplyCall->reply_size, 0); + // extract the reply-push synchronization pipe + auto pipeDesc = requestMessage.extractDescriptorAtIndex(requestMessage.descriptors().size() - 1); + char tmp = 1; + + if (pipeDesc < 0) { + throw std::runtime_error("Failed to extract reply-push synchronization pipe"); + } + if (!process->readMemory(pushReplyCall->reply, replyToSave.data().data(), pushReplyCall->reply_size)) { throw std::runtime_error("Failed to read client-pushed reply body"); } @@ -160,7 +168,12 @@ std::shared_ptr DarlingServer::Call::callFromMessage(Messag } } - callLog.debug() << *thread << ": Saved client-pushed reply" << callLog.endLog; + callLog.debug() << *thread << ": Saved client-pushed reply (" << ((thread->_pendingSavedReply) ? "pending" : "normal") << ")" << callLog.endLog; + + // write a byte to the pipe so the caller can continue + write(pipeDesc, &tmp, sizeof(tmp)); + // and close it + close(pipeDesc); return nullptr; }