diff options
Diffstat (limited to 'src/sessions.cpp')
-rw-r--r-- | src/sessions.cpp | 292 |
1 files changed, 0 insertions, 292 deletions
diff --git a/src/sessions.cpp b/src/sessions.cpp deleted file mode 100644 index 358527ea0..000000000 --- a/src/sessions.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* Session Limiting functions. - * - * (C) 2003-2011 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -#include "services.h" -#include "modules.h" - -/*************************************************************************/ - -/* SESSION LIMITING - * - * The basic idea of session limiting is to prevent one host from having more - * than a specified number of sessions (client connections/clones) on the - * network at any one time. To do this we have a list of sessions and - * exceptions. Each session structure records information about a single host, - * including how many clients (sessions) that host has on the network. When a - * host reaches it's session limit, no more clients from that host will be - * allowed to connect. - * - * When a client connects to the network, we check to see if their host has - * reached the default session limit per host, and thus whether it is allowed - * any more. If it has reached the limit, we kill the connecting client; all - * the other clients are left alone. Otherwise we simply increment the counter - * within the session structure. When a client disconnects, we decrement the - * counter. When the counter reaches 0, we free the session. - * - * Exceptions allow one to specify custom session limits for a specific host - * or a range thereof. The first exception that the host matches is the one - * used. - * - * -TheShadow (02 April 1999) - */ - -/*************************************************************************/ - -Anope::map<Session *> SessionList; - -std::vector<Exception *> exceptions; - -/*************************************************************************/ -/****************************** Statistics *******************************/ -/*************************************************************************/ - -void get_session_stats(long &count, long &mem) -{ - count = SessionList.size(); - mem = sizeof(Session) * SessionList.size(); - - for (Anope::map<Session *>::iterator it = SessionList.begin(), it_end = SessionList.end(); it != it_end; ++it) - { - Session *session = it->second; - mem += session->host.length() + 1; - } -} - -void get_exception_stats(long &count, long &mem) -{ - count = exceptions.size(); - mem = sizeof(Exception) * exceptions.size(); - - for (std::vector<Exception *>::const_iterator it = exceptions.begin(), it_end = exceptions.end(); it != it_end; ++it) - { - Exception *e = *it; - if (!e->mask.empty()) - mem += e->mask.length() + 1; - if (!e->reason.empty()) - mem += e->reason.length() + 1; - if (!e->who.empty()) - mem += e->who.length() + 1; - } -} - -/*************************************************************************/ -/********************* Internal Session Functions ************************/ -/*************************************************************************/ - -Session *findsession(const Anope::string &host) -{ - Anope::map<Session *>::iterator it = SessionList.find(host); - if (it != SessionList.end()) - return it->second; - return NULL; -} - -/* Attempt to add a host to the session list. If the addition of the new host - * causes the the session limit to be exceeded, kill the connecting user. - */ - -void add_session(User *u) -{ - const Anope::string &hostip = u->ip() ? u->ip.addr() : ""; - Session *session = findsession(u->host); - - if (session) - { - bool kill = false; - if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit) - { - kill = true; - Exception *exception = find_hostip_exception(u->host, hostip); - if (exception) - { - kill = false; - if (exception->limit && session->count >= exception->limit) - kill = true; - } - } - - if (kill) - { - if (!Config->SessionLimitExceeded.empty()) - u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->host.c_str()); - if (!Config->SessionLimitDetailsLoc.empty()) - u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str()); - - /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was - * decremented in do_quit, which caused problems and fixed here - * - * Now, we create the user struture before calling this to fix some user tracking issues, - * so we must increment this here no matter what because it will either be - * decremented in do_kill or in do_quit - Adam - */ - ++session->count; - kill_user(Config->s_OperServ, u, "Session limit exceeded"); - - ++session->hits; - if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && SGLine) - { - const Anope::string &akillmask = "*@" + u->host; - const Anope::string &akillreason = "Session limit exceeded for " + u->host; - SGLine->Add(NULL, NULL, akillmask, Anope::CurTime + Config->SessionAutoKillExpiry, akillreason); - ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask.c_str()); - } - } - else - { - ++session->count; - } - } - else - { - session = new Session(); - session->host = u->host; - session->count = 1; - session->hits = 0; - - SessionList[session->host] = session; - } -} - -void del_session(User *u) -{ - if (!Config->LimitSessions) - { - Log(LOG_DEBUG) << "del_session called when LimitSessions is disabled"; - return; - } - - if (!u) - { - Log(LOG_DEBUG) << "del_session called with NULL values"; - return; - } - - Log(LOG_DEBUG_2) << "del_session() called"; - - Session *session = findsession(u->host); - - if (!session) - { - if (debug) - { - ircdproto->SendGlobops(OperServ, "WARNING: Tried to delete non-existant session: \2%s", u->host.c_str()); - Log() << "session: Tried to delete non-existant session: " << u->host; - } - return; - } - - if (session->count > 1) - { - --session->count; - return; - } - - SessionList.erase(session->host); - - delete session; - - Log(LOG_DEBUG_2) << "del_session() done"; -} - -/*************************************************************************/ -/********************** Internal Exception Functions *********************/ -/*************************************************************************/ - -void expire_exceptions() -{ - for (unsigned i = exceptions.size(); i > 0; --i) - { - Exception *e = exceptions[i - 1]; - - if (!e->expires || e->expires > Anope::CurTime) - continue; - if (Config->WallExceptionExpire) - ircdproto->SendGlobops(OperServ, "Session limit exception for %s has expired.", e->mask.c_str()); - delete e; - exceptions.erase(exceptions.begin() + i - 1); - } -} - -/* Find the first exception this host matches and return it. */ -Exception *find_host_exception(const Anope::string &host) -{ - for (std::vector<Exception *>::const_iterator it = exceptions.begin(), it_end = exceptions.end(); it != it_end; ++it) - { - Exception *e = *it; - if (Anope::Match(host, e->mask)) - return e; - } - - return NULL; -} - -/* Same as find_host_exception() except - * this tries to find the exception by IP also. */ -Exception *find_hostip_exception(const Anope::string &host, const Anope::string &hostip) -{ - for (std::vector<Exception *>::const_iterator it = exceptions.begin(), it_end = exceptions.end(); it != it_end; ++it) - { - Exception *e = *it; - if (Anope::Match(host, e->mask) || (!hostip.empty() && Anope::Match(hostip, e->mask))) - return e; - } - - return NULL; -} - -/*************************************************************************/ -/************************ Exception Manipulation *************************/ -/*************************************************************************/ - -int exception_add(User *u, const Anope::string &mask, unsigned limit, const Anope::string &reason, const Anope::string &who, time_t expires) -{ - /* Check if an exception already exists for this mask */ - for (std::vector<Exception *>::iterator it = exceptions.begin(), it_end = exceptions.end(); it != it_end; ++it) - { - Exception *e = *it; - if (e->mask.equals_ci(mask)) - { - if (e->limit != limit) - { - e->limit = limit; - if (u) - u->SendMessage(OperServ, _("Exception for \002%s\002 has been updated to %d."), mask.c_str(), e->limit); - return -2; - } - else - { - if (u) - u->SendMessage(OperServ, _("\002%s\002 already exists on the EXCEPTION list."), mask.c_str()); - return -1; - } - } - } - - Exception *exception = new Exception(); - exception->mask = mask; - exception->limit = limit; - exception->reason = reason; - exception->time = Anope::CurTime; - exception->who = who; - exception->expires = expires; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnExceptionAdd, OnExceptionAdd(u, exception)); - if (MOD_RESULT == EVENT_STOP) - { - delete exception; - return -3; - } - - exceptions.push_back(exception); - - return 1; -} |