This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Undernet IRC Server Source Code.".
The branch, antiflood has been created
at 8864617996e0bd38a44067073b36e0382aedacc2 (commit)
- Log -----------------------------------------------------------------
commit 8864617996e0bd38a44067073b36e0382aedacc2
Author: Michael Poole <[email protected]>
Date: Wed Jan 25 22:25:38 2012 -0500
Minor cleanups for the channel anti-flood changes.
include/channel.h (STATUS_FLOOD_NOTICED): Move closer to its macros.
(SetFloodNoticed): Fix typo.
(NOTICE): Delete this.
(flood_attack_channel): Update name of the first parameter.
ircd/channel.c (client_can_send_to_channel): Flatten a nested if.
(flood_attack_channel): Update parameter name.
ircd/ircd_relay.c (relay_channel_message): Remove dead store to perm.
(relay_channel_message): Likewise.
diff --git a/include/channel.h b/include/channel.h
index 4c4c663..c35a4cd 100644
--- a/include/channel.h
+++ b/include/channel.h
@@ -146,8 +146,6 @@ typedef enum ChannelGetType {
#define MODE_ADD 0x40000000
#define MODE_DEL 0x20000000
-#define STATUS_FLOOD_NOTICED 0x10000000 /* XXX is this really free ? */
-
/* used in ListingArgs.flags */
#define LISTARG_TOPICLIMITS 0x0001
@@ -234,15 +232,12 @@ struct Membership {
#define ClearBurstJoined(x) ((x)->status &= ~CHFL_BURST_JOINED)
#define ClearDelayedJoin(x) ((x)->status &= ~CHFL_DELAYED)
-/* Channel flood control -Dianora */
-/* Sort later if needed */
+/* Channel flood control */
+#define STATUS_FLOOD_NOTICED 0x10000000
#define IsSetFloodNoticed(x) ((x)->status & STATUS_FLOOD_NOTICED)
-#define SetFloodNoticed(x) ((x)->status != STATUS_FLOOD_NOTICED)
+#define SetFloodNoticed(x) ((x)->status |= STATUS_FLOOD_NOTICED)
#define ClearFloodNoticed(x) ((x)->status &= ~STATUS_FLOOD_NOTICED)
-/* XXX NOTICE might not belong in channel.h ;-) */
-#define NOTICE 1
-
/** Mode information for a channel */
struct Mode {
unsigned int mode;
@@ -285,7 +280,7 @@ struct Channel {
struct SLink* invites; /**< List of invites on this channel */
struct Ban* banlist; /**< List of bans on this channel */
struct Mode mode; /**< This channels mode */
- int status;
+ int status; /**< Anti-flood status */
char topic[TOPICLEN + 1]; /**< Channels topic */
char topic_nick[NICKLEN + 1]; /**< Nick of the person who set
* The topic
@@ -464,6 +459,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);
-int flood_attack_channel(int p_or_n, struct Client *source_p,
+int flood_attack_channel(int is_notice, struct Client *source_p,
struct Channel *chptr);
#endif /* INCLUDED_channel_h */
diff --git a/ircd/channel.c b/ircd/channel.c
index ca44469..31bfa29 100644
--- a/ircd/channel.c
+++ b/ircd/channel.c
@@ -763,12 +763,10 @@ int client_can_send_to_channel(struct Client *cptr,
struct Channel *chptr, int r
if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) ||
((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr)))
return 0;
- else {
- if (find_ban(cptr, chptr->banlist))
- return 0;
- else
- return CHFL_CAN_SEND;
- }
+ else if (find_ban(cptr, chptr->banlist))
+ return 0;
+ else
+ return CHFL_CAN_SEND;
}
return member_can_send_to_channel(member, reveal);
}
@@ -3663,12 +3661,13 @@ void RevealDelayedJoinIfNeeded(struct Client *sptr,
struct Channel *chptr)
* Side effects: check for flood attack on target chptr
* modified from Hybrid by Dianora
*
- * @param[in] flag 0 if PRIVMSG 1 if NOTICE. RFC says NOTICE must not auto
reply
- * @param[in] source_p source Client
+ * @param[in] is_notice 0 if PRIVMSG, 1 if NOTICE (RFC says NOTICE
+ * must not auto reply)
+ * @param[in] source_p source Client
* @param[in] pointer to target channel
* @param[out] 1 if target is under flood attack
*/
-int flood_attack_channel(int p_or_n, struct Client *source_p,
+int flood_attack_channel(int is_notice, struct Client *source_p,
struct Channel *chptr)
{
int delta;
@@ -3701,7 +3700,7 @@ int flood_attack_channel(int p_or_n, struct Client
*source_p,
/* Add a bit of penalty */
chptr->received_number_of_privmsgs += 2;
}
- if (MyUser(source_p) && (p_or_n != NOTICE))
+ if (MyUser(source_p) && !is_notice)
sendcmdto_one(&me, CMD_NOTICE, source_p,
"%s :*** Message to %s throttled due to flooding", cli_name(source_p),
chptr->chname);
diff --git a/ircd/ircd_relay.c b/ircd/ircd_relay.c
index 1da202c..07d4a7a 100644
--- a/ircd/ircd_relay.c
+++ b/ircd/ircd_relay.c
@@ -86,7 +86,8 @@
void relay_channel_message(struct Client* sptr, const char* name, const char*
text)
{
struct Channel* chptr;
- int perm=0;
+ int perm;
+
assert(0 != sptr);
assert(0 != name);
assert(0 != text);
@@ -126,7 +127,8 @@ void relay_channel_message(struct Client* sptr, const char*
name, const char* te
void relay_channel_notice(struct Client* sptr, const char* name, const char*
text)
{
struct Channel* chptr;
- int perm=0;
+ int perm;
+
assert(0 != sptr);
assert(0 != name);
assert(0 != text);
commit b714bd2b740b13c11a1dd0c96afe84ccb24cf740
Author: Michael Poole <[email protected]>
Date: Wed Jan 25 22:24:17 2012 -0500
- First pass at adding anti channel flood code to ircu
[Code by Diane Bruce <[email protected]>. Conflicts resolved, with one tweak,
by Entrope: Reorder the test in ircd_relay.c to change less code. The
old change conflicted with delayed join handling.]
Conflicts:
include/ircd_features.h
ircd/channel.c
ircd/ircd_features.c
ircd/ircd_relay.c
diff --git a/include/channel.h b/include/channel.h
index 7cafdf8..4c4c663 100644
--- a/include/channel.h
+++ b/include/channel.h
@@ -146,6 +146,8 @@ typedef enum ChannelGetType {
#define MODE_ADD 0x40000000
#define MODE_DEL 0x20000000
+#define STATUS_FLOOD_NOTICED 0x10000000 /* XXX is this really free ? */
+
/* used in ListingArgs.flags */
#define LISTARG_TOPICLIMITS 0x0001
@@ -232,6 +234,15 @@ struct Membership {
#define ClearBurstJoined(x) ((x)->status &= ~CHFL_BURST_JOINED)
#define ClearDelayedJoin(x) ((x)->status &= ~CHFL_DELAYED)
+/* Channel flood control -Dianora */
+/* Sort later if needed */
+#define IsSetFloodNoticed(x) ((x)->status & STATUS_FLOOD_NOTICED)
+#define SetFloodNoticed(x) ((x)->status != STATUS_FLOOD_NOTICED)
+#define ClearFloodNoticed(x) ((x)->status &= ~STATUS_FLOOD_NOTICED)
+
+/* XXX NOTICE might not belong in channel.h ;-) */
+#define NOTICE 1
+
/** Mode information for a channel */
struct Mode {
unsigned int mode;
@@ -274,10 +285,13 @@ struct Channel {
struct SLink* invites; /**< List of invites on this channel */
struct Ban* banlist; /**< List of bans on this channel */
struct Mode mode; /**< This channels mode */
+ int status;
char topic[TOPICLEN + 1]; /**< Channels topic */
char topic_nick[NICKLEN + 1]; /**< Nick of the person who set
* The topic
*/
+ time_t first_received_message_time; /**< channel flood control */
+ int received_number_of_privmsgs; /**< number of possible flooding
messages */
char chname[1]; /**< Dynamically allocated string of
the
* channel name
*/
@@ -450,4 +464,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);
+int flood_attack_channel(int p_or_n, struct Client *source_p,
+ struct Channel *chptr);
#endif /* INCLUDED_channel_h */
diff --git a/include/ircd_features.h b/include/ircd_features.h
index 42c54ac..a9a2e33 100644
--- a/include/ircd_features.h
+++ b/include/ircd_features.h
@@ -156,6 +156,7 @@ enum Feature {
FEAT_NETWORK,
FEAT_URL_CLIENTS,
FEAT_URLREG,
+ FEAT_CHANNEL_FLOOD_COUNT,
FEAT_LAST_F
};
diff --git a/ircd/channel.c b/ircd/channel.c
index 9c0f192..ca44469 100644
--- a/ircd/channel.c
+++ b/ircd/channel.c
@@ -623,7 +623,7 @@ int is_chan_op(struct Client *cptr, struct Channel *chptr)
* @param chptr The channel to check.
*
* @returns True if the client (cptr) is a zombie on the channel (chptr),
- * False otherwise.
+ * False otherwise.
*
* @see \ref zombie
*/
@@ -640,7 +640,7 @@ int is_zombie(struct Client *cptr, struct Channel *chptr)
/** Returns if a user has voice on a channel.
*
- * @param cptr The client
+ * @param cptr The client
* @param chptr The channel
*
* @returns True if the client (cptr) is voiced on (chptr) and is not a zombie.
@@ -657,6 +657,9 @@ int has_voice(struct Client* cptr, struct Channel* chptr)
return 0;
}
+/* XXX Maybe move this into channel.h ? - Dianora */
+#define CHFL_CAN_SEND 0x800000
+
/** Can this member send to a channel
*
* A user can speak on a channel iff:
@@ -673,9 +676,11 @@ int has_voice(struct Client* cptr, struct Channel* chptr)
*
* @param member The membership of the user
* @param reveal If true, the user will be "revealed" on a delayed
- * joined channel.
+ * joined channel.
*
- * @returns True if the client can speak on the channel.
+ * @returns CHFL_CAN_SEND or CHFL_VOICED_OR_OPPED if
+ * the client can speak on the channel.
+ * 0 if the client cannot speak on the channel.
*/
int member_can_send_to_channel(struct Membership* member, int reveal)
{
@@ -689,7 +694,7 @@ int member_can_send_to_channel(struct Membership* member,
int reveal)
{
if (IsDelayedJoin(member) && reveal)
RevealDelayedJoin(member);
- return 1;
+ return CHFL_CAN_SEND;
}
/* Discourage using the Apass to get op. They should use the Upass. */
@@ -698,7 +703,7 @@ int member_can_send_to_channel(struct Membership* member,
int reveal)
/* If you have voice or ops, you can speak. */
if (IsVoicedOrOpped(member))
- return 1;
+ return CHFL_VOICED_OR_OPPED;
/*
* If it's moderated, and you aren't a privileged user, you can't
@@ -718,9 +723,10 @@ int member_can_send_to_channel(struct Membership* member,
int reveal)
if (IsDelayedJoin(member) && reveal)
RevealDelayedJoin(member);
- return 1;
+ return CHFL_CAN_SEND;
}
+
/** Check if a client can send to a channel.
*
* Has the added check over member_can_send_to_channel() of servers can
@@ -731,11 +737,12 @@ int member_can_send_to_channel(struct Membership* member,
int reveal)
* @param reveal If the user should be revealed (see
* member_can_send_to_channel())
*
- * @returns true if the client is allowed to speak on the channel, false
- * otherwise
+ * @returns CHFL_CAN_SEND
+ * if the client is allowed to speak on the channel, 0 otherwise
*
* @see member_can_send_to_channel()
*/
+
int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int
reveal)
{
struct Membership *member;
@@ -744,7 +751,7 @@ int client_can_send_to_channel(struct Client *cptr, struct
Channel *chptr, int r
* Servers can always speak on channels.
*/
if (IsServer(cptr))
- return 1;
+ return CHFL_CAN_SEND;
member = find_channel_member(cptr, chptr);
@@ -756,8 +763,12 @@ int client_can_send_to_channel(struct Client *cptr, struct
Channel *chptr, int r
if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) ||
((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr)))
return 0;
- else
- return !find_ban(cptr, chptr->banlist);
+ else {
+ if (find_ban(cptr, chptr->banlist))
+ return 0;
+ else
+ return CHFL_CAN_SEND;
+ }
}
return member_can_send_to_channel(member, reveal);
}
@@ -3647,3 +3658,58 @@ void RevealDelayedJoinIfNeeded(struct Client *sptr,
struct Channel *chptr)
if (member && IsDelayedJoin(member))
RevealDelayedJoin(member);
}
+
+/** Check whether a channel is being flooded or not
+ * Side effects: check for flood attack on target chptr
+ * modified from Hybrid by Dianora
+ *
+ * @param[in] flag 0 if PRIVMSG 1 if NOTICE. RFC says NOTICE must not auto
reply
+ * @param[in] source_p source Client
+ * @param[in] pointer to target channel
+ * @param[out] 1 if target is under flood attack
+ */
+int flood_attack_channel(int p_or_n, struct Client *source_p,
+ struct Channel *chptr)
+{
+ int delta;
+
+ if (feature_int(FEAT_CHANNEL_FLOOD_COUNT) != 0)
+ {
+ if ((chptr->first_received_message_time + 1) < CurrentTime)
+ {
+ delta = CurrentTime - chptr->first_received_message_time;
+ chptr->received_number_of_privmsgs -= delta;
+ chptr->first_received_message_time = CurrentTime;
+ if (chptr->received_number_of_privmsgs <= 0)
+ {
+ chptr->received_number_of_privmsgs = 0;
+ ClearFloodNoticed(chptr);
+ }
+ }
+
+ if ((chptr->received_number_of_privmsgs >=
+ feature_int(FEAT_CHANNEL_FLOOD_COUNT))
+ || IsSetFloodNoticed(chptr))
+ {
+ if (!IsSetFloodNoticed(chptr))
+ {
+ sendto_opmask_butone(0, SNO_OLDSNO,
+ "Possible Flooder %s target: %s",
+ cli_name(source_p), chptr->chname);
+ SetFloodNoticed(chptr);
+
+ /* Add a bit of penalty */
+ chptr->received_number_of_privmsgs += 2;
+ }
+ if (MyUser(source_p) && (p_or_n != NOTICE))
+ sendcmdto_one(&me, CMD_NOTICE, source_p,
+ "%s :*** Message to %s throttled due to flooding", cli_name(source_p),
+ chptr->chname);
+ return(1);
+ }
+ else
+ chptr->received_number_of_privmsgs++;
+ }
+
+ return(0);
+}
diff --git a/ircd/ircd_features.c b/ircd/ircd_features.c
index 6d64f89..715d11c 100644
--- a/ircd/ircd_features.c
+++ b/ircd/ircd_features.c
@@ -421,6 +421,7 @@ static struct FeatureDesc {
F_S(NETWORK, 0, "UnderNet", 0),
F_S(URL_CLIENTS, 0, "ftp://ftp.undernet.org/pub/irc/clients", 0),
F_S(URLREG, 0, "http://cservice.undernet.org/live/", 0),
+ F_I(CHANNEL_FLOOD_COUNT, 0, 3, 0),
#undef F_S
#undef F_B
diff --git a/ircd/ircd_relay.c b/ircd/ircd_relay.c
index b7a751d..1da202c 100644
--- a/ircd/ircd_relay.c
+++ b/ircd/ircd_relay.c
@@ -86,6 +86,7 @@
void relay_channel_message(struct Client* sptr, const char* name, const char*
text)
{
struct Channel* chptr;
+ int perm=0;
assert(0 != sptr);
assert(0 != name);
assert(0 != text);
@@ -97,7 +98,9 @@ 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, 0)) {
+ perm = client_can_send_to_channel(sptr, chptr, 1);
+
+ if (perm == 0) {
send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
return;
}
@@ -105,6 +108,10 @@ void relay_channel_message(struct Client* sptr, const
char* name, const char* te
check_target_limit(sptr, chptr, chptr->chname, 0))
return;
+ /* Chanops and Voiced get a free pass */
+ if (((perm & CHFL_VOICED_OR_OPPED) == 0)
+ && flood_attack_channel(0, sptr, chptr))
+ return;
RevealDelayedJoinIfNeeded(sptr, chptr);
sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr),
SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text);
@@ -119,6 +126,7 @@ void relay_channel_message(struct Client* sptr, const char*
name, const char* te
void relay_channel_notice(struct Client* sptr, const char* name, const char*
text)
{
struct Channel* chptr;
+ int perm=0;
assert(0 != sptr);
assert(0 != name);
assert(0 != text);
@@ -128,13 +136,19 @@ 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, 0))
+ perm = client_can_send_to_channel(sptr, chptr, 1);
+
+ if (perm == 0)
return;
if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
check_target_limit(sptr, chptr, chptr->chname, 0))
return;
+ /* Chanops and Voiced get a free pass */
+ if (((perm & CHFL_VOICED_OR_OPPED) == 0)
+ && flood_attack_channel(1, sptr, chptr))
+ return;
RevealDelayedJoinIfNeeded(sptr, chptr);
sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr),
SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text);
-----------------------------------------------------------------------
hooks/post-receive
--
Undernet IRC Server Source Code.
_______________________________________________
Patches mailing list
[email protected]
http://undernet.sbg.org/mailman/listinfo/patches