-
Notifications
You must be signed in to change notification settings - Fork 7
feat(transport): add rate limiting for messages and connections #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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>
There was a problem hiding this 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'); |
There was a problem hiding this comment.
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)
ece964a to
24cc1f6
Compare
|
Superseded by new PR based on merged main |
Closes #661
Summary
maxMessagesPerSecond)maxConnectionAttemptsPerMinute)Implementation Details
SlidingWindowRateLimiterclass with automatic pruning of old eventssendRemoteMessagebefore sendingResourceLimitErrorwhen limits are exceededTest plan
Depends on
🤖 Generated with Claude Code
Note
Implements flow-control and restructures transport for reliability and maintainability.
DEFAULT_MESSAGE_RATE_LIMIT(1s window) andDEFAULT_CONNECTION_RATE_LIMIT(1m window); exposemaxMessagesPerSecondandmaxConnectionAttemptsPerMinuteoptions; enforce insendRemoteMessagechannel-utils(error logging, write timeout),constants,validators(message size/connection limit),peer-state-manager(peer tracking, stale cleanup),reconnection-lifecycle(orchestration); integrate intotransport.tscleanupOrphanMessagesand invoke duringRemoteHandlerecovery; tests updated to verify cleanup and crash-repair pathsWritten by Cursor Bugbot for commit 50bb648. This will update automatically on new commits. Configure here.