summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorattilamolnar <attilamolnar@hush.com>2013-01-14 19:59:47 +0100
committerattilamolnar <attilamolnar@hush.com>2013-01-14 19:59:47 +0100
commitee5e5aa77574a8e2cf9d142ccecf76de1fe72eb6 (patch)
treea1bb526ea1cb116044bd008ab4514e191ef8879d /src
parent61dcf0d999ef05347b8a2a556912f7a235335987 (diff)
m_spanningtree Fix rare desync when a KILL crosses a message that has the killed user's prefix and modifies global state
Diffstat (limited to 'src')
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp22
1 files changed, 19 insertions, 3 deletions
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;
+ }
}
}