]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Merge throttle.
authorGunnar Beutner <redacted>
Mon, 12 Aug 2013 22:45:38 +0000 (00:45 +0200)
committerGunnar Beutner <redacted>
Mon, 12 Aug 2013 22:45:38 +0000 (00:45 +0200)
trusts/trusts.h
trusts/trusts_commands.c
trusts/trusts_management.c
trusts/trusts_policy.c

index 542bfc8f5acf0a029d2ac47f4a55eeafe8a2397c..88190a82b4b3ac85ec9b115b294af1aec2aedd49 100644 (file)
@@ -43,6 +43,7 @@
 #define TRUST_NO_CLEANUP 2
 #define TRUST_PROTECTED 4
 #define TRUST_RELIABLE_USERNAME 8
+#define TRUST_UNTHROTTLE 16
 
 #define TRUST_MIN_UNPRIVILEGED_BITS_IPV4 (96 + 20)
 #define TRUST_MIN_UNPRIVILEGED_BITS_IPV6 32
@@ -50,6 +51,8 @@
 #define TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV4 (96 + 24)
 #define TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV6 48
 
+#define TRUST_MIN_TIME_RETHROTTLE 120
+
 struct trustmigration;
 
 struct trusthost;
index c3a31028d7a8e3594edf28a31ab6f305de05e095..9fd092d3ad2a57fa41ee092f7e4c1d7c4cfc80be 100644 (file)
@@ -147,6 +147,13 @@ static char *formatflags(int flags) {
     strncat(buf, "reliable username", 512);
   }
 
+  if(flags & TRUST_UNTHROTTLE) {
+    if(buf[0])
+      strncat(buf, ", ", 512);
+
+    strncat(buf, "unthrottled", 512);
+  }
+
   buf[512-1] = '\0';
 
   return buf;
index 387f6f80b4d52ea5ed2ca9f65c49e852a6345a6a..4520fb5af633f09ff8db9a03bc1d3d0d6e2c89ca 100644 (file)
@@ -401,6 +401,20 @@ static int modifyreliableusername(void *arg, char *num, nick *source, int overri
   return 1;
 }
 
