java.lang.Object
net.i2p.router.tunnel.pool.ParticipatingThrottler
Count how often we have accepted a tunnel with the peer as the previous or next hop. We limit each peer to a percentage of all participating tunnels, subject to minimum and maximum values for the limit.
This offers basic protection against simple attacks but is not a complete solution, as by design, we don't know the originator of a tunnel request.
This also effectively limits the number of tunnels between any given pair of routers, which probably isn't a bad thing.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumResult of throttling decision for tunnel participation requests.Field Summary
FieldsModifier and TypeFieldDescriptionstatic intLoad weight: how much load inflates effective ratio (0-300%, default 100%).static intMax tunnels per peer before throttling.static intMin tunnels per peer before throttling.static intMax pct of participating tunnels per peer.static intRejection steepness: 100=linear ramp, 200=quadratic, higher=faster escalation.static intRejection threshold: start rejecting at count/limit ratio this high (30-100, default 70%).(package private) static final booleanTrue on platforms we treat as slow.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescription(package private) static intbaseLimitFor(int numTunnels, boolean isUnreachable, boolean isLowShare, int minLimit, int maxLimit, int pctLimit, boolean isSlow) Percentage share of participating tunnels granted to one peer, before any relaxation.(package private) static floatcalculateLoadScore(RouterContext context) Computes a 0.0–1.0 load score from job queue lag, CPU load, system load, and bandwidth queue pressure, reusing the score computed within the lastLOAD_SCORE_CACHE_MS.(package private) static intcomputeLimit(int numTunnels, boolean isUnreachable, boolean isLowShare, boolean isFast, int maxTunnels, double bwUsage, int sysLoad) The participation-limit arithmetic, with every input supplied, so it can be exercised without a RouterContext.(package private) static floatcomputeLoadScore(RouterContext context) Uncached 0.0–1.0 load score from job queue lag, CPU load, system load, and bandwidth queue pressure.static intThe load weight.static intThe participating maximum limit.static intThe participating minimum limit.static intThe participating percent limit.static intThe rejection steepness.static intThe rejection threshold.(package private) static booleanlimitInvariantCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx) Whether the two invariant limit inputs are old enough to re-read.(package private) static booleanloadScoreCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx) Whether the cached load score is old enough to recompute.static voidsetLoadWeight(int val) The load weight.static voidsetParticipatingMaxLimit(int val) The participating maximum limit.static voidsetParticipatingMinLimit(int val) The participating minimum limit.static voidsetParticipatingPctLimit(int val) The participating percent limit.static voidsetRejectSteepness(int val) The rejection steepness.static voidsetRejectThreshold(int val) The rejection threshold.(package private) ParticipatingThrottler.ResultDetermines whether to throttle tunnel participation for the given router, counting the request against the peer's limit.(package private) ParticipatingThrottler.ResultshouldThrottle(Hash h, boolean countRequest) Determines whether to throttle tunnel participation for the given router.
Field Details
IS_SLOW
static final boolean IS_SLOWTrue on platforms we treat as slow. Selects a more conservative percentage divisor (300 rather than 100) and a lower_minLimitcap inbaseLimitFor(int, boolean, boolean, int, int, int, boolean). Package-visible so the limit arithmetic can be pinned for both branches without a RouterContext._minLimit
public static volatile int _minLimitMin tunnels per peer before throttling._maxLimit
public static volatile int _maxLimitMax tunnels per peer before throttling._percentLimit
public static volatile int _percentLimitMax pct of participating tunnels per peer._rejectThreshold
public static volatile int _rejectThresholdRejection threshold: start rejecting at count/limit ratio this high (30-100, default 70%)._rejectSteepness
public static volatile int _rejectSteepnessRejection steepness: 100=linear ramp, 200=quadratic, higher=faster escalation._loadWeight
public static volatile int _loadWeightLoad weight: how much load inflates effective ratio (0-300%, default 100%).
Constructor Details
ParticipatingThrottler
ParticipatingThrottler(RouterContext ctx) Participating throttler.- Parameters:
ctx- the router context supplying properties, rate stats and the ban logger that records throttled peers
Method Details
getParticipatingMinLimit
public static int getParticipatingMinLimit()The participating minimum limit.- Returns:
- tunnels per peer below which throttling never applies
setParticipatingMinLimit
public static void setParticipatingMinLimit(int val) The participating minimum limit.- Parameters:
val- tunnels per peer below which throttling never applies, clamped to 20-500
getParticipatingMaxLimit
public static int getParticipatingMaxLimit()The participating maximum limit.- Returns:
- tunnels per peer at which throttling is at full strength
setParticipatingMaxLimit
public static void setParticipatingMaxLimit(int val) The participating maximum limit.- Parameters:
val- tunnels per peer at which throttling is at full strength, clamped to 50-1000
getParticipatingPctLimit
public static int getParticipatingPctLimit()The participating percent limit.- Returns:
- max percentage of a peer's tunnels that may participate
setParticipatingPctLimit
public static void setParticipatingPctLimit(int val) The participating percent limit.- Parameters:
val- max percentage of a peer's tunnels that may participate, clamped to 5-100
getRejectThreshold
public static int getRejectThreshold()The rejection threshold.- Returns:
- count/limit ratio percentage at which rejection starts
setRejectThreshold
public static void setRejectThreshold(int val) The rejection threshold.- Parameters:
val- count/limit ratio percentage at which rejection starts, clamped to 30-100
getRejectSteepness
public static int getRejectSteepness()The rejection steepness.- Returns:
- how fast rejection probability ramps past the threshold; 100 is linear
setRejectSteepness
public static void setRejectSteepness(int val) The rejection steepness.- Parameters:
val- how fast rejection probability ramps past the threshold, clamped to 100-500
getLoadWeight
public static int getLoadWeight()The load weight.- Returns:
- how much system load inflates the effective ratio, as a percentage
setLoadWeight
public static void setLoadWeight(int val) The load weight.- Parameters:
val- how much system load inflates the effective ratio, clamped to 0-300
shouldThrottle
Determines whether to throttle tunnel participation for the given router, counting the request against the peer's limit.- Parameters:
h- the hash of the router to check- Returns:
- the throttling Result (ACCEPT, REJECT, or DROP)
shouldThrottle
Determines whether to throttle tunnel participation for the given router. WhencountRequestis set the request increments the peer's counter; consult-only checks read the current count without advancing it, and never DROP or ban on it: a count this request did not contribute to must not silently kill it, and mid-chain hops would otherwise accumulate roughly twice per tunnel via both their prev-hop and next-hop roles.- Parameters:
h- the hash of the router to checkcountRequest- true to increment the peer's counter- Returns:
- the throttling Result (ACCEPT, REJECT, or DROP)
limitInvariantCacheStale
static boolean limitInvariantCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx) Whether the two invariant limit inputs are old enough to re-read. Never-read (lastQueried == 0) counts as stale so the first call reads them rather than trusting the field initializers. A swapped RouterContext (unit tests build their own) invalidates regardless of age, as does a wall-clock step backwards, which a plain age comparison would keep serving until the clock caught up again.- Parameters:
lastQueried- the wall-clock ms of the previous read, or 0now- the current wall-clock mscachedCtx- the context the cached values were read againstctx- the context being asked for now- Returns:
- true if the cached values should be refreshed
computeLimit
static int computeLimit(int numTunnels, boolean isUnreachable, boolean isLowShare, boolean isFast, int maxTunnels, double bwUsage, int sysLoad) The participation-limit arithmetic, with every input supplied, so it can be exercised without a RouterContext. Reads the policy fields (_minLimit,_maxLimit,_percentLimit,IS_SLOW) and applies the capacity relaxation, the idle-CPU bonus and the participation floor.- Parameters:
numTunnels- the current count of participating tunnelsisUnreachable- true if the router is unreachableisLowShare- true if the router has low bandwidth shareisFast- true if the router has high bandwidth share; not consumed by the current arithmetic, kept so the signature matchescalculateLimit(int, boolean, boolean, boolean)andshouldThrottle(Hash, boolean)maxTunnels- the configured participating tunnel ceilingbwUsage- outbound bandwidth usage as a fraction of the limit, 0 when unknownsysLoad- system load 0-100- Returns:
- the per-peer tunnel participation limit, floored to prevent starvation
baseLimitFor
static int baseLimitFor(int numTunnels, boolean isUnreachable, boolean isLowShare, int minLimit, int maxLimit, int pctLimit, boolean isSlow) Percentage share of participating tunnels granted to one peer, before any relaxation. Unreachable and low-share peers are held to a fifth of the nominal share (a tenth on slow platforms) and capped at the min limit. Everyone else gets the full share and may reach three times the min limit, bounded below by half the max limit. The divisors are applied in floating point so a lowpctLimitcannot truncate the share to zero.- Parameters:
numTunnels- the current count of participating tunnelsisUnreachable- true if the router is unreachableisLowShare- true if the router has low bandwidth shareminLimit- the min limitmaxLimit- the max limitpctLimit- the max pct of participating tunnels per peerisSlow- true to use the conservative slow-platform divisor- Returns:
- the unrelaxed percentage-based limit
calculateLoadScore
Computes a 0.0–1.0 load score from job queue lag, CPU load, system load, and bandwidth queue pressure, reusing the score computed within the lastLOAD_SCORE_CACHE_MS. Used to shift the rejection probability curve left when the router is under load. Shared by ParticipatingThrottler and RequestThrottler; both the score and the RateStat handle are cached per context.Publication order matters: the score and its context are written before the timestamp, so a thread that sees a fresh timestamp also sees the matching score. Concurrent callers may both compute - the worst case is one redundant computation per interval, so no lock is taken.
- Parameters:
context- the context to read the load inputs from- Returns:
- the load score, 0.0 (idle) to 1.0 (saturated)
- See Also:
loadScoreCacheStale
static boolean loadScoreCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx) Whether the cached load score is old enough to recompute. Never-computed (lastQueried == 0) counts as stale so the first call computes rather than returning the 0.0 initializer. A swapped RouterContext (unit tests build their own) invalidates regardless of age, as does a wall-clock step backwards, which a plain age comparison would keep serving until the clock caught up again.- Parameters:
lastQueried- the wall-clock ms of the previous computation, or 0now- the current wall-clock mscachedCtx- the context the cached score was computed againstctx- the context being asked for now- Returns:
- true if the score should be recomputed
computeLoadScore
Uncached 0.0–1.0 load score from job queue lag, CPU load, system load, and bandwidth queue pressure. Job lag contributes 40% of the score and saturates at 1000ms, CPU load 25%, system load 20%, and bandwidth queue pressure 15%, saturating at 100KB/s. Each input is clamped to its own range so a lagging counter cannot push the total past 1.0.- Parameters:
context- the context to read the load inputs from- Returns:
- the load score, 0.0 (idle) to 1.0 (saturated)