]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Implement pernodemax/nodebits for THs.
authorGunnar Beutner <redacted>
Mon, 17 Jun 2013 10:22:55 +0000 (12:22 +0200)
committerGunnar Beutner <redacted>
Mon, 17 Jun 2013 10:22:55 +0000 (12:22 +0200)
--HG--
branch : shroudtrusts

12 files changed:
core/hooks.h
nick/nick.c
nick/nick.h
patricianick/patricianick.c
patricianick/patricianick.h
trusts/data.c
trusts/events.c
trusts/formats.c
trusts/trusts.h
trusts/trusts_commands.c
trusts/trusts_db.c
trusts/trusts_policy.c

index 28f961c3efc1ec89f7fb002de3e1aaad232394ba..67a3e9ab4d7eb3c9c49ce9727476c29a747d9dc2 100644 (file)
@@ -41,6 +41,7 @@
 #define HOOK_NICK_MODEOPER         307  /* Argument is void*[2] (nick, modes) */
 #define HOOK_NICK_KILL             308  /* Argument is void*[2] (nick, reason) */
 #define HOOK_NICK_MASKPRIVMSG      309  /* Argument is void*[3] (nick, target, message) ** NICK COULD BE NULL ** */
+#define HOOK_NICK_MOVENODE         310  /* Argument is void*[2] (nick, oldnode) */
 
 #define HOOK_CHANNEL_BURST         400  /* Argument is channel pointer */
 #define HOOK_CHANNEL_CREATE        401  /* Argument is void*[2] (channel, nick) */
index 10203dc64fbb3fe40d973e93fe5e4422c98c319b..05fea70cbb7dd71108501462d7a5a214d32d67f5 100644 (file)
@@ -370,6 +370,31 @@ char *visibleuserhost(nick *np, char *buf) {
   return buf;
 }
 
+/*
+ * setipnodebits:
+ *  Moves the nick to a different ipnode.
+ */
+void setipnodebits(nick *np, int bits) {
+  struct irc_in_addr ipaddress;
+  patricia_node_t *oldnode;
+  void *harg[2];
+
+  if(np->ipnode->prefix->bitlen == bits)
+    return;
+
+  memcpy(&ipaddress, &np->p_nodeaddr, sizeof(ipaddress));
+  node_decrement_usercount(np->ipnode);
+  oldnode = np->ipnode;
+  np->ipnode = refnode(iptree, &ipaddress, bits);
+  node_increment_usercount(np->ipnode);
+
+  harg[0] = np;
+  harg[1] = oldnode;
+  triggerhook(HOOK_NICK_MOVENODE, harg);
+
+  derefnode(iptree, oldnode);
+}
+
 #if 0
 
 /*
@@ -423,5 +448,6 @@ nick *getnickbynumericstr(char *numericstr) {
   return getnickbynumeric(numerictolong(numericstr,5));
 }
 
+
 #endif
 
index 984d1407b0137fa352cc06e79998608d5b11417c..eab487b1b2ddcc1cd39d46c0ab2472f2c79f6386 100644 (file)
@@ -154,6 +154,7 @@ typedef struct nick {
 } nick;
 
 #define p_ipaddr ipaddress
+#define p_nodeaddr ipnode->prefix->sin
 
 #define NICKHASHSIZE      60000
 #define HOSTHASHSIZE      40000
@@ -199,6 +200,7 @@ int findnickext(const char *name);
 void releasenickext(int index);
 char *visiblehostmask(nick *np, char *buf);
 char *visibleuserhost(nick *np, char *buf);
+void setipnodebits(nick *np, int bits);
 
 /* nickhandlers.c functions */
 int handlenickmsg(void *source, int cargc, char **cargv);
index 9eca059ebcfe9d2705dca3b1be23f76512c4d727..e9e00aa052488d34c3c983a0bb3a6bd52ffb0675 100644 (file)
@@ -46,6 +46,7 @@ void _init() {
 
   registerhook(HOOK_NICK_NEWNICK, &pn_hook_newuser);
   registerhook(HOOK_NICK_LOSTNICK, &pn_hook_lostuser);
+  registerhook(HOOK_NICK_MOVENODE, &pn_hook_movenodeuser);
 
   registercontrolhelpcmd("nodeuserlist", NO_OPER, 1, &pn_cmd_nodeuserlist, "Usage: nodeuserlist <ipv4|ipv6|cidr4|cidr6>\nLists all users on a given IP address or CIDR range.");
 }
