Author: Kev <klmitch@mit.edu>
authorKevin L. Mitchell <klmitch@mit.edu>
Sat, 3 Jun 2000 03:01:11 +0000 (03:01 +0000)
committerKevin L. Mitchell <klmitch@mit.edu>
Sat, 3 Jun 2000 03:01:11 +0000 (03:01 +0000)
Log message:

GLINE storm fix...yeah, this is pretty complicated :/  Basically, if
there's a gline for a user we send a NICK for, we make sure and insert
%<lastmod>:<mask> after the user modes, if present.

Status: compiled, tested

Testing needed:

Test all the code paths thoroughly; this is a rather complicated change, so
take nothing for granted.  In particular, make sure bursting servers send
the right stuff, especially in the no-usermode case, which is the only part
I haven't stringently tested.

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@248 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/gline.h
include/s_user.h
ircd/gline.c
ircd/m_nick.c
ircd/m_pong.c
ircd/m_user.c
ircd/s_conf.c
ircd/s_serv.c
ircd/s_user.c

index 70c41e79da4e9fbdd219e008f3b8f92ce6512881..715e41dc54db122b2d3d428ee6815d3e08f656b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
 2000-06-02  Kevin L. Mitchell  <klmitch@mit.edu>
 
+       * ircd/s_user.c: add struct Gline * argument to register_user;
+       look up global glines and repropagate them if necessary; send
+       acknowledgement of gline to remote servers when registering users
+
+       * ircd/s_serv.c (server_estab): don't send acknowledgement of
+       local glines to remote servers; do send gline acknowledgement of
+       bursted users
+
+       * ircd/m_user.c (m_user): pass new struct Gline * argument to
+       register_user
+
+       * ircd/m_pong.c: pass new struct Gline * argument to register_user
+
+       * ircd/m_nick.c (ms_nick): document protocol change
+
+       * ircd/gline.c: support GLINE_LASTMOD
+
+       * include/s_user.h: add struct Gline * argument to register_user
+
+       * include/gline.h: add GLINE_LASTMOD to look up non-zero lastmods
+
+       * ircd/s_conf.c (find_kill): add unsigned int argument to
+       gline_lookup()
+
+       * ircd/gline.c: add GLINE_GLOBAL to lookup or find only global
+       glines; add unsigned int argument to gline_lookup()
+
+       * include/gline.h: add GLINE_GLOBAL flag; add unsigned int
+       argument to gline_lookup()
+
        * ircd/m_server.c: Resend jupe only when there is no %<lastmod>
        parameter, or when it falls out of bounds: see comments prior to
        call to jupe_resend(); call server_estab with struct Jupe
 #
 # ChangeLog for ircu2.10.11
 #
-# $Id: ChangeLog,v 1.142 2000-06-03 00:09:12 kev Exp $
+# $Id: ChangeLog,v 1.143 2000-06-03 03:01:10 kev Exp $
 #
 # Insert new changes at beginning of the change list.
 #
