java.lang.Object
net.i2p.router.tunnel.pool.ParticipatingThrottler

public class ParticipatingThrottlerextends Object
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

    Modifier and Type
    Class
    Description
    private class 
    Periodic timer event that clears the participation counts to reset throttling.
    private class 
    Timer event that disconnects a router after a delay.
    static enum 
    Result of throttling decision for tunnel participation requests.
  • Field Summary

    Modifier and Type
    Field
    Description
    private BanLogger
    Logs the routers rejected as too old.
    private static RateStat
    Rate stat tracking the participation queue.
    private static RouterContext
    Context the cached limit invariants were read against; a different context invalidates them.
    private static long
    Wall-clock ms the cached limit invariants were read, or 0 if never.
    private static float
    Cached 0.0-1.0 load score; only valid once _loadScoreQueried is set.
    private static RouterContext
    Context the cached load score was computed against; a different context invalidates it.
    private static long
    Wall-clock ms the cached load score was computed, or 0 if never.
    static int
    Load weight: how much load inflates effective ratio (0-300%, default 100%).
    private final Log
    Logger for the participation throttler.
    static int
    Max tunnels per peer before throttling.
    private static int
    Cached router.maxParticipatingTunnels; only valid once _limitInvQueried is set.
    static int
    Min tunnels per peer before throttling.
    private final LHMCache<Hash,long[]>
    No-version offense state per hash: {count, lastOffenseMs}.
    static int
    Max pct of participating tunnels per peer.
    private final LHMCache<Hash,Long>
    Router hashes looked up recently, with the time.
    static int
    Rejection steepness: 100=linear ramp, 200=quadratic, higher=faster escalation.
    static int
    Rejection threshold: start rejecting at count/limit ratio this high (30-100, default 70%).
    private static RouterContext
    Cached RateStat handle for the shared load-score computation; refreshed when the context changes.
    private static int
    Cached system load 0-100; only valid once _limitInvQueried is set.
    private static final long
    Interval between clearing the participation counts.
    private final RouterContext
    The router context.
    private final ObjectCounter<Hash>
    How many tunnels each router participates in.
    private static final boolean
    Whether old routers are blocked unless configured.
    (package private) static final boolean
    True on platforms we treat as slow.
    private static final long
    Minimum interval between re-reading the two limit inputs that cannot change under us within a request, in ms.
    private static final long
    Minimum interval between two full load-score recomputations, in ms.
    private static final String
    Oldest router version allowed to participate.
    private static final int
    Offenses inside the escalation window before a ban is issued.
    private static final long
    Repeated no-version joins inside this window escalate to a ban.
    private static final String
    Config key for blocking the old router versions.
    private static final long[]
    Time windows of the bandwidth rate stats.
    private static final long
    Time before a failed router lookup is retried.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Participating throttler.
  • Method Summary

    Modifier and Type
    Method
    Description
    private void
    _logAcceptRequest(String caps, int count)
    Logs debug information for accepted tunnel requests.
    private void
    _logHighRequestCount(Hash h, String caps, int count, int limit)
    Logs warnings for high count tunnel request rejections.
    (package private) 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.
    private int
    calculateLimit(int numTunnels, boolean isUnreachable, boolean isLowShare, boolean isFast)
    Calculates the participation limit for tunnels based on the number of tunnels and router capabilities such as reachability and bandwidth share.
    (package private) static float
    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 last LOAD_SCORE_CACHE_MS.
    private boolean
    checkLowShareAndVersion(String version, boolean isLU, boolean shouldBlockOldRouters, Hash h, boolean shouldDisconnect, boolean isBanned, String caps, int bantime, RouterInfo ri)
    Checks if a low-share, old-version router should be banned and disconnected.
    private boolean
    checkUnreachableAndOld(String version, boolean isUnreachable, boolean isFast, boolean shouldBlockOldRouters, Hash h, boolean shouldDisconnect, boolean isBanned, String caps)
    Checks if an unreachable and old router should be banned or ignored.
    private boolean
    checkVersionAndCompressibility(String version, boolean isCompressible, boolean shouldDisconnect, Hash h, boolean isBanned, String caps, RouterInfo ri)
    Checks router version and compressibility of RouterInfo to decide on banning.
    private static int
    clamp(int val, int lo, int hi)
    Constrain a configured property to an allowed range, so a single expression both reads the property and clamps it rather than storing the raw value and overwriting it unread on the next line.
    (package private) 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.
    (package private) static float
    Uncached 0.0–1.0 load score from job queue lag, CPU load, system load, and bandwidth queue pressure.
    evaluateThrottleConditions(int count, int limit, boolean shouldThrottle, boolean isFast, boolean isLowShare, boolean isUnreachable, Hash h, String caps, boolean isBanned, int bantime, RouterInfo ri, boolean countRequest)
    Evaluates whether to accept, reject, or drop tunnel requests based on probabilistic rejection curve modulated by system load.
    private static RateStat
    Resolves the "bwLimiter.participatingBandwidthQueue" RateStat once per context.
    static int
    The load weight.
    static int
    The participating maximum limit.
    static int
    The participating minimum limit.
    static int
    The participating percent limit.
    static int
    The rejection steepness.
    static int
    The rejection threshold.
    private void
    handleExcessiveRequests(Hash h, String caps, int count, int limit, int bantime, RouterInfo ri)
    Handles excessive tunnel request counts by banning and scheduling disconnect.
    private void
    handleNoVersion(boolean shouldDisconnect, Hash h, boolean isBanned, String caps, RouterInfo ri, String version)
    Handles joins from routers whose held RouterInfo carries no version.
    (package private) static boolean
    limitInvariantCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx)
    Whether the two invariant limit inputs are old enough to re-read.
    (package private) static boolean
    loadScoreCacheStale(long lastQueried, long now, RouterContext cachedCtx, RouterContext ctx)
    Whether the cached load score is old enough to recompute.
    private void
    Re-reads the two invariant limit inputs when the cache is stale.
    private void
    Rate-limited background resolution for transit peers missing from our local netDb, so throttler decisions graduate from count-only to full classification without blocking or hammering the netdb.
    static void
    setLoadWeight(int val)
    The load weight.
    static void
    The participating maximum limit.
    static void
    The participating minimum limit.
    static void
    The participating percent limit.
    static void
    The rejection steepness.
    static void
    The rejection threshold.
    Determines whether to throttle tunnel participation for the given router, counting the request against the peer's limit.
    shouldThrottle(Hash h, boolean countRequest)
    Determines whether to throttle tunnel participation for the given router.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • context

      private final RouterContext context
      The router context.
    • counter

      private final ObjectCounter<Hash> counter
      How many tunnels each router participates in.
    • _log

      private final Log _log
      Logger for the participation throttler.
    • _banLogger

      private BanLogger _banLogger
      Logs the routers rejected as too old.
    • IS_SLOW

      static final boolean IS_SLOW
      True on platforms we treat as slow. Selects a more conservative percentage divisor (300 rather than 100) and a lower _minLimit cap in baseLimitFor(int, boolean, boolean, int, int, int, boolean). Package-visible so the limit arithmetic can be pinned for both branches without a RouterContext.
    • DEFAULT_BLOCK_OLD_ROUTERS

      private static final boolean DEFAULT_BLOCK_OLD_ROUTERS
      Whether old routers are blocked unless configured.
      See Also:
    • PROP_BLOCK_OLD_ROUTERS

      private static final String PROP_BLOCK_OLD_ROUTERS
      Config key for blocking the old router versions.
      See Also:
    • _minLimit

      public static volatile int _minLimit
      Min tunnels per peer before throttling.
    • _maxLimit

      public static volatile int _maxLimit
      Max tunnels per peer before throttling.
    • _percentLimit

      public static volatile int _percentLimit
      Max pct of participating tunnels per peer.
    • _rejectThreshold

      public static volatile int _rejectThreshold
      Rejection threshold: start rejecting at count/limit ratio this high (30-100, default 70%).
    • _rejectSteepness

      public static volatile int _rejectSteepness
      Rejection steepness: 100=linear ramp, 200=quadratic, higher=faster escalation.
    • _loadWeight

      public static volatile int _loadWeight
      Load weight: how much load inflates effective ratio (0-300%, default 100%).
    • _scoreCtx

      private static volatile RouterContext _scoreCtx
      Cached RateStat handle for the shared load-score computation; refreshed when the context changes.
    • _bwQueueRateStat

      private static volatile RateStat _bwQueueRateStat
      Rate stat tracking the participation queue.
    • LOAD_SCORE_CACHE_MS

      private static final long LOAD_SCORE_CACHE_MS
      Minimum interval between two full load-score recomputations, in ms.

      The score is consulted on every throttled participating request and is shared with RequestThrottler, but its inputs are all coarse: job queue lag in whole milliseconds, a 60s-smoothed CPU load, a 1/5/15-minute load average and a 60s bandwidth rate. None of them move meaningfully inside one second, so recomputing per request only buys CPU. Staleness is bounded at LOAD_SCORE_CACHE_MS of wall clock plus whatever the underlying inputs are themselves smoothed over, which is invisible against a rejection curve that turns over on a per-request random draw.

      See Also:
    • _loadScoreQueried

      private static volatile long _loadScoreQueried
      Wall-clock ms the cached load score was computed, or 0 if never.
    • _loadScore

      private static volatile float _loadScore
      Cached 0.0-1.0 load score; only valid once _loadScoreQueried is set.
    • _loadScoreCtx

      private static volatile RouterContext _loadScoreCtx
      Context the cached load score was computed against; a different context invalidates it.
    • LIMIT_INVARIANT_CACHE_MS

      private static final long LIMIT_INVARIANT_CACHE_MS
      Minimum interval between re-reading the two limit inputs that cannot change under us within a request, in ms.

      router.maxParticipatingTunnels is a static configuration property and getSystemLoad() reports a load average; both were re-read on every participating request even though neither moves on a second timescale. Staleness is bounded at LIMIT_INVARIANT_CACHE_MS: a limit can therefore lag a live property change or a load swing by at most that much. The TTL is deliberately the same short 1s the load score uses rather than something longer - the limit is a policy value that gates participation, and computeLimit(int, boolean, boolean, boolean, int, double, int) still re-reads every live input (participating count, bandwidth usage) on each call, so only the two invariants are smoothed.

      See Also:
    • _limitInvQueried

      private static volatile long _limitInvQueried
      Wall-clock ms the cached limit invariants were read, or 0 if never.
    • _maxParticipatingTunnels

      private static volatile int _maxParticipatingTunnels
      Cached router.maxParticipatingTunnels; only valid once _limitInvQueried is set.
    • _systemLoad

      private static volatile int _systemLoad
      Cached system load 0-100; only valid once _limitInvQueried is set.
    • _limitInvCtx

      private static volatile RouterContext _limitInvCtx
      Context the cached limit invariants were read against; a different context invalidates them.
    • CLEAN_TIME

      private static final long CLEAN_TIME
      Interval between clearing the participation counts.
      See Also:
    • RATES

      private static final long[] RATES
      Time windows of the bandwidth rate stats.
    • MIN_VERSION

      private static final String MIN_VERSION
      Oldest router version allowed to participate.
      See Also:
    • _noVersionOffenses

      private final LHMCache<Hash,long[]> _noVersionOffenses
      No-version offense state per hash: {count, lastOffenseMs}. Bounded LRU.
    • NO_VERSION_ESCALATION_MS

      private static final long NO_VERSION_ESCALATION_MS
      Repeated no-version joins inside this window escalate to a ban.
      See Also:
    • NO_VERSION_BAN_THRESHOLD

      private static final int NO_VERSION_BAN_THRESHOLD
      Offenses inside the escalation window before a ban is issued.
      See Also:
    • _recentLookups

      private final LHMCache<Hash,Long> _recentLookups
      Router hashes looked up recently, with the time.
    • ROUTER_LOOKUP_RETRY_MS

      private static final long ROUTER_LOOKUP_RETRY_MS
      Time before a failed router lookup is retried.
      See Also:
  • 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
    • clamp

      private static int clamp(int val, int lo, int hi)
      Constrain a configured property to an allowed range, so a single expression both reads the property and clamps it rather than storing the raw value and overwriting it unread on the next line.
      Parameters:
      val - the value read from the properties
      lo - the lowest permitted value
      hi - the highest permitted value
      Returns:
      val limited to [lo, hi]
    • 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

      ParticipatingThrottler.Result shouldThrottle(Hash h, boolean countRequest)
      Determines whether to throttle tunnel participation for the given router. When countRequest is 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 check
      countRequest - true to increment the peer's counter
      Returns:
      the throttling Result (ACCEPT, REJECT, or DROP)
    • calculateLimit

      private int calculateLimit(int numTunnels, boolean isUnreachable, boolean isLowShare, boolean isFast)
      Calculates the participation limit for tunnels based on the number of tunnels and router capabilities such as reachability and bandwidth share. Relaxes limits when we have spare capacity (bandwidth headroom + available transit slots). Enforces a floor (2 for low-share/unreachable, 5 for normal) to prevent zero limits from integer division truncation at low percentage values.

      Only the two inputs that cannot move under us - the router.maxParticipatingTunnels property and the system load average - are served from a LIMIT_INVARIANT_CACHE_MS cache. Everything that reflects current router state (participating count, outbound bandwidth limit, bandwidth queue usage) is re-read on every call, and all of the arithmetic lives in computeLimit(int, boolean, boolean, boolean, int, double, int).

      Parameters:
      numTunnels - the current count of participating tunnels
      isUnreachable - true if the router is unreachable
      isLowShare - true if the router has low bandwidth share
      isFast - true if the router has high bandwidth share
      Returns:
      the per-peer tunnel participation limit, floored to prevent starvation
    • refreshLimitInvariants

      private void refreshLimitInvariants()
      Re-reads the two invariant limit inputs when the cache is stale. Publication order matters: both values and the context are written before the timestamp, so a thread that sees a fresh timestamp also sees the matching values. A concurrent duplicate refresh is harmless - the worst case is one extra property read plus one extra load sample, so no lock.
    • 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 0
      now - the current wall-clock ms
      cachedCtx - the context the cached values were read against
      ctx - 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 tunnels
      isUnreachable - true if the router is unreachable
      isLowShare - true if the router has low bandwidth share
      isFast - true if the router has high bandwidth share; not consumed by the current arithmetic, kept so the signature matches calculateLimit(int, boolean, boolean, boolean) and shouldThrottle(Hash, boolean)
      maxTunnels - the configured participating tunnel ceiling
      bwUsage - outbound bandwidth usage as a fraction of the limit, 0 when unknown
      sysLoad - 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 low pctLimit cannot truncate the share to zero.
      Parameters:
      numTunnels - the current count of participating tunnels
      isUnreachable - true if the router is unreachable
      isLowShare - true if the router has low bandwidth share
      minLimit - the min limit
      maxLimit - the max limit
      pctLimit - the max pct of participating tunnels per peer
      isSlow - true to use the conservative slow-platform divisor
      Returns:
      the unrelaxed percentage-based limit
    • handleNoVersion

      private void handleNoVersion(boolean shouldDisconnect, Hash h, boolean isBanned, String caps, RouterInfo ri, String version)
      Handles joins from routers whose held RouterInfo carries no version.

      Minor infraction: the offending join is answered with a transient reject (the caller maps Result.REJECT accordingly) and only repeated no-version offenses within NO_VERSION_ESCALATION_MS graduate to a banlist entry. A single sighting is far more likely a stale or buggy router than an attacker, and an immediate multi-hour ban on first sight was poisoning the peer pool.

      Parameters:
      shouldDisconnect - whether to disconnect the router after banning
      h - the router hash
      isBanned - true if already banned
      caps - router capabilities string, used in log lines only
      ri - RouterInfo for IP extraction and logging
      version - router version string, used if disconnect is scheduled
    • scheduleRouterLookup

      private void scheduleRouterLookup(Hash h)
      Rate-limited background resolution for transit peers missing from our local netDb, so throttler decisions graduate from count-only to full classification without blocking or hammering the netdb.
      Parameters:
      h - the hash of the transit peer to resolve
    • checkVersionAndCompressibility

      private boolean checkVersionAndCompressibility(String version, boolean isCompressible, boolean shouldDisconnect, Hash h, boolean isBanned, String caps, RouterInfo ri)
      Checks router version and compressibility of RouterInfo to decide on banning.
      Parameters:
      version - router software version string
      isCompressible - true if RouterInfo data is compressible (potentially suspicious)
      shouldDisconnect - whether to disconnect after banning
      h - hash of the router being evaluated
      isBanned - true if already banned
      caps - router capabilities string
      ri - the router info, used for the IP:port in the ban log
      Returns:
      true if the router should be dropped (banned), false otherwise
    • checkLowShareAndVersion

      private boolean checkLowShareAndVersion(String version, boolean isLU, boolean shouldBlockOldRouters, Hash h, boolean shouldDisconnect, boolean isBanned, String caps, int bantime, RouterInfo ri)
      Checks if a low-share, old-version router should be banned and disconnected.
      Parameters:
      version - router version string
      isLU - true if router is low share and unreachable
      shouldBlockOldRouters - whether to block old routers
      h - hash of the router being evaluated
      shouldDisconnect - whether to disconnect after banning
      isBanned - true if already banned
      caps - router capabilities string
      bantime - ban duration in milliseconds
      ri - the router info, used for the IP:port in the ban log
      Returns:
      true if the router should be dropped (banned), false otherwise
    • checkUnreachableAndOld

      private boolean checkUnreachableAndOld(String version, boolean isUnreachable, boolean isFast, boolean shouldBlockOldRouters, Hash h, boolean shouldDisconnect, boolean isBanned, String caps)
      Checks if an unreachable and old router should be banned or ignored.
      Parameters:
      version - router version string
      isUnreachable - true if router is unreachable
      isFast - true if router has high bandwidth
      shouldBlockOldRouters - whether to block old routers
      h - hash of the router being evaluated
      shouldDisconnect - whether to disconnect after banning
      isBanned - true if already banned
      caps - router capabilities string
      Returns:
      true if the router should be dropped (ignored), false otherwise
    • evaluateThrottleConditions

      private ParticipatingThrottler.Result evaluateThrottleConditions(int count, int limit, boolean shouldThrottle, boolean isFast, boolean isLowShare, boolean isUnreachable, Hash h, String caps, boolean isBanned, int bantime, RouterInfo ri, boolean countRequest)
      Evaluates whether to accept, reject, or drop tunnel requests based on probabilistic rejection curve modulated by system load. Replaces the old deterministic count > limit cutoff with a smooth probability function that ramps from 0 at the reject threshold to near-1 under load or high ratio.
      Parameters:
      count - current participation count for the router
      limit - maximum allowed participation
      shouldThrottle - true if throttling is enabled
      isFast - true if router is high bandwidth
      isLowShare - true if router is low bandwidth
      isUnreachable - true if router is unreachable
      h - hash of the router being evaluated
      caps - router capabilities string
      isBanned - true if router is already banned
      bantime - ban duration in milliseconds
      ri - the RouterInfo, for ban logging
      countRequest - true when this request advanced the counter; consult-only checks downgrade DROP to REJECT and never ban on a count they did not contribute to
      Returns:
      Result indicating ACCEPT, REJECT, or DROP action
    • calculateLoadScore

      static float calculateLoadScore(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 last LOAD_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 0
      now - the current wall-clock ms
      cachedCtx - the context the cached score was computed against
      ctx - the context being asked for now
      Returns:
      true if the score should be recomputed
    • computeLoadScore

      static float computeLoadScore(RouterContext context)
      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)
    • getBwQueueRateStat

      private static RateStat getBwQueueRateStat(RouterContext context)
      Resolves the "bwLimiter.participatingBandwidthQueue" RateStat once per context. The stat is registered during startup and never replaced, so the handle is only looked up again when the context changes. A stat that is not registered yet leaves the cache untouched and returns null, so a later call retries instead of caching the absence.
      Parameters:
      context - the context to resolve against
      Returns:
      the cached stat, or null if it is not registered yet
    • handleExcessiveRequests

      private void handleExcessiveRequests(Hash h, String caps, int count, int limit, int bantime, RouterInfo ri)
      Handles excessive tunnel request counts by banning and scheduling disconnect.
      Parameters:
      h - hash of the router requesting too many tunnels
      caps - router capabilities string
      count - current participation count
      limit - maximum allowed participation
      bantime - ban duration in milliseconds
      ri - the router info for IP extraction and logging
    • _logHighRequestCount

      private void _logHighRequestCount(Hash h, String caps, int count, int limit)
      Logs warnings for high count tunnel request rejections.
      Parameters:
      h - the router whose requests are being rejected
      caps - the router capabilities string, may be null
      count - the request count in the 90 second window
      limit - the allowed maximum in the 90 second window
    • _logAcceptRequest

      private void _logAcceptRequest(String caps, int count)
      Logs debug information for accepted tunnel requests.
      Parameters:
      caps - the router capabilities string, empty when none
      count - the request count in the 90 second window