@@ -63,6 +64,7 @@ void _fini() {
 
   deregisterhook(HOOK_NICK_NEWNICK, &pn_hook_newuser);
   deregisterhook(HOOK_NICK_LOSTNICK, &pn_hook_lostuser);
+  deregisterhook(HOOK_NICK_MOVENODE, &pn_hook_movenodeuser);
 
   deregistercontrolcmd("nodeuserlist", &pn_cmd_nodeuserlist);
 }
@@ -146,6 +148,14 @@ void pn_hook_lostuser(int hook, void *arg) {
   deletenickfromnode(np->ipnode, np);
 }
 
+void pn_hook_nodemoveuser(int hook, void *arg) {
+  nick *np = ((void **)arg)[0];
+  patricia_node_t *oldnode = ((void **)arg)[1];
+
+  deletenickfromnode(oldnode, np);
+  addnicktonode(np->ipnode, np);
+}
+
 int pn_cmd_nodeuserlist(void *source, int cargc, char **cargv) {
   nick *np=(nick *)source;
   struct irc_in_addr sin;
index 339c20d10880f43b042543bbf98ec6955fbf285c..f89c5c7991d9da91544c56bbc29256674f6e3482 100644 (file)
@@ -16,6 +16,7 @@ extern int pnick_ext;
 
 void pn_hook_newuser(int hook, void *arg);
 void pn_hook_lostuser(int hook, void *arg);
+void pn_hook_movenodeuser(int hook, void *arg);
 
 void addnicktonode(patricia_node_t *node, nick *nick);
 void deletenickfromnode(patricia_node_t *node, nick *nick);
index eed4c504d21043890da3668a514bbc0be847d8bc..f1cc016f7986f187b63692bff0727441e8e6fb67 100644 (file)
@@ -91,6 +91,9 @@ trusthost *th_add(trusthost *ith) {
   th->users = NULL;
   th->count = 0;
 
+  th->maxpernode = 0;
+  th->nodebits = 128;
+
   th->parent = NULL;
   th->children = NULL;
 
@@ -354,7 +357,7 @@ void th_adjusthosts(trusthost *th, trusthost *superset, trusthost *subset) {
     nick *np, *nnp;
     for(np=superset->users;np;np=nnp) {
       nnp = nextbytrust(np);
-      if((irc_in_addr_v4_to_int(&np->p_ipaddr) & th->mask) == th->ip) {
+      if((irc_in_addr_v4_to_int(&np->p_nodeaddr) & th->mask) == th->ip) {
         trusts_lostnick(np, 1);
         trusts_newnick(np, 1);
       }
@@ -367,7 +370,7 @@ void th_adjusthosts(trusthost *th, trusthost *superset, trusthost *subset) {
 
     for(i=0;i<NICKHASHSIZE;i++)
       for(np=nicktable[i];np;np=np->next)
-        if(!gettrusthost(np) && ((irc_in_addr_v4_to_int(&np->p_ipaddr) & th->mask) == th->ip))
+        if(!gettrusthost(np) && ((irc_in_addr_v4_to_int(&np->p_nodeaddr) & th->mask) == th->ip))
           trusts_newnick(np, 1);
   }
 }
index 797fc4ba6782cfd39cb9d5b6099e3c0977899548..ca0efdb9322ae808b271540e0f469c27b8aa152d 100644 (file)
@@ -23,6 +23,7 @@ void trusts_newnick(nick *sender, int moving) {
   } else {
     setnextbytrust(sender, th->users);
     th->users = sender;
+    setipnodebits(sender, th->nodebits);
   }
 
   arg[0] = sender;
index 771673511824a4d1a9917fe2a86103e93363add2..d6a15c181026705e7a9814c5a60ae4a3fe12728c 100644 (file)
@@ -79,7 +79,7 @@ char *dumpth(trusthost *th, int oformat) {
   if(oformat) {
     snprintf(buf, sizeof(buf), "#%u,%s,%u,%u,%jd", th->group->id, trusts_cidr2str(th->ip, th->mask), th->count, th->maxusage, (intmax_t)th->lastseen);
   } else {
-    snprintf(buf, sizeof(buf), "%u,%s,%u,%u,%jd,%jd", th->group->id, trusts_cidr2str(th->ip, th->mask), th->id, th->maxusage, (intmax_t)th->lastseen, (intmax_t)th->created);
+    snprintf(buf, sizeof(buf), "%u,%s,%u,%u,%jd,%jd,%u,%u", th->group->id, trusts_cidr2str(th->ip, th->mask), th->id, th->maxusage, (intmax_t)th->lastseen, (intmax_t)th->created, th->maxpernode, th->nodebits);
   }
 
   return buf;
@@ -189,6 +189,7 @@ int parsetg(char *buf, trustgroup *tg, int oformat) {
 
 int parseth(char *line, trusthost *th, unsigned int *tgid, int oformat) {
   unsigned long lastseen, created;
+  int maxpernode, nodebits;
   char *ip, xbuf[1024], *id;
 
 /* #id,213.230.192.128/26,20,23,1222732944
@@ -223,12 +224,14 @@ int parseth(char *line, trusthost *th, unsigned int *tgid, int oformat) {
       return 0;
     created = time(NULL);
   } else {
-    if(sscanf(line, "%u,%u,%lu,%lu", &th->id, &th->maxusage, &lastseen, &created) != 4)
+    if(sscanf(line, "%u,%u,%lu,%lu,%d,%d", &th->id, &th->maxusage, &lastseen, &created, &maxpernode, &nodebits) != 6)
       return 0;
   }
 
   th->lastseen = (time_t)lastseen;
   th->created = (time_t)created;
+  th->maxpernode = maxpernode;
+  th->nodebits = nodebits;
 
   return 1;
 }
index 3a55300a8721a42562ecf32fd4e6d71e5a578aa1..6898f83ee3931ba0341ede91b57e730f3538c9ea 100644 (file)
@@ -35,7 +35,6 @@ struct trusthost;
 typedef struct trusthost {
   unsigned int id;
 
-
   uint32_t ip, mask;
   unsigned int maxusage;
   time_t created;
@@ -46,6 +45,9 @@ typedef struct trusthost {
 
   unsigned int count;
 
+  int maxpernode;
+  int nodebits;
+
   struct trusthost *parent, *children;
   unsigned int marker;
 
index 7a52145b2c7f2c73e26c7b721b00b00ef870f630..09af67003652dc4b1a6dafde4d51b4880c4b1faf 100644 (file)
@@ -75,6 +75,7 @@ static void marktree(array *parents, unsigned int marker, trusthost *th) {
 
 static void outputtree(nick *np, unsigned int marker, trustgroup *originalgroup, trusthost *th, int depth) {
   char *cidrstr, *prespacebuf, *postspacebuf, parentbuf[512];
+  int mask;
 
   if(th->marker != marker)
     return;
@@ -92,7 +93,10 @@ static void outputtree(nick *np, unsigned int marker, trustgroup *originalgroup,
     snprintf(parentbuf, sizeof(parentbuf), "%-10d %s", th->group->id, th->group->name->content);
   }
 
-  controlreply(np, "%s%s%s %-10d %-10d %-21s%s", prespacebuf, cidrstr, postspacebuf, th->count, th->maxusage, (th->count>0)?"(now)":((th->lastseen>0)?trusts_timetostr(th->lastseen):"(never)"), trusts_timetostr(th->created), parentbuf);  
+  /*if (!ipv6) */
+    mask = th->nodebits - 96;
+
+  controlreply(np, "%s%s%s %-10d %-10d %-21s %-15d /%-14d%s", prespacebuf, cidrstr, postspacebuf, th->count, th->maxusage, (th->count>0)?"(now)":((th->lastseen>0)?trusts_timetostr(th->lastseen):"(never)"), th->maxpernode, mask, parentbuf);  
 
   for(th=th->children;th;th=th->nextbychild)
     outputtree(np, marker, originalgroup, th, depth + 1);
@@ -119,7 +123,7 @@ static void displaygroup(nick *sender, trustgroup *tg) {
   controlreply(sender, "Max usage        : %d", tg->maxusage);
   controlreply(sender, "Last max reset   : %s", tg->lastmaxusereset?trusts_timetostr(tg->lastmaxusereset):"(never)");
 
-  controlreply(sender, "Host                 Current    Max        Last seen            Created              Group ID   Group name");
+  controlreply(sender, "Host                 Current    Max        Last seen             Max per Node    Node Mask      Group ID   Group name");
 
   marker = nextthmarker();
   array_init(&parents, sizeof(trusthost *));
index 1ad9f17e98b2a2fd907c9fd0aed93b06f828a674..f49699acbd61eb861e0b64e8bde3557bc84990e0 100644 (file)
@@ -38,7 +38,7 @@ void createtrusttables(int mode) {
   );
 
   /* I'd like multiple keys here but that's not gonna happen on a cross-database platform :( */
-  trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, created INT, lastseen INT)", "Td", hosts, TRUSTHOSTLEN);
+  trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, created INT, lastseen INT, maxpernode INT, nodebits INT)", "Td", hosts, TRUSTHOSTLEN);
 
   trustsdb->createtable(trustsdb, NULL, NULL,
     "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, groupname VARCHAR(?), ts INT, username VARCHAR(?), message VARCHAR(?))",
@@ -80,7 +80,7 @@ static void loadhosts_data(const DBAPIResult *result, void *tag) {
     return;
   }
 
-  if(result->fields != 6) {
+  if(result->fields != 8) {
     Error("trusts", ERR_ERROR, "Wrong number of fields in hosts table.");
     loaderror = 1;
 
@@ -114,6 +114,8 @@ static void loadhosts_data(const DBAPIResult *result, void *tag) {
     th.maxusage = strtoul(result->get(result, 3), NULL, 10);
     th.created = (time_t)strtoul(result->get(result, 4), NULL, 10);
     th.lastseen = (time_t)strtoul(result->get(result, 5), NULL, 10);
+    th.maxpernode = strtol(result->get(result, 6), NULL, 10);
+    th.nodebits = strtol(result->get(result, 7), NULL, 10);
 
     if(!th_add(&th))
       Error("trusts", ERR_WARNING, "Error adding host to trust %d: %s", groupid, host);
@@ -312,8 +314,8 @@ trustgroup *tg_new(trustgroup *itg) {
 
 void trustsdb_insertth(char *table, trusthost *th, unsigned int groupid) {
   trustsdb->squery(trustsdb,
-    "INSERT INTO ? (id, groupid, host, maxusage, created, lastseen) VALUES (?, ?, ?, ?, ?, ?)",
-    "Tuusuut", table, th->id, groupid, trusts_cidr2str(th->ip, th->mask), th->maxusage, th->created, th->lastseen
+    "INSERT INTO ? (id, groupid, host, maxusage, created, lastseen, maxpernode, nodebits) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
+    "Tuusuutuu", table, th->id, groupid, trusts_cidr2str(th->ip, th->mask), th->maxusage, th->created, th->lastseen, th->maxpernode, th->nodebits
   );
 }
 
index 32a8ca515ceda2aa37420a571d7c6c84de87eb25..5882a13aaa2f6c6bbc92feb94f0ac99b95a9815f 100644 (file)
@@ -15,9 +15,12 @@ static void policycheck(int hooknum, void *arg) {
   if(moving)
     return;
 
-  if(!th) {
+  if(!th)
+    return;
+
+  if(th->maxpernode > np->ipnode->usercount) {
     if(np->ipnode->usercount > 5)
-      controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on IP: %s (untrusted) %d connected, 5 max.", IPtostr(np->p_ipaddr), np->ipnode->usercount);
+      controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on IP: %s (group: %s) %d connected, %d max.", IPtostr(np->p_ipaddr), tg->name->content, np->ipnode->usercount, th->maxpernode);
     return;
   }