mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Fix recursion of QuitUser in SendQ quits
This commit is contained in:
parent
f5409f04cd
commit
58ab072505
@ -22,11 +22,13 @@
|
||||
class CoreExport CullList
|
||||
{
|
||||
std::vector<classbase*> list;
|
||||
std::vector<LocalUser*> SQlist;
|
||||
|
||||
public:
|
||||
/** Adds an item to the cull list
|
||||
*/
|
||||
void AddItem(classbase* item) { list.push_back(item); }
|
||||
void AddSQItem(LocalUser* item) { SQlist.push_back(item); }
|
||||
|
||||
/** Applies the cull list (deletes the contents)
|
||||
*/
|
||||
|
@ -348,6 +348,12 @@ class CoreExport User : public Extensible
|
||||
*/
|
||||
unsigned int quitting:1;
|
||||
|
||||
/** Recursion fix: user is out of SendQ and will be quit as soon as possible.
|
||||
* This can't be handled normally because QuitUser itself calls Write on other
|
||||
* users, which could trigger their SendQ to overrun.
|
||||
*/
|
||||
unsigned int quitting_sendq:1;
|
||||
|
||||
/** This is true if the user matched an exception (E:Line). It is used to save time on ban checks.
|
||||
*/
|
||||
unsigned int exempt:1;
|
||||
|
@ -16,6 +16,19 @@
|
||||
|
||||
void CullList::Apply()
|
||||
{
|
||||
std::vector<LocalUser *> working;
|
||||
while (!SQlist.empty())
|
||||
{
|
||||
working.swap(SQlist);
|
||||
for(std::vector<LocalUser *>::iterator a = working.begin(); a != working.end(); a++)
|
||||
{
|
||||
LocalUser *u = *a;
|
||||
ServerInstance->SNO->WriteGlobalSno('a', "User %s SendQ exceeds connect class maximum of %lu",
|
||||
u->nick.c_str(), u->MyClass->GetSendqHardMax());
|
||||
ServerInstance->Users->QuitUser(u, "SendQ exceeded");
|
||||
}
|
||||
working.clear();
|
||||
}
|
||||
std::set<classbase*> gone;
|
||||
std::vector<classbase*> queue;
|
||||
queue.reserve(list.size() + 32);
|
||||
|
@ -193,6 +193,7 @@ User::User(const std::string &uid, const std::string& sid, int type)
|
||||
signon = idle_lastmsg = 0;
|
||||
registered = 0;
|
||||
quietquit = quitting = exempt = dns_done = false;
|
||||
quitting_sendq = false;
|
||||
client_sa.sa.sa_family = AF_UNSPEC;
|
||||
|
||||
ServerInstance->Logs->Log("USERS", DEBUG, "New UUID for user: %s", uuid.c_str());
|
||||
@ -519,16 +520,13 @@ eol_found:
|
||||
|
||||
void UserIOHandler::AddWriteBuf(const std::string &data)
|
||||
{
|
||||
if (user->quitting_sendq)
|
||||
return;
|
||||
if (!user->quitting && getSendQSize() + data.length() > user->MyClass->GetSendqHardMax() &&
|
||||
!user->HasPrivPermission("users/flood/increased-buffers"))
|
||||
{
|
||||
/*
|
||||
* Quit the user FIRST, because otherwise we could recurse
|
||||
* here and hit the same limit.
|
||||
*/
|
||||
ServerInstance->Users->QuitUser(user, "SendQ exceeded");
|
||||
ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ exceeds connect class maximum of %lu",
|
||||
user->nick.c_str(), user->MyClass->GetSendqHardMax());
|
||||
user->quitting_sendq = true;
|
||||
ServerInstance->GlobalCulls.AddSQItem(user);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user