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

public abstract class BuildRequestorextends Object
Utility class for creating and dispatching tunnel build request messages.

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.

  • Field Details

    • MIN_NEWTBM_VERSION

      private static final String MIN_NEWTBM_VERSION
      Oldest version with the new tunnel build messages.
      See Also:
    • SEND_VARIABLE

      private static final boolean SEND_VARIABLE
      Developer switch for the variable build records.
      See Also:
    • SHORT_RECORDS

      private static final int SHORT_RECORDS
      Build records sent by the short variant.
      See Also:
    • MEDIUM_RECORDS

      private static final int MEDIUM_RECORDS
      5 records (~2600 bytes) fit well within 3 tunnel messages.
      See Also:
    • PROP_PRECONNECT_ENABLED

      static final String 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_DEFAULT
      Default: true.
      See Also:
    • MAX_PRECONNECT_RETRIES

      static final int MAX_PRECONNECT_RETRIES
      Pre-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_MS
      How 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

      private static volatile RouterContext _cfgCtx
      Context the cached config values came from.
    • _cfgRefreshed

      private static volatile long _cfgRefreshed
      When the config values were last read.
    • _cachedRequestTimeout

      private static volatile int _cachedRequestTimeout
      Cached build reply timeout, in ms.
    • _cachedFirstHopTimeout

      private static volatile int _cachedFirstHopTimeout
      Cached first hop reply timeout, in ms.
    • CONFIG_REFRESH_MS

      private static final long CONFIG_REFRESH_MS
      Time the cached config values stay valid.
      See Also:
    • _tunedRequestTimeout

      private static volatile int _tunedRequestTimeout
      Tuned build timeouts, -1 = use router config. Set by the Tuner when autotuning the corresponding build params.
    • _tunedFirstHopTimeout

      private static volatile int _tunedFirstHopTimeout
      Tuner override for the first hop timeout.
    • ORDER

      private static final List<Integer> ORDER
      Record order for a full length build.
    • SHORT_ORDER

      private static final List<Integer> SHORT_ORDER
      Record order for the short build variant.
    • MEDIUM_ORDER

      private static final List<Integer> MEDIUM_ORDER
      Record order for the medium build variant.
    • PRIORITY

      private static final int PRIORITY
      Send priority of our own build messages.
      See Also:
    • BUILD_MSG_TIMEOUT

      private static final int BUILD_MSG_TIMEOUT
      Base expiration for the TunnelBuildMessage itself. Randomized per-message by +/- 20s jitter to obscure tunnel length.
      See Also:
    • PROP_MIN_BW

      static final String PROP_MIN_BW
      Proposal 168 minimum bandwidth property key.
      See Also:
    • PROP_REQ_BW

      static final String PROP_REQ_BW
      Proposal 168 required bandwidth property key.
      See Also:
    • PROP_MAX_BW

      static final String PROP_MAX_BW
      Proposal 168 maximum bandwidth property key.
      See Also:
    • PROP_AVAIL_BW

      static final String 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

      private static void refreshBuildConfig(RouterContext ctx)
      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

      public static int getRequestTimeout(RouterContext ctx)
      How long we wait for a reply before trying a different pool/peers. Adaptive mechanism in BuildExecutor adjusts 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

      public static int getFirstHopTimeout(RouterContext ctx)
      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

      public static Hash getBuildRequestPeer(PooledTunnelCreatorConfig cfg)
      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:
      true always
    • prepare

      private static void prepare(RouterContext ctx, PooledTunnelCreatorConfig cfg)
      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 IDs
      cfg - 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 build
      cfg - tunnel configuration (must have ReplyMessageId set)
      exec - executor to notify on completion
      firstHopTimeout - adaptive first-hop timeout ms (from BuildExecutor stats)
      Returns:
      true if 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 manager
      pool - the pool being built for, deciding exploratory vs strict client pairing
      cfg - the new tunnel's config, whose far end the reply tunnel must reach
      exec - the build executor, currently unused
      log - 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 layer
      cfg - the inbound tunnel config, whose first hop receives the request
      pairedTunnel - the tunnel carrying the request toward the IBGW
      msgIn - the inbound TunnelBuildMessage, wrapped if the IBGW must stay hidden
      exec - completes the build as failed when there is no first hop or sending fails
      log - 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 context
      cfg - the tunnel being built
      pairedTunnel - the inbound tunnel it is paired with, null if none
      msg - the build message being replaced, null for a new build
      exec - the executor to run the build on
      log - the logger for the build
      firstHopTimeout - 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 identity
      pool - the pool being built for; client pools check their destination for ECIES support
      cfg - the new tunnel's config, supplying the hop session keys
      pairedTunnel - the tunnel carrying the reply, its first hop being the reply router
      exec - the build executor, currently unused
      Returns:
      the message, or null on error
    • buildZeroHop

      private static void buildZeroHop(RouterContext ctx, PooledTunnelCreatorConfig cfg, BuildExecutor exec)
      Sends the records for a zero hop tunnel.
      Parameters:
      ctx - the router context
      cfg - the tunnel being built
      exec - 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 from TunnelBuildFirstHopFailJob when 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_RETRIES retries per PRECONNECT_RETRY_WINDOW_MS; once the budget is spent the build is abandoned rather than re-dispatched again.

      Parameters:
      ctx - the router context
      peer - the first-hop peer that failed
      cfg - the tunnel configuration
      exec - 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