Skip to content

OF-3170: Implement basic rate limiting for new connections (C2S and S2S)#3127

Open
guusdk wants to merge 7 commits intoigniterealtime:mainfrom
guusdk:OF-3170_Rate-Limit-New-Connections
Open

OF-3170: Implement basic rate limiting for new connections (C2S and S2S)#3127
guusdk wants to merge 7 commits intoigniterealtime:mainfrom
guusdk:OF-3170_Rate-Limit-New-Connections

Conversation

@guusdk
Copy link
Copy Markdown
Member

@guusdk guusdk commented Jan 22, 2026

  • Introduce NewConnectionLimiterRegistry to track new connections per type.
  • Add per-group rate limiting: client-to-server (C2S) and server-to-server (S2S).
  • By default, rate limiting is disabled for both C2S and S2S.
  • Support dynamic updates via system properties for permits per second, max burst, and enabled flag.
  • Add optional logging for rejected connections with configurable suppression interval.
  • Ensure unsupported connection types receive unlimited limiters while still collecting metrics.

This lays the foundation for controlling the rate of new connections, without yet exposing admin console configuration or statistics.

@guusdk
Copy link
Copy Markdown
Member Author

guusdk commented Feb 12, 2026

I've now added exposure of rate-limiting statistics via Statistics API

Integrate rate-limiting counters into Openfire's Statistics API so they are automatically available via JMX and the Monitoring plugin.

This adds real-time, thread-safe statistics for rate limiters used for all connection types (eg: socket_c2s, socket_s2s), tracking accepted and rejected connection attempts. Metrics are incremented on every connection attempt, but reset after rate limit configuration changes.

Acceptance ratio is intentionally not exposed. Ratios would be derived from cumulative totals since the last rate-limiter reset, causing them to converge over time and potentially mislead users expecting a time-windowed value. Consumers can derive meaningful ratios themselves from the provided accepted and rejected counters.

@guusdk guusdk force-pushed the OF-3170_Rate-Limit-New-Connections branch 2 times, most recently from d903e5e to 20e1dd6 Compare March 6, 2026 16:19
@akrherz akrherz requested a review from Copilot March 6, 2026 20:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements a first iteration of connection-rate limiting for inbound connections in Openfire by introducing a shared token-bucket limiter per logical connection group (C2S, S2S), and wiring it into Netty (TCP), BOSH and WebSocket entry points while exposing basic metrics via the StatisticsManager/i18n bundles.

Changes:

  • Add a generic TokenBucketRateLimiter (with metrics) plus unit tests.
  • Add NewConnectionLimiterRegistry to manage shared limiters for C2S/S2S, dynamic reconfiguration via system properties, and optional rejection logging.
  • Enforce rate limiting on new connections for TCP (Netty handler), BOSH session creation, and WebSocket creation; add i18n strings and tests for the registry.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
xmppserver/src/main/java/org/jivesoftware/util/TokenBucketRateLimiter.java Adds synchronized token-bucket rate limiter with metrics and unlimited mode.
xmppserver/src/test/java/org/jivesoftware/util/TokenBucketRateLimiterTest.java Adds unit tests for token-bucket behavior and metrics.
xmppserver/src/main/java/org/jivesoftware/openfire/ratelimit/NewConnectionLimiterRegistry.java Adds shared limiter registry, system properties, rejection logging, and StatisticsManager integration.
xmppserver/src/test/java/org/jivesoftware/openfire/ratelimit/NewConnectionLimiterRegistryTest.java Tests limiter sharing, unsupported types, and dynamic property-driven updates.
xmppserver/src/main/java/org/jivesoftware/openfire/nio/NewConnectionRateLimitHandler.java Adds Netty handler that closes channels immediately when rate limited.
xmppserver/src/main/java/org/jivesoftware/openfire/spi/NettyServerInitializer.java Inserts rate-limit handler at the start of the Netty child pipeline.
xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpBindServlet.java Applies limiter to BOSH new-session creation path.
xmppserver/src/main/java/org/jivesoftware/openfire/websocket/OpenfireWebSocketServlet.java Applies limiter to WebSocket connection creation path.
i18n/src/main/resources/openfire_i18n.properties Adds i18n for new system properties and rate-limit stats (EN).
i18n/src/main/resources/openfire_i18n_nl.properties Adds i18n for new system properties and rate-limit stats (NL).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@guusdk guusdk force-pushed the OF-3170_Rate-Limit-New-Connections branch 2 times, most recently from 23953f1 to 7f8def7 Compare March 6, 2026 21:12
@akrherz akrherz added this to the 5.1.0 milestone Mar 12, 2026
@guusdk guusdk force-pushed the OF-3170_Rate-Limit-New-Connections branch 2 times, most recently from f5fb26f to fef3c46 Compare March 26, 2026 11:41
@guusdk guusdk requested a review from Copilot March 26, 2026 11:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@guusdk guusdk force-pushed the OF-3170_Rate-Limit-New-Connections branch 2 times, most recently from 229e61e to ed2c02a Compare March 26, 2026 12:05
@guusdk guusdk requested a review from Copilot March 26, 2026 12:05
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

