Skip to content

feat: rate limit inbound streams per protocol per connection#3446

Draft
paschal533 wants to merge 2 commits intolibp2p:mainfrom
paschal533:feat/inbound-stream-rate-limit
Draft

feat: rate limit inbound streams per protocol per connection#3446
paschal533 wants to merge 2 commits intolibp2p:mainfrom
paschal533:feat/inbound-stream-rate-limit

Conversation

@paschal533
Copy link
Copy Markdown
Contributor

@paschal533 paschal533 commented Apr 9, 2026

Problem

As raised in #2093, there's currently no way to rate limit inbound streams per protocol per connection. The existing maxInboundStreams only caps concurrent open streams, a malicious peer can still spam a protocol like identify/push by rapidly opening and closing streams, burning bandwidth and CPU on the receiving end without ever hitting the concurrent limit.

Fix

Adds an optional inboundStreamRateLimit field to StreamHandlerOptions:

await libp2p.handle('/my-protocol/1.0.0', handler, {
  inboundStreamRateLimit: { count: 5, interval: 10_000 }
})

This uses a fixed-window counter per protocol per connection. When a peer opens more than count streams within interval ms, the excess streams are aborted with InboundStreamRateLimitError before they reach the handler.

The counter resets automatically after the window expires, so legitimate traffic is unaffected after the window rolls over.

Changes

  • packages/interface/src/stream-handler.ts - added inboundStreamRateLimit?: { count, interval } to StreamHandlerOptions
  • packages/interface/src/errors.ts - added InboundStreamRateLimitError
  • packages/libp2p/src/connection.ts - added per-protocol fixed-window tracking in onIncomingStream, checked after the existing maxInboundStreams guard
  • packages/libp2p/test/connection/index.spec.ts - 4 new tests

Tests

  • streams within the limit are allowed through
  • the (count+1)th stream within the window is aborted
  • counter resets after the interval expires and new streams are allowed again
  • rate limits per protocol are independent of each other
  • protocols with no inboundStreamRateLimit configured are unaffected

Notes

This PR only adds the mechanism to the core. Built-in protocols like identify/push (the original motivation in #1469/#2093) would need a follow-up in protocol-identify to wire up sensible defaults via their init options. Happy to do that as a follow-up once this gets feedback.

Closes #2093

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.

feat: rate limit inbound streams per protocol per connection

1 participant