CVSROOT    : /cvsroot/undernet-ircu
Module     : ircu2.10
Branch tags: u2_10_11_03
Commit time: 2002-11-24 19:16:24 UTC

Modified files:
  Tag: u2_10_11_03
     ChangeLog ircd/m_create.c ircd/m_settime.c ircd/s_user.c

Log message:

Author: Kev <[EMAIL PROTECTED]>
Log message:

Most of these changes are to support a kinder, gentler timestamp drift
correction algorithm in ms_create().  The basic idea is that if the
timestamp drift is bad enough for the server to send a server notice about
it, then it *also* sends a SETTIME to correct the time.  Now this alone is
insufficient if we're the server that's off--that's where the modifications
to m_settime.c come in.  We now allow servers to send SETTIMEs to specific
remote servers, rather than only spamming the network.  If we handle such
a directed SETTIME that is not directed to *us*, and if we're
RELIABLE_CLOCK and the timestamp on the incoming SETTIME was more than 30
seconds out of bounds, then we send a corrective SETTIME back up the line
to our previous hop.  This requires all of the hubs to be RELIABLE_CLOCK in
order to work properly.  The mod to s_user.c is necessary to remove an
assertion that prevented hunt_server_prio_cmd() from being used with
messages originating from a server.

A side-effect of this change, since I rewrote mo_settime() from scratch, is
to allow opers to specify a timestamp of 0 to SETTIME--if the oper-
specified timestamp is 0 or if we're a RELIABLE_CLOCK server, then our
current time is substituted instead.

---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.290.2.125.2.21 ircu2.10/ChangeLog:1.290.2.125.2.22
--- ircu2.10/ChangeLog:1.290.2.125.2.21 Sat Nov 23 21:27:24 2002
+++ ircu2.10/ChangeLog  Sun Nov 24 11:16:13 2002
@@ -1,5 +1,22 @@
 2002-11-24  Kevin L Mitchell  <[EMAIL PROTECTED]>
 
