From db11f2b24c6aeb5ab7ba4678638890bc68b1d0c1 Mon Sep 17 00:00:00 2001 From: brain Date: Fri, 29 Apr 2005 15:01:13 +0000 Subject: [PATCH] Fixed some flood checking added noticeall git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1262 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/inspircd.h | 1 + include/users.h | 8 +++++- src/commands.cpp | 21 ++++++++++------ src/inspircd.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++--- src/users.cpp | 12 ++++++++- src/xline.cpp | 6 +++++ 6 files changed, 98 insertions(+), 12 deletions(-) diff --git a/include/inspircd.h b/include/inspircd.h index 2ade03588..d5f149456 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -161,6 +161,7 @@ long GetMaxBans(char* name); bool LoadModule(const char* filename); bool UnloadModule(const char* filename); char* ModuleError(); +void NoticeAll(userrec *source, bool local_only, char* text, ...); // mesh network functions diff --git a/include/users.h b/include/users.h index a607f12c5..0dfbc2223 100644 --- a/include/users.h +++ b/include/users.h @@ -63,12 +63,17 @@ class ConnectClass : public classbase /** (Optional) Password for this line */ char pass[MAXBUF]; + + /** Threshold value for flood disconnect + */ + long threshold; ConnectClass() { registration_timeout = 0; flood = 0; pingtime = 0; + threshold = 0; strlcpy(host,"",MAXBUF); strlcpy(pass,"",MAXBUF); } @@ -183,6 +188,7 @@ class userrec : public connection */ long lines_in; time_t reset_due; + long threshold; userrec(); @@ -221,7 +227,7 @@ class userrec : public connection */ bool HasPermission(char* command); - void userrec::AddBuffer(std::string a); + bool userrec::AddBuffer(std::string a); bool userrec::BufferIsReady(); void userrec::ClearBuffer(); std::string userrec::GetBuffer(); diff --git a/src/commands.cpp b/src/commands.cpp index c098bbb10..610b694bc 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1863,18 +1863,25 @@ void handle_V(char token,char* params,serverrec* source,serverrec* reply, char* userrec* user = Find(src); if (user) { - userrec* dst = Find(dest); - - if (dst) + // notice all - only issuable by a server + if (strcmp(dest,"*")) { - WriteTo(user, dst, "NOTICE %s :%s", dst->nick, text); + NoticeAll(user,true,"%s",text); } else { - chanrec* d = FindChan(dest); - if (d) + userrec* dst = Find(dest); + if (dst) { - ChanExceptSender(d, user, "NOTICE %s :%s", d->name, text); + WriteTo(user, dst, "NOTICE %s :%s", dst->nick, text); + } + else + { + chanrec* d = FindChan(dest); + if (d) + { + ChanExceptSender(d, user, "NOTICE %s :%s", d->name, text); + } } } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 3c2ab09a8..59256f8c0 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -341,7 +341,7 @@ void readfile(file_cache &F, const char* fname) void ReadConfig(bool bail, userrec* user) { char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF]; - char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF]; + char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF]; ConnectClass c; std::stringstream errstr; @@ -446,6 +446,7 @@ void ReadConfig(bool bail, userrec* user) ConfValue("connect","timeout",i,timeout,&config_f); ConfValue("connect","flood",i,flood,&config_f); ConfValue("connect","pingfreq",i,pfreq,&config_f); + ConfValue("connect","threshold",i,thold,&config_f); if (Value[0]) { strlcpy(c.host,Value,MAXBUF); @@ -456,6 +457,11 @@ void ReadConfig(bool bail, userrec* user) c.registration_timeout = 90; // default is 2 minutes c.pingtime = 120; c.flood = atoi(flood); + c.threshold = 5; + if (atoi(thold)>0) + { + c.threshold = atoi(thold); + } if (atoi(timeout)>0) { c.registration_timeout = atoi(timeout); @@ -1171,6 +1177,37 @@ void WriteMode(const char* modes, int flags, const char* text, ...) } +void NoticeAll(userrec *source, bool local_only, char* text, ...) +{ + if ((!text) || (!source)) + { + log(DEFAULT,"*** BUG *** WriteOpers was given an invalid parameter"); + return; + } + + char textbuffer[MAXBUF]; + va_list argsPtr; + va_start (argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + + for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) + { + if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER)) + { + WriteFrom(i->second->fd,source,"NOTICE $* :%s",textbuffer); + } + } + + if (!local_only) + { + char buffer[MAXBUF]; + snprintf(buffer,MAXBUF,"V %s * :%s",source->nick,textbuffer); + NetSendToAll(buffer); + } + +} + void WriteWallOps(userrec *source, bool local_only, char* text, ...) { if ((!text) || (!source)) @@ -2414,6 +2451,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) // set the registration timeout for this user unsigned long class_regtimeout = 90; int class_flood = 0; + long class_threshold = 5; for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++) { @@ -2422,6 +2460,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) class_regtimeout = (unsigned long)i->registration_timeout; class_flood = i->flood; clientlist[tempnick]->pingmax = i->pingtime; + class_threshold = i->threshold; break; } } @@ -2429,6 +2468,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) clientlist[tempnick]->nping = TIME+clientlist[tempnick]->pingmax+dns_timeout; clientlist[tempnick]->timeout = TIME+class_regtimeout; clientlist[tempnick]->flood = class_flood; + clientlist[tempnick]->threshold = class_threshold; for (int i = 0; i < MAXCHANS; i++) { @@ -4081,7 +4121,23 @@ int InspIRCd(void) userrec* current = count2a->second; int currfd = current->fd; int floodlines = 0; - current->AddBuffer(data); + // add the data to the users buffer + if (!current->AddBuffer(data)) + { + // AddBuffer returned false, theres too much data in the user's buffer and theyre up to no good. + if (current->registered == 7) + { + kill_link(current,"RecvQ exceeded"); + } + else + { + WriteOpers("*** Excess flood from %s",current->ip); + log(DEFAULT,"Excess flood from: %s",current->ip); + add_zline(120,ServerName,"Flood from unregistered connection",current->ip); + apply_lines(); + } + goto label; + } if (current->recvq.length() > NetBufferSize) { if (current->registered == 7) @@ -4103,7 +4159,7 @@ int InspIRCd(void) floodlines++; if (TIME > current->reset_due) { - current->reset_due = TIME+3; + current->reset_due = TIME + current->threshold; current->lines_in = 0; } current->lines_in++; diff --git a/src/users.cpp b/src/users.cpp index 0ece63bc9..0d305a3b7 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -166,7 +166,7 @@ bool userrec::HasPermission(char* command) } -void userrec::AddBuffer(std::string a) +bool userrec::AddBuffer(std::string a) { std::string b = ""; for (int i = 0; i < a.length(); i++) @@ -175,6 +175,16 @@ void userrec::AddBuffer(std::string a) std::stringstream stream(recvq); stream << b; recvq = stream.str(); + int i = 0; + // count the size of the first line in the buffer. + while (i < recvq.length()) + { + if (recvq[i++] == '\n') + break; + } + // return false if we've had more than 600 characters WITHOUT + // a carriage return (this is BAD, drop the socket) + return (i < 600); } bool userrec::BufferIsReady() diff --git a/src/xline.cpp b/src/xline.cpp index 92f5ac3a4..7452d81f0 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -288,6 +288,12 @@ void add_zline(long duration, const char* source, const char* reason, const char del_zline(ipaddr); ZLine item; item.duration = duration; + if (strchr(ipaddr,'@')) + { + while (*ipaddr != '@') + ipaddr++; + ipaddr++; + } strlcpy(item.ipaddr,ipaddr,MAXBUF); strlcpy(item.reason,reason,MAXBUF); strlcpy(item.source,source,MAXBUF); -- 2.39.2