diff options
author | attilamolnar <attilamolnar@hush.com> | 2013-01-14 19:59:47 +0100 |
---|---|---|
committer | attilamolnar <attilamolnar@hush.com> | 2013-01-14 19:59:47 +0100 |
commit | ee5e5aa77574a8e2cf9d142ccecf76de1fe72eb6 (patch) | |
tree | a1bb526ea1cb116044bd008ab4514e191ef8879d /src | |
parent | 61dcf0d999ef05347b8a2a556912f7a235335987 (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.cpp | 22 |
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; + } } } |