+       * ircd/m_settime.c: rewrite m[so]_settime().  Critical changes
+       are: servers may also send SETTIMEs to specific remote servers
+       (but are not required to); if we handle such a SETTIME that is
+       *not* for us, not only forward it, but if it's more than 30
+       seconds off in either direction (automatically corrected by code
+       before this), bounce a corrective SETTIME to our previous hop
+       (only if we're RELIABLE_CLOCK, of course); opers may now specify a
+       time of "0" to SETTIME to have the server fill it
+       in--RELIABLE_CLOCK servers will always fill in their own time
+
+       * ircd/m_create.c (ms_create): initialize the joinbufs just before
+       the for loop; issue a SETTIME if the remote server is > 1 minute
+       ahead, rather than squiting if it's > 5 minutes ahead
+
+       * ircd/s_user.c (hunt_server_prio_cmd): comment out the assert--we
+       now permit servers to send SETTIME to targeted servers
+
        * ircd/m_create.c (ms_create): exit the client's *server*, not the
        client--I was wondering why we weren't seeing any of these squits
        on the network!
Index: ircu2.10/ircd/m_create.c
diff -u ircu2.10/ircd/m_create.c:1.9.2.2.8.2 ircu2.10/ircd/m_create.c:1.9.2.2.8.3
--- ircu2.10/ircd/m_create.c:1.9.2.2.8.2        Sat Nov 23 21:27:24 2002
+++ ircu2.10/ircd/m_create.c    Sun Nov 24 11:16:13 2002
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: m_create.c,v 1.9.2.2.8.2 2002/11/24 05:27:24 klmitch Exp $
+ * $Id: m_create.c,v 1.9.2.2.8.3 2002/11/24 19:16:13 klmitch Exp $
  */
 
 /*
@@ -122,9 +122,6 @@
 
   chanTS = atoi(parv[2]);
 
-  joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
-  joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, chanTS);
-
   /* A create that didn't appear during a burst has that servers idea of
    * the current time.  Use it for lag calculations.
    */
@@ -136,15 +133,19 @@
   if (TStime() - chanTS<-60) {
     static time_t rate;
     sendto_opmask_butone_ratelimited(0, SNO_NETWORK, &rate,
-                                    "Timestamp drift from %C (%is)",
+                                    "Timestamp drift from %C (%is); issuing "
+                                    "SETTIME to correct this",
                                     cli_user(sptr)->server,
                                     chanTS - TStime());
-
-    /* If this server is >5 minutes fast, squit it */
-    if (TStime() - chanTS<-5*60*60)
-      return exit_client(cptr, cli_user(sptr)->server, &me,
-                        "Timestamp Drift/Bogus TS");
+    /* Now issue a SETTIME to resync.  If we're in the wrong, our
+     * (RELIABLE_CLOCK) hub will bounce a SETTIME back to us.
+     */
+    sendcmdto_prio_one(&me, CMD_SETTIME, cli_user(sptr)->server,
+                      "%Tu %C", TStime(), cli_user(sptr)->server);
   }
+
+  joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
+  joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, chanTS);
 
   /* For each channel in the comma seperated list: */
   for (name = ircd_strtok(&p, parv[1], ","); name;
Index: ircu2.10/ircd/m_settime.c
diff -u ircu2.10/ircd/m_settime.c:1.10.2.1 ircu2.10/ircd/m_settime.c:1.10.2.1.8.1
--- ircu2.10/ircd/m_settime.c:1.10.2.1  Tue Aug 27 16:52:24 2002
+++ ircu2.10/ircd/m_settime.c   Sun Nov 24 11:16:14 2002
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: m_settime.c,v 1.10.2.1 2002/08/27 23:52:24 kev Exp $
+ * $Id: m_settime.c,v 1.10.2.1.8.1 2002/11/24 19:16:14 klmitch Exp $
  */
 
 /*
@@ -104,72 +104,71 @@
  *
  * parv[0] = sender prefix
  * parv[1] = new time
- * parv[2] = servername (Only used when sptr is an Oper).
+ * parv[2] = server name (only used when sptr is an oper)
  */
-int ms_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
+int ms_settime(struct Client* cptr, struct Client* sptr, int parc,
+              char* parv[])
 {
   time_t t;
-  long int dt;
+  long dt;
   static char tbuf[11];
   struct DLink *lp;
 
-  if (!IsPrivileged(sptr))
-    return 0;
-
-  if (parc < 2)
+  if (parc < 2) /* verify argument count */
     return need_more_params(sptr, "SETTIME");
 
-  if (parc == 2 && MyUser(sptr))
-    parv[parc++] = cli_name(&me);
-
-  t = atoi(parv[1]);
+  t = atoi(parv[1]); /* convert time and compute delta */
   dt = TStime() - t;
 
-  if (t < OLDEST_TS || dt < -9000000)
-  {
-    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value", sptr);
+  /* verify value */
+  if (t < OLDEST_TS || dt < -9000000) {
+    if (IsServer(sptr)) /* protocol violation if it's from a server */
+      protocol_violation(sptr, "SETTIME: Bad value (%Tu, delta %l)", t, dt);
+    else
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value (%Tu, "
+                   "delta %l)", sptr, t, dt);
     return 0;
   }
 
-  if (IsServer(sptr))           /* send to unlagged servers */
-  {
-    if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-      ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-      parv[1] = tbuf;
-    }
+  if (feature_bool(FEAT_RELIABLE_CLOCK)) { /* reset time */
+    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
+    parv[1] = tbuf;
+  }
 
+  if (BadPtr(parv[2])) { /* spam the network */
     for (lp = cli_serv(&me)->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && MsgQLength(&(cli_sendQ(lp->value.cptr))) < 8000)
+      if (cptr != lp->value.cptr)
        sendcmdto_prio_one(sptr, CMD_SETTIME, lp->value.cptr, "%s", parv[1]);
-  }
-  else
-  {
-    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-    parv[1] = tbuf;
+  } else {
     if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
-                            parv) != HUNTED_ISME)
+                            parv) != HUNTED_ISME) {
+      /* If the destination was *not* me, but I'm RELIABLE_CLOCK and the
+       * delta is more than 30 seconds off, bounce back a corrected
+       * SETTIME
+       */
+      if (feature_bool(FEAT_RELIABLE_CLOCK) && (dt > 30 || dt < -30))
+       sendcmdto_prio_one(&me, CMD_SETTIME, cptr, "%s %C", parv[1], cptr);
       return 0;
+    }
   }
 
