summaryrefslogtreecommitdiff
path: root/src/cull_list.cpp
diff options
context:
space:
mode:
authorGravatar brain2006-03-07 20:21:54 +0000
committerGravatar brain2006-03-07 20:21:54 +0000
commit003fa072fcc5cb2349ceee6798efaaaa1e63d64f (patch)
treefb43a6dd1c0e1ce3160dbe23327ef75bbb615dd5 /src/cull_list.cpp
parentBuffer flush time now under 0.5 secs (diff)
Safety checking (a really really clever trick btw) in CullList, to make sure that the user we're removing IS the user that was marked for deletion X seconds ago, even if the user has since quit, to be replaced by another unfortunate wretch who was given the same pointer address (eeep)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3529 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/cull_list.cpp')
-rw-r--r--src/cull_list.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/cull_list.cpp b/src/cull_list.cpp
index 7c4afa16c..224a9e3da 100644
--- a/src/cull_list.cpp
+++ b/src/cull_list.cpp
@@ -54,10 +54,29 @@ extern user_hash clientlist;
bool CullList::IsValid(userrec* user)
{
+ time_t esignon = 0;
+ std::map<userrec*,time_t>::iterator es = exempt.find(user);
+ if (es != exempt.end())
+ esignon = es->second;
+
for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
{
+ /*
+ * BUGFIX
+ *
+ * Because there is an undetermined period of time between a user existing,
+ * and this function being called, we have to check for the following condition:
+ *
+ * Between CullList::AddItem(u) being called, and CullList::IsValid(u) being called,
+ * the user with the pointer u has quit, but only to be REPLACED WITH A NEW USER WHO
+ * BECAUSE OF ALLOCATION RULES, HAS THE SAME MEMORY ADDRESS! To prevent this, we
+ * cross reference each pointer to the user's signon time, and if the signon times
+ * do not match, we return false here to indicate this user is NOT valid as it
+ * seems to differ from the pointer snapshot we got a few seconds earlier. Should
+ * prevent a few random crashes during netsplits.
+ */
if (user == u->second)
- return true;
+ return (u->second->signon == esignon);
}
return false;
}
@@ -90,7 +109,7 @@ void CullList::AddItem(userrec* user, std::string reason)
{
CullItem item(user,reason);
list.push_back(item);
- exempt[user] = 1;
+ exempt[user] = user->signon;
}
}