From 786093b7515e923921f65125ab5bf18f2279f923 Mon Sep 17 00:00:00 2001 From: brain Date: Fri, 2 Nov 2007 12:35:18 +0000 Subject: [PATCH] xline gutting, once more. There is no longer an active_lines vector, and no requirement for sorting. Expiry will be cheked on a per-line basis for each positive hit on that line, saving on cpu time. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8457 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/xline.h | 40 +++------- src/commands/cmd_nick.cpp | 2 +- src/users.cpp | 10 +-- src/xline.cpp | 155 +++++++++++--------------------------- 4 files changed, 57 insertions(+), 150 deletions(-) diff --git a/include/xline.h b/include/xline.h index 5de773aaf..7efc6a744 100644 --- a/include/xline.h +++ b/include/xline.h @@ -392,16 +392,10 @@ class CoreExport XLineManager */ InspIRCd* ServerInstance; - /** This functor is used by the std::sort() function to keep all lines in order - */ - static bool XSortComparison (const XLine *one, const XLine *two); - /** Used to hold XLines which have not yet been applied. */ std::vector pending_lines; - std::vector active_lines; - std::map line_factory; GLineFactory* GFact; @@ -469,35 +463,19 @@ class CoreExport XLineManager */ XLineFactory* GetFactory(const char type); - /** Check if a nickname matches a QLine - * @return nick The nick to check against + /** Check if a user matches an XLine + * @param type The type of line to look up + * @param user The user to match against (what is checked is specific to the xline type) * @return The reason for the line if there is a match, or NULL if there is no match */ - QLine* matches_qline(const char* nick); + XLine* MatchesLine(const char type, User* user); - /** Check if a hostname matches a GLine - * @param user The user to check against - * @return The reason for the line if there is a match, or NULL if there is no match - */ - GLine* matches_gline(User* user); - - /** Check if a user's IP matches a ZLine - * @param user The user to check against - * @return The reason for the line if there is a match, or NULL if there is no match - */ - ZLine* matches_zline(User *user); - - /** Check if a hostname matches a KLine - * @param user The user to check against - * @return The reason for the line if there is a match, or NULL if there is no match - */ - KLine* matches_kline(User* user); - - /** Check if a hostname matches a ELine - * @param user The user to check against - * @return The reason for the line if there is a match, or NULL if there is no match + /** Check if a pattern matches an XLine + * @param type The type of line to look up + * @param pattern A pattern string specific to the xline type + * @return The matching XLine if there is a match, or NULL if there is no match */ - ELine* matches_exception(User* user); + XLine* MatchesLine(const char type, const std::string &pattern); /** Expire any lines that should be expired. */ diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp index 04b03055e..aaa6698ac 100644 --- a/src/commands/cmd_nick.cpp +++ b/src/commands/cmd_nick.cpp @@ -60,7 +60,7 @@ CmdResult CommandNick::Handle (const char** parameters, int, User *user) } else { - QLine* mq = ServerInstance->XLines->matches_qline(parameters[0]); + XLine* mq = ServerInstance->XLines->MatchesLine('Q',parameters[0]); if (mq) { ServerInstance->SNO->WriteToSnoMask('x', "Q-Lined nickname %s from %s!%s@%s: %s", parameters[0], user->nick, user->ident, user->host, mq->reason); diff --git a/src/users.cpp b/src/users.cpp index 5f61ce1df..0f451d2a9 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -830,10 +830,10 @@ void User::AddClient(InspIRCd* Instance, int socket, int port, bool iscached, in } #endif - New->exempt = (Instance->XLines->matches_exception(New) != NULL); + New->exempt = (Instance->XLines->MatchesLine('E',New) != NULL); if (!New->exempt) { - ZLine* r = Instance->XLines->matches_zline(New); + XLine* r = Instance->XLines->MatchesLine('Z',New); if (r) { @@ -942,7 +942,7 @@ void User::FullConnect() if (!this->exempt) { - GLine* r = ServerInstance->XLines->matches_gline(this); + XLine* r = ServerInstance->XLines->MatchesLine('G',this); if (r) { @@ -955,7 +955,7 @@ void User::FullConnect() return; } - KLine* n = ServerInstance->XLines->matches_kline(this); + XLine* n = ServerInstance->XLines->MatchesLine('K',this); if (n) { @@ -1065,7 +1065,7 @@ bool User::ForceNickChange(const char* newnick) return false; } - if (ServerInstance->XLines->matches_qline(newnick)) + if (ServerInstance->XLines->MatchesLine('Q',newnick)) { ServerInstance->stats->statsCollisions++; return false; diff --git a/src/xline.cpp b/src/xline.cpp index 8fbb73280..a3ae9ffa8 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -120,9 +120,6 @@ bool XLineManager::AddLine(XLine* line, User* user) return false; /*ELine* item = new ELine(ServerInstance, ServerInstance->Time(), duration, source, reason, ih.first.c_str(), ih.second.c_str());*/ - - active_lines.push_back(line); - sort(active_lines.begin(), active_lines.end(), XLineManager::XSortComparison); pending_lines.push_back(line); lookup_lines[line->type][line->Displayable()] = line; line->OnAdd(); @@ -135,51 +132,40 @@ bool XLineManager::AddLine(XLine* line, User* user) return true; } -/*bool XLineManager::AddZLine(long duration, const char* source, const char* reason, const char* ipaddr) -{ - if (strchr(ipaddr,'@')) - { - while (*ipaddr != '@') - ipaddr++; - ipaddr++; - }*/ - -// deletes a g:line, returns true if the line existed and was removed +// deletes a line, returns true if the line existed and was removed bool XLineManager::DelLine(const char* hostmask, char type, User* user, bool simulate) { - IdentHostPair ih = IdentSplit(hostmask); - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) - { - if ((*i)->type == type) - { - if ((*i)->MatchesLiteral(hostmask)) - { - if (!simulate) - { - (*i)->Unset(); + std::map >::iterator x = lookup_lines.find(type); - if (lookup_lines.find(type) != lookup_lines.end()) - lookup_lines[type].erase(hostmask); + if (x == lookup_lines.end()) + return false; - FOREACH_MOD(I_OnDelLine,OnDelLine(user, *i)); + std::map::iterator y = lookup_lines[type].find(hostmask); - std::vector::iterator pptr = std::find(pending_lines.begin(), pending_lines.end(), *i); - if (pptr != pending_lines.end()) - pending_lines.erase(pptr); + if (y == lookup_lines[type].end()) + return false; - if (!(*i)->duration) - PermLines--; + if (simulate) + return true; - delete *i; - active_lines.erase(i); - } - return true; - } - } - } + FOREACH_MOD(I_OnDelLine,OnDelLine(user, y->second)); - return false; + y->second->Unset(); + + lookup_lines[type].erase(hostmask); + + std::vector::iterator pptr = std::find(pending_lines.begin(), pending_lines.end(), y->second); + if (pptr != pending_lines.end()) + pending_lines.erase(pptr); + + if (y->second->duration) + PermLines--; + + delete y->second; + lookup_lines[type].erase(y); + + return true; } @@ -198,101 +184,43 @@ void ELine::Unset() // returns a pointer to the reason if a nickname matches a qline, NULL if it didnt match -QLine* XLineManager::matches_qline(const char* nick) -{ - if (lookup_lines.find('Q') == lookup_lines.end()) - return NULL; - - if (lookup_lines.find('Q') != lookup_lines.end() && lookup_lines['Q'].empty()) - return NULL; - - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) - if ((*i)->type == 'Q' && (*i)->Matches(nick)) - return (QLine*)(*i); - return NULL; -} - -// returns a pointer to the reason if a host matches a gline, NULL if it didnt match - -GLine* XLineManager::matches_gline(User* user) +XLine* XLineManager::MatchesLine(const char type, User* user) { - if (lookup_lines.find('G') == lookup_lines.end()) - return NULL; - - if (lookup_lines.find('G') != lookup_lines.end() && lookup_lines['G'].empty()) - return NULL; - - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) - if ((*i)->type == 'G' && (*i)->Matches(user)) - return (GLine*)(*i); - - return NULL; -} + std::map >::iterator x = lookup_lines.find(type); -ELine* XLineManager::matches_exception(User* user) -{ - if (lookup_lines.find('E') == lookup_lines.end()) + if (x == lookup_lines.end()) return NULL; - if (lookup_lines.find('E') != lookup_lines.end() && lookup_lines['E'].empty()) - return NULL; - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) + for (std::map::iterator i = x->second.begin(); i != x->second.end(); i++) { - if ((*i)->type == 'E' && (*i)->Matches(user)) - return (ELine*)(*i); + if (i->second->Matches(user)) + return i->second; } return NULL; } -// returns a pointer to the reason if an ip address matches a zline, NULL if it didnt match - -ZLine* XLineManager::matches_zline(User *u) -{ - if (lookup_lines.find('Z') == lookup_lines.end()) - return NULL; - - if (lookup_lines.find('Z') != lookup_lines.end() && lookup_lines['Z'].empty()) - return NULL; - - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) - if ((*i)->type == 'Z' && (*i)->Matches(u)) - return (ZLine*)(*i); - return NULL; -} - -// returns a pointer to the reason if a host matches a kline, NULL if it didnt match - -KLine* XLineManager::matches_kline(User* user) +XLine* XLineManager::MatchesLine(const char type, const std::string &pattern) { - if (lookup_lines.find('K') == lookup_lines.end()) - return NULL; + std::map >::iterator x = lookup_lines.find(type); - if (lookup_lines.find('K') != lookup_lines.end() && lookup_lines['K'].empty()) + if (x == lookup_lines.end()) return NULL; - for (std::vector::iterator i = active_lines.begin(); i != active_lines.end(); i++) - if ((*i)->Matches(user)) - return (KLine*)(*i); + for (std::map::iterator i = x->second.begin(); i != x->second.end(); i++) + { + if (i->second->Matches(pattern)) + return i->second; + } return NULL; } -bool XLineManager::XSortComparison(const XLine *one, const XLine *two) -{ - return (one->expiry) < (two->expiry); -} // removes lines that have expired void XLineManager::expire_lines() { - time_t current = ServerInstance->Time(); - - /* Because we now store all our XLines in sorted order using ((*i)->duration + (*i)->set_time) as a key, this - * means that to expire the XLines we just need to do a while, picking off the top few until there are - * none left at the head of the queue that are after the current time. We use PermLines as an offset into the - * vector past the first item with a duration 0. - */ +/* time_t current = ServerInstance->Time(); std::vector::iterator start = active_lines.begin() + PermLines; @@ -313,9 +241,10 @@ void XLineManager::expire_lines() delete *start; active_lines.erase(start); - } + }*/ } + // applies lines, removing clients and changing nicks etc as applicable void XLineManager::ApplyLines() { -- 2.39.5