From d736eba00b274c87662bd73a3acf8288135643d6 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Sun, 5 Jan 2014 14:17:12 +0100 Subject: [PATCH] Improve UserManager::QuitUser() and related code - Make operreason optional; NULL means same as quitreason - Remove User::quietquit, it is now handled internally in spanningtree - Send snotice about quitting remote users from spanningtree --- include/usermanager.h | 4 +- include/users.h | 4 -- src/commands/cmd_quit.cpp | 11 +---- src/modules/m_spanningtree/main.cpp | 15 ++++++- src/modules/m_spanningtree/main.h | 4 ++ src/modules/m_spanningtree/treeserver.cpp | 10 +---- src/modules/m_spanningtree/treesocket1.cpp | 5 +++ src/usermanager.cpp | 48 +++++----------------- src/users.cpp | 2 +- src/xline.cpp | 4 +- 10 files changed, 43 insertions(+), 64 deletions(-) diff --git a/include/usermanager.h b/include/usermanager.h index c6745ace6..a807cd447 100644 --- a/include/usermanager.h +++ b/include/usermanager.h @@ -102,10 +102,10 @@ class CoreExport UserManager /** Disconnect a user gracefully * @param user The user to remove * @param quitreason The quit reason to show to normal users - * @param operreason The quit reason to show to opers + * @param operreason The quit reason to show to opers, can be NULL if same as quitreason * @return Although this function has no return type, on exit the user provided will no longer exist. */ - void QuitUser(User *user, const std::string &quitreason, const char* operreason = ""); + void QuitUser(User* user, const std::string& quitreason, const std::string* operreason = NULL); /** Add a user to the local clone map * @param user The user to add diff --git a/include/users.h b/include/users.h index aa11a2b82..fa9d97c21 100644 --- a/include/users.h +++ b/include/users.h @@ -328,10 +328,6 @@ class CoreExport User : public Extensible */ unsigned int registered:3; - /** Whether or not to send an snotice about this user's quitting - */ - unsigned int quietquit:1; - /** If this is set to true, then all socket operations for the user * are dropped into the bit-bucket. * This value is set by QuitUser, and is not needed seperately from that call. diff --git a/src/commands/cmd_quit.cpp b/src/commands/cmd_quit.cpp index 61a88e2b5..144f4675b 100644 --- a/src/commands/cmd_quit.cpp +++ b/src/commands/cmd_quit.cpp @@ -56,21 +56,14 @@ CmdResult CommandQuit::Handle (const std::vector& parameters, User quitmsg = ServerInstance->Config->FixedQuit; else quitmsg = parameters.size() ? - ServerInstance->Config->PrefixQuit + std::string(parameters[0]) + ServerInstance->Config->SuffixQuit + ServerInstance->Config->PrefixQuit + parameters[0] + ServerInstance->Config->SuffixQuit : "Client exited"; } else quitmsg = parameters.size() ? parameters[0] : "Client exited"; std::string* operquit = ServerInstance->OperQuit.get(user); - if (operquit) - { - ServerInstance->Users->QuitUser(user, quitmsg, operquit->c_str()); - } - else - { - ServerInstance->Users->QuitUser(user, quitmsg); - } + ServerInstance->Users->QuitUser(user, quitmsg, operquit); return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 8d8a51ede..8c04d6c90 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -63,6 +63,7 @@ void ModuleSpanningTree::init() delete ServerInstance->PI; ServerInstance->PI = new SpanningTreeProtocolInterface; loopCall = false; + SplitInProgress = false; // update our local user count Utils->TreeRoot->UserCount = ServerInstance->Users->local_users.size(); @@ -547,13 +548,25 @@ void ModuleSpanningTree::OnUserPart(Membership* memb, std::string &partmessage, void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const std::string &oper_message) { - if ((IS_LOCAL(user)) && (user->registered == REG_ALL)) + if (IS_LOCAL(user)) { if (oper_message != reason) ServerInstance->PI->SendMetaData(user, "operquit", oper_message); CmdBuilder(user, "QUIT").push_last(reason).Broadcast(); } + else + { + // Hide the message if one of the following is true: + // - User is being quit due to a netsplit and quietbursts is on + // - Server is a silent uline + bool hide = (((this->SplitInProgress) && (Utils->quiet_bursts)) || (ServerInstance->SilentULine(user->server))); + if (!hide) + { + ServerInstance->SNO->WriteToSnoMask('Q', "Client exiting on server %s: %s (%s) [%s]", + user->server.c_str(), user->GetFullRealHost().c_str(), user->GetIPString().c_str(), oper_message.c_str()); + } + } // Regardless, We need to modify the user Counts.. TreeServer* SourceServer = Utils->FindServer(user->server); diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index c275207bf..bef94a53b 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -73,6 +73,10 @@ class ModuleSpanningTree : public Module */ bool loopCall; + /** True if users are quitting due to a netsplit + */ + bool SplitInProgress; + /** Constructor */ ModuleSpanningTree(); diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp index 8af3e777d..2fce9a504 100644 --- a/src/modules/m_spanningtree/treeserver.cpp +++ b/src/modules/m_spanningtree/treeserver.cpp @@ -139,7 +139,7 @@ void TreeServer::FinishBurst() int TreeServer::QuitUsers(const std::string &reason) { - const char* reason_s = reason.c_str(); + std::string publicreason = ServerInstance->Config->HideSplits ? "*.net *.split" : reason; std::vector time_to_die; for (user_hash::iterator n = ServerInstance->Users->clientlist->begin(); n != ServerInstance->Users->clientlist->end(); n++) { @@ -153,13 +153,7 @@ int TreeServer::QuitUsers(const std::string &reason) User* a = (User*)*n; if (!IS_LOCAL(a)) { - if (Utils->quiet_bursts) - a->quietquit = true; - - if (ServerInstance->Config->HideSplits) - ServerInstance->Users->QuitUser(a, "*.net *.split", reason_s); - else - ServerInstance->Users->QuitUser(a, reason_s); + ServerInstance->Users->QuitUser(a, publicreason, &reason); } } return time_to_die.size(); diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index 3c838177d..fa8a94f72 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -192,7 +192,12 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) int num_lost_servers = 0; int num_lost_users = 0; std::string from = Current->GetParent()->GetName()+" "+Current->GetName(); + + ModuleSpanningTree* st = Utils->Creator; + st->SplitInProgress = true; SquitServer(from, Current, num_lost_servers, num_lost_users); + st->SplitInProgress = false; + ServerInstance->SNO->WriteToSnoMask(LocalSquit ? 'l' : 'L', "Netsplit complete, lost \002%d\002 user%s on \002%d\002 server%s.", num_lost_users, num_lost_users != 1 ? "s" : "", num_lost_servers, num_lost_servers != 1 ? "s" : ""); Current->Tidy(); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 1d1a05fa2..745934fd4 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -169,7 +169,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs FOREACH_MOD(OnUserInit, (New)); } -void UserManager::QuitUser(User *user, const std::string &quitreason, const char* operreason) +void UserManager::QuitUser(User* user, const std::string& quitreason, const std::string* operreason) { if (user->quitting) { @@ -186,57 +186,31 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char user->quitting = true; ServerInstance->Logs->Log("USERS", LOG_DEBUG, "QuitUser: %s=%s '%s'", user->uuid.c_str(), user->nick.c_str(), quitreason.c_str()); - user->Write("ERROR :Closing link: (%s@%s) [%s]", user->ident.c_str(), user->host.c_str(), *operreason ? operreason : quitreason.c_str()); + user->Write("ERROR :Closing link: (%s@%s) [%s]", user->ident.c_str(), user->host.c_str(), operreason ? operreason->c_str() : quitreason.c_str()); std::string reason; - std::string oper_reason; reason.assign(quitreason, 0, ServerInstance->Config->Limits.MaxQuit); - if (operreason && *operreason) - oper_reason.assign(operreason, 0, ServerInstance->Config->Limits.MaxQuit); - else - oper_reason = quitreason; + if (!operreason) + operreason = &reason; ServerInstance->GlobalCulls.AddItem(user); if (user->registered == REG_ALL) { - FOREACH_MOD(OnUserQuit, (user, reason, oper_reason)); - user->WriteCommonQuit(reason, oper_reason); + FOREACH_MOD(OnUserQuit, (user, reason, *operreason)); + user->WriteCommonQuit(reason, *operreason); } - - if (user->registered != REG_ALL) - if (ServerInstance->Users->unregistered_count) - ServerInstance->Users->unregistered_count--; + else + unregistered_count--; if (IS_LOCAL(user)) { LocalUser* lu = IS_LOCAL(user); FOREACH_MOD(OnUserDisconnect, (lu)); lu->eh.Close(); - } - /* - * this must come before the ServerInstance->SNO->WriteToSnoMaskso that it doesnt try to fill their buffer with anything - * if they were an oper with +s +qQ. - */ - if (user->registered == REG_ALL) - { - if (IS_LOCAL(user)) - { - if (!user->quietquit) - { - ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s (%s) [%s]", - user->GetFullRealHost().c_str(), user->GetIPString().c_str(), oper_reason.c_str()); - } - } - else - { - if ((!ServerInstance->SilentULine(user->server)) && (!user->quietquit)) - { - ServerInstance->SNO->WriteToSnoMask('Q',"Client exiting on server %s: %s (%s) [%s]", - user->server.c_str(), user->GetFullRealHost().c_str(), user->GetIPString().c_str(), oper_reason.c_str()); - } - } + if (lu->registered == REG_ALL) + ServerInstance->SNO->WriteToSnoMask('q',"Client exiting: %s (%s) [%s]", user->GetFullRealHost().c_str(), user->GetIPString().c_str(), operreason->c_str()); } user_hash::iterator iter = this->clientlist->find(user->nick); @@ -246,7 +220,7 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char else ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: Nick not found in clientlist, cannot remove: " + user->nick); - ServerInstance->Users->uuidlist->erase(user->uuid); + uuidlist->erase(user->uuid); } void UserManager::AddLocalClone(User *user) diff --git a/src/users.cpp b/src/users.cpp index 39a717190..fa4bb7a42 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -75,7 +75,7 @@ User::User(const std::string &uid, const std::string& sid, int type) age = ServerInstance->Time(); signon = 0; registered = 0; - quietquit = quitting = false; + quitting = false; client_sa.sa.sa_family = AF_UNSPEC; ServerInstance->Logs->Log("USERS", LOG_DEBUG, "New UUID for user: %s", uuid.c_str()); diff --git a/src/xline.cpp b/src/xline.cpp index bc8e596bd..63a64d6b9 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -537,7 +537,7 @@ void XLine::DefaultApply(User* u, const std::string &line, bool bancache) u->WriteNotice("*** " + ServerInstance->Config->XLineMessage); if (ServerInstance->Config->HideBans) - ServerInstance->Users->QuitUser(u, line + "-Lined", banReason.c_str()); + ServerInstance->Users->QuitUser(u, line + "-Lined", &banReason); else ServerInstance->Users->QuitUser(u, banReason); @@ -545,7 +545,7 @@ void XLine::DefaultApply(User* u, const std::string &line, bool bancache) if (bancache) { ServerInstance->Logs->Log("BANCACHE", LOG_DEBUG, "BanCache: Adding positive hit (" + line + ") for " + u->GetIPString()); - ServerInstance->BanCache->AddHit(u->GetIPString(), this->type, line + "-Lined: " + this->reason, this->duration); + ServerInstance->BanCache->AddHit(u->GetIPString(), this->type, banReason, this->duration); } } -- 2.39.2