+static int modifyunthrottle(void *arg, char *num, nick *source, int override) {
+  trustgroup *tg = arg;
+
+  if(num[0] == '1') {
+    tg->flags |= TRUST_UNTHROTTLE;
+  } else if(num[0] == '0') {
+    tg->flags &= ~TRUST_UNTHROTTLE;
+  } else {
+    return 0;
+  }
+
+  return 1;
+}
+
 static int modifyexpires(void *arg, char *expires, nick *source, int override) {
   trustgroup *tg = arg;
   int howlong = durationtolong(expires);
@@ -803,6 +817,7 @@ static void setupmods(void) {
   MSGROUP(trustedfor);
   MSGROUP(cleanup);
   MSGROUP(protected);
+  MSGROUP(unthrottle);
 
   MSHOST(maxpernode);
   MSHOST(nodebits);
index a8d9c141cc56d4c34996023c337f3df0ff7ec157..71c49a99cbcb258d6199de8099b2ee0b83953473 100644 (file)
@@ -64,9 +64,12 @@ typedef struct trustaccount {
 
 trustaccount trustaccounts[MAXSERVERS];
 
-static int checkconnectionth(const char *username, struct irc_in_addr *ip, trusthost *th, int hooknum, int usercountadjustment, char *message, size_t messagelen) {
+static int checkconnectionth(const char *username, struct irc_in_addr *ip, trusthost *th, int hooknum, int usercountadjustment, char *message, size_t messagelen, int *unthrottle) {
   trustgroup *tg;
 
+  if (unthrottle)
+    *unthrottle = 0;
+
   if(messagelen>0)
     message[0] = '\0';
   
@@ -140,14 +143,10 @@ static int checkconnectionth(const char *username, struct irc_in_addr *ip, trust
   if(tg->trustedfor > 0)
     snprintf(message, messagelen, "Trust has %d out of %d allowed connections.", tg->count + usercountadjustment, tg->trustedfor);
 
-  return POLICY_SUCCESS;
-}
-
-static int checkconnection(const char *username, struct irc_in_addr *ip, int hooknum, int cloneadjustment, char *message, size_t messagelen) {
-  struct irc_in_addr ip_canonicalized;
-  ip_canonicalize_tunnel(&ip_canonicalized, ip);
+  if(unthrottle && (tg->flags & TRUST_UNTHROTTLE))
+    *unthrottle = 1; /* TODO: Do _some_ kind of rate-limiting */
 
-  return checkconnectionth(username, &ip_canonicalized, th_getbyhost(&ip_canonicalized), hooknum, cloneadjustment, message, messagelen);
+  return POLICY_SUCCESS;
 }
 
 static int trustdowrite(trustsocket *sock, char *format, ...) {
@@ -171,16 +170,18 @@ static int trustdowrite(trustsocket *sock, char *format, ...) {
 
 static int policycheck_auth(trustsocket *sock, const char *sequence_id, const char *username, const char *host) {
   char message[512];
-  int verdict;
-  struct irc_in_addr ip;
+  int verdict, unthrottle;
+  struct irc_in_addr ip, ip_canonicalized;
   unsigned char bits;
+  trustsocket *ts;
   
   if(!ipmask_parse(host, &ip, &bits)) {
     sock->accepted++;
     return trustdowrite(sock, "PASS %s", sequence_id);
   }
-  
-  verdict = checkconnection(username, &ip, HOOK_TRUSTS_NEWNICK, 1, message, sizeof(message));
+
+  ip_canonicalize_tunnel(&ip_canonicalized, &ip);
+  verdict = checkconnectionth(username, &ip_canonicalized, th_getbyhost(&ip_canonicalized), HOOK_TRUSTS_NEWNICK, 1, message, sizeof(message), &unthrottle);
 
   if(!enforcepolicy_auth)
     verdict = POLICY_SUCCESS;
@@ -188,6 +189,11 @@ static int policycheck_auth(trustsocket *sock, const char *sequence_id, const ch
   if (verdict == POLICY_SUCCESS) {
     sock->accepted++;
 
+    if (unthrottle) {
+      for (ts = tslist; ts; ts = ts->next)
+        trustdowrite(ts, "UNTHROTTLE %s", IPtostr(ip));
+    }
+
     if(message[0])
       return trustdowrite(sock, "PASS %s %s", sequence_id, message);
     else
@@ -476,15 +482,16 @@ static void policycheck_irc(int hooknum, void *arg) {
   nick *np = args[0];
   long moving = (long)args[1];
   char message[512];
-  int verdict;
+  int verdict, unthrottle;
   struct irc_in_addr ipaddress_canonical;
+  trustsocket *ts;
 
   if(moving)
     return;
 
   ip_canonicalize_tunnel(&ipaddress_canonical, &np->ipaddress);
 
-  verdict = checkconnectionth(np->ident, &ipaddress_canonical, gettrusthost(np), hooknum, 0, message, sizeof(message));
+  verdict = checkconnectionth(np->ident, &ipaddress_canonical, gettrusthost(np), hooknum, 0, message, sizeof(message), &unthrottle);
     
   if(!enforcepolicy_irc)
     verdict = POLICY_SUCCESS;
@@ -500,6 +507,11 @@ static void policycheck_irc(int hooknum, void *arg) {
       glinebynick(np, POLICY_GLINE_DURATION, message, GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST, "trusts_policy");
       break;
   }
+
+  if (unthrottle && hooknum == HOOK_NICK_LOSTNICK && np->timestamp > getnettime() - TRUST_MIN_TIME_RETHROTTLE) {
+    for (ts = tslist; ts; ts = ts->next)
+      trustdowrite(ts, "THROTTLE %s", IPtostr(np->ipaddress));
+  }
 }
 
 static int trusts_cmdtrustpolicyirc(void *source, int cargc, char **cargv) {