Преглед изворни кода

* Port [2500] [3336] [3337] to 1.2.14
* Add channel flag 'nomassjoin' to set +im on a timer during join floods (drones)



svn: 3338

Bryan Drewery пре 19 година
родитељ
комит
d643424c95

+ 1 - 0
doc/UPDATES

@@ -32,6 +32,7 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
 * Fixed +voice flaw where users in channels that were +voice AND +private would only be voiced with |v.
 * Added cmd_clearhosts
 * Added 'whois restrictions' to more cmds.
+* Add channel flag 'nomassjoin' to set +im on a timer during join floods (drones)
 
 1.2.13 - http://wraith.shatow.net/milestone/1.2.13
 * Fix cmd_chanset accepting invalid flags

+ 3 - 0
misc/help.txt

@@ -432,6 +432,9 @@ See also: link
                        the bot from fighting with services such as ChanServ, or
                        from kicking IRCops when setting channel modes without
                        having ops.
+        $bnomassjoin$b     If more than 6 clients join in 1 second, set +im
+                           for 2 minutes. (Could be triggered from net-split
+                           rejoin if clients hop servers and change nicks)
         $bprivate$b        This by far is probably the single most unique and
                        important feature of this pack. With this set, users with
                        global +o will not implicitly have access to the channel.

+ 5 - 1
src/chan.h

