Committer : entrope
CVSROOT : /cvsroot/undernet-ircu
Module : ircu2.10
Branch tags: u2_10_12_branch
Commit time: 2006-03-18 15:53:08 UTC
Modified files:
Tag: u2_10_12_branch
ChangeLog ircd/channel.c ircd/m_create.c ircd/m_mode.c
Log message:
Avoid unwanted races for mode handling during burst processing.
---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.710.2.79 ircu2.10/ChangeLog:1.710.2.80
--- ircu2.10/ChangeLog:1.710.2.79 Tue Mar 14 06:56:51 2006
+++ ircu2.10/ChangeLog Sat Mar 18 07:52:57 2006
@@ -1,3 +1,15 @@
+2006-06-18 Michael Poole <[EMAIL PROTECTED]>
+
+ * ircd/channel.c (modebuf_flush_int): Fix typo about changing
+ oplevels. Send correct channel TS for modes to other servers.
+ (mode_parse): Accept timestamps on modes from users on other
+ servers. If the received timestamp is too large, handle that.
+
+ * ircd/m_create.c (ms_create): Mention the CREATE-during-burst
+ case and handle it.
+
+ * ircd/m_mode.c (ms_mode): Put back HACK(3) when oplevels are off.
+
2006-03-14 Wouter Coekarts <[EMAIL PROTECTED]>
* ircd/s_err.c (RPL_STATSILINE): Add two %s to the first field.
Index: ircu2.10/ircd/channel.c
diff -u ircu2.10/ircd/channel.c:1.155.2.12 ircu2.10/ircd/channel.c:1.155.2.13
--- ircu2.10/ircd/channel.c:1.155.2.12 Fri Jan 6 17:08:29 2006
+++ ircu2.10/ircd/channel.c Sat Mar 18 07:52:58 2006
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Channel management and maintenance
- * @version $Id: channel.c,v 1.155.2.12 2006/01/07 01:08:29 entrope Exp $
+ * @version $Id: channel.c,v 1.155.2.13 2006/03/18 15:52:58 entrope Exp $
*/
#include "config.h"
@@ -1805,7 +1805,7 @@
strptr_i = &remstr_i;
}
- /* if we're changing oplevels we know the oplevel, pass it on */
+ /* if we're changing oplevels and we know the oplevel, pass it on */
if (mbuf->mb_channel->mode.apass[0]
&& (MB_TYPE(mbuf, i) & MODE_CHANOP)
&& MB_OPLEVEL(mbuf, i) < MAXOPLEVEL)
@@ -1849,9 +1849,9 @@
addbuf, remstr, addstr);
} else if (mbuf->mb_dest & MODEBUF_DEST_BOUNCE) {
/*
- * If HACK2 was set, we're bouncing; we send the MODE back to the
- * connection we got it from with the senses reversed and a TS of 0;
- * origin is us
+ * If HACK2 was set, we're bouncing; we send the MODE back to
+ * the connection we got it from with the senses reversed and
+ * the proper TS; origin is us
*/
sendcmdto_one(&me, CMD_MODE, mbuf->mb_connect, "%H %s%s%s%s%s%s %Tu",
mbuf->mb_channel, addbuf_i ? "-" : "", addbuf,
@@ -1859,21 +1859,14 @@
mbuf->mb_channel->creationtime);
} else {
/*
- * We're propagating a normal MODE command to the rest of the network;
- * we send the actual channel TS unless this is a HACK3 or a HACK4
+ * We're propagating a normal (or HACK3 or HACK4) MODE command
+ * to the rest of the network. We send the actual channel TS.
*/
- if (IsServer(mbuf->mb_source) || IsMe(mbuf->mb_source))
- sendcmdto_serv_butone(mbuf->mb_source, CMD_MODE, mbuf->mb_connect,
- "%H %s%s%s%s%s%s %Tu", mbuf->mb_channel,
- rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
- addbuf, remstr, addstr,
- (mbuf->mb_dest & MODEBUF_DEST_HACK4) ? 0 :
- mbuf->mb_channel->creationtime);
- else
- sendcmdto_serv_butone(mbuf->mb_source, CMD_MODE, mbuf->mb_connect,
- "%H %s%s%s%s%s%s", mbuf->mb_channel,
- rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
- addbuf, remstr, addstr);
+ sendcmdto_serv_butone(mbuf->mb_source, CMD_MODE, mbuf->mb_connect,
+ "%H %s%s%s%s%s%s %Tu", mbuf->mb_channel,
+ rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "",
+ addbuf, remstr, addstr,
+ mbuf->mb_channel->creationtime);
}
}
@@ -3272,7 +3265,7 @@
state.parc--;
/* is it a TS? */
- if (IsServer(state.sptr) && !state.parc && IsDigit(*modestr)) {
+ if (IsServer(state.cptr) && !state.parc && IsDigit(*modestr)) {
time_t recv_ts;
if (!(state.flags & MODE_PARSE_SET)) /* don't set earlier TS if */
@@ -3282,6 +3275,35 @@
if (recv_ts && recv_ts < state.chptr->creationtime)
state.chptr->creationtime = recv_ts; /* respect earlier TS */
+ else if (recv_ts > state.chptr->creationtime) {
+ struct Client *sserv;
+
+ /* Check whether the originating server has fully processed
+ * the burst to it. */
+ sserv = state.cptr;
+ if (!IsServer(sserv))
+ sserv = cli_user(sserv)->server;
+ if (IsBurstOrBurstAck(sserv)) {
+ /* This is a legal but unusual case; the source server
+ * probably just has not processed the BURST for this
+ * channel. It SHOULD wipe out all its modes soon, so
+ * silently ignore the mode change rather than send a
+ * bounce that could desync modes from our side (that
+ * have already been sent).
+ */
+ state.mbuf->mb_add = 0;
+ state.mbuf->mb_rem = 0;
+ state.mbuf->mb_count = 0;
+ return state.args_used;
+ } else {
+ /* Server is desynced; bounce the mode and deop the source
+ * to fix it. */
+ state.mbuf->mb_dest &= ~MODEBUF_DEST_CHANNEL;
+ state.mbuf->mb_dest |= MODEBUF_DEST_BOUNCE | MODEBUF_DEST_HACK2;
+ if (!IsServer(state.cptr))
+ state.mbuf->mb_dest |= MODEBUF_DEST_DEOP;
+ }
+ }
break; /* break out of while loop */
} else if (state.flags & MODE_PARSE_STRICT ||
Index: ircu2.10/ircd/m_create.c
diff -u ircu2.10/ircd/m_create.c:1.18.2.2 ircu2.10/ircd/m_create.c:1.18.2.3
--- ircu2.10/ircd/m_create.c:1.18.2.2 Fri Dec 23 09:12:06 2005
+++ ircu2.10/ircd/m_create.c Sat Mar 18 07:52:58 2006
@@ -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.18.2.2 2005/12/23 17:12:06 klmitch Exp $
+ * $Id: m_create.c,v 1.18.2.3 2006/03/18 15:52:58 entrope Exp $
*/
/*
@@ -172,7 +172,7 @@
the fact that it was a zannel. The influence of this on a network
that is completely 2.10.12.03 or higher is neglectable: Normally
a server only sends a CREATE after first sending a DESTRUCT. Thus,
- by receiving a CREATE for a zannel one of two things happened:
+ by receiving a CREATE for a zannel one of three things happened:
1. The DESTRUCT was sent during a net.break; this could mean that
our zannel is at the verge of expiring too, it should have been
destructed. It is correct to copy the newer TS now, all modes
@@ -185,28 +185,45 @@
already left within the time span of a message propagation.
The channel will therefore be less than 48 hours old and no
'protection' is necessary.
+ 3. The source server sent the CREATE while linking,
+ before it got the BURST for our zannel. If this
+ happens, we should reset the channel back to the old
+ timestamp. This can be distinguished from case #1 by
+ checking IsBurstOrBurstAck(cli_user(sptr)->server).
*/
!(chptr->users == 0 && !chptr->mode.apass[0]))) {
- modebuf_init(&mbuf, sptr, cptr, chptr,
- (MODEBUF_DEST_SERVER | /* Send mode to server */
- MODEBUF_DEST_HACK2 | /* Send a HACK(2) message */
- MODEBUF_DEST_BOUNCE)); /* And bounce the mode */
+ if (!IsBurstOrBurstAck(cli_user(sptr)->server)) {
+ modebuf_init(&mbuf, sptr, cptr, chptr,
+ (MODEBUF_DEST_SERVER | /* Send mode to server */
+ MODEBUF_DEST_HACK2 | /* Send a HACK(2) message */
+ MODEBUF_DEST_BOUNCE)); /* And bounce the mode */
+
+ modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr, MAXOPLEVEL
+ 1);
+
+ modebuf_flush(&mbuf);
+
+ badop = 1;
+ } else if (chanTS > chptr->creationtime + 4) {
+ /* If their handling of the BURST will lead to deopping the
+ * user, have the user join without getting ops (if the
+ * server's handling of the BURST keeps their ops, the channel
+ * will use our timestamp).
+ */
+ badop = 1;
+ }
- modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr, MAXOPLEVEL +
1);
-
- modebuf_flush(&mbuf);
-
- badop = 1;
+ if (badop)
+ joinbuf_join(&join, chptr, 0);
}
}
else /* Channel doesn't exist: create it */
chptr = get_channel(sptr, name, CGT_CREATE);
- if (!badop) /* Set/correct TS */
+ if (!badop) {
+ /* Set (or correct) our copy of the TS */
chptr->creationtime = chanTS;
-
- joinbuf_join(badop ? &join : &create, chptr,
- (badop ? 0 : CHFL_CHANOP));
+ joinbuf_join(&create, chptr, CHFL_CHANOP);
+ }
}
joinbuf_flush(&join); /* flush out the joins and creates */
Index: ircu2.10/ircd/m_mode.c
diff -u ircu2.10/ircd/m_mode.c:1.15.2.2 ircu2.10/ircd/m_mode.c:1.15.2.3
--- ircu2.10/ircd/m_mode.c:1.15.2.2 Sat Feb 4 16:50:22 2006
+++ ircu2.10/ircd/m_mode.c Sat Mar 18 07:52:58 2006
@@ -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_mode.c,v 1.15.2.2 2006/02/05 00:50:22 entrope Exp $
+ * $Id: m_mode.c,v 1.15.2.3 2006/03/18 15:52:58 entrope Exp $
*/
/*
@@ -86,6 +86,7 @@
#include "client.h"
#include "hash.h"
#include "ircd.h"
+#include "ircd_features.h"
#include "ircd_log.h"
#include "ircd_reply.h"
#include "ircd_string.h"
@@ -177,10 +178,15 @@
(MODEBUF_DEST_CHANNEL | /* Send mode to clients */
MODEBUF_DEST_SERVER | /* Send mode to servers */
MODEBUF_DEST_HACK4)); /* Send a HACK(4) message */
+ else if (!feature_bool(FEAT_OPLEVELS))
+ modebuf_init(&mbuf, sptr, cptr, chptr,
+ (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
+ MODEBUF_DEST_SERVER | /* Send mode to servers */
+ MODEBUF_DEST_HACK3)); /* Send a HACK(3) message */
else
/* Servers need to be able to op people who join using the Apass
- * or upass, as well as people joining a zannel, therefore we no
- * longer generate HACK3. */
+ * or upass, as well as people joining a zannel, therefore we do
+ * not generate HACK3 when oplevels are on. */
modebuf_init(&mbuf, sptr, cptr, chptr,
(MODEBUF_DEST_CHANNEL | /* Send mode to clients */
MODEBUF_DEST_SERVER)); /* Send mode to servers */
----------------------- End of diff -----------------------
_______________________________________________
Patches mailing list
[email protected]
http://undernet.sbg.org/mailman/listinfo/patches