From 4a7847537113d86b64ef1df4d264332750df9fbf Mon Sep 17 00:00:00 2001 From: brain Date: Wed, 24 May 2006 10:44:53 +0000 Subject: ALL THROW A WHILD PARTY! CRASH-ON-NETSPLIT should be fixed!!! git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3964 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/m_spanningtree.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/modules/m_spanningtree.cpp') diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 652a8d5f2..47b5a6b25 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -168,6 +168,7 @@ class TreeServer time_t NextPing; /* After this time, the server should be PINGed*/ bool LastPingWasGood; /* True if the server responded to the last PING with a PONG */ std::map Users; /* Users on this server */ + bool DontModifyHash; /* When the server is splitting, this is set to true so we dont bash our own iterator to death */ public: @@ -182,6 +183,7 @@ class TreeServer VersionString = ""; UserCount = OperCount = 0; VersionString = Srv->GetVersion(); + DontModifyHash = false; } /* We use this constructor only to create the 'root' item, TreeRoot, which @@ -266,6 +268,9 @@ class TreeServer void AddUser(userrec* user) { + if (this->DontModifyHash) + return; + log(DEBUG,"Add user %s to server %s",user->nick,this->ServerName.c_str()); std::map::iterator iter; iter = Users.find(user); @@ -275,6 +280,14 @@ class TreeServer void DelUser(userrec* user) { + /* FIX BY BRAIN: + * Quitting the user in QuitUsers changes the hash by removing the user here, + * corrupting the iterator! + * When netsplitting, this->DontModifyHash is set to prevent it now! + */ + if (this->DontModifyHash) + return; + log(DEBUG,"Remove user %s from server %s",user->nick,this->ServerName.c_str()); std::map::iterator iter; iter = Users.find(user); @@ -287,12 +300,15 @@ class TreeServer int x = Users.size(); log(DEBUG,"Removing all users from server %s",this->ServerName.c_str()); const char* reason_s = reason.c_str(); + this->DontModifyHash = true; for (std::map::iterator n = Users.begin(); n != Users.end(); n++) { - log(DEBUG,"Kill %s",n->second->nick); - kill_link(n->second,reason_s); + log(DEBUG,"Kill %s fd=%d",n->second->nick,n->second->fd); + if (!IS_LOCAL(n->second)) + kill_link(n->second,reason_s); } Users.clear(); + this->DontModifyHash = false; return x; } -- cgit v1.2.3