]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Remove the anti-flood functionality and implement fast-tracking requests.
authorGunnar Beutner <redacted>
Fri, 28 Jun 2013 14:48:03 +0000 (16:48 +0200)
committerGunnar Beutner <redacted>
Fri, 28 Jun 2013 14:48:03 +0000 (16:48 +0200)
--HG--
branch : shroudrequest

request/Makefile.in
request/lrequest.c
request/request.c
request/request_block.c
request/request_block.h
request/request_fasttrack.c [new file with mode: 0644]
request/request_fasttrack.h [new file with mode: 0644]
request/sqrequest.c

index 2e1b6aa878c10c88fa4aa6d38dc3722476b4e09a..11b767f32be5e8abc8a5a6374f90d8610d83aacd 100644 (file)
@@ -6,4 +6,4 @@ LDFLAGS+=$(LIBPGSQL)
 .PHONY: all
 all: request.so
 
-request.so: lrequest.o request.o request_block.o sqrequest.o user.o 
+request.so: lrequest.o request.o request_block.o request_fasttrack.o sqrequest.o user.o 
index f8da1b2a67db9ba6259285bb63bb3579c6a3375b..77a383f246e48a2f588120de2cbdf5ecfd7b4b00 100644 (file)
@@ -5,6 +5,7 @@
 #include "request.h"
 #include "lrequest.h"
 #include "request_block.h"
+#include "request_fasttrack.h"
 #include "../localuser/localuser.h"
 
 /* stats counters */
