- All Implemented Interfaces:
Runnable
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classReplies for inbound tunnels we have created.private static classNormal inbound requests from other people.private static classReplies for outbound tunnels that we have created.private static enumWhich of the exploratory tunnels are up.private classJob that forwards one build request after its lookup.private static classA pending lookup request waiting for a concurrent lookup slot.private classJob that times out one unanswered build request.private static classNo-op job returned once a tunnel build message is handled.private classHandle incoming Tunnel Build Messages, which are generally requests to us, but could also be the reply where we are the IBEP.private static classRemove the participating tunnel if we can't contact the next hop Not strictly necessary, as the entry doesn't use that much space, but it affects capacity calculations.private static classNo-op job returned once a tunnel build reply message is handled.private classBuilds the job that handles one inbound build reply.Field Summary
FieldsModifier and TypeFieldDescriptionprivate intDrops counted since that warning.private final BanLoggerLogger for peers banned by build handling.private final JobJob handling inbound build requests.private final BuildReplyHandlerMatches build replies to the requests they answer.private final JobJob handling inbound build replies.private static longCached job lag past which requests are dropped, in ms.private static intCached cap for concurrent RI lookups.private static intCached cap on tunnels offered for transit.private static intCached cap on pending next-hop lookups.private static longCached oldest accepted build request age, in ms.private static longSame for ECIES-encrypted requests, in ms.private static longCached future clock skew a request may show, in ms.private static intCached floor for concurrent RI lookups.private static intCached next-hop lookup timeout, in ms.private static intCached next-hop lookup share, in percent.private static RouterContextThe context the cached config values belong to.private static longTime the cached config values were last read.private final RouterContextThe router running these tunnels.private final BuildExecutorExecutor running the build requests.private BuildHandler.ExplStateWhich exploratory tunnels exist, if any.private final IdleTunnelMonitorMonitor expiring idle tunnels.private final BlockingQueue<BuildHandler.BuildMessageState> Queue of received build messages.private booleanTrue while the handler is running.private longTime of the last ban-on-drop warning.private final LogLogger for this class.private final ConcurrentHashMap<Hash, AtomicInteger> Distinct next-hop keys currently being resolved, each carrying the refcount of build requests waiting on it.private final TunnelPoolManagerThe tunnel pools the built tunnels join.private static intMost build messages queued before dropping.private final StringOldest peer version that honors capacity flags.private static final AtomicLong[]Counters for each next-hop lookup outcome.private static final AtomicLongTime of the next next-hop summary log line.private final ConcurrentLinkedDeque<BuildHandler.PendingLookup> FIFO of deferred lookups waiting for a concurrent-lookup slot.private final BuildMessageProcessorThread draining that queue.private final RequestThrottlerThrottles inbound build requests under load.private final ObjectLock serializing handler startup.private final ParticipatingThrottlerThrottles transit participation under load.private static intTuner-set lookup cap, -1 when untuned.private static intTuned lookup-limit statics, -1 = use router config.private static intTuner-set lookup share, -1 when untuned.private static final longMinimum gap between banned-next-hop rejection warnings, and the number suppressed in between.(package private) static final longAge below which a ban is treated as having landed during the build.private static final longAge past which the cached config is re-read.private static final booleanTrue on a machine too slow for the default queue size.private static final longGrace added to the lookup timeout for the independent slot-release deadline, so the normal callbacks (which release earlier) win the race in the common case and the deadline only catches leaks.private static final intConcurrent next-hop search ceiling.(package private) static final intExtra RI lookup attempts allowed after a next-hop lookup times out.(package private) static final intWe declined the inbound build request.private static final intBudget for a next-hop lookup, in ms.private static final intNumber of next-hop outcome counters.(package private) static final intOutcome of one next-hop contact, for the rate-limited WARN summary.(package private) static final longHow often the next-hop summary may be logged, ms.(package private) static final intNext hop did not answer within the hop-contact window.private static final intMessage priority for build replies.private static final Stringi2p.tunnel.build.maxPendingLookupsproperty; seegetMaxPendingLookups(RouterContext).private static final StringProperty overriding the build queue cap.private static final StringProperty turning the transit throttle on or off.private static final long[]Rate periods shown in the throttle stats.private static final longCold-start window for next-hop lookup concurrency: until this long after startup, the lookup limit uses its full configured ceiling, because the netDb miss rate is high whileparticipating x pctwould clamp concurrency to near the floor exactly when inbound builds need it most.Constructor Summary
ConstructorsConstructorDescriptionBuildHandler(RouterContext ctx, TunnelPoolManager manager, BuildExecutor exec) Wires up the pool manager, executor and ban logger, and registers the tunnel build rate stats.Method Summary
Modifier and TypeMethodDescriptionprivate static final StringMark a string for extraction by xgettext and translation.(package private) static booleanattachLookupKey(ConcurrentHashMap<Hash, AtomicInteger> inFlight, Hash key, int limit) Attach a build request's next hop to the in-flight lookup set.(package private) static StringbanSeverity(long banAgeMs) Classify why a next-hop peer is banlisted, for the rejection log.(package private) static booleancountNextHopOutcome(int outcome, Log log, long now) Count one next-hop outcome and, at most once perNEXT_HOP_SUMMARY_INTERVAL_MS, log the ratio at WARN.(package private) static voidcreateRejectStats(StatManager mgr, long[] periods) Register the per-reason counters for build rejections we send back.private voidDrain the pending lookup queue, starting lookups for entries while we have capacity.private static StringformatBandwidth(int bps) Formats a rate for the stats display.intThe number of inbound build messages queued.private StringExtract IP:port fromRouterInfofor a peer hash.private static longGives the job lag past which tunnel requests are dropped.static intThe max concurrent RI lookup limit in effect, tuned value if set else config.private static intUpper bound on participating tunnels before the router drops incoming build requests, tunable viarouter.maxParticipatingTunnels.private static intPending next-hop lookups allowed to wait for a free slot while their build request is still inside the originator's budget.static intGets the current cap on the build message queue.private static longGives the oldest accepted build request age.private static longSame age limit for ECIES-encrypted requests.private static longGives the future clock skew a request may show.private static intGives the floor for concurrent RI lookups.static intThe next-hop lookup timeout in effect, tuned value if set else config.static intThe percent lookup limit in effect, tuned value if set else config.private voidBlocking call to handle a single inbound request.private voidhandleReply(TunnelBuildReplyMessage msg, PooledTunnelCreatorConfig cfg, long delay) Blocking call to handle a single inbound reply.private voidBlocking call to handle a single inbound reply.private voidhandleReq(RouterInfo nextPeerInfo, BuildHandler.BuildMessageState state, BuildRequestRecord req, Hash nextPeer) Actually process the request and send the reply.private longhandleRequest(BuildHandler.BuildMessageState state, long now) Decrypt the request, lookup the RI locally, and callhandleReq(RouterInfo, BuildMessageState, BuildRequestRecord, Hash)if found or queue a lookup job.private voidThis request is actually a reply, process it as such.(package private) voidinit()Call the same time you start the threads.(package private) static intlookupLimit(int numTunnels, int minLimit, int maxLimit, int percentLimit, long uptimeMs) Concurrent next-hop lookup limit for the current request.(package private) static StringnextHopSummaryText(long[] counts, long windowMs) Format the next-hop summary line.(package private) static longpendingLookupMaxAge(long requestTimeoutMs, long nextHopLookupTimeoutMs) How long a queued next-hop lookup may wait before it is discarded as stale.private static voidRefresh the cached build configuration from properties at most once per CONFIG_REFRESH_MS, or immediately when the context changes.(package private) static StringrejectStatName(int response) Stat name for the rejection reason we answer a build request with, or null if that reason has no stat.(package private) static voidreleaseLookupKey(ConcurrentHashMap<Hash, AtomicInteger> inFlight, Hash key) Release one build request's attachment to an in-flight lookup key, dropping the key entry once its last waiting request completes so released slots become visible to new arrivals.(package private) static voidReset the counters, for tests.voidrestart()Drops any queued inbound build messages left over from before the restart.voidrun()Thread to handle inbound requests.private voidscheduleLookupDeadline(BuildHandler.BuildMessageState state, Hash nextPeer, AtomicBoolean decremented, int attempts) Schedule an independent deadline that releases this request's lookup attachment if neither callback has done so by then.static voidsetMaxLookupLimit(int limit) Set the max concurrent RI lookup limit (called by Tuner).static voidsetMaxQueue(int val) Sets the cap on the build message queue.static voidsetNextHopLookupTimeout(int ms) Set the next-hop lookup timeout (called by Tuner).static voidsetPercentLookupLimit(int pct) Set the percent lookup limit (called by Tuner).(package private) static booleanshouldRetryLookup(int retriesLeft, long lookupStartedMs, long nowMs, int lookupTimeoutMs, int requestTimeoutMs) Whether a timed-out next-hop lookup deserves one more attempt.voidshutdown(int numThreads) Cannot be restarted.(package private) static long[]Current next-hop outcome counts.
Field Details
_context
The router running these tunnels._log
Logger for this class._manager
The tunnel pools the built tunnels join._exec
Executor running the build requests._buildMessageHandlerJob
Job handling inbound build requests._buildReplyMessageHandlerJob
Job handling inbound build replies._inboundBuildMessages
Queue of received build messages._processor
Thread draining that queue._requestThrottler
Throttles inbound build requests under load._throttler
Throttles transit participation under load._buildReplyHandler
Matches build replies to the requests they answer._idleTunnelMonitor
Monitor expiring idle tunnels._banLogger
Logger for peers banned by build handling._lookupKeys
Distinct next-hop keys currently being resolved, each carrying the refcount of build requests waiting on it. Slots count KEYS, not requests: N builds missing the same hop attach to one shared search, because the netdb coalesces duplicate lookups into a single network round trip._pendingLookups
FIFO of deferred lookups waiting for a concurrent-lookup slot._isRunning
private volatile boolean _isRunningTrue while the handler is running._startupLock
Lock serializing handler startup._explState
Which exploratory tunnels exist, if any._minVersionHonorCaps
Oldest peer version that honors capacity flags.- See Also:
PROP_SHOULD_THROTTLE
Property turning the transit throttle on or off.- See Also:
IS_SLOW
private static final boolean IS_SLOWTrue on a machine too slow for the default queue size._maxQueue
private static volatile int _maxQueueMost build messages queued before dropping.PROP_MAX_QUEUE
Property overriding the build queue cap.- See Also:
NEXT_HOP_LOOKUP_TIMEOUT
private static final int NEXT_HOP_LOOKUP_TIMEOUTBudget for a next-hop lookup, in ms.- See Also:
MAX_NEXT_HOP_LOOKUP_RETRIES
static final int MAX_NEXT_HOP_LOOKUP_RETRIESExtra RI lookup attempts allowed after a next-hop lookup times out. A timeout here is a local netdb miss (floodfills slow, RI just evicted), not evidence the peer is bad — rejecting threw away builds the next attempt would have completed. One retry keeps the total inside the originator's request budget (BuildRequestor.getRequestTimeout(RouterContext), gated byshouldRetryLookup(int, long, long, int, int)).- See Also:
PRIORITY
MAX_LOOKUP_LIMIT
private static final int MAX_LOOKUP_LIMITConcurrent next-hop search ceiling. Deliberately NOT cores-scaled: a lookup slot is an I/O-bound wait on floodfill replies, not CPU work, so hardware size doesn't change how many can be in flight. Network load is bounded downstream by per-key search coalescing, IterativeSearchJob fan-out caps, and the recently-queried floodfill cooldowns. Overridable viai2p.tunnel.build.maxLookupLimit.PROP_MAX_PENDING_LOOKUPS
i2p.tunnel.build.maxPendingLookupsproperty; seegetMaxPendingLookups(RouterContext).- See Also:
LOOKUP_DEADLINE_MARGIN_MS
private static final long LOOKUP_DEADLINE_MARGIN_MSGrace added to the lookup timeout for the independent slot-release deadline, so the normal callbacks (which release earlier) win the race in the common case and the deadline only catches leaks.- See Also:
STARTUP_LOOKUP_BOOST_MS
private static final long STARTUP_LOOKUP_BOOST_MSCold-start window for next-hop lookup concurrency: until this long after startup, the lookup limit uses its full configured ceiling, because the netDb miss rate is high whileparticipating x pctwould clamp concurrency to near the floor exactly when inbound builds need it most.- See Also:
_cfgCtx
The context the cached config values belong to._cfgRefreshed
private static volatile long _cfgRefreshedTime the cached config values were last read._cachedNextHopLookupTimeout
private static volatile int _cachedNextHopLookupTimeoutCached next-hop lookup timeout, in ms._cachedMinLookupLimit
private static volatile int _cachedMinLookupLimitCached floor for concurrent RI lookups._cachedMaxLookupLimit
private static volatile int _cachedMaxLookupLimitCached cap for concurrent RI lookups._cachedPercentLookupLimit
private static volatile int _cachedPercentLookupLimitCached next-hop lookup share, in percent._cachedMaxPendingLookups
private static volatile int _cachedMaxPendingLookupsCached cap on pending next-hop lookups._cachedMaxRequestFuture
private static volatile long _cachedMaxRequestFutureCached future clock skew a request may show, in ms._cachedMaxRequestAge
private static volatile long _cachedMaxRequestAgeCached oldest accepted build request age, in ms._cachedMaxRequestAgeEcies
private static volatile long _cachedMaxRequestAgeEciesSame for ECIES-encrypted requests, in ms._cachedJobLagLimitTunnel
private static volatile long _cachedJobLagLimitTunnelCached job lag past which requests are dropped, in ms._cachedMaxParticipatingTunnels
private static volatile int _cachedMaxParticipatingTunnelsCached cap on tunnels offered for transit.CONFIG_REFRESH_MS
private static final long CONFIG_REFRESH_MSAge past which the cached config is re-read.- See Also:
_tunedNextHopLookupTimeout
private static volatile int _tunedNextHopLookupTimeoutTuned lookup-limit statics, -1 = use router config. Set by the Tuner when autotuning the corresponding build params._tunedMaxLookupLimit
private static volatile int _tunedMaxLookupLimitTuner-set lookup cap, -1 when untuned._tunedPercentLookupLimit
private static volatile int _tunedPercentLookupLimitTuner-set lookup share, -1 when untuned.RATES
private static final long[] RATESRate periods shown in the throttle stats.BAN_INFLIGHT_THRESHOLD_MS
static final long BAN_INFLIGHT_THRESHOLD_MSAge below which a ban is treated as having landed during the build.A tunnel build takes tens of seconds, so a ban recorded seconds ago cannot have been visible to the peer selector that dispatched this request. Longer than that, the ban predates the request and selection handed out a peer the banlist already held.
- See Also:
BAN_DROP_WARN_INTERVAL_MS
private static final long BAN_DROP_WARN_INTERVAL_MSMinimum gap between banned-next-hop rejection warnings, and the number suppressed in between.One line per rejection buried the real warnings: a starved pool can reject hundreds of builds a minute, all identical, which is exactly when the log is needed for something else.
- See Also:
_lastBanDropWarn
private volatile long _lastBanDropWarnTime of the last ban-on-drop warning._banDropsSinceWarn
private volatile int _banDropsSinceWarnDrops counted since that warning.NEXT_HOP_REPLIED
static final int NEXT_HOP_REPLIEDOutcome of one next-hop contact, for the rate-limited WARN summary.- See Also:
NEXT_HOP_TIMEOUT
static final int NEXT_HOP_TIMEOUTNext hop did not answer within the hop-contact window.- See Also:
NEXT_HOP_DROPPED
static final int NEXT_HOP_DROPPEDWe declined the inbound build request.- See Also:
NEXT_HOP_OUTCOMES
private static final int NEXT_HOP_OUTCOMESNumber of next-hop outcome counters.- See Also:
NEXT_HOP_SUMMARY_INTERVAL_MS
static final long NEXT_HOP_SUMMARY_INTERVAL_MSHow often the next-hop summary may be logged, ms. The individual events fire hundreds of times a minute at this rate, so they stay at DEBUG and only the rolled-up ratio is worth a WARN.- See Also:
_nextHopOutcomes
Counters for each next-hop lookup outcome._nextHopSummaryLog
Time of the next next-hop summary log line.
Constructor Details
BuildHandler
Wires up the pool manager, executor and ban logger, and registers the tunnel build rate stats.- Parameters:
ctx- the router context supplying properties, logging and statisticsmanager- the pool manager this handler reports build failures and successes toexec- the executor that runs the build passes this handler queues work for
Method Details
setNextHopLookupTimeout
public static void setNextHopLookupTimeout(int ms) Set the next-hop lookup timeout (called by Tuner).- Parameters:
ms- the per-lookup timeout in ms
setMaxLookupLimit
public static void setMaxLookupLimit(int limit) Set the max concurrent RI lookup limit (called by Tuner).- Parameters:
limit- the max lookup limit
setPercentLookupLimit
public static void setPercentLookupLimit(int pct) Set the percent lookup limit (called by Tuner).- Parameters:
pct- the lookup percent
getNextHopLookupTimeout
The next-hop lookup timeout in effect, tuned value if set else config.- Parameters:
ctx- the router context- Returns:
- the per-lookup timeout in ms
getMaxLookupLimit
The max concurrent RI lookup limit in effect, tuned value if set else config.- Parameters:
ctx- the router context- Returns:
- the max lookup limit
getPercentLookupLimit
The percent lookup limit in effect, tuned value if set else config.- Parameters:
ctx- the router context- Returns:
- the lookup percent
refreshBuildConfig
Refresh the cached build configuration from properties at most once per CONFIG_REFRESH_MS, or immediately when the context changes. Benign race: duplicate refreshes are idempotent writes.- Parameters:
ctx- the router context supplying the clock and properties
getMinLookupLimit
Gives the floor for concurrent RI lookups.- Parameters:
ctx- the router being configured- Returns:
- the floor for concurrent RouterInfo lookups
getMaxPendingLookups
Pending next-hop lookups allowed to wait for a free slot while their build request is still inside the originator's budget. Sized near the useful maximum - a full queue drains inside the staleness window (drain rate x window is roughly 200) - so bursts absorb instead of dying. Entries past the originator's budget are discarded by the staleness check either way.- Parameters:
ctx- router context, for config lookup- Returns:
- the queue depth cap
lookupLimit
static int lookupLimit(int numTunnels, int minLimit, int maxLimit, int percentLimit, long uptimeMs) Concurrent next-hop lookup limit for the current request.Within
STARTUP_LOOKUP_BOOST_MSof startup the full ceiling applies regardless of participating count: the netDb is still filling, so cache misses dominate and the proportional formula would clamp concurrency to near its floor exactly when inbound builds queue up. Afterward, scale with transit population as before, floored at minLimit so a drained pool can't zero out lookups.Pure decision — safe for unit tests.
- Parameters:
numTunnels- current participating (transit) tunnel countminLimit- configured floor for the proportional formulamaxLimit- configured ceiling for the proportional formulapercentLimit- percent of participating count usable as slotsuptimeMs- router uptime in ms- Returns:
- the concurrent lookup limit, never below minLimit
attachLookupKey
static boolean attachLookupKey(ConcurrentHashMap<Hash, AtomicInteger> inFlight, Hash key, int limit) Attach a build request's next hop to the in-flight lookup set. Capacity counts DISTINCT keys: requests joining an already-attached key consume no extra slot, because the netdb coalesces duplicate lookups for one key into a single network round trip. Without this, N builds missing the same popular hop would burn N slots to run one search and starve unrelated keys.The limit is soft: racing handler threads may transiently overshoot by at most the thread count, which is harmless.
Pure decision on its map argument — safe for unit tests.
- Parameters:
inFlight- distinct next-hop keys currently being resolvedkey- next hop of this requestlimit- concurrent distinct-key ceiling- Returns:
- true if attached and a lookup should be issued; false when the ceiling is reached and the request must queue
releaseLookupKey
Release one build request's attachment to an in-flight lookup key, dropping the key entry once its last waiting request completes so released slots become visible to new arrivals.Pure decision on its map argument. Safe for unit tests.
- Parameters:
inFlight- distinct next-hop keys currently being resolvedkey- next hop being released by one request
scheduleLookupDeadline
private void scheduleLookupDeadline(BuildHandler.BuildMessageState state, Hash nextPeer, AtomicBoolean decremented, int attempts) Schedule an independent deadline that releases this request's lookup attachment if neither callback has done so by then.Slot release must never depend solely on the netdb callbacks: any silent path between attach and callback registration (a dropped job, a search that never schedules, a constructor failure) would leak the key forever, pinning the distinct-key set at its ceiling and - since the pending queue drains only from release callbacks - freezing the queue full until restart. Observed live as exactly that deadlock. With this deadline, every attachment is guaranteed to release within attempts × lookupTimeout + margin, so leaks self-heal and the queue always has a drain trigger. The attempt count covers the bounded retry chain (
MAX_NEXT_HOP_LOOKUP_RETRIES) so the deadline cannot reclaim the slot while a retry attempt is still in flight.- Parameters:
state- the build request state carrying the per-request released flag shared with the callbacksnextPeer- the attached next hopdecremented- exactly-once flag shared with HandleReq/TimeoutReqattempts- total lookup attempts covered (initial + retries)
shouldRetryLookup
static boolean shouldRetryLookup(int retriesLeft, long lookupStartedMs, long nowMs, int lookupTimeoutMs, int requestTimeoutMs) Whether a timed-out next-hop lookup deserves one more attempt. Retry only when a full extra lookup still fits inside the originator's build-request budget. Past that, the originator has given up and completing the join is wasted work (same reasoning aspendingLookupMaxAge(long, long)).- Parameters:
retriesLeft- remaining retries for this requestlookupStartedMs- wall-clock time the first lookup started, 0 if unknownnowMs- current wall-clock timelookupTimeoutMs- per-lookup timeout (ms)requestTimeoutMs- originator's build request timeout (ms)- Returns:
- true when another full attempt fits in the remaining budget
pendingLookupMaxAge
static long pendingLookupMaxAge(long requestTimeoutMs, long nextHopLookupTimeoutMs) How long a queued next-hop lookup may wait before it is discarded as stale. Capped by the originator's build request timeout less the lookup timeout: past that budget the originator has given up, so completing the join is wasted work, while discarding earlier abandons builds that could still have succeeded within the originator's budget.- Parameters:
requestTimeoutMs- the originator's build request timeout in msnextHopLookupTimeoutMs- the per-lookup timeout in ms- Returns:
- the pending entry max age in ms, always positive
getMaxRequestFuture
Gives the future clock skew a request may show.- Parameters:
ctx- the router being configured- Returns:
- the skew, in ms
getMaxRequestAge
Gives the oldest accepted build request age.- Parameters:
ctx- the router being configured- Returns:
- the age, in ms
getMaxRequestAgeEcies
Same age limit for ECIES-encrypted requests.- Parameters:
ctx- the router being configured- Returns:
- the age, in ms
getJobLagLimitTunnel
Gives the job lag past which tunnel requests are dropped.- Parameters:
ctx- the router being configured- Returns:
- the lag, in ms
getMaxParticipatingTunnels
Upper bound on participating tunnels before the router drops incoming build requests, tunable viarouter.maxParticipatingTunnels.- Parameters:
ctx- the router context whose properties are cached- Returns:
- the cached limit on participating tunnels
formatBandwidth
Formats a rate for the stats display.- Parameters:
bps- the rate, in bytes per second- Returns:
- the text to show
getMaxQueue
public static int getMaxQueue()Gets the current cap on the build message queue.- Returns:
- the cap on queued build messages
setMaxQueue
public static void setMaxQueue(int val) Sets the cap on the build message queue.- Parameters:
val- the requested cap, clamped to the range 16 to 2048
init
void init()Call the same time you start the threads.restart
public void restart()Drops any queued inbound build messages left over from before the restart.shutdown
public void shutdown(int numThreads) Cannot be restarted.- Parameters:
numThreads- the number of threads to be shut down
run
banSeverity
Classify why a next-hop peer is banlisted, for the rejection log.Pure and static so the classification is testable without a banlist. Keyed on how long the banlist has held the peer (
Banlist.getBanAge), not on the ban's duration class: a peer permanently banned mid-flight and one banned last week both report as "permanent", so the duration class cannot distinguish the case that points at peer selection from the case that points at a selection-time cooldown.- Parameters:
banAgeMs- age of the standing ban, ms; negative when unknown- Returns:
- a short label for the log line, never null
handleInboundRequest
private void handleInboundRequest()Blocking call to handle a single inbound request.handleReply
Blocking call to handle a single inbound reply.- Parameters:
state- the received reply message with its receive time
handleReply
Blocking call to handle a single inbound reply.- Parameters:
msg- the reply message whose records report each hop's resultcfg- the building tunnel config this reply was matched todelay- ms this reply waited in the queue before being handled, 0 or more
handleRequest
Decrypt the request, lookup the RI locally, and callhandleReq(RouterInfo, BuildMessageState, BuildRequestRecord, Hash)if found or queue a lookup job.- Parameters:
state- the received build message with sender and receive timenow- the current time in ms, compared against the receive time- Returns:
- handle time or -1 if it wasn't completely handled
handleRequestAsInboundEndpoint
This request is actually a reply, process it as such.- Parameters:
state- the received end message holding the reply records
drainPendingLookups
private void drainPendingLookups()Drain the pending lookup queue, starting lookups for entries while we have capacity. Discard stale entries.createRejectStats
Register the per-reason counters for build rejections we send back.Split out from the constructor so a test can prove that every name rejectStatName() hands to addRateData() is registered here. An unregistered name is dropped silently by StatManager.addRateData(), which is how the earlier "tunnel.reject." + response form measured nothing for its whole life.
- Parameters:
mgr- the stat manager to register the counters withperiods- the rate periods, normally RateConstants.SHORT_TERM_RATES
rejectStatName
Stat name for the rejection reason we answer a build request with, or null if that reason has no stat.A table rather than "tunnel.reject." + response: the concatenated names were never registered, so StatManager.addRateData() dropped every write and the router had no count of why it was rejecting builds, while the concatenation allocated a string per rejection on a path a remote peer can inflate.
- Parameters:
response- the TunnelHistory reject code- Returns:
- the registered stat name, or null if the code has none
handleReq
private void handleReq(RouterInfo nextPeerInfo, BuildHandler.BuildMessageState state, BuildRequestRecord req, Hash nextPeer) Actually process the request and send the reply.Todo: Replies are not subject to RED for bandwidth reasons, and the bandwidth is not credited to any tunnel. If we did credit the reply to the tunnel, it would prevent the classification of the tunnel as 'inactive' on tunnels.jsp.
- Parameters:
nextPeerInfo- the local RouterInfo of the next hop to forward towardstate- the received build message with sender hash and receive timereq- the decrypted request record to act onnextPeer- hash of the next hop this request is addressed to
getInboundBuildQueueSize
public int getInboundBuildQueueSize()The number of inbound build messages queued.- Returns:
- the inbound build queue size
countNextHopOutcome
Count one next-hop outcome and, at most once perNEXT_HOP_SUMMARY_INTERVAL_MS, log the ratio at WARN.This exists because the failure was invisible: 42% of handled inbound builds hit the hop-contact timeout, but the only record was one DEBUG line per event, so an eepsite silently stopped serving and nothing at WARN reflected it. The rate is the diagnostic signal, not any single event — one slow peer is noise, a sustained third of builds unanswered is a reachability problem.
- Parameters:
outcome- one ofNEXT_HOP_REPLIED,NEXT_HOP_TIMEOUT,NEXT_HOP_DROPPEDlog- the log to write to, may be nullnow- current time in ms- Returns:
- true if a summary was logged
snapshotNextHopOutcomes
static long[] snapshotNextHopOutcomes()Current next-hop outcome counts.- Returns:
- [replied, timedOut, dropped]
resetNextHopOutcomes
static void resetNextHopOutcomes()Reset the counters, for tests.nextHopSummaryText
Format the next-hop summary line. Pure so the wording and the division are testable without a live router, and so the denominator is explicit: the timeout percentage is of handled requests, not of all outcomes.- Parameters:
counts- [replied, timedOut, dropped]windowMs- window the counts cover- Returns:
- a WARN summary on two lines, plus a third naming the suspect when the unanswered rate reaches the flag threshold
getIPPortFromHash
Extract IP:port fromRouterInfofor a peer hash.- Parameters:
h- the peer hash to look up locally, unvalidated- Returns:
- host:port of the first usable address, or "UNKNOWN" if the RouterInfo is not stored locally
_x