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 -----------------------