summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/inspircd.conf.example6
-rw-r--r--include/users.h18
-rw-r--r--src/configreader.cpp10
-rw-r--r--src/users.cpp7
4 files changed, 30 insertions, 11 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example
index e37c07b8a..52159a404 100644
--- a/docs/inspircd.conf.example
+++ b/docs/inspircd.conf.example
@@ -211,7 +211,7 @@
# #
# Syntax is as follows: #
# #
-# <connect name="myallow" allow="1.2.3.0/24" #
+# <connect name="myallow" allow="1.2.3.0/24" limit="5" #
# password="blahblah" timeout="10" timeout="blah" #
# flood="5" threshold="8" pingfreq="120" sendq="99999" #
# revcq="696969" localmax="3" globalmax="3" #
@@ -241,6 +241,10 @@
# specifies the amount of time given before an unknown connection #
# is closed if USER/NICK/PASS are not given. This value is in secs. #
# #
+# You may optionally limit the number of clients that are matched #
+# by a single <connect> tag by specifying the maximum in the limit #
+# parameter. If set to 0, there is no limit, which is the default. #
+# #
# You should also include a flood="x" line which indicates #
# the number of lines a user may place into their buffer at once #
# before they are disconnected for excess flood. This feature can #
diff --git a/include/users.h b/include/users.h
index d51e06ba9..b11d346b7 100644
--- a/include/users.h
+++ b/include/users.h
@@ -181,14 +181,14 @@ public:
registration_timeout(source->registration_timeout), flood(source->flood), host(source->host),
pingtime(source->pingtime), pass(source->pass), threshold(source->threshold), sendqmax(source->sendqmax),
recvqmax(source->recvqmax), maxlocal(source->maxlocal), maxglobal(source->maxglobal), maxchans(source->maxchans),
- port(source->port), RefCount(0), disabled(false)
+ port(source->port), RefCount(0), disabled(false), limit(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), RefCount(0), disabled(false)
+ threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), RefCount(0), disabled(false), limit(0)
{
}
@@ -209,14 +209,14 @@ public:
const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq,
unsigned long maxl, unsigned long maxg, unsigned int maxc, int p = 0) :
type(CC_ALLOW), name(thename), registration_timeout(timeout), flood(fld), host(hst), pingtime(ping), pass(pas),
- threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), maxchans(maxc), port(p), RefCount(0), disabled(false) { }
+ threshold(thres), sendqmax(sendq), recvqmax(recvq), maxlocal(maxl), maxglobal(maxg), maxchans(maxc), port(p), RefCount(0), disabled(false), limit(0) { }
/** Create a new connect class to DENY connections
* @param thename Name of the connect class
* @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), RefCount(0), disabled(false)
+ flood(0), host(hst), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0), maxlocal(0), maxglobal(0), maxchans(0), port(0), RefCount(0), disabled(false), limit(0)
{
}
@@ -228,7 +228,7 @@ public:
registration_timeout(source->registration_timeout), flood(source->flood), host(source->host),
pingtime(source->pingtime), pass(source->pass), threshold(source->threshold), sendqmax(source->sendqmax),
recvqmax(source->recvqmax), maxlocal(source->maxlocal), maxglobal(source->maxglobal), maxchans(source->maxchans),
- port(source->port), RefCount(0), disabled(false)
+ port(source->port), RefCount(0), disabled(false), limit(0)
{
}
@@ -246,7 +246,7 @@ public:
*/
void Update(unsigned int timeout, unsigned int fld, const std::string &hst, unsigned int ping,
const std::string &pas, unsigned int thres, unsigned long sendq, unsigned long recvq,
- unsigned long maxl, unsigned long maxg, unsigned int maxc, int p)
+ unsigned long maxl, unsigned long maxg, unsigned int maxc, int p, unsigned long limit)
{
if (timeout)
registration_timeout = timeout;
@@ -272,6 +272,8 @@ public:
maxchans = maxc;
if (p)
port = p;
+
+ this->limit = limit;
}
/** Reference counter. Contains an int as to how many users are connected to this class. :)
@@ -284,6 +286,10 @@ public:
*/
bool disabled;
+ /** How many users may be in this connect class before they are refused? (0 = disabled = default)
+ */
+ unsigned long limit;
+
int GetMaxChans()
{
return maxchans;
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 6317bca95..4de90cd78 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -459,6 +459,7 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*)
const char* name = values[12].GetString();
const char* parent = values[13].GetString();
int maxchans = values[14].GetInteger();
+ unsigned long limit = values[15].GetInteger();
/*
* duplicates check: Now we don't delete all connect classes on rehash, we need to ensure we don't add dupes.
@@ -489,7 +490,7 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*)
if (c->GetName() == parent)
{
ConnectClass* c = new ConnectClass(name, c);
- c->Update(timeout, flood, *allow ? allow : deny, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port);
+ c->Update(timeout, flood, *allow ? allow : deny, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans, port, limit);
conf->Classes.push_back(c);
}
}
@@ -500,6 +501,7 @@ bool DoConnect(ServerConfig* conf, const char*, char**, ValueList &values, int*)
if (*allow)
{
ConnectClass* c = new ConnectClass(name, timeout, flood, allow, pingfreq, password, threshold, sendq, recvq, localmax, globalmax, maxchans);
+ c->limit = limit;
c->SetPort(port);
conf->Classes.push_back(c);
}
@@ -746,15 +748,15 @@ void ServerConfig::Read(bool bail, User* user)
{"connect",
{"allow", "deny", "password", "timeout", "pingfreq", "flood",
"threshold", "sendq", "recvq", "localmax", "globalmax", "port",
- "name", "parent", "maxchans",
+ "name", "parent", "maxchans", "limit",
NULL},
{"", "", "", "", "120", "",
"", "", "", "3", "3", "0",
- "", "", "0",
+ "", "", "0", "0",
NULL},
{DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_INTEGER, DT_INTEGER, DT_INTEGER,
DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER, DT_INTEGER,
- DT_CHARPTR, DT_CHARPTR, DT_INTEGER},
+ DT_CHARPTR, DT_CHARPTR, DT_INTEGER, DT_INTEGER},
InitConnect, DoConnect, DoneConnect},
{"uline",
diff --git a/src/users.cpp b/src/users.cpp
index 381806e50..1affa67db 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1762,6 +1762,13 @@ ConnectClass* User::SetClass(const std::string &explicit_name)
/* ensure we don't fuck things up refcount wise, only remove them from a class if we find a new one :P */
if (found)
{
+ /* deny change if change will take class over the limit */
+ if (found->RefCount + 1 >= found->limit)
+ {
+ ServerInstance->Log(DEBUG, "OOPS: Connect class limit (%u) hit, denying", found->limit);
+ return this->MyClass;
+ }
+
/* should always be valid, but just in case .. */
if (this->MyClass)
{