diff options
-rw-r--r-- | include/users.h | 23 | ||||
-rw-r--r-- | src/users.cpp | 32 |
2 files changed, 53 insertions, 2 deletions
diff --git a/include/users.h b/include/users.h index f1dd935e0..211ae8c04 100644 --- a/include/users.h +++ b/include/users.h @@ -183,12 +183,16 @@ public: recvqmax(source.recvqmax), maxlocal(source.maxlocal), maxglobal(source.maxglobal), maxchans(source.maxchans), port(source.port) { + this->RefCount = 0; } /** Create a new connect class with no settings. */ ConnectClass() : type(CC_DENY), name("unnamed"), registration_timeout(0), flood(0), host(""), pingtime(0), pass(""), - threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0) { } + threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0) + { + this->RefCount = 0; + } /** Create a new connect class to ALLOW connections. * @param thename Name of the connect class @@ -214,7 +218,10 @@ public: * @param hst The IP mask to deny */ ConnectClass(const std::string &thename, const std::string &hst) : type(CC_DENY), name(thename), registration_timeout(0), - flood(0), host(hst), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0) { } + flood(0), host(hst), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0) + { + this->RefCount = 0; + } /* Create a new connect class based on another class * @param thename The name of the connect class @@ -226,6 +233,7 @@ public: recvqmax(source.recvqmax), maxlocal(source.maxlocal), maxglobal(source.maxglobal), maxchans(source.maxchans), port(source.port) { + this->RefCount = 0; } /* Update an existing entry with new values @@ -260,6 +268,12 @@ public: port = p; } + /** Reference counter. Contains an int as to how many users are connected to this class. :) + * This will be 0 if no users are connected. If a <connect> is removed from the config, and there + * are 0 users on it - it will go away in RAM. :) + */ + unsigned long RefCount; + int GetMaxChans() { return maxchans; @@ -483,6 +497,11 @@ class CoreExport User : public connection unsigned int MaxChans; public: + /** Contains a pointer to the connect class a user is on from - this will be NULL for remote connections. + * The pointer is guarenteed to *always* be valid. :) + */ + ConnectClass *MyClass; + /** Resolvers for looking up this users IP address * This will occur if and when res_reverse completes. * When this class completes its lookup, User::dns_done diff --git a/src/users.cpp b/src/users.cpp index fec5694a4..49d807ac1 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -188,6 +188,7 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance res_forward = res_reverse = NULL; Visibility = NULL; ip = NULL; + MyClass = NULL; chans.clear(); invites.clear(); memset(modes,0,sizeof(modes)); @@ -234,6 +235,13 @@ void User::RemoveCloneCounts() User::~User() { + /* NULL for remote users :) */ + if (this->MyClass) + { + this->MyClass->RefCount--; + ServerInstance->Log(DEBUG, "User destructor -- connect refcount now: %u", this->MyClass->RefCount); + } + this->InvalidateCache(); this->DecrementModes(); if (operquit) @@ -1707,6 +1715,10 @@ unsigned int User::GetMaxChans() * NOTE: If the <ALLOW> or <DENY> tag specifies an ip, and this user resolves, * then their ip will be taken as 'priority' anyway, so for example, * <connect allow="127.0.0.1"> will match joe!bloggs@localhost + * + * NOTE: This will CACHE (i.e. once a user is in a class, subsequent calls will return the + * same class value. + * NOTE 2: As of 1.2, explicit_name is DEPRECATED, as we now tie users to classes :) */ ConnectClass* User::GetClass(const std::string &explicit_name) { @@ -1715,11 +1727,19 @@ ConnectClass* User::GetClass(const std::string &explicit_name) for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { if (explicit_name == i->GetName()) + { return &(*i); + } } } else { + if (this->MyClass) + return this->MyClass; + + if (!IS_LOCAL(this)) + return NULL; + for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++) { if (((match(this->GetIPString(),i->GetHost().c_str(),true)) || (match(this->host,i->GetHost().c_str())))) @@ -1727,15 +1747,27 @@ ConnectClass* User::GetClass(const std::string &explicit_name) if (i->GetPort()) { if (this->GetPort() == i->GetPort()) + { + this->MyClass = &(*i); + this->MyClass->RefCount++; + ServerInstance->Log(DEBUG, "User tied to class -- connect refcount now: %u", this->MyClass->RefCount); return &(*i); + } else continue; } else + { + this->MyClass = &(*i); + this->MyClass->RefCount++; + ServerInstance->Log(DEBUG, "User tied to class -- connect refcount now: %u", this->MyClass->RefCount); return &(*i); + } } } } + + /* will only happen for remote users. */ return NULL; } |