-  if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-    if ((dt > 600) || (dt < -600))
-      sendcmdto_serv_butone(&me, CMD_WALLOPS, 0, ":Bad SETTIME from %s: %Tu",
-                           cli_name(sptr), t);
-    if (IsUser(sptr)) {
-      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld "
-                   "seconds %s : RELIABLE_CLOCK is defined", sptr,
-                   (dt < 0) ? -dt : dt, (dt < 0) ? "forwards" : "backwards");
-    }
-  } else {
+  if (feature_bool(FEAT_RELIABLE_CLOCK)) { /* don't apply settime--reliable */
+    if (dt > 600 || dt < -600) /* If it was off more than 5 min, complain */
+      sendcmdto_serv_butone(&me, CMD_DESYNCH, 0, ":Bad SETTIME from %s: %Tu "
+                           "(delta %l)", cli_name(sptr), t, dt);
+    if (IsUser(sptr)) /* Let user know we're ignoring him */
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld seconds "
+                   "%s: RELIABLE_CLOCK is defined", sptr, (dt < 0) ? -dt : dt,
+                   (dt < 0) ? "forward" : "backward");
+  } else { /* tell opers about time change */
     sendto_opmask_butone(0, SNO_OLDSNO, "SETTIME from %s, clock is set %ld "
                         "seconds %s", cli_name(sptr), (dt < 0) ? -dt : dt,
-                        (dt < 0) ? "forwards" : "backwards");
-    TSoffset -= dt;
-    if (IsUser(sptr)) {
+                        (dt < 0) ? "forward" : "backward");
+    TSoffset -= dt; /* apply time change */
+    if (IsUser(sptr)) /* let user know what we did */
       sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is set %ld seconds %s",
                    sptr, (dt < 0) ? -dt : dt,
-                   (dt < 0) ? "forwards" : "backwards");
-    }
+                   (dt < 0) ? "forward" : "backward");
   }
 
   return 0;
@@ -180,72 +179,63 @@
  *
  * parv[0] = sender prefix
  * parv[1] = new time
- * parv[2] = servername (Only used when sptr is an Oper).
+ * parv[2] = server name (only used when sptr is an oper)
  */
-int mo_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
+int mo_settime(struct Client* cptr, struct Client* sptr, int parc,
+              char* parv[])
 {
   time_t t;
-  long int dt;
+  long dt = 0;
   static char tbuf[11];
-  struct DLink *lp;
-
-  if (!IsPrivileged(sptr))
-    return 0;
 
-  if (parc < 2)
+  if (!IsOper(sptr)) /* Must be a global oper */
+    return send_reply(sptr, ERR_NOPRIVILEGES);
+  if (parc < 2) /* verify argument count */
     return need_more_params(sptr, "SETTIME");
 
-  if (parc == 2 && MyUser(sptr))
+  if (parc == 2 && MyUser(sptr)) /* default to me */
     parv[parc++] = cli_name(&me);
 
-  t = atoi(parv[1]);
-  dt = TStime() - t;
+  t = atoi(parv[1]); /* convert the time */
 
-  if (t < OLDEST_TS || dt < -9000000)
-  {
-    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value", sptr);
-    return 0;
+  /* If we're reliable_clock or if the oper specified a 0 time, use current */
+  if (!t || feature_bool(FEAT_RELIABLE_CLOCK)) {
+    t = TStime();
+    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
+    parv[1] = tbuf;
   }
 
-  if (IsServer(sptr))           /* send to unlagged servers */
-  {
-    if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-      ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-      parv[1] = tbuf;
-    }
+  dt = TStime() - t; /* calculate the delta */
 
-    for (lp = cli_serv(&me)->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && MsgQLength(&(cli_sendQ(lp->value.cptr))) < 8000)
-       sendcmdto_prio_one(sptr, CMD_SETTIME, lp->value.cptr, "%s", parv[1]);
-  }
-  else
-  {
-    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-    parv[1] = tbuf;
-    if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
-                            parv) != HUNTED_ISME)
-      return 0;
+  /* verify value */
+  if (t < OLDEST_TS || dt < -9000000) {
+    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value (%Tu, "
+                 "delta %l)", sptr, t, dt);
+    return 0;
   }
 
