Implement penalty-based IRC flood protection (RFC 2813 §5.8)#284
Open
kofany wants to merge 4 commits intoaatxe:developfrom
Open
Implement penalty-based IRC flood protection (RFC 2813 §5.8)#284kofany wants to merge 4 commits intoaatxe:developfrom
kofany wants to merge 4 commits intoaatxe:developfrom
Conversation
Add command-aware flood throttling modeled after irssi and IRCd (RFC 2813 penalty model). Each outgoing command incurs a penalty cost that mirrors the server's own flood detection: PRIVMSG/JOIN/NICK = 2000ms, WHO/WHOIS/ LIST = 4000ms, PONG/QUIT/CAP = 0ms. When accumulated penalty exceeds a configurable threshold (default 10s), outgoing messages are delayed until the penalty drains below the threshold at real-time rate. New config field: flood_penalty_threshold (milliseconds, default 10000, set to 0 to disable). Deprecates the unimplemented burst_window_length and max_messages_in_burst fields. Closes aatxe#190
Add message-length base cost: (1 + bytes/100) * 1000ms per message, matching the server's own flood calculation. Fix per-command penalties to closely mirror irc2.11 reference implementation: - WHO/NAMES/LIST without args: 10s (was 4s) - WHO/NAMES/LIST with args: 2s (was 4s) - NICK: 3s (was 2s) - PART: 4s (was 2s) - WHOIS/WHOWAS: 3s (was 4s) - INFO/MOTD/USERS: 5s (was 4s) - PRIVMSG/NOTICE: 2s (unchanged) - PONG/QUIT/CAP: 0s (unchanged, client-side exemption) Without the length factor, rapid sends of long messages would trigger the server's Excess Flood detection despite client-side throttling.
start_send only buffers into the codec — without poll_flush the data never reaches the TCP socket. When many messages are delayed by the penalty system, they accumulate in the codec buffer and burst all at once when the stream goes idle, triggering Excess Flood on the IRCd. Add poll_flush in two places: 1. After sending a delayed-buffered message — ensures it hits TCP before we loop back for more. 2. Before returning Pending for a new delay — ensures any messages start_send'd earlier in this poll cycle are flushed before sleeping. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 12 unit tests covering command_penalty(), length_penalty(), and flood_penalty_threshold config defaults. Update repeater example to use flood_penalty_threshold instead of deprecated burst fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds penalty-based outgoing message throttling modeled after the IRCd flood detection formula (RFC 2813 §5.8), replacing the unimplemented
burst_window_length/max_messages_in_burstconfig fields.(1 + message_bytes / 100) * 1000ms + command_penalty_ms, matching the server-side calculation. Penalty drains in real-time at 1ms/1ms elapsed.flood_penalty_thresholdconfig field (default 10,000ms / 10s). When accumulated penalty exceeds the threshold, messages are delayed. Set to0to disable.start_sendonly buffers into the codec — messages accumulate across delay cycles and burst on idle, causing Excess Flood disconnects.burst_window_lengthandmax_messages_in_burstmarked#[deprecated]with guidance to useflood_penalty_threshold.command_penalty(),length_penalty(), and config defaults.repeater.rsmigrated from deprecated fields toflood_penalty_threshold.Commits
9257dff— Implement penalty-based IRC flood protectionb02e137— Improve flood penalty to match IRCd formula (RFC 2813 §5.8)2d996b1— Fix Excess Flood: flush each message to TCP after penalty delayfee0838— Add unit tests for flood penalty and update deprecated exampleTest plan
cargo test --lib— 79 tests pass (67 existing + 12 new)cargo fmt --check— cleancargo clippy --all-targets --all-features— no new warnings