index 24090168b0502ad96423292f8aa496282cfe6dc1..d623e856639a178b01c8f6b5d219e73aca6e94ea 100644 (file)
@@ -54,6 +54,8 @@ struct Gline {
 #define GLINE_FORCE    0x0020
 #define GLINE_EXACT    0x0040
 #define GLINE_LDEACT   0x0080  /* locally deactivated */
+#define GLINE_GLOBAL   0x0100  /* find only global glines */
+#define GLINE_LASTMOD  0x0200  /* find only glines with non-zero lastmod */
 
 #define GLINE_MASK     (GLINE_ACTIVE | GLINE_BADCHAN | GLINE_LOCAL)
 #define GLINE_ACTMASK  (GLINE_ACTIVE | GLINE_LDEACT)
@@ -80,7 +82,7 @@ extern int gline_deactivate(struct Client *cptr, struct Client *sptr,
                            struct Gline *gline, time_t lastmod,
                            unsigned int flags);
 extern struct Gline *gline_find(char *userhost, unsigned int flags);
-extern struct Gline *gline_lookup(struct Client *cptr);
+extern struct Gline *gline_lookup(struct Client *cptr, unsigned int flags);
 extern void gline_free(struct Gline *gline);
 extern void gline_burst(struct Client *cptr);
 extern int gline_resend(struct Client *cptr, struct Gline *gline);
index 03d3a3934918ee60a5730fb1170e6ef6de160809..70da19bfa9333f87c3ecd79fd75da67c0e95d59d 100644 (file)
@@ -12,6 +12,7 @@
 
 struct Client;
 struct User;
+struct Gline;
 
 /*
  * Macros
@@ -55,7 +56,8 @@ typedef char* (*InfoFormatter)(struct Client* who, char* buf);
 extern struct User* make_user(struct Client *cptr);
 extern void         free_user(struct User *user);
 extern int          register_user(struct Client* cptr, struct Client* sptr,
-                                  const char* nick, char* username);
+                                  const char* nick, char* username,
+                                 struct Gline *agline);
 
 extern void         user_count_memory(size_t* count_out, size_t* bytes_out);
 
index 50c8773b6453bdd792f5d98943980910d34faa7c..53bd096e60e0c5db5bebbb3ee582bfe4de732496 100644 (file)
@@ -381,6 +381,9 @@ gline_find(char *userhost, unsigned int flags)
 
       if (gline->gl_expire <= CurrentTime)
        gline_free(gline);
+      else if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
+              (flags & GLINE_LASTMOD && !gline->gl_lastmod))
+       continue;
       else if ((flags & GLINE_EXACT ? ircd_strcmp(gline->gl_user, userhost) :
                match(gline->gl_user, userhost)) == 0)
        return gline;
@@ -403,6 +406,9 @@ gline_find(char *userhost, unsigned int flags)
 
     if (gline->gl_expire <= CurrentTime)
       gline_free(gline);
+    else if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
+            (flags & GLINE_LASTMOD && !gline->gl_lastmod))
+      continue;
     else if (flags & GLINE_EXACT) {
       if (ircd_strcmp(gline->gl_host, host) == 0 &&
          ((!user && ircd_strcmp(gline->gl_user, "*") == 0) ||
@@ -422,7 +428,7 @@ gline_find(char *userhost, unsigned int flags)
 }
 
 struct Gline *
-gline_lookup(struct Client *cptr)
+gline_lookup(struct Client *cptr, unsigned int flags)
 {
   struct Gline *gline;
   struct Gline *sgline;
@@ -432,6 +438,9 @@ gline_lookup(struct Client *cptr)
 
     if (gline->gl_expire <= CurrentTime)
       gline_free(gline);
+    else if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) ||
+            (flags & GLINE_LASTMOD && !gline->gl_lastmod))
+      continue;
     else if ((GlineIsIpMask(gline) ?
              match(gline->gl_host, ircd_ntoa((const char *)&cptr->ip)) :
              match(gline->gl_host, cptr->user->host)) == 0 &&
index fe02d167a9c9f9c9e47d99d2dcfa8139a5666774..bf3110524a9e5aad7884f555e2b1d3e6eafa8e1e 100644 (file)
@@ -244,6 +244,7 @@ int m_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
  *   parv[4] = username
  *   parv[5] = hostname
  *   parv[6] = umode (optional)
+ *   parv[parc-4] = %<lastmod>:<mask>   <- Only if matching GLINE
  *   parv[parc-3] = IP#                 <- Only Protocol >= 10
  *   parv[parc-2] = YXX, numeric nick   <- Only Protocol >= 10
  *   parv[parc-1] = info
index 95a411ee2e74fd63ad5126a2f177bdbd83badb13..bed24122bfa8d9f0ff8d31c6d73b68835544230e 100644 (file)
@@ -167,7 +167,7 @@ int mr_pong(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
         /*
          * NICK and USER OK
          */
-        return register_user(cptr, sptr, sptr->name, sptr->user->username);
+        return register_user(cptr, sptr, sptr->name, sptr->user->username, 0);
     }
     else  
       send_reply(sptr, SND_EXPLICIT | ERR_BADPING,
@@ -220,7 +220,7 @@ int m_pong(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
       sptr->cookie = COOKIE_VERIFIED;
       if (sptr->user && *sptr->user->host && sptr->name[0])        /* NICK and
                                                                    USER OK */
-        return register_user(cptr, sptr, sptr->name, sptr->user->username);
+        return register_user(cptr, sptr, sptr->name, sptr->user->username); /* XXX DEAD */
     }
     else
       sendto_one(sptr, ":%s %d %s :To connect, type /QUOTE PONG %u", /* XXX DEAD */
index ee7325ec7af7c52aabd61da7f67d67acefd23a19..ad0ce75424248d3f1c411ad46f5a8fd8b32dd4af 100644 (file)
@@ -165,7 +165,7 @@ int m_user(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     /*
      * NICK and PONG already received, now we have USER...
      */
-    return register_user(cptr, sptr, sptr->name, username);
+    return register_user(cptr, sptr, sptr->name, username, 0);
   }
   else {
     ircd_strncpy(user->username, username, USERLEN);
index 258d4a07aaa29659ce2cef0a52b3abf70a0d5584..53be6e9dc69a56915c011a6f4f06aca42881dbcc 100644 (file)
@@ -1437,7 +1437,7 @@ int find_kill(struct Client *cptr)
 
   /* find active glines */
   /* added a check against the user's IP address to find_gline() -Kev */
-  else if ((agline = gline_lookup(cptr)) && GlineIsActive(agline))
+  else if ((agline = gline_lookup(cptr, 0)) && GlineIsActive(agline))
     send_reply(cptr, SND_EXPLICIT | ERR_YOUREBANNEDCREEP, ":%s.",
               GlineReason(agline));
   else
index 93e8793f3b0381fcdd0f11891de68eb59fd11399..c4cf89841ed9d248c6e0ef934091686bd991fb5b 100644 (file)
@@ -237,7 +237,7 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf,
       split = (MyConnect(acptr) && 
                0 != ircd_strcmp(acptr->name, acptr->sockhost) &&
                0 != ircd_strncmp(acptr->info, "JUPE", 4));
-      if ((ajupe = jupe_find(acptr->name)))
+      if ((ajupe = jupe_find(acptr->name)) && !JupeIsLocal(ajupe))
        sendcmdto_one(acptr->serv->up, CMD_SERVER, cptr,
                      "%s %d 0 %Tu %s%u %s%s 0 %%%Tu :%s", acptr->name,
                      acptr->hopcount + 1, acptr->serv->timestamp,
@@ -261,13 +261,25 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf,
     {
       char xxx_buf[8];
       char *s = umode_str(acptr);
-      sendcmdto_one(acptr->user->server, CMD_NICK, cptr, *s ?
-                   "%s %d %Tu %s %s +%s %s %s%s :%s" :
-                   "%s %d %Tu %s %s %s%s %s%s :%s",
-                   acptr->name, acptr->hopcount + 1, acptr->lastnick,
-                   acptr->user->username, acptr->user->host, s,
-                   inttobase64(xxx_buf, ntohl(acptr->ip.s_addr), 6),
-                   NumNick(acptr), acptr->info);
+      struct Gline *agline = 0;
+      if ((agline = gline_lookup(acptr, GLINE_GLOBAL | GLINE_LASTMOD)))
+       sendcmdto_one(acptr->user->server, CMD_NICK, cptr,
+                     "%s %d %Tu %s %s %s%s%s%%%Tu:%s@%s %s %s%s :%s",
+                     acptr->name, acptr->hopcount + 1, acptr->lastnick,
+                     acptr->user->username, acptr->user->host,
+                     *s ? "+" : "", s, *s ? " " : "",
+                     GlineLastMod(agline), GlineUser(agline),
+                     GlineHost(agline),
+                     inttobase64(xxx_buf, ntohl(acptr->ip.s_addr), 6),
+                     NumNick(acptr), acptr->info);
+      else
+       sendcmdto_one(acptr->user->server, CMD_NICK, cptr,
+                     "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
+                     acptr->name, acptr->hopcount + 1, acptr->lastnick,
+                     acptr->user->username, acptr->user->host,
+                     *s ? "+" : "", s, *s ? " " : "",
+                     inttobase64(xxx_buf, ntohl(acptr->ip.s_addr), 6),
+                     NumNick(acptr), acptr->info);
     }
   }
   /*
index d1912d911f94c9affc8b6ae225776ead56c69e9f..4696248d0cb33944753b511a054856cc44e083a8 100644 (file)
@@ -407,7 +407,7 @@ static char *clean_user_id(char *dest, char *source, int tilde)
  *    nick from local user or kill him/her...
  */
 int register_user(struct Client *cptr, struct Client *sptr,
-                  const char *nick, char *username)
+                  const char *nick, char *username, struct Gline *agline)
 {
   struct ConfItem* aconf;
   char*            parv[3];
@@ -426,7 +426,6 @@ int register_user(struct Client *cptr, struct Client *sptr,
   struct User*     user = sptr->user;
   char             ip_base64[8];
   char             featurebuf[512];
-  struct Gline*    gline;
 
   user->last = CurrentTime;
   parv[0] = sptr->name;
@@ -594,11 +593,17 @@ int register_user(struct Client *cptr, struct Client *sptr,
   else {
     ircd_strncpy(user->username, username, USERLEN);
     Count_newremoteclient(UserStats, user->server);
-    if ((gline = gline_lookup(sptr)) && GlineIsActive(gline))
-      gline_resend(cptr, gline);
   }
   SetUser(sptr);
 
+  /* a gline wasn't passed in, so find a matching global one that isn't
+   * a Uworld-set one, and propagate it if there is such an animal.
+   */
+  if (!agline &&
+      (agline = gline_lookup(sptr, GLINE_GLOBAL | GLINE_LASTMOD)) &&
+      !IsBurstOrBurstAck(cptr))
+    gline_resend(cptr, agline);
+
   if (IsInvisible(sptr))
     ++UserStats.inv_clients;
   if (IsOper(sptr))
@@ -664,13 +669,24 @@ int register_user(struct Client *cptr, struct Client *sptr,
   }
 
   tmpstr = umode_str(sptr);
-  sendcmdto_serv_butone(user->server, CMD_NICK, cptr, *tmpstr ?
-                       "%s %d %d %s %s +%s %s %s%s :%s" :
-                       "%s %d %d %s %s %s%s %s%s :%s",
-                       nick, sptr->hopcount + 1, sptr->lastnick,
-                       user->username, user->host, tmpstr,
-                       inttobase64(ip_base64, ntohl(sptr->ip.s_addr), 6),
-                       NumNick(sptr), sptr->info);
+  if (agline)
+    sendcmdto_serv_butone(user->server, CMD_NICK, cptr,
+                         "%s %d %Tu %s %s %s%s%s%%%Tu:%s@%s %s %s%s :%s",
+                         nick, sptr->hopcount + 1, sptr->lastnick,
+                         user->username, user->host,
+                         *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
+                         GlineLastMod(agline), GlineUser(agline),
+                         GlineHost(agline),
+                         inttobase64(ip_base64, ntohl(sptr->ip.s_addr), 6),
+                         NumNick(sptr), sptr->info);
+  else
+    sendcmdto_serv_butone(user->server, CMD_NICK, cptr,
+                         "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
+                         nick, sptr->hopcount + 1, sptr->lastnick,
+                         user->username, user->host,
+                         *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
+                         inttobase64(ip_base64, ntohl(sptr->ip.s_addr), 6),
+                         NumNick(sptr), sptr->info);
 
   /* Send umode to client */
   if (MyUser(sptr))
@@ -725,6 +741,8 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
   if (IsServer(sptr)) {
     int   i;
     const char* p;
+    char *t;
+    struct Gline *agline = 0;
 
     /*
      * A server introducing a new client, change source
@@ -763,7 +781,21 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
     ircd_strncpy(new_client->username, parv[4], USERLEN);
     ircd_strncpy(new_client->user->host, parv[5], HOSTLEN);
     ircd_strncpy(new_client->info, parv[parc - 1], REALLEN);
-    return register_user(cptr, new_client, new_client->name, parv[4]);
+
+    /* Deal with GLINE parameters... */
+    if (*parv[parc - 4] == '%' && (t = strchr(parv[parc - 4] + 1, ':'))) {
+      time_t lastmod;
+
+      *(t++) = '\0';
+      lastmod = atoi(parv[parc - 4] + 1);
+
+      if (lastmod &&
+         (agline = gline_find(t, GLINE_EXACT | GLINE_GLOBAL | GLINE_LASTMOD))
+         && GlineLastMod(agline) > lastmod && !IsBurstOrBurstAck(cptr))
+       gline_resend(cptr, agline);
+    }
+
+    return register_user(cptr, new_client, new_client->name, parv[4], agline);
   }
   else if (sptr->name[0]) {
     /*
@@ -856,7 +888,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
        * for it - must test this and exit m_nick too !
        */
       sptr->lastnick = TStime();        /* Always local client */
-      if (register_user(cptr, sptr, nick, sptr->user->username) == CPTR_KILLED)
+      if (register_user(cptr, sptr, nick, sptr->user->username, 0) == CPTR_KILLED)
         return CPTR_KILLED;
     }
   }