Andrew Miller wrote: >Progs wrote: > > > >>Hi, >> >>If I have two servers, AA and AB, with AAAAA and ABAAA on #foo, a +D channel. >>AAAAA is delayed on #foo and ABAAA is +d. >>There are only AAAAA and ABAAA in #foo. >>When AAAAA speaks on #foo, ABAAA is +d so AB doesn't receive message, so >>ABAAA doesn't see AAAAA's join. >> >>Bug or feature ?:) >> >This could be used to build a map of the network and determine where the >hubs are. Anything which breaks HIS that bad is a bug. > >There are several fixes: >Fix A: We need to globally synchronise delayed state, which means that >we need to transmit it in BURST. We can then apply the "don't propagate >WASDELAYED" because we can track delayed state in each server. Finally, >if a message causes RevealDelayed, it should propagate to all servers, >not just those with non-deaf members on the channel. > >Fix B: Deaf users can't join +D or +d channels, and users in +D or + d >channels can't become deaf. > >Fix C: Deaf users joining a +D or +d channel force a full reveal to >everyone on that server(I think we can rule this one out) > >Fix D: Deaf users joining a +D or +d channel can see everyone, and can't >set -d usermode(to prevent seeing the same join twice, when >RevealDelayed is called) while in channel. > >Fix E: Deaf users joining +D or +d channel get a full reveal, and if >they set -d, we set WASDEAF on all +D or +d channels they are in. Users >with Deaf usermode or WASDEAF status in the channel do not see messages >sent by RevealDelayed as they have already seen them earlier. They do >see parts for delayed users. > >How many users set -d once they are connected anyway? Probably not many, >so fix D might be reasonable. Fix A requires a server protocol >change(and costs extra bandwidth on burst). In the light of the >bandwidth problems with A and C, and the feature restrictions of B and >D, only E remains(or G, "do nothing" :) ). > > Patch for option E attached. It needs review, because there are lots of cases to consider(and it is 4am here :( ). Feel free to commit it if people agree with the solution. I haven't added a changelog in the patch so if you commit it don't forget that too.
Andrew
? deaf_delayed.patch ? wasdelayed-bugfix.patch ? ircd/.Rhistory ? ircd/convert-conf ? ircd/test/ircd_match_t Index: include/channel.h =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/include/channel.h,v retrieving revision 1.55 diff -b -u -d -r1.55 channel.h --- include/channel.h 27 Sep 2005 02:41:57 -0000 1.55 +++ include/channel.h 28 Oct 2005 14:58:19 -0000 @@ -81,6 +81,7 @@ * channel */ #define CHFL_DELAYED 0x40000 /**< User's join message is delayed */ +#define CHFL_SEENDELAYED 0x80000 /**< User has been sent delayed list */ #define CHFL_OVERLAP (CHFL_CHANOP | CHFL_VOICE) #define CHFL_BANVALIDMASK (CHFL_BANVALID | CHFL_BANNED) @@ -219,6 +220,7 @@ #define IsChannelManager(x) ((x)->status & CHFL_CHANNEL_MANAGER) #define IsUserParting(x) ((x)->status & CHFL_USER_PARTING) #define IsDelayedJoin(x) ((x)->status & CHFL_DELAYED) +#define HasSeenDelayed(x) ((x)->status & CHFL_SEENDELAYED) #define SetBanned(x) ((x)->status |= CHFL_BANNED) #define SetBanValid(x) ((x)->status |= CHFL_BANVALID) @@ -230,6 +232,7 @@ #define SetOpLevel(x, v) (void)((x)->oplevel = (v)) #define SetUserParting(x) ((x)->status |= CHFL_USER_PARTING) #define SetDelayedJoin(x) ((x)->status |= CHFL_DELAYED) +#define SetSeenDelayed(x) ((x)->status |= CHFL_SEENDELAYED) #define ClearBanned(x) ((x)->status &= ~CHFL_BANNED) #define ClearBanValid(x) ((x)->status &= ~CHFL_BANVALID) @@ -454,5 +457,6 @@ extern struct Ban *find_ban(struct Client *cptr, struct Ban *banlist); extern int apply_ban(struct Ban **banlist, struct Ban *newban, int free); extern void free_ban(struct Ban *ban); +extern void ShowClientAllDelayed(struct Client *client); #endif /* INCLUDED_channel_h */ Index: include/s_user.h =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/include/s_user.h,v retrieving revision 1.21 diff -b -u -d -r1.21 s_user.h --- include/s_user.h 18 Oct 2005 03:20:53 -0000 1.21 +++ include/s_user.h 28 Oct 2005 14:58:26 -0000 @@ -113,6 +113,8 @@ #define NAMES_VIS 2 /**< List only visible users in non-secret channels */ #define NAMES_EON 4 /**< Add an 'End Of Names' reply to the end */ #define NAMES_DEL 8 /**< Show delayed joined users only */ +#define NAMES_INCLUDEDEL 16 /**< Show delayed joined users additionally */ + void do_names(struct Client* sptr, struct Channel* chptr, int filter); Index: include/send.h =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/include/send.h,v retrieving revision 1.22 diff -b -u -d -r1.22 send.h --- include/send.h 16 Dec 2004 03:28:51 -0000 1.22 +++ include/send.h 28 Oct 2005 14:58:27 -0000 @@ -91,6 +91,11 @@ #define SKIP_NONOPS 0x04 /**< skip users that aren't chanops */ #define SKIP_NONVOICES 0x08 /**< skip users that aren't voiced (includes chanops) */ +#define SKIP_SEENDELAYED 0x10 /**< skip users that have seen delayed joins. + */ +#define SKIP_NOTSEENDELAYED 0x20 /**< skip users that have not seen delayed + joins. */ + /* Send command to all users having a particular flag set */ extern void sendwallto_group_butone(struct Client *from, int type, Index: ircd/channel.c =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/channel.c,v retrieving revision 1.156 diff -b -u -d -r1.156 channel.c --- ircd/channel.c 6 Oct 2005 23:49:25 -0000 1.156 +++ ircd/channel.c 28 Oct 2005 14:59:18 -0000 @@ -3280,11 +3280,21 @@ SetUserParting(member); /* Send notification to channel */ - if (!(flags & (CHFL_ZOMBIE | CHFL_DELAYED))) - sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL, 0, - (flags & CHFL_BANNED || !jbuf->jb_comment) ? - ":%H" : "%H :%s", chan, jbuf->jb_comment); - else if (MyUser(jbuf->jb_source)) + if (!(flags & CHFL_ZOMBIE)) + sendcmdto_channel_butserv_butone + ( + jbuf->jb_source, CMD_PART, chan, NULL, + (flags & CHFL_DELAYED) ? SKIP_NOTSEENDELAYED : 0, + (flags & CHFL_BANNED || !jbuf->jb_comment) ? ":%H" : "%H :%s", chan, + jbuf->jb_comment + ); + + /* If the parting user hasn't seen their own part yet, send it now. */ + if ( + MyUser(jbuf->jb_source) && + ((flags & CHFL_ZOMBIE) || + ((flags & CHFL_DELAYED) && !HasSeenDelayed(member))) + ) sendcmdto_one(jbuf->jb_source, CMD_PART, jbuf->jb_source, (flags & CHFL_BANNED || !jbuf->jb_comment) ? ":%H" : "%H :%s", chan, jbuf->jb_comment); @@ -3320,16 +3330,27 @@ "%H %Tu", chan, chan->creationtime); } - if (!((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED))) { + if (!(flags & CHFL_VOICED_OR_OPPED)) { /* Send the notification to the channel */ - sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, 0, "%H", chan); + sendcmdto_channel_butserv_butone + (jbuf->jb_source, CMD_JOIN, chan, NULL, + (chan->mode.mode & MODE_DELJOINS) ? SKIP_NOTSEENDELAYED : 0, "%H", + chan); /* send an op, too, if needed */ if (flags & CHFL_CHANOP && (oplevel < MAXOPLEVEL || !MyUser(jbuf->jb_source))) - sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &his : jbuf->jb_source), - CMD_MODE, chan, NULL, 0, "%H +o %C", - chan, jbuf->jb_source); - } else if (MyUser(jbuf->jb_source)) + sendcmdto_channel_butserv_butone + ((chan->mode.apass[0] ? &his : jbuf->jb_source), + CMD_MODE, chan, NULL, + (chan->mode.mode & MODE_DELJOINS) ? SKIP_NOTSEENDELAYED : 0, + "%H +o %C", chan, jbuf->jb_source); + } + /* If the parting user hasn't seen their own part yet, send it now. */ + if ( + MyUser(jbuf->jb_source) && + ((flags & CHFL_VOICED_OR_OPPED) || + ((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_SEENDELAYED))) + ) sendcmdto_one(jbuf->jb_source, CMD_JOIN, jbuf->jb_source, ":%H", chan); } @@ -3414,11 +3435,33 @@ void RevealDelayedJoin(struct Membership *member) { ClearDelayedJoin(member); - sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, member->user, 0, ":%H", + sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, + member->user, SKIP_SEENDELAYED, ":%H", member->channel); CheckDelayedJoins(member->channel); } +void ShowClientAllDelayed(struct Client *client) +{ + struct Membership *member, *member2; + + for (member = cli_user(client)->channel; member; member=member->next_channel) + { + if (HasSeenDelayed(member) || + !(member->channel->mode.mode & (MODE_WASDELJOINS | MODE_DELJOINS))) + continue; + + SetSeenDelayed(member); + for (member2 = member->channel->members; member2; + member2=member2->next_member) + { + if (member2 == member || !IsDelayedJoin(member2)) + continue; + sendcmdto_one(member2->user, CMD_JOIN, client, ":%H", member->channel); + } + } +} + /* CheckDelayedJoins: checks and clear +d if necessary */ void CheckDelayedJoins(struct Channel *chan) Index: ircd/m_join.c =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/m_join.c,v retrieving revision 1.35 diff -b -u -d -r1.35 m_join.c --- ircd/m_join.c 6 Oct 2005 23:49:25 -0000 1.35 +++ ircd/m_join.c 28 Oct 2005 14:59:26 -0000 @@ -112,6 +112,7 @@ char *chanlist; char *name; char *keys; + int filter = NAMES_ALL|NAMES_EON; if (parc < 2 || *parv[1] == '\0') return need_more_params(sptr, "JOIN"); @@ -123,6 +124,9 @@ keys = parv[2]; /* remember where keys are */ + if (IsDeaf(sptr)) + filter |= NAMES_INCLUDEDEL; + for (name = ircd_strtok(&p, chanlist, ","); name; name = ircd_strtok(&p, 0, ",")) { char *key = 0; @@ -247,7 +251,9 @@ chptr->topic_time); } - do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */ + do_names(sptr, chptr, filter); /* send /names list */ + if (IsDeaf(sptr)) + SetSeenDelayed((cli_user(sptr))->channel); } joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */ Index: ircd/m_names.c =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/m_names.c,v retrieving revision 1.23 diff -b -u -d -r1.23 m_names.c --- ircd/m_names.c 6 Oct 2005 04:00:36 -0000 1.23 +++ ircd/m_names.c 28 Oct 2005 14:59:32 -0000 @@ -156,7 +156,8 @@ if (IsZombie(member) && member->user != sptr) continue; - if (IsDelayedJoin(member) && (member->user != sptr) && !(filter & NAMES_DEL)) + if (IsDelayedJoin(member) && (member->user != sptr) && + !(filter & (NAMES_DEL | NAMES_INCLUDEDEL))) continue; if ((!IsDelayedJoin(member) || (member->user == sptr)) && (filter & NAMES_DEL)) Index: ircd/s_user.c =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/s_user.c,v retrieving revision 1.100 diff -b -u -d -r1.100 s_user.c --- ircd/s_user.c 18 Oct 2005 03:20:53 -0000 1.100 +++ ircd/s_user.c 28 Oct 2005 15:00:04 -0000 @@ -1437,6 +1437,9 @@ hide_hostmask(sptr, FLAG_HIDDENHOST); send_umode_out(cptr, sptr, &setflags, prop); + if (MyUser(sptr) && !FlagHas(&setflags, FLAG_DEAF) && IsDeaf(sptr)) + ShowClientAllDelayed(sptr); + return 0; } Index: ircd/send.c =================================================================== RCS file: /cvsroot/undernet-ircu/ircu2.10/ircd/send.c,v retrieving revision 1.55 diff -b -u -d -r1.55 send.c --- ircd/send.c 16 Dec 2004 03:28:50 -0000 1.55 +++ ircd/send.c 28 Oct 2005 15:00:19 -0000 @@ -544,7 +544,9 @@ || IsZombie(member) || (skip & SKIP_DEAF && IsDeaf(member->user)) || (skip & SKIP_NONOPS && !IsChanOp(member)) - || (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member))) + || (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member)) + || (skip & SKIP_SEENDELAYED && HasSeenDelayed(member)) + || (skip & SKIP_NOTSEENDELAYED && !HasSeenDelayed(member))) continue; send_buffer(member->user, mb, 0); }
_______________________________________________ Coder-com mailing list Coder-com@undernet.org http://undernet.sbg.org/mailman/listinfo/coder-com