@@ -30,55 +31,49 @@ int lr_requestl(nick *svc, nick *np, channel *cp, nick *qnick) {
 
   cf = cf_findchanfix(cp->index);
 
-  if (cf == NULL) {
-    sendnoticetouser(svc, np, "Sorry, your channel '%s' was created recently. "
-          "Please try again in an hour.", cp->index->name->content);
+  if(cf) {
+    rocount = cf_getsortedregops(cf, LR_TOPX, rolist);
 
-    lr_noregops++;
+    ro = NULL;
 
-    return RQ_ERROR;
-  }
-
-  rocount = cf_getsortedregops(cf, LR_TOPX, rolist);
-
-  ro = NULL;
-
-  for (i = 0; i < min(LR_TOPX, rocount); i++) {
-    if (cf_cmpregopnick(rolist[i], np)) {
-      ro = rolist[i];
-      break;
+    for (i = 0; i < min(LR_TOPX, rocount); i++) {
+      if (cf_cmpregopnick(rolist[i], np)) {
+        ro = rolist[i];
+        break;
+      }
     }
-  }
 
-  if (ro == NULL) {
-    sendnoticetouser(svc, np, "Sorry, you must be one of the top %d ops "
-          "for the channel '%s'.", LR_TOPX, cp->index->name->content);
+    if (ro == NULL) {
+      sendnoticetouser(svc, np, "Sorry, you must be one of the top %d ops "
+            "for the channel '%s'.", LR_TOPX, cp->index->name->content);
 
-    lr_top5++;
+      lr_top5++;
 
-    return RQ_ERROR;
+      return RQ_ERROR;
+    }
   }
 
-  /* treat blocked users as if their score is too low */
-  if (ro->score < LR_CFSCORE || rq_findblock(np->authname)) {
-    if (rq_isspam(np)) {
-      sendnoticetouser(svc, np, "Do not flood the request system. "
-            "Try again in %s.", rq_longtoduration(rq_blocktime(np)));
+  if(!rq_tryfasttrack(np)) {
+    if (cf == NULL) {
+      sendnoticetouser(svc, np, "Sorry, your channel '%s' was created recently. "
+            "Please try again in an hour.", cp->index->name->content);
 
-      lr_floodattempts++;
+      lr_noregops++;
 
       return RQ_ERROR;
     }
 
-    sendnoticetouser(svc, np, "Sorry, you do not meet the "
-          "%s request requirements; please try again in an hour, "
-          "see http://www.quakenet.org/faq/faq.php?c=1&f=6#6", RQ_QNICK);
+    /* treat blocked users as if their score is too low */
+    if (ro->score < LR_CFSCORE || rq_findblock(np->authname)) {
+      sendnoticetouser(svc, np, "Sorry, you do not meet the "
+            "%s request requirements; please try again in an hour, "
+            "see http://www.quakenet.org/faq/faq.php?c=1&f=6#6", RQ_QNICK);
 
-    lr_scoretoolow++;
+      lr_scoretoolow++;
 
-    return RQ_ERROR;
+      return RQ_ERROR;
+    }
   }
-
   
   sendmessagetouser(svc, qnick, "addchan %s #%s +jp upgrade %s", cp->index->name->content,
         np->authname, np->nick);
index 7b9fc1040681f810d5d29b0dd4102e9dad372d62..6d604ac5482fc581ce222cee67a4df0550b144a4 100644 (file)
@@ -12,6 +12,7 @@
 #include "../splitlist/splitlist.h"
 #include "request.h"
 #include "request_block.h"
+#include "request_fasttrack.h"
 #include "lrequest.h"
 #include "sqrequest.h"
 #include "user.h"
@@ -55,6 +56,9 @@ void _init(void) {
   if(!rq_initblocks())
     return;
 
+  if(!rq_initfasttrack())
+    return;
+
   extloaded = 1;
 
   rqcommands = newcommandtree();
@@ -106,6 +110,7 @@ void _fini(void) {
   destroycommandtree(rqcommands);
 
   rq_finiblocks();
+  rq_finifasttrack();
   qr_finirequest();
   ru_persist();
 
index fa7f59de0be26d16ad4cb426452563a38a1b2cb7..779c87f32e2383c20a267ddb04de91d2b034fba8 100644 (file)
@@ -7,19 +7,10 @@
 /* array of blocks */
 array rqblocks;
 
-/* our anti-flood nick extension */
-int rqnext;
-
 /* are we currently loading blocks? */
 int rq_loading;
 
-void rqhook_lostnick(int hook, void *arg);
-
 int rq_initblocks(void) {
-  rqnext = registernickext("request");
-  if(rqnext < 0)
-    return 0;
-
   array_init(&rqblocks, sizeof(rq_block));
   array_setlim1(&rqblocks, 5);
   array_setlim2(&rqblocks, 20);
@@ -31,15 +22,12 @@ int rq_initblocks(void) {
   rq_addblock("#qnet*", "Reserved for QuakeNet use only.", "request", 0, 0);
   rq_addblock("#help*", "Reserved for QuakeNet use only.", "request", 0, 0);
 
-  registerhook(HOOK_NICK_LOSTNICK, &rqhook_lostnick);
-
   return 1;
 }
 
 void rq_finiblocks(void) {
   int i;
   rq_block block;
-  nick *nip;
 
   for (i = 0; i < rqblocks.cursi; i++) {
     block = ((rq_block*)rqblocks.content)[i];
@@ -50,64 +38,6 @@ void rq_finiblocks(void) {
   }
 
   array_free(&rqblocks);
-
-  for (i=0; i<NICKHASHSIZE; i++)
-    for (nip=nicktable[i]; nip; nip=nip->next)
-      free(nip->exts[rqnext]);
-
-  deregisterhook(HOOK_NICK_LOSTNICK, &rqhook_lostnick);
-
-  releasenickext(rqnext);
-}
-
-void rqhook_lostnick(int hook, void *arg) {
-  nick *np = (nick*)arg;
-
-  free(np->exts[rqnext]);
-}
-
-int rq_isspam(nick *np) {
-  rq_flood *lf;
-
-  if (np->exts[rqnext] == NULL) {
-    np->exts[rqnext] = lf = (rq_flood*)malloc(sizeof(rq_flood));
-
-    lf->count = 1;
-    lf->created = getnettime();
-    lf->expire = 0;
-
-    return 0;
-  } else {
-    lf = np->exts[rqnext];
-
-    lf->count -= (getnettime() - lf->created) / (RQ_SPAMBLOCK / RQ_SPAMCOUNT);
-    
-    if (lf->count < 0)
-      lf->count = 0;
-
-    if (lf->count > RQ_SPAMCOUNT && lf->expire > getnettime()) {
-      return 1;
-    } else {
-      lf->count++;
-
-      if (lf->count > RQ_SPAMCOUNT) {
-        lf->expire = getnettime() + RQ_SPAMBLOCK;
-        
-        rq_addblock(np->authname, "Flooding the request system.", "request", 0, getnettime() + 3600);
-
-        return 1;
-      }
-
-      return 0;
-    }
-  }
-}
-
-time_t rq_blocktime(nick *np) {
-  if (np->exts[rqnext] == NULL)
-    return 0;
-  else
-    return ((rq_flood*)np->exts[rqnext])->expire - getnettime();
 }
 
 rq_block *rq_findblock(const char *pattern) {
index 8a73f898f15d5fb467964c5a97ec5fb85ab34de3..afca63fb3062d709be140650b8c5432c751aa4f0 100644 (file)
@@ -1,12 +1,6 @@
 #include "../nick/nick.h"
 #include "../channel/channel.h"
 
-typedef struct {
-  int count;
-  time_t created;
-  time_t expire;
-} rq_flood;
-
 typedef struct {
   sstring *pattern;
   sstring *reason;
@@ -21,9 +15,6 @@ extern array rqblocks;
 #define RQ_BLOCKFILE "data/rqblocks"
 #define RQ_BLOCKLEN 256
 
-#define RQ_SPAMCOUNT 5
-#define RQ_SPAMBLOCK 3600
-
 int rq_initblocks(void);
 void rq_finiblocks(void);
 
@@ -34,7 +25,3 @@ int rq_saveblocks(void);
 rq_block *rq_findblock(const char *pattern);
 void rq_addblock(const char *pattern, const char *reason, const char *creator, time_t created, time_t expires);
 int rq_removeblock(const char *pattern);
-
-/* anti-spam blocks */
-int rq_isspam(nick *np);
-time_t rq_blocktime(nick *np);
diff --git a/request/request_fasttrack.c b/request/request_fasttrack.c
new file mode 100644 (file)
index 0000000..2378b06
--- /dev/null
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <string.h>
+#include "../core/schedule.h"
+#include "../irc/irc.h"
+#include "../lib/irc_string.h"
+#include "request_fasttrack.h"
+
+typedef struct rq_fasttrack {
+  unsigned long userid;
+
+  unsigned int targets;
+  time_t refill_time;
+
+  struct rq_fasttrack *next;
+} rq_fasttrack;
+
+static rq_fasttrack *ftlist;
+
+/* our fast-track extension */
+int rqnext;
+
+static void rq_cleanup_fasttrack(void *arg);
+static void rqhook_account(int hook, void *arg);
+
+int rq_initfasttrack(void) {
+  rqnext = registernickext("request_fasttrack");
+  if(rqnext < 0)
+    return 0;
+
+  registerhook(HOOK_NICK_NEWNICK, &rqhook_account);
+  registerhook(HOOK_NICK_ACCOUNT, &rqhook_account);
+
+  schedulerecurring(time(NULL)+1, 0, 3600, rq_cleanup_fasttrack, NULL);
+
+  return 1;
+}
+
+void rq_finifasttrack(void) {
+  rq_fasttrack *ft;
+
+  deregisterhook(HOOK_NICK_NEWNICK, &rqhook_account);
+  deregisterhook(HOOK_NICK_ACCOUNT, &rqhook_account);
+
+  for(ft=ftlist;ft;ft=ft->next)
+    free(ft);
+
+  releasenickext(rqnext);
+}
+
+static void rqhook_account(int hook, void *arg) {
+  nick *np = (nick *)arg;
+  rq_fasttrack *ft;
+
+  /* Auth might be null for the newnick hook. */
+  if(!np->auth)
+    return;
+
+  /* Try to find an existing fasttrack record for this user. */
+  for(ft=ftlist;ft;ft=ft->next) {
+    if(np->auth->userid==ft->userid) {
+      np->exts[rqnext] = ft;
+      break;
+    }
+  }
+}
+
+static void rq_cleanup_fasttrack(void *arg) {
+
+}
+
+static rq_fasttrack *rq_getfasttrack(nick *np) {
+  rq_fasttrack *ft;
+
+  /* Use an existing fast-track record if the nick has one. */
+  if(np->exts[rqnext])
+    return np->exts[rqnext];
+
+  if(!np->auth)
+    return NULL;
+
+  ft = malloc(sizeof(rq_fasttrack));
+
+  if(!ft)
+    return NULL;
+
+  ft->userid = np->auth->userid;
+  ft->targets = 0;
+  ft->refill_time = 0;
+
+  np->exts[rqnext] = ft;
+
+  return ft;
+}
+
+int rq_tryfasttrack(nick *np) {
+  rq_fasttrack *ft = rq_getfasttrack(np);
+
+  /* Don't fast-track if we can't find a fast-track record. */
+  if(!ft)
+    return 0;
+
+  /* Refill targets if necessary. */
+  if(getnettime() > ft->refill_time) {
+    ft->targets = RQ_FASTTRACK_TARGETS;
+    ft->refill_time = getnettime() + RQ_FASTTRACK_TIMEOUT;
+  }
+
+  /* Check if we have a free target. */
+  if(ft->targets==0)
+    return 0;
+
+  ft->targets--;
+  return 1;
+}
+
diff --git a/request/request_fasttrack.h b/request/request_fasttrack.h
new file mode 100644 (file)
index 0000000..77c6d7e
--- /dev/null
@@ -0,0 +1,10 @@
+#include "../nick/nick.h"
+#include "../channel/channel.h"
+
+#define RQ_FASTTRACK_TARGETS 2
+#define RQ_FASTTRACK_TIMEOUT 60
+
+int rq_initfasttrack(void);
+void rq_finifasttrack(void);
+
+int rq_tryfasttrack(nick *np);
index 025be5cc6f2255465224b02462bffbe4eb9f22eb..7ba73f73df31f807d1bc6e945204e328500780bf 100644 (file)
@@ -730,21 +730,10 @@ int qr_instantrequestq(nick *sender, channel *cp) {
 
 int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *qnick) {
   chanindex *cip = cp->index;
-  int who = 0;
   requestrec *nextreq, *lastreq;
 
-  if (rq_isspam(sender)) {
-      sendnoticetouser(rqnick, sender, "Do not flood the request system."
-          " Try again in %s.", rq_longtoduration(rq_blocktime(sender)));
-    
-      return RQ_ERROR;
-  }
-
   /* check which service is on the channel */
   if (getnumerichandlefromchanhash(cp->users, qnick->numeric) != NULL) {
-    /* we've found Q */
-    who = QR_Q;
-
     /* Request stats from Q */
     sendmessagetouser(rqnick, qnick, "CHANLEV %s", cip->name->content);