-  if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-    if ((dt > 600) || (dt < -600))
-      sendcmdto_serv_butone(&me, CMD_WALLOPS, 0, ":Bad SETTIME from %s: %Tu",
-                           cli_name(sptr), t);
-    if (IsUser(sptr)) {
-      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld "
-                   "seconds %s : RELIABLE_CLOCK is defined", sptr,
-                   (dt < 0) ? -dt : dt, (dt < 0) ? "forwards" : "backwards");
-    }
-  } else {
+  /* OK, send the message off to its destination */
+  if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
+                          parv) != HUNTED_ISME)
+    return 0;
+
+  if (feature_bool(FEAT_RELIABLE_CLOCK)) { /* don't apply settime--reliable */
+    if (dt > 600 || dt < -600) /* If it was off more than 5 min, complain */
+      sendcmdto_serv_butone(&me, CMD_DESYNCH, 0, ":Bad SETTIME from %s: %Tu "
+                           "(delta %l)", cli_name(sptr), t, dt);
+    if (IsUser(sptr)) /* Let user know we're ignoring him */
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld seconds "
+                   "%s: RELIABLE_CLOCK is defined", sptr, (dt < 0) ? -dt : dt,
+                   (dt < 0) ? "forward" : "backward");
+  } else { /* tell opers about time change */
     sendto_opmask_butone(0, SNO_OLDSNO, "SETTIME from %s, clock is set %ld "
                         "seconds %s", cli_name(sptr), (dt < 0) ? -dt : dt,
-                        (dt < 0) ? "forwards" : "backwards");
-    TSoffset -= dt;
-    if (IsUser(sptr)) {
+                        (dt < 0) ? "forward" : "backward");
+    TSoffset -= dt; /* apply time change */
+    if (IsUser(sptr)) /* let user know what we did */
       sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is set %ld seconds %s",
                    sptr, (dt < 0) ? -dt : dt,
-                   (dt < 0) ? "forwards" : "backwards");
-    }
+                   (dt < 0) ? "forward" : "backward");
   }
 
   return 0;
Index: ircu2.10/ircd/s_user.c
diff -u ircu2.10/ircd/s_user.c:1.52.2.13.2.3 ircu2.10/ircd/s_user.c:1.52.2.13.2.4
--- ircu2.10/ircd/s_user.c:1.52.2.13.2.3        Sat Nov 23 11:05:09 2002
+++ ircu2.10/ircd/s_user.c      Sun Nov 24 11:16:14 2002
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: s_user.c,v 1.52.2.13.2.3 2002/11/23 19:05:09 klmitch Exp $
+ * $Id: s_user.c,v 1.52.2.13.2.4 2002/11/24 19:16:14 klmitch Exp $
  */
 #include "config.h"
 
@@ -276,7 +276,7 @@
     return HUNTED_NOSUCH;
   }
 
-  assert(!IsServer(from));
+  /* assert(!IsServer(from)); SETTIME to particular destinations permitted */
 
   parv[server] = (char *) acptr; /* HACK! HACK! HACK! ARGH! */
 
----------------------- End of diff -----------------------

Reply via email to