java.lang.Object
net.i2p.router.tunnel.TunnelDispatcher
All Implemented Interfaces:
Service

public class TunnelDispatcherextends Object implements Service
Handle the actual processing and forwarding of messages through the various tunnels.
For each type of tunnel, it creates a chain of handlers, as follows:

Following tunnels are created by us:

    Outbound Gateway > 0 hops:
      PumpedTunnelGateway
        BatchedRouterPreprocessor -> OutboundSender -> OutboundReceiver -> OutNetMessagePool

    Outbound zero-hop Gateway+Endpoint:
      TunnelGatewayZeroHop
        OutboundMessageDistributor -> OutNetMessagePool

    Inbound Endpoint > 0 hops:
      TunnelParticipant
       FragmentHandler ->  InboundEndpointProcessor -> InboundMessageDistributor -> InNetMessagePool

    Inbound zero-hop Gateway+Endpoint:
      TunnelGatewayZeroHop
        InboundMessageDistributor -> InNetMessagePool


Following tunnels are NOT created by us:

    Participant (not gateway or endpoint)
      TunnelParticipant
        HopProcessor -> OutNetMessagePool

    Outbound Endpoint > 0 hops:
      OutboundTunnelEndpoint
        FragmentHandler -> HopProcessor -> OutboundMessageDistributor -> OutNetMessagePool

    Inbound Gateway > 0 hops:
      ThrottledPumpedTunnelGateway
        BatchedRouterPreprocessor -> InboundSender -> InboundGatewayReceiver -> OutNetMessagePool
  • Constructor Details

    • TunnelDispatcher

      public TunnelDispatcher(RouterContext ctx)
      Creates a new instance of TunnelDispatcher.
      Parameters:
      ctx - the router context
  • Method Details

    • hasOutboundGateway

      public boolean hasOutboundGateway(TunnelId tid)
      Whether an outbound gateway exists for the given TunnelId. Lets callers avoid dispatching to a tunnel that is not ready yet.
      Parameters:
      tid - the tunnel ID
      Returns:
      true if we currently have an outbound gateway for the given TunnelId.
    • setTransitThrottleFactor

      public static void setTransitThrottleFactor(float f)
      Set the transit throttle factor (called by Tuner).
      Parameters:
      f - the transit throttle factor
    • getTransitThrottleFactor

      public static float getTransitThrottleFactor(RouterContext ctx, float def)
      The transit throttle factor in effect, tuned value if set else config.
      Parameters:
      ctx - the router context
      def - fallback when neither tuned nor configured (0.95f outbound, 0.0f inbound)
      Returns:
      the transit throttle factor
    • setPerTunnelBweDivisor

      public static void setPerTunnelBweDivisor(int div)
      Set the per-tunnel bandwidth divisor (called by Tuner).
      Parameters:
      div - the per-tunnel bandwidth divisor
    • getPerTunnelBweDivisor

      public static int getPerTunnelBweDivisor(RouterContext ctx)
      The per-tunnel bandwidth divisor in effect, tuned value if set else router.tunnel.perTunnelBweDivisor config, else the derived default of min(max tunnels, 100).
      Parameters:
      ctx - the router context
      Returns:
      the per-tunnel bandwidth divisor
    • getIVValidator

      public BloomFilterIVValidator getIVValidator()
      The tunnel IV validator, so the Tuner can retune its size. Null before setup and after shutdown.
      Returns:
      the validator, or null
    • registerFragmentStats

      static void registerFragmentStats(StatManager sm)
      Declare the rate stats emitted by FragmentHandler on the endpoint side. They must be declared as required: createRateStat is a no-op unless stat.full is set, and StatManager discards addRateData for an unregistered stat, so these failure and abuse signals would silently never appear in the default configuration.

      Package-visible and static so a unit test can assert the registration without standing up a whole router.

      Parameters:
      sm - the stat manager to declare into
    • getLastParticipatingExpiration

      public long getLastParticipatingExpiration()
      Returns the timestamp of the last participating tunnel expiration.
      Returns:
      last expiration in milliseconds since epoch, or -1 if none
    • joinOutbound

      public boolean joinOutbound(TunnelCreatorConfig cfg)
      We are the outbound gateway - we created this tunnel.
      Parameters:
      cfg - config for the outbound tunnel we created
      Returns:
      true if successful, false if tunnel ID is a duplicate
    • joinInbound

      public boolean joinInbound(TunnelCreatorConfig cfg)
      We are the inbound endpoint - we created this tunnel.
      Parameters:
      cfg - config for the inbound tunnel we created
      Returns:
      true if successful, false if tunnel ID is a duplicate
    • joinParticipant

      public boolean joinParticipant(HopConfig cfg)
      We are a participant in this tunnel, but not as the endpoint or gateway.
      Parameters:
      cfg - config for the tunnel we're joining as participant
      Returns:
      true if successful, false if tunnel ID is a duplicate
    • joinOutboundEndpoint

      public boolean joinOutboundEndpoint(HopConfig cfg)
      We are the outbound endpoint in this tunnel, and did not create it.
      Parameters:
      cfg - config for the tunnel we're joining as outbound endpoint
      Returns:
      true if successful, false if tunnel ID is a duplicate
    • joinInboundGateway

      public boolean joinInboundGateway(HopConfig cfg)
      We are the inbound gateway in this tunnel, and did not create it.
      Parameters:
      cfg - config for the tunnel we're joining as inbound gateway
      Returns:
      true if successful, false if tunnel ID is a duplicate
    • getAllocatedBW

      public int getAllocatedBW()
      The total bandwidth allocated for participating tunnels.
      Returns:
      the allocated b w
    • getParticipatingCount

      public int getParticipatingCount()
      The number of participating tunnels.
      Returns:
      the participating count
    • getNewOBGWID

      public TunnelId getNewOBGWID()
      A random send tunnel ID that isn't a duplicate.
      Returns:
      the new o b g w i d
    • getNewIBEPID

      public TunnelId getNewIBEPID()
      A random receive tunnel ID that isn't a duplicate.
      Returns:
      the new i b e p i d
    • getNewIBZeroHopID

      public TunnelId getNewIBZeroHopID()
      A random receive tunnel ID that isn't a duplicate (zero hop).
      Returns:
      the new i b zero hop i d
    • remove

      public void remove(TunnelCreatorConfig cfg)
      Remove a tunnel we created.
      Parameters:
      cfg - the tunnel being dropped, whose direction picks the outbound gateway or inbound participant map it is removed from, and whose message and failure counts are recorded in the stats
    • remove

      public void remove(HopConfig cfg)
      Remove a tunnel we're participating in.
      Parameters:
      cfg - the tunnel being dropped, identified by its receive tunnel; releases its allocated bandwidth, null is ignored, and a second removal of the same config is a no-op
    • freeBandwidth

      public void freeBandwidth(int bw)
      Free allocated bandwidth for a tunnel. Called when dropping idle tunnels.
      Parameters:
      bw - bytes per second to give back to the participating allocation; 0 or less is ignored so the total can never go negative
    • removeFromExpirationQueue

      public void removeFromExpirationQueue(HopConfig cfg)
      Remove a tunnel from the expiration queue. Called when dropping idle tunnels to prevent memory leaks.
      Parameters:
      cfg - tunnel to stop tracking for expiry, matched by identity; null is ignored
    • dispatch

      public void dispatch(TunnelDataMessage msg, Hash recvFrom)
      Dispatch a TunnelDataMessage to the appropriate participant or endpoint.
      Parameters:
      msg - transit message to deliver, routed by its tunnel ID
      recvFrom - hash of the peer that sent it, recorded in the dispatch log and passed on for profile accounting
    • dispatch

      public void dispatch(TunnelGatewayMessage msg)
      Dispatch a TunnelGatewayMessage to the appropriate gateway.
      Parameters:
      msg - gateway message wrapping the I2NP message to forward; both its own and the wrapped expiration must fall within -CLOCK_FUDGE_FACTOR and +MAX_FUTURE_EXPIRATION of now
    • dispatchOutbound

      public boolean dispatchOutbound(I2NPMessage msg, TunnelId outboundTunnel, Hash targetPeer)
      Dispatch an outbound message through a tunnel.
      Parameters:
      msg - message to send; an already expired one is dropped, and a short expiration is extended to at least 20s for transit
      outboundTunnel - send tunnel to hand the message to, which must exist or the message is dropped
      targetPeer - hash of the eventual destination, passed to the gateway for per-peer limits and message history
      Returns:
      true if the message was accepted by the tunnel gateway, false if dropped
    • dispatchOutbound

      public boolean dispatchOutbound(I2NPMessage msg, TunnelId outboundTunnel, TunnelId targetTunnel, Hash targetPeer)
      Dispatch an outbound message through a tunnel.
      Parameters:
      msg - message to send; an already expired one is dropped, and a short expiration is extended to at least 20s for transit
      outboundTunnel - send tunnel to hand the message to, which must exist or the message is dropped
      targetTunnel - tunnel of a target that is itself reachable, or null for an ordinary peer destination; a non-null value also marks the dispatch as tunnel-targeted in the stats
      targetPeer - hash of the eventual destination, passed to the gateway for per-peer limits and message history
      Returns:
      true if the message was accepted by the tunnel gateway, false if dropped
    • listParticipatingTunnels

      public List<HopConfig> listParticipatingTunnels()
      The participating tunnels for console display. Filters out tunnels that are > 30 seconds past expiration.
      Returns:
      snapshot list of the participating tunnel configs still within 30s of their expiration
    • updateParticipatingStats

      public void updateParticipatingStats(int ms)
      Update stats for participating tunnels.
      Parameters:
      ms - length in ms of the coalescing interval the counters cover; also the averaging period applied to the message rates, so the per-tunnel average is scaled to a 10 minute figure
    • updateThrottleFactors

      void updateThrottleFactors()
      Update cached transit throttle factors from router properties.
    • shouldDropParticipatingMessage

      boolean shouldDropParticipatingMessage(TunnelDispatcher.Location loc, int type, int length, SyntheticREDQueue bwe)
      Implement RED (Random Early Discard) to enforce bandwidth limits. Only active when queue size > minThreshold (congestion). When queue > maxThreshold, ALL messages are dropped (regardless of factor).
      Parameters:
      loc - role of the sender in the tunnel, used for logging only
      type - message type, used for logging only
      length - message size in bytes; 0 or less is never dropped
      bwe - per-tunnel estimator consulted before the global limit, may be null to skip the per-tunnel check
      Returns:
      true to drop, false to accept
    • shouldDropParticipatingInboundMessage

      boolean shouldDropParticipatingInboundMessage(TunnelDispatcher.Location loc, int type, int length, SyntheticREDQueue bwe)
      Check if we should drop an inbound participating tunnel message. Implements symmetric throttling: both inbound and outbound transit traffic should be throttled equally to prevent inbound traffic from overwhelming outbound capacity.
      Parameters:
      loc - location in tunnel (IBGP, PARTICIPANT, OBEP)
      type - I2NP message type, reported in the drop log only
      length - message size in bytes
      bwe - per-tunnel bandwidth estimator (may be null)
      Returns:
      true to drop, false to accept
    • getMaxPerTunnelBandwidth

      int getMaxPerTunnelBandwidth(TunnelDispatcher.Location loc)
      The max bandwidth per transit tunnel. Scales with allocation: higher share = higher per-tunnel cap. Uses outbound bandwidth only. On floodfill routers inbound is far smaller than outbound and would create an artificial bottleneck.
      Parameters:
      loc - role in the tunnel, currently unused; the cap depends only on the outbound rate and our share percentage
      Returns:
      cap in bytes per second, floored at 10KB (30KB or 50KB for the larger allocation tiers) once the computed value exceeds 256KB
    • startup

      public void startup()
      Start up the TunnelDispatcher.
      Specified by:
      startup in interface Service
    • shutdown

      public void shutdown()
      Shut down TunnelDispatcher.
      Specified by:
      shutdown in interface Service
    • restart

      public void restart()
      Restart the TunnelDispatcher.
      Specified by:
      restart in interface Service
    • renderStatusHTML

      public void renderStatusHTML(Writer out) throws IOException
      Required by Service; status rendering moved to routerconsole.
      Specified by:
      renderStatusHTML in interface Service
      Parameters:
      out - the writer to write to
      Throws:
      IOException - if an error occurs writing
    • getShareBandwidth

      public static int getShareBandwidth(RouterContext ctx)
      The current bandwidth share in KBps.
      Parameters:
      ctx - router context whose bandwidth limiter and share percentage are read
      Returns:
      the share bandwidth
    • getRequeueTime

      public static long getRequeueTime()
      The delay before an idle gateway pumper is requeued.
      Returns:
      the requeue delay in ms
    • setRequeueTime

      public static void setRequeueTime(long ms)
      The delay before an idle gateway pumper is requeued.
      Parameters:
      ms - delay in ms, clamped to [10, 200]
    • getMaxObMsgsPerPump

      public static int getMaxObMsgsPerPump()
      The cap on messages a single outbound pump pass may handle.
      Returns:
      the max outbound messages per pump
    • getPumperQueueCapacity

      public static int getPumperQueueCapacity()
      The capacity given to each gateway pumper's queue.
      Returns:
      the per-pumper queue capacity
    • setPumperQueueCapacity

      public static void setPumperQueueCapacity(int value)
      The capacity given to each gateway pumper's queue.
      Parameters:
      value - capacity, clamped to [64, 4096]; takes effect on the next pumper, existing queues are untouched
    • resizePumperQueue

      public static void resizePumperQueue(int value)
      Apply a new capacity to the running pumper instance's queue.
      Parameters:
      value - capacity to resize to
    • getPumperMaxThreads

      public static int getPumperMaxThreads()
      The cap on how many gateway pumper threads may run.
      Returns:
      the max pumper threads
    • getPumperUtilization

      public static double getPumperUtilization()
      The pumper pool utilization as a ratio (0.0-1.0). Returns NaN if not started.
      Returns:
      the pumper utilization
    • setPumperMaxThreads

      public static void setPumperMaxThreads(int value)
      The cap on how many gateway pumper threads may run.
      Parameters:
      value - thread count, clamped to [2, 16]
    • adjustPumperThreads

      public static void adjustPumperThreads(int value)
      Change the thread count of the running pumper instance.
      Parameters:
      value - desired thread count, applied to the live instance
    • setMaxObMsgsPerPump

      public static void setMaxObMsgsPerPump(int val)
      The cap on messages a single outbound pump pass may handle.
      Parameters:
      val - messages per pump, clamped to [8, 1024]
    • getMaxIbMsgsPerPump

      public static int getMaxIbMsgsPerPump()
      The cap on messages a single inbound pump pass may handle.
      Returns:
      the max inbound messages per pump
    • setMaxIbMsgsPerPump

      public static void setMaxIbMsgsPerPump(int val)
      The cap on messages a single inbound pump pass may handle.
      Parameters:
      val - messages per pump, clamped to [8, 1024]