guusdk added 6 commits March 26, 2026 13:17
- Introduce NewConnectionLimiterRegistry to track new connections per type.
- Add per-group rate limiting: client-to-server (C2S) and server-to-server (S2S).
- By default, rate limiting is disabled for both C2S and S2S.
- Support dynamic updates via system properties for permits per second, max burst, and enabled flag.
- Add optional logging for rejected connections with configurable suppression interval.
- Ensure unsupported connection types receive unlimited limiters while still collecting metrics.

This lays the foundation for controlling the rate of new connections, without yet exposing admin console configuration or statistics.
Integrate rate-limiting counters into Openfire's Statistics API so they are automatically available via JMX and the Monitoring plugin.

This adds real-time, thread-safe statistics for rate limiters used for all connection types (eg: socket_c2s, socket_s2s), tracking accepted and rejected connection attempts. Metrics are incremented on every connection attempt, but reset after rate limit configuration changes.

Acceptance ratio is intentionally not exposed. Ratios would be derived from cumulative totals since the last rate-limiter reset, causing them to converge over time and potentially mislead users expecting a time-windowed value. Consumers can derive meaningful ratios themselves from the provided accepted and rejected counters.
Add NewConnectionRateLimitHandler, a @sharable ChannelInboundHandlerAdapter that intercepts channelActive at the head of the child channel pipeline.

Rejected connections are now closed before any downstream handler runs, avoiding TLS negotiation, XML parser allocation, and session scaffolding for connections that would be discarded anyway.
…kenBucketRateLimiter

Replace AtomicLong/LongAdder with plain longs guarded by synchronized methods, fixing a race condition between refill and consume.

Fix overflow in refillIfNeeded for large elapsed times and capacity values.

Fix unlimited() instances eventually exhausting by introducing a dedicated code path that bypasses token accounting.

Expand test coverage accordingly.
Preserve fractional refill time in TokenBucketRateLimiter by carrying sub-token remainder across refill cycles, instead of discarding it when whole tokens are added.
Replace Thread.sleep-based timing in unit tests with the new FakeNanoClock to make tests deterministic, faster, and less flaky.
@guusdk guusdk force-pushed the OF-3170_Rate-Limit-New-Connections branch from ed2c02a to 3c566f8 Compare March 26, 2026 12:17
Expose new-connection rate limiting settings on the C2S and S2S connection settings pages.
@guusdk guusdk changed the title OF-3171: Implement basic rate limiting for new connections (C2S and S2S) OF-3170: Implement basic rate limiting for new connections (C2S and S2S) Mar 26, 2026
@guusdk
Copy link
Copy Markdown
Member Author

guusdk commented Mar 26, 2026

I've now added an implementation for the last subtask: an admin console interface to control rate limiting.

A new config block has been added on the preexisting pages for client-to-server and server-to-server connectivity. The client-to-server configuration is also re-used for the web bindings, which may be slightly confusing - but I couldn't think of an easy way to make this less confusing.

image image

@guusdk guusdk requested a review from Copilot March 26, 2026 15:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants