This class handles:
- Preparation of tunnel hop IDs
- Selection of paired or exploratory tunnels for replies
- Construction of
TunnelBuildMessage, including legacy and new-style (Short/Variable) formats - Garlic encryption for inbound builds
- Timeout and failure handling
Paired tunnels are always used (as of 0.9.50+) to improve client isolation and prevent correlation across tunnel pools.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classJob executed when the first hop of an outbound tunnel build fails to receive the request.Field Summary
FieldsModifier and TypeFieldDescriptionprivate static intCached first hop reply timeout, in ms.private static intCached build reply timeout, in ms.private static RouterContextContext the cached config values came from.private static longWhen the config values were last read.private static intTuner override for the first hop timeout.private static intTuned build timeouts, -1 = use router config.private static final intBase expiration for the TunnelBuildMessage itself.private static final longTime the cached config values stay valid.(package private) static final intPre-connect retries one tunnel may spend per window.Record order for the medium build variant.private static final int5 records (~2600 bytes) fit well within 3 tunnel messages.private static final StringOldest version with the new tunnel build messages.Record order for a full length build.(package private) static final longHow long a spent pre-connect retry is remembered.private static final intSend priority of our own build messages.(package private) static final StringProposal 168 available bandwidth property key.(package private) static final StringProposal 168 maximum bandwidth property key.(package private) static final StringProposal 168 minimum bandwidth property key.(package private) static final StringProperty to enable/disable pre-connect fallback on build failure.private static final booleanDefault: true.(package private) static final StringProposal 168 required bandwidth property key.private static final booleanDeveloper switch for the variable build records.Record order for the short build variant.private static final intBuild records sent by the short variant.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionprivate static voidbuildZeroHop(RouterContext ctx, PooledTunnelCreatorConfig cfg, BuildExecutor exec) Sends the records for a zero hop tunnel.private static TunnelBuildMessagecreateTunnelBuildMessage(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, BuildExecutor exec) Creates a tunnel build message using the most efficient format supported by all hops and the local router.static HashThe peer that will receive the tunnel build request (TBM): the gateway (peer 0) for inbound tunnels, or the next hop (peer 1) for outbound tunnels.static intHow long the OutNetMessage for the first hop gets before TunnelBuildFirstHopFailJob fires.static intHow long we wait for a reply before trying a different pool/peers.private static booleanhandleInboundBuild(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, I2NPMessage msgIn, BuildExecutor exec, Log log) Dispatch an inbound build request through the paired tunnel, garlic-wrapping the ShortTBM when the IBGW differs from the paired tunnel's endpoint so the IBGW identity stays hidden.private static voidhandleOutboundBuild(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, I2NPMessage msg, BuildExecutor exec, Log log, long firstHopTimeout) Builds and sends the records for one outbound tunnel.(package private) static booleanpreConnectFallback(RouterContext ctx, Hash peer, PooledTunnelCreatorConfig cfg, BuildExecutor exec) Approach 2: Fire-and-forget fallback — attempt to establish the transport session and retry the build once.private static voidprepare(RouterContext ctx, PooledTunnelCreatorConfig cfg) Assigns tunnel IDs to each hop in the configuration.private static voidRefresh the cached build configuration from properties at most once per CONFIG_REFRESH_MS, or immediately when the context changes.static booleanrequest(RouterContext ctx, PooledTunnelCreatorConfig cfg, BuildExecutor exec, long firstHopTimeout) Initiates a tunnel build request.private static TunnelInfoselectPairedTunnel(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec, Log log) Selects an appropriate tunnel for sending the build reply.static voidsetFirstHopTimeout(int ms) Set the first-hop timeout (called by Tuner).static voidsetRequestTimeout(int ms) Set the build request timeout (called by Tuner).private static booleanPaired tunnels are always used for client tunnels to prevent correlation between different clients or tunnel pools.
Field Details
MIN_NEWTBM_VERSION
Oldest version with the new tunnel build messages.- See Also:
SEND_VARIABLE
private static final boolean SEND_VARIABLEDeveloper switch for the variable build records.- See Also:
SHORT_RECORDS
private static final int SHORT_RECORDSBuild records sent by the short variant.- See Also:
MEDIUM_RECORDS
private static final int MEDIUM_RECORDS5 records (~2600 bytes) fit well within 3 tunnel messages.- See Also:
PROP_PRECONNECT_ENABLED
Property to enable/disable pre-connect fallback on build failure.- See Also:
PROP_PRECONNECT_ENABLED_DEFAULT
private static final boolean PROP_PRECONNECT_ENABLED_DEFAULTDefault: true.- See Also:
MAX_PRECONNECT_RETRIES
static final int MAX_PRECONNECT_RETRIESPre-connect retries one tunnel may spend per window. The fallback re-dispatches the whole build, so more than one retry per window buys nothing when the first hop is simply dead.- See Also:
PRECONNECT_RETRY_WINDOW_MS
static final long PRECONNECT_RETRY_WINDOW_MSHow long a spent pre-connect retry is remembered. Longer than two request timeouts, so a runaway first-hop loop hits the cap, while isolated failures minutes apart still get their retry.- See Also:
_cfgCtx
Context the cached config values came from._cfgRefreshed
private static volatile long _cfgRefreshedWhen the config values were last read._cachedRequestTimeout
private static volatile int _cachedRequestTimeoutCached build reply timeout, in ms._cachedFirstHopTimeout
private static volatile int _cachedFirstHopTimeoutCached first hop reply timeout, in ms.CONFIG_REFRESH_MS
private static final long CONFIG_REFRESH_MSTime the cached config values stay valid.- See Also:
_tunedRequestTimeout
private static volatile int _tunedRequestTimeoutTuned build timeouts, -1 = use router config. Set by the Tuner when autotuning the corresponding build params._tunedFirstHopTimeout
private static volatile int _tunedFirstHopTimeoutTuner override for the first hop timeout.ORDER
SHORT_ORDER
MEDIUM_ORDER
PRIORITY
private static final int PRIORITYSend priority of our own build messages.- See Also:
BUILD_MSG_TIMEOUT
private static final int BUILD_MSG_TIMEOUTBase expiration for the TunnelBuildMessage itself. Randomized per-message by +/- 20s jitter to obscure tunnel length.- See Also:
PROP_MIN_BW
Proposal 168 minimum bandwidth property key.- See Also:
PROP_REQ_BW
Proposal 168 required bandwidth property key.- See Also:
PROP_MAX_BW
Proposal 168 maximum bandwidth property key.- See Also:
PROP_AVAIL_BW
Proposal 168 available bandwidth property key.- See Also:
Constructor Details
BuildRequestor
private BuildRequestor()Prevents instantiating the utility class.
Method Details
setRequestTimeout
public static void setRequestTimeout(int ms) Set the build request timeout (called by Tuner).- Parameters:
ms- the build request timeout in ms
setFirstHopTimeout
public static void setFirstHopTimeout(int ms) Set the first-hop timeout (called by Tuner).- Parameters:
ms- the first-hop timeout in ms
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 context supplying the clock and the timeout properties
getRequestTimeout
How long we wait for a reply before trying a different pool/peers. Adaptive mechanism inBuildExecutoradjusts this upward when success rates are low or timeout rates are high. Default: 13s (normal), 18s (slow systems).- Parameters:
ctx- the router context- Returns:
- request timeout in ms
getFirstHopTimeout
How long the OutNetMessage for the first hop gets before TunnelBuildFirstHopFailJob fires. Shorter than request timeout so first-hop failure is detected before the full build timeout.- Parameters:
ctx- the router context- Returns:
- first hop timeout in ms
getBuildRequestPeer
The peer that will receive the tunnel build request (TBM): the gateway (peer 0) for inbound tunnels, or the next hop (peer 1) for outbound tunnels. BuildExecutor's per-peer pacing guard must target the same peer the dispatch code sends the request to, so both use this single derivation.Returns null for a config too short to have a hop 1. Exploratory pools build length-1 tunnels whose peer array holds only the gateway, so asking for hop 1 would throw and abandon the build outright — which stops every exploratory pool from populating.
- Parameters:
cfg- non-null; may be a short config- Returns:
- the dispatch target peer, or null if the config has no hop 1
usePairedTunnels
private static boolean usePairedTunnels()Paired tunnels are always used for client tunnels to prevent correlation between different clients or tunnel pools.Historically this was configurable via
router.usePairedTunnels, but it is now permanently enabled for security reasons.- Returns:
truealways
prepare
Assigns tunnel IDs to each hop in the configuration. For zero-hop tunnels, dummy IDs are assigned to maintain consistency.- Parameters:
ctx- the router context supplying the new tunnel IDscfg- tunnel configuration to prepare
request
public static boolean request(RouterContext ctx, PooledTunnelCreatorConfig cfg, BuildExecutor exec, long firstHopTimeout) Initiates a tunnel build request.- Parameters:
ctx- the router context issuing the buildcfg- tunnel configuration (must have ReplyMessageId set)exec- executor to notify on completionfirstHopTimeout- adaptive first-hop timeout ms (from BuildExecutor stats)- Returns:
trueif request was successfully dispatched
selectPairedTunnel
private static TunnelInfo selectPairedTunnel(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, BuildExecutor exec, Log log) Selects an appropriate tunnel for sending the build reply. Exploratory pools use exploratory tunnels. Client pools pair strictly within their own pool: borrowing another pool's tunnel for build traffic would correlate otherwise-isolated clients. If the pool has no tunnel yet (cold start), an exploratory tunnel bootstraps the first builds until the pool can pair with its own.On failure, the hops of a timed-out or refused build are cooled down out of selection (see BuildExecutor.penalizeTimeout / cooldownFailedPeers), so retries reselect peers rather than retrying the same failing set.
- Parameters:
ctx- the context supplying the tunnel managerpool- the pool being built for, deciding exploratory vs strict client pairingcfg- the new tunnel's config, whose far end the reply tunnel must reachexec- the build executor, currently unusedlog- the logger for the no-tunnel info messages- Returns:
- the tunnel to carry the build reply, or null if none is available
handleInboundBuild
private static boolean handleInboundBuild(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, I2NPMessage msgIn, BuildExecutor exec, Log log) Dispatch an inbound build request through the paired tunnel, garlic-wrapping the ShortTBM when the IBGW differs from the paired tunnel's endpoint so the IBGW identity stays hidden.- Parameters:
ctx- the context supplying the key manager and garlic layercfg- the inbound tunnel config, whose first hop receives the requestpairedTunnel- the tunnel carrying the request toward the IBGWmsgIn- the inbound TunnelBuildMessage, wrapped if the IBGW must stay hiddenexec- completes the build as failed when there is no first hop or sending failslog- the logger for the warning and error messages- Returns:
- true if the request was dispatched
handleOutboundBuild
private static void handleOutboundBuild(RouterContext ctx, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, I2NPMessage msg, BuildExecutor exec, Log log, long firstHopTimeout) Builds and sends the records for one outbound tunnel.- Parameters:
ctx- the router contextcfg- the tunnel being builtpairedTunnel- the inbound tunnel it is paired with, null if nonemsg- the build message being replaced, null for a new buildexec- the executor to run the build onlog- the logger for the buildfirstHopTimeout- the reply timeout for the first hop, in ms
createTunnelBuildMessage
private static TunnelBuildMessage createTunnelBuildMessage(RouterContext ctx, TunnelPool pool, PooledTunnelCreatorConfig cfg, TunnelInfo pairedTunnel, BuildExecutor exec) Creates a tunnel build message using the most efficient format supported by all hops and the local router.- Parameters:
ctx- the context supplying the key manager and router identitypool- the pool being built for; client pools check their destination for ECIES supportcfg- the new tunnel's config, supplying the hop session keyspairedTunnel- the tunnel carrying the reply, its first hop being the reply routerexec- the build executor, currently unused- Returns:
- the message, or
nullon error
buildZeroHop
private static void buildZeroHop(RouterContext ctx, PooledTunnelCreatorConfig cfg, BuildExecutor exec) Sends the records for a zero hop tunnel.- Parameters:
ctx- the router contextcfg- the tunnel being builtexec- the executor to run the build on
preConnectFallback
static boolean preConnectFallback(RouterContext ctx, Hash peer, PooledTunnelCreatorConfig cfg, BuildExecutor exec) Approach 2: Fire-and-forget fallback — attempt to establish the transport session and retry the build once. Called fromTunnelBuildFirstHopFailJobwhen the first hop has no established or connecting transport session.Calls
TunnelPeerSelector.preConnectTo(RouterContext, Hash)to force the session handshake, then re-dispatches the tunnel build message. Returns true if the retry was initiated.A tunnel may spend at most
MAX_PRECONNECT_RETRIESretries perPRECONNECT_RETRY_WINDOW_MS; once the budget is spent the build is abandoned rather than re-dispatched again.- Parameters:
ctx- the router contextpeer- the first-hop peer that failedcfg- the tunnel configurationexec- the build executor to notify on completion- Returns:
- true if the retry was initiated, false if pre-connect failed and the build should be abandoned