From ee5e5aa77574a8e2cf9d142ccecf76de1fe72eb6 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Mon, 14 Jan 2013 19:59:47 +0100 Subject: m_spanningtree Fix rare desync when a KILL crosses a message that has the killed user's prefix and modifies global state --- src/modules/m_spanningtree/treesocket2.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 9c3fe9c36..04ca9edb1 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -244,9 +244,25 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, * due to various race conditions such as the KILL message for a user somehow * crossing the users QUIT further upstream from the server. Thanks jilles! */ - ServerInstance->Logs->Log("m_spanningtree", DEBUG, "Command '%s' from unknown prefix '%s'! Dropping entire command.", - command.c_str(), prefix.c_str()); - return; + + if ((prefix.length() == UUID_LENGTH-1) && (isdigit(prefix[0])) && + ((command == "FMODE") || (command == "MODE") || (command == "KICK") || (command == "TOPIC") || (command == "KILL") || (command == "ADDLINE") || (command == "DELLINE"))) + { + /* Special case, we cannot drop these commands as they've been committed already on a + * part of the network by the time we receive them, so in this scenario pretend the + * command came from a server to avoid desync. + */ + + who = ServerInstance->FindUUID(prefix.substr(0, 3)); + if (!who) + who = this->MyRoot->ServerUser; + } + else + { + ServerInstance->Logs->Log("m_spanningtree", DEBUG, "Command '%s' from unknown prefix '%s'! Dropping entire command.", + command.c_str(), prefix.c_str()); + return; + } } } -- cgit v1.2.3