[svn] Port over ratbox 2.2 r23507, r23624, r23626 (jilles/anfl):
Change TS6 JOIN processing - don't send out simple modes in TS6 JOIN and TS5 SJOIN when a local user joins an existing channel - don't send out simple modes in TS6 JOIN and TS5 SJOIN when propagating a TS6 JOIN - don't interpret simple modes in an incoming TS6 JOIN This is to avoid desyncs when certain mode changes (e.g. -im) cross with joins. A downside is that simple modes will be more desynched when a JOIN creates a channel or lowers TS, but that's less important. Update the TS6 specification to include this, and clarify that TMODE can come from a server and that MODE must be translated into TMODE from other servers too.
This commit is contained in:
parent
9b6ff0c8f9
commit
bee3b6716c
4 changed files with 102 additions and 171 deletions
|
@ -1,3 +1,12 @@
|
|||
jilles 2007/02/11 16:54:43 UTC (20070211-3209)
|
||||
Log:
|
||||
Make -logfile work again.
|
||||
|
||||
|
||||
Changes: Modified:
|
||||
+2 -2 trunk/src/s_log.c (File Modified)
|
||||
|
||||
|
||||
nenolod 2007/02/09 22:18:23 UTC (20070209-3205)
|
||||
Log:
|
||||
- fix off-by-one memory overflow error.
|
||||
|
|
|
@ -1,11 +1,35 @@
|
|||
$Id: ts6.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
$Id: ts6.txt 3211 2007-02-20 00:34:28Z jilles $
|
||||
|
||||
TS6 Proposal (v7)
|
||||
TS6 Proposal (v8)
|
||||
Written by Lee H <lee@leeh.co.uk>
|
||||
Ideas borrowed heavily from ircnet (Beeth, jv, Q)
|
||||
|
||||
Introduction
|
||||
------------
|
||||
- Changes between v7 and v8 -
|
||||
-----------------------------
|
||||
|
||||
In the v7 specification, the JOIN command included the channel modes of a
|
||||
channel, and acted on them following TS rules. In the v8 specification,
|
||||
JOIN will never send modes.
|
||||
|
||||
Desyncs can occur both when they are sent and when they are not. If they
|
||||
are sent, then you can have a situation where a user on one side of the
|
||||
network issues "MODE #channel -l", and a user on another side of the network
|
||||
issues "JOIN #channel" whilst the +l still exists. As the JOIN string sent
|
||||
server<->server includes the full modes at the time of the user joining,
|
||||
this will propagate the +l, but there is a -l crossing in the other
|
||||
direction. Desync will occur beyond where they intersect.
|
||||
|
||||
If the modes are not sent, then a lower TS JOIN command, or a JOIN command
|
||||
that creates a channel will cause a desync.
|
||||
|
||||
It is judged that the desync with sending the modes is worse than the desync
|
||||
by not sending them, as such the v8 specification dictates modes are not
|
||||
sent with a JOIN command server<->server.
|
||||
|
||||
The v8 specification also clarifies that servers may issue TMODE.
|
||||
|
||||
- Introduction -
|
||||
----------------
|
||||
|
||||
This document aims to fix some of the flaws that are still present in the
|
||||
current TS system.
|
||||
|
@ -28,8 +52,8 @@ issue a mode during a netburst and the mode will be set on the server
|
|||
we are bursting to.
|
||||
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
- Definitions -
|
||||
---------------
|
||||
|
||||
Throughout this document, the following terms are used:
|
||||
|
||||
|
@ -43,8 +67,8 @@ UID - An ID concateneted to a SID. This forms the clients UID.
|
|||
TS6 - The TS version 6.
|
||||
|
||||
|
||||
Support
|
||||
-------
|
||||
- Support -
|
||||
-----------
|
||||
|
||||
Support for this document is given by the TS version 6.
|
||||
|
||||
|
@ -60,8 +84,8 @@ http://www.leeh.co.uk/ircd/encap.txt
|
|||
The TS6 protocol does not supports masked entities.
|
||||
|
||||
|
||||
Nick TS rules
|
||||
-------------
|
||||
- Nick TS rules -
|
||||
-----------------
|
||||
|
||||
A server receiving a command that requires nick TS rules must check for a
|
||||
collision between an existing user, and the nick in the received message.
|
||||
|
@ -81,8 +105,8 @@ clients user@host are different it will collide the new user and drop the
|
|||
message.
|
||||
|
||||
|
||||
Nick TS collisions
|
||||
------------------
|
||||
- Nick TS collisions -
|
||||
----------------------
|
||||
|
||||
If both users are to be collided, we must issue a KILL for the existing
|
||||
user to all servers. If the new user has a UID then we must also issue a
|
||||
|
@ -98,8 +122,8 @@ If only the new user is being collided, we must issue a KILL for the new user
|
|||
back to the server sending us data if the new user has a UID.
|
||||
|
||||
|
||||
Channel TS rules
|
||||
----------------
|
||||
- Channel TS rules -
|
||||
--------------------
|
||||
|
||||
A server receiving a command that requires normal channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
@ -125,8 +149,8 @@ losing their op (+o) status who do not have a UID as 'deopped'. A server must
|
|||
ignore any "MODE" commands from a user marked as 'deopped'.
|
||||
|
||||
|
||||
Simple channel TS rules
|
||||
-----------------------
|
||||
- Simple channel TS rules -
|
||||
---------------------------
|
||||
|
||||
A server receiving a command that requires simple channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
@ -139,11 +163,11 @@ Simple channel TS rules do not affect current modes in the channel except
|
|||
for the modes we are accepting.
|
||||
|
||||
|
||||
The following commands are defined here as the TS6 protocol
|
||||
-----------------------------------------------------------
|
||||
- The following commands are defined here as the TS6 protocol -
|
||||
---------------------------------------------------------------
|
||||
|
||||
PASS:
|
||||
PASS <PASSWORD> TS <TS_CURRENT> :<SID>
|
||||
- PASS -
|
||||
PASS <PASSWORD> TS <TS_CURRENT> :<SID>
|
||||
|
||||
This command is used for password verification with the server we are
|
||||
connecting to.
|
||||
|
@ -156,8 +180,8 @@ The <PASSWORD> field is the password we have stored for this server,
|
|||
<TS_CURRENT> is our current TS version. If this field is not present then
|
||||
the server does not support TS6. <SID> is the SID of the server.
|
||||
|
||||
UID:
|
||||
:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
|
||||
- UID -
|
||||
:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
|
||||
|
||||
This command is used for introducing clients to the network.
|
||||
|
||||
|
@ -176,8 +200,8 @@ clients UID. The <GECOS> field is the clients gecos.
|
|||
|
||||
A server receiving a UID command must apply nick TS rules to the nick.
|
||||
|
||||
SID:
|
||||
:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
|
||||
- SID -
|
||||
:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
|
||||
|
||||
This command is used for introducing servers to the network.
|
||||
|
||||
|
@ -196,8 +220,8 @@ connected server through which the command was received.
|
|||
Client and servers which do not have a UID/SID must be introduced by old
|
||||
methods.
|
||||
|
||||
SJOIN:
|
||||
:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
|
||||
- SJOIN -
|
||||
:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
|
||||
|
||||
This command is used for introducing users to channels.
|
||||
|
||||
|
@ -216,23 +240,28 @@ to introduce a single user to an existing channel. It must instead
|
|||
use the "JOIN" command defined in this specification. A TS6 server must
|
||||
still use SJOIN for creating channels.
|
||||
|
||||
JOIN:
|
||||
:<UID> JOIN <TS> <CHANNAME> +<CHANMODES>
|
||||
- JOIN -
|
||||
:<UID> JOIN <TS> <CHANNAME> +
|
||||
|
||||
This command is used for introducing one user unopped to an existing channel.
|
||||
|
||||
The <UID> field is the UID of the client joining the channel. The
|
||||
<TS> field is the channels current TS, <CHANNAME> is the channels
|
||||
current name, <CHANMODES> are the channels current modes.
|
||||
current name.
|
||||
|
||||
A server receiving a JOIN must apply normal channel TS rules to the JOIN.
|
||||
|
||||
It should be noted that whilst JOIN would not normally create a
|
||||
channel, during specific race conditions it can. This can create
|
||||
a ban desync that this specification does not rectify.
|
||||
No channel modes are sent with the JOIN command. In previous versions of
|
||||
this specification, the "+" parameter contained the channels current modes.
|
||||
A server following this version of the specification must not interpret this
|
||||
argument and must not propagate any value other than "+" for this parameter.
|
||||
|
||||
BMASK:
|
||||
:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
|
||||
It should be noted that whilst JOIN would not normally create a
|
||||
channel or lower the timestamp, during specific conditions it can. This
|
||||
can create a desync that this specification does not rectify.
|
||||
|
||||
- BMASK -
|
||||
:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
|
||||
|
||||
This command is used for bursting channel bans to a network.
|
||||
|
||||
|
@ -253,17 +282,18 @@ It should be noted however, that a BMASK with a lower TS should
|
|||
not be possible without a desync, due to it being sent after
|
||||
SJOIN.
|
||||
|
||||
TMODE:
|
||||
:<UID> TMODE <TS> <CHANNAME> <MODESTRING>
|
||||
- TMODE -
|
||||
:<SID|UID> TMODE <TS> <CHANNAME> <MODESTRING>
|
||||
|
||||
This command is used for clients issuing modes on a channel.
|
||||
|
||||
<UID> is the UID of the client setting the mode. <TS> is the
|
||||
current TS of the channel, <CHANNAME> is the channels name.
|
||||
<MODESTRING> is the raw mode the client is setting.
|
||||
<SID|UID> is either the UID of the client setting the mode, or the SID of
|
||||
the server setting the mode. <TS> is the current TS of the channel,
|
||||
<CHANNAME> is the channels name. <MODESTRING> is the raw mode the client is
|
||||
setting.
|
||||
|
||||
A server receiving a TMODE must apply simple channel TS rules to the TMODE.
|
||||
|
||||
A TS6 server must translate MODEs issued by a local client into TMODE
|
||||
to send to other TS6 capable servers.
|
||||
A TS6 server must translate MODEs issued by a local client, or received from
|
||||
a server into TMODE to send to other TS6 capable servers.
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
#define SERNO "20070209-3205"
|
||||
#define SERNO "20070211-3209"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
* $Id: m_join.c 3173 2007-01-31 23:57:18Z jilles $
|
||||
* $Id: m_join.c 3211 2007-02-20 00:34:28Z jilles $
|
||||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
|
@ -62,7 +62,7 @@ mapi_hlist_av1 join_hlist[] = {
|
|||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3173 $");
|
||||
DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3211 $");
|
||||
|
||||
static void do_join_0(struct Client *client_p, struct Client *source_p);
|
||||
static int check_channel_name_loc(struct Client *source_p, const char *name);
|
||||
|
@ -342,17 +342,15 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
|
|||
}
|
||||
else
|
||||
{
|
||||
const char *modes = channel_modes(chptr, &me);
|
||||
|
||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||
":%s JOIN %ld %s %s",
|
||||
":%s JOIN %ld %s +",
|
||||
use_id(source_p), (long) chptr->channelts,
|
||||
chptr->chname, modes);
|
||||
chptr->chname);
|
||||
|
||||
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
||||
":%s SJOIN %ld %s %s :%s",
|
||||
":%s SJOIN %ld %s + :%s",
|
||||
me.name, (long) chptr->channelts,
|
||||
chptr->chname, modes, source_p->name);
|
||||
chptr->chname, source_p->name);
|
||||
}
|
||||
|
||||
del_invite(chptr, source_p);
|
||||
|
@ -396,13 +394,10 @@ static int
|
|||
ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||
{
|
||||
struct Channel *chptr;
|
||||
static struct Mode mode, *oldmode;
|
||||
const char *s;
|
||||
const char *modes;
|
||||
static struct Mode mode;
|
||||
time_t oldts;
|
||||
time_t newts;
|
||||
int isnew;
|
||||
int args = 0;
|
||||
int keep_our_modes = YES;
|
||||
int keep_new_modes = YES;
|
||||
dlink_node *ptr, *next_ptr;
|
||||
|
@ -428,89 +423,11 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
|||
mode.key[0] = mode.forward[0] = '\0';
|
||||
mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
|
||||
|
||||
s = parv[3];
|
||||
while(*s)
|
||||
{
|
||||
switch (*(s++))
|
||||
{
|
||||
case 'i':
|
||||
mode.mode |= MODE_INVITEONLY;
|
||||
break;
|
||||
case 'n':
|
||||
mode.mode |= MODE_NOPRIVMSGS;
|
||||
break;
|
||||
case 'p':
|
||||
mode.mode |= MODE_PRIVATE;
|
||||
break;
|
||||
case 's':
|
||||
mode.mode |= MODE_SECRET;
|
||||
break;
|
||||
case 'm':
|
||||
mode.mode |= MODE_MODERATED;
|
||||
break;
|
||||
case 't':
|
||||
mode.mode |= MODE_TOPICLIMIT;
|
||||
break;
|
||||
case 'r':
|
||||
mode.mode |= MODE_REGONLY;
|
||||
break;
|
||||
case 'L':
|
||||
mode.mode |= MODE_EXLIMIT;
|
||||
break;
|
||||
case 'P':
|
||||
mode.mode |= MODE_PERMANENT;
|
||||
break;
|
||||
case 'c':
|
||||
mode.mode |= MODE_NOCOLOR;
|
||||
break;
|
||||
case 'g':
|
||||
mode.mode |= MODE_FREEINVITE;
|
||||
break;
|
||||
case 'z':
|
||||
mode.mode |= MODE_OPMODERATE;
|
||||
break;
|
||||
case 'F':
|
||||
mode.mode |= MODE_FREETARGET;
|
||||
break;
|
||||
case 'Q':
|
||||
mode.mode |= MODE_DISFORWARD;
|
||||
break;
|
||||
case 'f':
|
||||
if(parc < 5 + args)
|
||||
return 0;
|
||||
strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
|
||||
args++;
|
||||
break;
|
||||
case 'j':
|
||||
/* sent a +j without an arg. */
|
||||
if(parc < 5 + args)
|
||||
return 0;
|
||||
sscanf(parv[4 + args], "%d:%d", &mode.join_num, &mode.join_time);
|
||||
args++;
|
||||
break;
|
||||
case 'k':
|
||||
/* sent a +k without a key, eek. */
|
||||
if(parc < 5 + args)
|
||||
return 0;
|
||||
strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
|
||||
args++;
|
||||
break;
|
||||
case 'l':
|
||||
/* sent a +l without a limit. */
|
||||
if(parc < 5 + args)
|
||||
return 0;
|
||||
mode.limit = atoi(parv[4 + args]);
|
||||
args++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
|
||||
return 0;
|
||||
|
||||
newts = atol(parv[1]);
|
||||
oldts = chptr->channelts;
|
||||
oldmode = &chptr->mode;
|
||||
|
||||
#ifdef IGNORE_BOGUS_TS
|
||||
if(newts < 800000000)
|
||||
|
@ -547,55 +464,30 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
|||
else
|
||||
keep_new_modes = NO;
|
||||
|
||||
if(!keep_new_modes)
|
||||
mode = *oldmode;
|
||||
else if(keep_our_modes)
|
||||
{
|
||||
mode.mode |= oldmode->mode;
|
||||
if(oldmode->limit > mode.limit)
|
||||
mode.limit = oldmode->limit;
|
||||
if(strcmp(mode.key, oldmode->key) < 0)
|
||||
strcpy(mode.key, oldmode->key);
|
||||
if(oldmode->join_num > mode.join_num ||
|
||||
(oldmode->join_num == mode.join_num &&
|
||||
oldmode->join_time > mode.join_time))
|
||||
{
|
||||
mode.join_num = oldmode->join_num;
|
||||
mode.join_time = oldmode->join_time;
|
||||
}
|
||||
if(irccmp(mode.forward, oldmode->forward) < 0)
|
||||
strcpy(mode.forward, oldmode->forward);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If setting -j, clear join throttle state -- jilles */
|
||||
if (!mode.join_num)
|
||||
chptr->join_count = chptr->join_delta = 0;
|
||||
}
|
||||
|
||||
set_final_mode(&mode, oldmode);
|
||||
chptr->mode = mode;
|
||||
|
||||
/* Lost the TS, other side wins, so remove modes on this side */
|
||||
if(!keep_our_modes)
|
||||
{
|
||||
set_final_mode(&mode, &chptr->mode);
|
||||
chptr->mode = mode;
|
||||
remove_our_modes(chptr, source_p);
|
||||
DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
|
||||
{
|
||||
del_invite(chptr, ptr->data);
|
||||
}
|
||||
/* If setting -j, clear join throttle state -- jilles */
|
||||
chptr->join_count = chptr->join_delta = 0;
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
|
||||
me.name, chptr->chname, chptr->chname,
|
||||
(long) oldts, (long) newts);
|
||||
if(*modebuf != '\0')
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s",
|
||||
source_p->servptr->name,
|
||||
chptr->chname, modebuf, parabuf);
|
||||
*modebuf = *parabuf = '\0';
|
||||
}
|
||||
|
||||
if(*modebuf != '\0')
|
||||
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
|
||||
source_p->user->server, chptr->chname, modebuf, parabuf);
|
||||
|
||||
*modebuf = *parabuf = '\0';
|
||||
|
||||
if(!IsMember(source_p, chptr))
|
||||
{
|
||||
add_user_to_channel(chptr, source_p, CHFL_PEON);
|
||||
|
@ -611,14 +503,14 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
|||
source_p->host, chptr->chname);
|
||||
}
|
||||
|
||||
modes = channel_modes(chptr, client_p);
|
||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||
":%s JOIN %ld %s %s",
|
||||
source_p->id, (long) chptr->channelts, chptr->chname, modes);
|
||||
":%s JOIN %ld %s +",
|
||||
source_p->id, (long) chptr->channelts, chptr->chname);
|
||||
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
||||
":%s SJOIN %ld %s %s :%s",
|
||||
source_p->user->server, (long) chptr->channelts,
|
||||
chptr->chname, modes, source_p->name);
|
||||
chptr->chname, keep_new_modes ? "+" : "0",
|
||||
source_p->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue