diff options
-rw-r--r-- | docs/inspircd.conf.example | 6 | ||||
-rw-r--r-- | include/users.h | 18 | ||||
-rw-r--r-- | src/configreader.cpp | 10 | ||||
-rw-r--r-- | src/users.cpp | 7 |
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) { |