Skip to content

Conversation

@sirtimid
Copy link
Contributor

@sirtimid sirtimid commented Jan 26, 2026

Closes #661

Summary

  • Add sliding window rate limiting to protect against flooding attacks
  • Message rate limiting: 100 messages/second per peer (configurable via maxMessagesPerSecond)
  • Connection attempt rate limiting: 10 attempts/minute per peer (configurable via maxConnectionAttemptsPerMinute)

Implementation Details

  • New SlidingWindowRateLimiter class with automatic pruning of old events
  • Rate checks integrated into sendRemoteMessage before sending
  • Connection rate checks before dialing new connections
  • Rate limiter state cleaned up when peers become stale or transport stops
  • Throws ResourceLimitError when limits are exceeded

Test plan

  • All 1665 tests pass
  • Lint passes
  • New test file with 28 tests for rate limiter

Depends on

🤖 Generated with Claude Code


Note

Implements flow-control and restructures transport for reliability and maintainability.

  • Add sliding-window rate limiting (per-peer): DEFAULT_MESSAGE_RATE_LIMIT (1s window) and DEFAULT_CONNECTION_RATE_LIMIT (1m window); expose maxMessagesPerSecond and maxConnectionAttemptsPerMinute options; enforce in sendRemoteMessage
  • Refactor transport into modules: channel-utils (error logging, write timeout), constants, validators (message size/connection limit), peer-state-manager (peer tracking, stale cleanup), reconnection-lifecycle (orchestration); integrate into transport.ts
  • Kernel store: add cleanupOrphanMessages and invoke during RemoteHandle recovery; tests updated to verify cleanup and crash-repair paths
  • Extensive unit tests for new modules (rate limiter, peer state, reconnection lifecycle, validators, channel utils)
  • CI: split coverage publish into reusable workflow; post coverage on PRs and publish HTML on main; adjust Vitest coverage reporters

Written by Cursor Bugbot for commit 50bb648. This will update automatically on new commits. Configure here.

sirtimid and others added 9 commits January 23, 2026 12:51
Move transport-related constants to constants.ts:
- DEFAULT_MAX_CONCURRENT_CONNECTIONS
- DEFAULT_MAX_MESSAGE_SIZE_BYTES
- DEFAULT_CLEANUP_INTERVAL_MS
- DEFAULT_STALE_PEER_TIMEOUT_MS
- DEFAULT_WRITE_TIMEOUT_MS
- SCTP_USER_INITIATED_ABORT

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move peer state management to dedicated PeerStateManager class:
- Encapsulates peerStates, lastConnectionTime, intentionallyClosed
- Provides methods: getState, countActiveConnections, updateConnectionTime
- Handles intentional close tracking (mark, check, clear)
- Location hints management (addLocationHints)
- Stale peer detection and removal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move the writeWithTimeout utility function to a dedicated
channel-utils.ts module for better separation of concerns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create factory functions for validators:
- makeMessageSizeValidator: validates message size limits
- makeConnectionLimitChecker: validates connection limits

Both use ResourceLimitError with structured data for error handling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add factory function for creating error logging functions with
peer context, reducing boilerplate in transport.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move handleConnectionLoss and attemptReconnection to reconnection-lifecycle.ts:
- Creates makeReconnectionLifecycle factory function
- Uses holder pattern to break circular dependency
- Encapsulates reconnection orchestration logic

This significantly reduces transport.ts complexity while keeping
the reconnection logic cohesive and testable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive test coverage for the newly extracted modules:
- validators.test.ts: Tests for message size and connection limit validators
- channel-utils.test.ts: Tests for error logging and writeWithTimeout
- peer-state-manager.test.ts: Tests for PeerStateManager class
- reconnection-lifecycle.test.ts: Tests for reconnection lifecycle functions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sliding window rate limiting to protect against flooding attacks:
- Message rate limiting: 100 messages/second per peer (configurable)
- Connection attempt rate limiting: 10 attempts/minute per peer (configurable)

Implementation:
- Add SlidingWindowRateLimiter class with automatic pruning
- Add maxMessagesPerSecond and maxConnectionAttemptsPerMinute options
- Integrate rate checks in sendRemoteMessage before sending
- Integrate connection rate checks before dialing new connections
- Clean up rate limiter state when peers become stale or transport stops

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive test coverage for SlidingWindowRateLimiter:
- Basic limit checking (wouldExceedLimit)
- Event recording and pruning
- checkAndRecord with error handling
- getCurrentCount with window expiration
- clearKey and clear methods
- pruneStale for cleanup
- Sliding window behavior with real timing

Also test factory functions and constants.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sirtimid sirtimid requested a review from a team as a code owner January 26, 2026 17:53
@sirtimid sirtimid changed the base branch from main to sirtimid/split-transport-concerns January 26, 2026 17:56
@sirtimid sirtimid closed this Jan 26, 2026
@sirtimid sirtimid reopened this Jan 26, 2026
@sirtimid sirtimid marked this pull request as draft January 26, 2026 17:59
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.


const state = getPeerState(targetPeerId);
// Check message rate limit
messageRateLimiter.checkAndRecord(targetPeerId, 'messages');
Copy link

Choose a reason for hiding this comment

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

Rate limiting only applies to outbound, not inbound messages

High Severity

The PR claims to "protect against flooding attacks" but the messageRateLimiter.checkAndRecord() is only called in sendRemoteMessage (outbound path). The receiveMessage function processes all inbound messages without any rate limiting. This means a malicious peer can flood the system with unlimited messages while the rate limiter only prevents our own system from sending too fast. The security goal stated in the PR description is not achieved by this implementation.

Additional Locations (1)

Fix in Cursor Fix in Web

@sirtimid sirtimid force-pushed the sirtimid/split-transport-concerns branch from ece964a to 24cc1f6 Compare January 26, 2026 19:10
Base automatically changed from sirtimid/split-transport-concerns to main January 26, 2026 19:45
@sirtimid
Copy link
Contributor Author

Superseded by new PR based on merged main

@sirtimid sirtimid closed this Jan 26, 2026
@sirtimid sirtimid deleted the sirtimid/add-rate-limiting branch January 26, 2026 20:06
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.

Remote comms: Basic Rate Limiting

2 participants