mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 08:14:42 +00:00
Meter established-link msg1 separately from stranger admission
The msg1 rate limiter ran one bucket for everything, so a rekey or restart msg1 from an established peer competed for admission with strangers. Under inbound pressure the maintenance traffic lost, and an established session could not re-handshake until the stranger flood eased. Classify the source before the rate-limit decision and give established links their own bucket. Classification costs two map lookups and no crypto, so it runs first. The predicate cannot be the one the master line uses. There, IK has learned the peer identity by the time msg1 is handled, so a hit in the address-to-link map is enough to prove an established peer. Under XX no identity is known at msg1, and an in-flight handshake populates that map before the peer is promoted, so the same predicate would let a stranger draw on the established bucket for the whole life of its handshake. This version requires a promoted peer, which is the property actually being asserted. Two tests cover the difference and both fail if the predicate is replaced with the master-line one: a pending inbound stranger must keep drawing on the stranger bucket for its whole lifetime, and the established gate must not admit on a bare map hit. The four handshake reject arms that leak a session index are untouched; every hunk here sits at or above the end of the msg1 handler.
This commit is contained in:
@@ -78,6 +78,19 @@ pub struct RateLimitConfig {
|
||||
/// Max handshake resends per attempt (`node.rate_limit.handshake_max_resends`).
|
||||
#[serde(default = "RateLimitConfig::default_handshake_max_resends")]
|
||||
pub handshake_max_resends: u32,
|
||||
/// Burst capacity of the established-link msg1 bucket
|
||||
/// (`node.rate_limit.established_handshake_burst`).
|
||||
///
|
||||
/// Absent (the normal case) derives it from `node.limits.max_peers`.
|
||||
#[serde(default)]
|
||||
pub established_handshake_burst: Option<u32>,
|
||||
/// Tokens/sec refill rate of the established-link msg1 bucket
|
||||
/// (`node.rate_limit.established_handshake_rate`).
|
||||
///
|
||||
/// Absent (the normal case) derives it from `node.limits.max_peers`,
|
||||
/// `node.rekey.after_secs` and `handshake_max_resends`.
|
||||
#[serde(default)]
|
||||
pub established_handshake_rate: Option<f64>,
|
||||
}
|
||||
|
||||
impl Default for RateLimitConfig {
|
||||
@@ -89,6 +102,8 @@ impl Default for RateLimitConfig {
|
||||
handshake_resend_interval_ms: 1000,
|
||||
handshake_resend_backoff: 2.0,
|
||||
handshake_max_resends: 5,
|
||||
established_handshake_burst: None,
|
||||
established_handshake_rate: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user