1
0
Эх сурвалжийг харах

Track all clients to detect mass flooding (#37)

Bryan Drewery 14 жил өмнө
parent
commit
6e3914f177

+ 1 - 0
doc/UPDATES

@@ -1,6 +1,7 @@
 * Fix flood kicking not properly tracking multiple clients at once (#43)
 * Add chanset 'flood-bytes' to count how many bytes:second a user sends before getting kicked for flood. (#42)
 * Bot will now lockdown channel (+im) if banlist becomes full (#37)
+* Bot will now lockdown channel (+im) if a drone flood is detected (#37)
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.

+ 29 - 1
src/mod/irc.mod/chan.c

@@ -634,6 +634,34 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
       return 0;
   }
 
+  // Track across all clients in the channel
+  if (!chan->channel.floodtime->contains("all")) {
+    (*chan->channel.floodtime)["all"][which] = now;
+    (*chan->channel.floodnum)["all"][which] = increment;
+    return 0;
+  }
+
+  bd::HashTable<flood_t, time_t>      *global_floodtime = &(*chan->channel.floodtime)["all"];
+  bd::HashTable<flood_t, int>         *global_floodnum = &(*chan->channel.floodnum)["all"];
+
+  if ((*global_floodtime)[which] < now - lapse) {
+    /* Flood timer expired, reset it */
+    (*global_floodtime)[which] = now;
+    (*global_floodnum)[which] = increment;
+  } else {
+    (*global_floodnum)[which] += increment;
+
+    if ((*global_floodnum)[which] >= thr) {	/* FLOOD */
+      /* Reset counters */
+      (*global_floodnum).remove(which);
+      (*global_floodtime).remove(which);
+      if (!chan->channel.drone_set_mode) {
+        lockdown_chan(chan, FLOOD_DRONE);
+      }
+    }
+  }
+
+  // Track individual hosts/clients
   bd::HashTable<flood_t, time_t>      *floodtime; // floodtime[FLOOD_PRIVMSG] = now;
   bd::HashTable<flood_t, int>         *floodnum;  //  floodnum[FLOOD_PRIVMSG] = 1;
 
@@ -2745,7 +2773,7 @@ static int gotjoin(char *from, char *chname)
           chan->channel.drone_jointime = now;
 
           if (!chan->channel.drone_set_mode && chan->channel.drone_joins >= chan->flood_mjoin_thr) {  //flood from dronenet, let's attempt to set +im
-            lockdown_chan(chan, FLOOD_DRONE);
+            lockdown_chan(chan, FLOOD_MASSJOIN);
           }
         }
 

+ 4 - 2
src/mod/irc.mod/irc.c

@@ -189,10 +189,12 @@ void lockdown_chan(struct chanset_t* chan, flood_reason_t reason) {
     howlong.usec = 0;
     timer_create_complex(&howlong, "unlock", (Function) unlock_chan, (void *) chan, 0);
 
-    if (reason == FLOOD_DRONE) {
-      putlog(LOG_MISC, "*", "Flood detected in %s! Locking for %d seconds.", chan->dname, chan->flood_lock_time);
+    if (reason == FLOOD_MASSJOIN) {
+      putlog(LOG_MISC, "*", "Join flood detected in %s! Locking for %d seconds.", chan->dname, chan->flood_lock_time);
     } else if (reason == FLOOD_BANLIST) {
       putlog(LOG_MISC, "*", "Banlist full in %s! Locking for %d seconds.", chan->dname, chan->flood_lock_time);
+    } else if (reason == FLOOD_DRONE) {
+      putlog(LOG_MISC, "*", "Drone flood detected in %s! Locking for %d seconds.", chan->dname, chan->flood_lock_time);
     }
   }
 }

+ 3 - 2
src/mod/irc.mod/irc.h

@@ -25,8 +25,9 @@ namespace bd {
 }
 
 enum flood_reason_t {
-  FLOOD_DRONE,
-  FLOOD_BANLIST
+  FLOOD_MASSJOIN,
+  FLOOD_BANLIST,
+  FLOOD_DRONE
 };
 
 #ifdef CACHE