@@ -92,13 +92,16 @@ struct chan_t {
   time_t jointime;
   time_t parttime;
   time_t no_op;
+  time_t drone_jointime;
   int fighting;
+  int drone_joins;
 #ifdef G_BACKUP
   int backup_time;              /* If non-0, set +backup when now>backup_time */
 #endif /* G_BACKUP */
   int maxmembers;
   int members;
   int do_opreq;
+  bool set_im;
   char *topic;
   char *key;
   unsigned short int mode;
@@ -222,7 +225,7 @@ struct chanset_t {
 #define CHAN_CYCLE          BIT11	/* cycle the channel if possible      */
 #define CHAN_INACTIVE       BIT12	/* no irc support for this channel */
 #define CHAN_VOICE          BIT13	/* a bot +y|y will voice *, except +q */
-#undef  CHAN_14             /* BIT14	 */
+#define CHAN_NOMASSJOIN     BIT14       /* watch for mass join for flood nets and react */
 #define CHAN_NODESYNCH      BIT15
 #define CHAN_FASTOP         BIT16	/* Bots will not use +o-b to op (no cookies) */ 
 #define CHAN_PRIVATE        BIT17	/* users need |o to access chan */ 
@@ -285,6 +288,7 @@ struct chanset_t *findchan_by_dname(const char *name);
 #define channel_fastop(chan) (chan->status & CHAN_FASTOP)
 #define channel_privchan(chan) (chan->status & CHAN_PRIVATE)
 #define channel_autoop(chan) (chan->status & CHAN_AUTOOP)
+#define channel_nomassjoin(chan) (chan->status & CHAN_NOMASSJOIN)
 /* Chanflag template
  *#define channel_temp(chan) (chan->status & CHAN_PRIVATE)
  */

+ 2 - 0
src/mod/channels.mod/channels.c

@@ -867,6 +867,8 @@ void channels_report(int idx, int details)
  *	if (channel_temp(chan))
  *	  i += my_strcpy(s + i, "temp ");
 */
+        if (channel_nomassjoin(chan))
+          i += my_strcpy(s + i, "nomassjoin ");
         if (channel_botbitch(chan))
           i += my_strcpy(s + i, "botbitch ");
         if (channel_backup(chan))

+ 1 - 0
src/mod/channels.mod/cmdschan.c

@@ -1209,6 +1209,7 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_FLAG("fastop",		channel_fastop(chan));
     SHOW_FLAG("inactive",	channel_inactive(chan));
     SHOW_FLAG("nodesynch",	channel_nodesynch(chan));
+    SHOW_FLAG("nomassjoin",	channel_nomassjoin(chan));
     SHOW_FLAG("private",	channel_privchan(chan));
     SHOW_FLAG("protectops",	channel_protectops(chan));
 //    SHOW_FLAG("revenge",	channel_revenge(chan));

+ 4 - 0
src/mod/channels.mod/tclchan.c

@@ -557,6 +557,10 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       chan->status |= CHAN_BOTBITCH;
     else if (!strcmp(item[i], "-botbitch"))
       chan->status &= ~CHAN_BOTBITCH;
+    else if (!strcmp(item[i], "+nomassjoin"))
+      chan->status |= CHAN_NOMASSJOIN;
+    else if (!strcmp(item[i], "-nomassjoin"))
+      chan->status &= ~CHAN_NOMASSJOIN;
 /* Chanflag template
  *  else if (!strcmp(item[i], "+temp"))
  *    chan->status |= CHAN_TEMP;

+ 2 - 1
src/mod/channels.mod/userchan.c

@@ -735,7 +735,7 @@ exempt-time %lu invite-time %lu voice-non-ident %d \
 %cenforcebans %cdynamicbans %cuserban %cbitch %cprotectops \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
 %cdynamicinvites %cuserinvites %cnodesynch %cclosed %cvoice \
-%cfastop %cautoop %cbotbitch %cbackup %c%s}\n",
+%cfastop %cautoop %cbotbitch %cbackup %cnomassjoin %c%s}\n",
 	chan->dname,
 	w,
         chan->added_by,
@@ -786,6 +786,7 @@ exempt-time %lu invite-time %lu voice-non-ident %d \
         PLSMNS(channel_autoop(chan)),
         PLSMNS(channel_botbitch(chan)),
         PLSMNS(channel_backup(chan)),
+        PLSMNS(channel_nomassjoin(chan)),
 	HAVE_TAKE ? PLSMNS(channel_take(chan)) : 0,
         HAVE_TAKE ? "take " : " "
 /* Chanflag template

+ 33 - 0
src/mod/irc.mod/chan.c

@@ -2289,6 +2289,16 @@ static int got332(char *from, char *msg)
   return 0;
 }
 
+static time_t flood_im_time = 120;
+rate_t flood_massjoin = { 6, 1 };
+
+void unset_im(struct chanset_t *chan)
+{
+  dprintf(DP_MODE, "MODE %s :-im\n", chan->name[0] ? chan->name : chan->dname);
+  chan->channel.set_im = 0;
+}
+
+
 /* Got a join
  */
 static int gotjoin(char *from, char *chname)
@@ -2417,6 +2427,29 @@ static int gotjoin(char *from, char *chname)
 	m->flags |= STOPWHO;
         irc_log(chan, "%s returned from netsplit", m->nick);
       } else {
+         if (channel_nomassjoin(chan) && me_op(chan)) {
+           if (chan->channel.drone_jointime < now - flood_massjoin.time) {      //expired, reset counter
+             chan->channel.drone_joins = 0;
+           }
+
+           ++chan->channel.drone_joins;
+           chan->channel.drone_jointime = now;
+
+           if (!chan->channel.set_im && chan->channel.drone_joins >= flood_massjoin.count) {  //flood from dronenet, let's attempt to set +im
+             egg_timeval_t howlong;
+
+             chan->channel.set_im = 1;
+             chan->channel.drone_joins = 0;
+             chan->channel.drone_jointime = 0;
+             dprintf(DP_DUMP, "MODE %s :+im\n", chan->name);
+             howlong.sec = flood_im_time;
+             howlong.usec = 0;
+             timer_create_complex(&howlong, "Unset umode +im", (Function) unset_im, (void *) chan, 0);
+
+             putlog(LOG_MISC, "*", "Drone flood detected in %s! Setting +im for %li seconds.", chan->dname, flood_im_time);
+           }
+         }
+
 	if (m)
 	  killmember(chan, nick);
 	m = newmember(chan, nick);