From 9067d816e5797676004ae50babb262dc4ca702e1 Mon Sep 17 00:00:00 2001 From: brain Date: Tue, 24 May 2005 17:10:19 +0000 Subject: Added extra code to notify mainloop when the iterator has been mangled (e.g. by netsplit quits) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1499 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/connection.cpp | 3 ++- src/inspircd.cpp | 15 +++++++++++++-- src/servers.cpp | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/connection.cpp b/src/connection.cpp index f246a2dac..30a961e96 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -32,7 +32,7 @@ using namespace std; #include "inspstring.h" #include "helperfuncs.h" - +extern bool has_been_netsplit; extern std::vector modules; extern std::vector factory; @@ -200,6 +200,7 @@ bool ircd_connector::CheckPing() this->CloseConnection(); this->SetState(STATE_DISCONNECTED); WriteOpers("*** Ping timeout on link to %s (more routes may remain)",this->GetServerName().c_str()); + has_been_netsplit = true; return false; } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index f11070d07..6ee535cd9 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -119,6 +119,8 @@ int kq, lkq, skq; int ep, lep, sep; #endif +bool has_been_netsplit = false; + typedef nspace::hash_map, irc::StrHashComp> user_hash; typedef nspace::hash_map, irc::StrHashComp> chan_hash; typedef nspace::hash_map, irc::InAddr_HashComp> address_cache; @@ -1742,6 +1744,7 @@ void DoSplitEveryone() } } } + has_been_netsplit = true; } @@ -2341,6 +2344,7 @@ void DoSplit(const char* params) } } } + has_been_netsplit = true; } // removes a server. Will NOT remove its users! @@ -2940,6 +2944,7 @@ int InspIRCd(char** argv, int argc) msgs.clear(); while ((me[x]) && (me[x]->RecvPacket(msgs, tcp_host, sums))) // returns 0 or more lines (can be multiple lines!) { + has_been_netsplit = false; for (int ctr = 0; ctr < msgs.size(); ctr++) { strlcpy(tcp_msg,msgs[ctr].c_str(),MAXBUF); @@ -2974,8 +2979,14 @@ int InspIRCd(char** argv, int argc) goto label; } } - sums.clear(); // we're done, clear the list for the next operation - msgs.clear(); + sums.clear(); // we're done, clear the list for the next operation + msgs.clear(); + // theres been a netsplit, its unsafe to mess with the iterators! + if (has_been_netsplit) + { + log(DEBUG,"Iterator modified, bailing"); + goto label; + } } } diff --git a/src/servers.cpp b/src/servers.cpp index ff5f40a68..a791d3557 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -36,8 +36,11 @@ using namespace std; extern time_t TIME; extern int MaxConn; + extern serverrec* me[32]; +extern bool has_been_netsplit; + std::deque xsums; serverrec::serverrec() @@ -308,6 +311,7 @@ void serverrec::FlushWriteBuffers() WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); DoSplit(this->connectors[i].GetServerName().c_str()); } + has_been_netsplit = true; } } if (this->connectors[i].HasBufferedOutput()) @@ -323,6 +327,7 @@ void serverrec::FlushWriteBuffers() WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); DoSplit(this->connectors[i].GetServerName().c_str()); } + has_been_netsplit = true; } } } @@ -457,6 +462,7 @@ bool serverrec::RecvPacket(std::deque &messages, char* recvhost,std WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); DoSplit(this->connectors[i].GetServerName().c_str()); } + has_been_netsplit = true; } } int pushed = 0; @@ -472,6 +478,7 @@ bool serverrec::RecvPacket(std::deque &messages, char* recvhost,std WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); DoSplit(this->connectors[i].GetServerName().c_str()); } + has_been_netsplit = true; } if (this->connectors[i].BufferIsComplete()) { -- cgit v1.2.3