diff options
-rw-r--r-- | docs/inspircd.conf.example | 29 | ||||
-rw-r--r-- | include/users.h | 22 | ||||
-rw-r--r-- | src/InspIRCd.layout | 28 | ||||
-rw-r--r-- | src/inspircd.cpp | 49 | ||||
-rw-r--r-- | src/users.cpp | 24 |
5 files changed, 104 insertions, 48 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index ce24e89d0..6042dc3cf 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -105,15 +105,21 @@ # <connect allow="ip number"> # # <connect allow="ip number" password="blahblah"> # # <connect allow="ip number" password="blah" timeout="10"> # +# <connect allow="ip number" timeout="blah" flood="5"> # # <connect deny="ip number"> # # # -# You may optionally include timeout="x" on any alllow line, which # +# You may optionally include timeout="x" on any allow line, which # # 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 also optionally 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. The default is to # +# DISABLE this feature. A recommended value is 10. # + <connect allow="196.12.*" password="tiffany"> -<connect allow="*" timeout="60"> +<connect allow="*" timeout="60" flood="10"> <connect deny="69.254.*"> @@ -230,17 +236,20 @@ # # # Settings to define which features are useable on your server. # # # -# prefixquit - a prefix for a client's quit message # -# loglevel - specifies what detail of messages to log in the # -# log file. You may select from debug, verbose, # -# default, sparse and none. # -# allowhalfop - allows the +h channel mode # -# allowprotect - allows the +a channel mode # -# allowfounder - allows the +q channel mode # -# # +# prefixquit - a prefix for a client's quit message # +# loglevel - specifies what detail of messages to log in the # +# log file. You may select from debug, verbose, # +# default, sparse and none. # +# allowhalfop - allows the +h channel mode # +# allowprotect - allows the +a channel mode # +# allowfounder - allows the +q channel mode # +# netbuffersize - size of the buffer used to receive data from # +# clients. The ircd may only read() this amount # +# of text in one go at any time. (OPTIONAL) # <options prefixquit="Quit: " loglevel="default" + netbuffersize="10240" allowhalfop="yes" allowprotect="yes" allowfounder="yes"> diff --git a/include/users.h b/include/users.h index dbb237c5f..c1a6aa3af 100644 --- a/include/users.h +++ b/include/users.h @@ -34,14 +34,26 @@ class Invited : public classbase class ConnectClass : public classbase { public: + /** Type of line, either CC_ALLOW or CC_DENY + */ int type; + /** Max time to register the connection in seconds + */ int registration_timeout; + /** Number of lines in buffer before excess flood is triggered + */ + int flood; + /** Host mask for this line + */ char host[MAXBUF]; + /** (Optional) Password for this line + */ char pass[MAXBUF]; ConnectClass() { registration_timeout = 0; + flood = 0; strcpy(host,""); strcpy(pass,""); } @@ -113,8 +125,16 @@ class userrec : public connection */ char result[256]; - char carryover[MAXBUF]; + /** Number of lines the user can place into the buffer + * (up to the global NetBufferSize bytes) before they + * are disconnected for excess flood + */ + int flood; + /** Number of seconds this user is given to send USER/NICK + * If they do not send their details in this time limit they + * will be disconnected + */ unsigned long timeout; userrec(); diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index 3e666488f..6a8683441 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -1,6 +1,6 @@ [Editors] -Focused=1 -Order=1,2,-1,4 +Focused=6 +Order=1,2,-1,4,6 [Editor_0] Open=0 @@ -12,10 +12,10 @@ LeftChar=1 [Editor_1] Open=1 -Top=1 -CursorCol=15 -CursorRow=5535 -TopLine=5513 +Top=0 +CursorCol=24 +CursorRow=1459 +TopLine=1431 LeftChar=1 [Editor_2] @@ -51,11 +51,11 @@ TopLine=1 LeftChar=1 [Editor_6] -Open=0 -Top=0 -CursorCol=1 -CursorRow=36 -TopLine=1 +Open=1 +Top=1 +CursorCol=2 +CursorRow=92 +TopLine=37 LeftChar=1 [Editor_7] @@ -181,9 +181,9 @@ LeftChar=1 [Editor_22] Open=1 Top=0 -CursorCol=25 -CursorRow=116 -TopLine=65 +CursorCol=5 +CursorRow=137 +TopLine=101 LeftChar=1 [Editor_23] diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 63aa079d8..81dee527e 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -75,6 +75,7 @@ int WHOWAS_STALE = 48; // default WHOWAS Entries last 2 days before they go 'sta int WHOWAS_MAX = 100; // default 100 people maximum in the WHOWAS list int DieDelay = 5; time_t startup_time = time(NULL); +int NetBufferSize = 10240; // NetBufferSize used as the buffer size for all read() ops extern vector<Module*> modules; vector<string> module_names; @@ -382,7 +383,7 @@ void readfile(file_cache &F, const char* fname) void ReadConfig(void) { - char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF]; + char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF]; ConnectClass c; LoadConf(CONFIG_FILE,&config_f); @@ -401,6 +402,13 @@ void ReadConfig(void) ConfValue("options","prefixquit",0,PrefixQuit,&config_f); ConfValue("die","value",0,DieValue,&config_f); ConfValue("options","loglevel",0,dbg,&config_f); + ConfValue("options","netbuffersize",0,NB,&config_f); + NetBufferSize = atoi(NB); + if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024)) + { + log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240."); + NetBufferSize = 10240; + } if (!strcmp(dbg,"debug")) LogLevel = DEBUG; if (!strcmp(dbg,"verbose")) @@ -421,6 +429,7 @@ void ReadConfig(void) strcpy(Value,""); ConfValue("connect","allow",i,Value,&config_f); ConfValue("connect","timeout",i,timeout,&config_f); + ConfValue("connect","flood",i,flood,&config_f); if (strcmp(Value,"")) { strcpy(c.host,Value); @@ -429,12 +438,13 @@ void ReadConfig(void) ConfValue("connect","password",i,Value,&config_f); strcpy(c.pass,Value); c.registration_timeout = 90; // default is 2 minutes + c.flood = atoi(flood); if (atoi(timeout)>0) { c.registration_timeout = atoi(timeout); } Classes.push_back(c); - log(DEBUG,"Read connect class type ALLOW, host=%s password=%s",c.host,c.pass); + log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood); } else { @@ -3614,8 +3624,19 @@ void AddClient(int socket, char* host, int port, bool iscached) break; } } - log(DEBUG,"Client has a connection timeout value of %d",class_regtimeout); + + int class_flood = 0; + for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++) + { + if (match(clientlist[tempnick]->host,i->host) && (i->type == CC_ALLOW)) + { + class_flood = i->flood; + break; + } + } + clientlist[tempnick]->timeout = time(NULL)+class_regtimeout; + clientlist[tempnick]->flood = class_flood; if (clientlist.size() == MAXCLIENTS) kill_link(clientlist[tempnick],"No more connections allowed in this class"); @@ -4989,7 +5010,6 @@ void process_buffer(const char* cmdbuf,userrec *user) log(DEFAULT,"*** BUG *** process_buffer was given an invalid parameter"); return; } - log(DEBUG,"A: %s",cmdbuf); if (!strcmp(cmdbuf,"")) { return; @@ -4999,25 +5019,20 @@ void process_buffer(const char* cmdbuf,userrec *user) { return; } - log(DEBUG,"B: %s",cmd); if ((cmd[strlen(cmd)-1] == 13) || (cmd[strlen(cmd)-1] == 10)) { cmd[strlen(cmd)-1] = '\0'; } - log(DEBUG,"C: %s",cmd); if ((cmd[strlen(cmd)-1] == 13) || (cmd[strlen(cmd)-1] == 10)) { cmd[strlen(cmd)-1] = '\0'; } - log(DEBUG,"D: %s",cmd); if (!strcmp(cmd,"")) { return; } - log(DEBUG,"E: %s",cmd); log(DEBUG,"InspIRCd: processing: %s %s",user->nick,cmd); tidystring(cmd); - log(DEBUG,"F: %s",cmd); if ((user) && (cmd)) { process_command(user,cmd); @@ -5530,10 +5545,19 @@ int InspIRCd(void) userrec* current = count2a->second; int currfd = current->fd; char* l = strtok(data,"\n"); + int floodlines = 0; while (l) { - char sanitized[10240]; - memset(sanitized, 0, 10240); + floodlines++; + if ((floodlines > current->flood) && (current->flood != 0)) + { + log(DEFAULT,"Excess flood from: %s!%s@%s",current->nick,current->ident,current->host); + WriteOpers("*** Excess flood from: %s!%s@%s",current->nick,current->ident,current->host); + kill_link(current,"Excess flood"); + goto label; + } + char sanitized[NetBufferSize]; + memset(sanitized, 0, NetBufferSize); int ptt = 0; for (int pt = 0; pt < strlen(l); pt++) { @@ -5543,7 +5567,6 @@ int InspIRCd(void) } } sanitized[ptt] = '\0'; - l = strtok(NULL,"\n"); if (strlen(sanitized)) { @@ -5551,7 +5574,6 @@ int InspIRCd(void) // we're gonna re-scan to check if the nick is gone, after every // command - if it has, we're gonna bail bool find_again = false; - log(DEBUG,"\nProcess line: %s %d\n",sanitized,strlen(sanitized)); process_buffer(sanitized,current); // look for the user's record in case it's changed @@ -5569,6 +5591,7 @@ int InspIRCd(void) goto label; } + l = strtok(NULL,"\n"); } goto label; } diff --git a/src/users.cpp b/src/users.cpp index 4c7173e30..eb4954897 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -23,7 +23,7 @@ userrec::userrec() strcpy(server,""); strcpy(awaymsg,""); fd = lastping = signon = idle_lastmsg = nping = registered = 0; - port = bytes_in = bytes_out = cmds_in = cmds_out = 0; + flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0; haspassed = false; strcpy(result,""); for (int i = 0; i < MAXCHANS; i++) @@ -72,17 +72,21 @@ void userrec::InviteTo(char* channel) void userrec::RemoveInvite(char* channel) { log(DEBUG,"Removing invites"); - if (invites.size()) + if (channel) { - for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++) - { - if (i->channel) { - if (!strcasecmp(i->channel,channel)) + if (invites.size()) + { + for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++) + { + if (i->channel) { - invites.erase(i); - return; - } - } + if (!strcasecmp(i->channel,channel)) + { + invites.erase(i); + return; + } + } + } } } } |