summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/users.h23
-rw-r--r--src/users.cpp32
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;
}