From db5ce1caa14de28c6b333ac3e1484ed068dfd236 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Sat, 4 Jul 2009 22:46:00 +0000 Subject: [PATCH] Attempt to fix SF bug #2568366 (sending JOIN before hitting a target limit). git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1913 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 17 +++++++++++++++++ include/channel.h | 1 + include/gline.h | 4 ++-- ircd/channel.c | 9 +++++++++ ircd/ircd_relay.c | 6 ++++-- ircd/m_wallchops.c | 3 ++- ircd/m_wallvoices.c | 3 ++- ircd/s_user.c | 8 ++++---- tests/ircd.conf | 1 + 9 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffb41e1..67592a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2009-07-04 Michael Poole + + * include/channel.h (RevealDelayedJoinIfNeeded): Declare. + + * ircd/channel.c (RevealDelayedJoinIfNeeded): Implement. + + * ircd/ircd_relay.c (relay_channel_message): Only reveal the user + if he passes the check_target_limit() test. + (relay_channel_notice): Likewise. + + * ircd/m_wallchops.c (m_wallchops): Likewise. + + * ircd/m_wallvoices.c (m_wallvoices): Likewise. + + * ircd/s_user.c (check_target_limit): Micro-optimize to only check + the user's channel list for invites if we are about to deny it. + 2009-03-25 Michael Poole * ircd/ircd.c (main): Unconditionally set +6 flag on self. diff --git a/include/channel.h b/include/channel.h index 318cf4c..7cafdf8 100644 --- a/include/channel.h +++ b/include/channel.h @@ -405,6 +405,7 @@ extern char *pretty_mask(char *mask); extern void del_invite(struct Client *cptr, struct Channel *chptr); extern void list_set_default(void); /* this belongs elsewhere! */ +extern void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr); extern void RevealDelayedJoin(struct Membership *member); extern void CheckDelayedJoins(struct Channel *chan); diff --git a/include/gline.h b/include/gline.h index 44798a6..f79b801 100644 --- a/include/gline.h +++ b/include/gline.h @@ -50,13 +50,13 @@ struct Gline { struct Gline *gl_next; /**< Next G-line in linked list. */ struct Gline**gl_prev_p; /**< Previous pointer to this G-line. */ char *gl_user; /**< Username mask (or channel/realname mask). */ - char *gl_host; /**< Host prtion of mask. */ + char *gl_host; /**< Host portion of mask. */ char *gl_reason; /**< Reason for G-line. */ time_t gl_expire; /**< Expiration timestamp. */ time_t gl_lastmod; /**< Last modification timestamp. */ time_t gl_lifetime; /**< Record expiration timestamp. */ struct irc_in_addr gl_addr; /**< IP address (for IP-based G-lines). */ - unsigned char gl_bits; /**< Usable bits in gl_addr. */ + unsigned char gl_bits; /**< Bits in gl_addr used in the mask. */ unsigned int gl_flags; /**< G-line status flags. */ enum GlineLocalState gl_state;/**< G-line local state. */ }; diff --git a/ircd/channel.c b/ircd/channel.c index 471face..ee5a887 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -3636,3 +3636,12 @@ void CheckDelayedJoins(struct Channel *chan) "%H -d", chan); } } + +/** Send a join for the user if (s)he is a hidden member of the channel. + */ +void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr) +{ + struct Membership *member = find_member_link(chptr, sptr); + if (member && IsDelayedJoin(member)) + RevealDelayedJoin(member); +} diff --git a/ircd/ircd_relay.c b/ircd/ircd_relay.c index 0cb7e80..b7a751d 100644 --- a/ircd/ircd_relay.c +++ b/ircd/ircd_relay.c @@ -97,7 +97,7 @@ void relay_channel_message(struct Client* sptr, const char* name, const char* te /* * This first: Almost never a server/service */ - if (!client_can_send_to_channel(sptr, chptr, 1)) { + if (!client_can_send_to_channel(sptr, chptr, 0)) { send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); return; } @@ -105,6 +105,7 @@ void relay_channel_message(struct Client* sptr, const char* name, const char* te check_target_limit(sptr, chptr, chptr->chname, 0)) return; + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr), SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); } @@ -127,13 +128,14 @@ void relay_channel_notice(struct Client* sptr, const char* name, const char* tex /* * This first: Almost never a server/service */ - if (!client_can_send_to_channel(sptr, chptr, 1)) + if (!client_can_send_to_channel(sptr, chptr, 0)) return; if ((chptr->mode.mode & MODE_NOPRIVMSGS) && check_target_limit(sptr, chptr, chptr->chname, 0)) return; + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr), SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); } diff --git a/ircd/m_wallchops.c b/ircd/m_wallchops.c index 5b60959..c575351 100644 --- a/ircd/m_wallchops.c +++ b/ircd/m_wallchops.c @@ -115,10 +115,11 @@ int m_wallchops(struct Client* cptr, struct Client* sptr, int parc, char* parv[] return send_reply(sptr, ERR_NOTEXTTOSEND); if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { - if (client_can_send_to_channel(sptr, chptr, 1)) { + if (client_can_send_to_channel(sptr, chptr, 0)) { if ((chptr->mode.mode & MODE_NOPRIVMSGS) && check_target_limit(sptr, chptr, chptr->chname, 0)) return 0; + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_WALLCHOPS, chptr, cptr, SKIP_DEAF | SKIP_BURST | SKIP_NONOPS, "%H :@ %s", chptr, parv[parc - 1]); diff --git a/ircd/m_wallvoices.c b/ircd/m_wallvoices.c index c5d0461..a0dcd0e 100644 --- a/ircd/m_wallvoices.c +++ b/ircd/m_wallvoices.c @@ -114,10 +114,11 @@ int m_wallvoices(struct Client* cptr, struct Client* sptr, int parc, char* parv[ return send_reply(sptr, ERR_NOTEXTTOSEND); if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { - if (client_can_send_to_channel(sptr, chptr, 1)) { + if (client_can_send_to_channel(sptr, chptr, 0)) { if ((chptr->mode.mode & MODE_NOPRIVMSGS) && check_target_limit(sptr, chptr, chptr->chname, 0)) return 0; + RevealDelayedJoinIfNeeded(sptr, chptr); sendcmdto_channel_butone(sptr, CMD_WALLVOICES, chptr, cptr, SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES, "%H :+ %s", chptr, parv[parc - 1]); diff --git a/ircd/s_user.c b/ircd/s_user.c index 1fdfcbf..a989a06 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -702,10 +702,6 @@ int check_target_limit(struct Client *sptr, void *target, const char *name, assert(cli_local(sptr)); targets = cli_targets(sptr); - /* If user is invited to channel, give him/her a free target */ - if (IsChannelName(name) && IsInvited(sptr, target)) - return 0; - /* * Same target as last time? */ @@ -723,6 +719,10 @@ int check_target_limit(struct Client *sptr, void *target, const char *name, */ if (!created) { if (CurrentTime < cli_nexttarget(sptr)) { + /* If user is invited to channel, give him/her a free target */ + if (IsChannelName(name) && IsInvited(sptr, target)) + return 0; + if (cli_nexttarget(sptr) - CurrentTime < TARGET_DELAY + 8) { /* * No server flooding diff --git a/tests/ircd.conf b/tests/ircd.conf index e58c936..26f2800 100644 --- a/tests/ircd.conf +++ b/tests/ircd.conf @@ -39,4 +39,5 @@ Features { "HUB" = "TRUE"; "CONFIG_OPERCMDS" = "TRUE"; "CHANNELLEN" = "50"; + "MAXCHANNELSPERUSER" = "20"; }; -- 2.20.1