java.lang.Object
net.i2p.router.tunnel.TunnelDispatcher
- All Implemented Interfaces:
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
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumLocation in the tunnel for RED (Random Early Discard) logic.Constructor Summary
ConstructorsConstructorDescriptionCreates a new instance of TunnelDispatcher.Method Summary
Modifier and TypeMethodDescriptionstatic voidadjustPumperThreads(int value) Change the thread count of the running pumper instance.voiddispatch(TunnelDataMessage msg, Hash recvFrom) Dispatch a TunnelDataMessage to the appropriate participant or endpoint.voidDispatch a TunnelGatewayMessage to the appropriate gateway.booleandispatchOutbound(I2NPMessage msg, TunnelId outboundTunnel, Hash targetPeer) Dispatch an outbound message through a tunnel.booleandispatchOutbound(I2NPMessage msg, TunnelId outboundTunnel, TunnelId targetTunnel, Hash targetPeer) Dispatch an outbound message through a tunnel.voidfreeBandwidth(int bw) Free allocated bandwidth for a tunnel.intThe total bandwidth allocated for participating tunnels.The tunnel IV validator, so the Tuner can retune its size.longReturns the timestamp of the last participating tunnel expiration.static intThe cap on messages a single inbound pump pass may handle.static intThe cap on messages a single outbound pump pass may handle.(package private) intThe max bandwidth per transit tunnel.A random receive tunnel ID that isn't a duplicate.A random receive tunnel ID that isn't a duplicate (zero hop).A random send tunnel ID that isn't a duplicate.intThe number of participating tunnels.static intThe per-tunnel bandwidth divisor in effect, tuned value if set elserouter.tunnel.perTunnelBweDivisorconfig, else the derived default of min(max tunnels, 100).static intThe cap on how many gateway pumper threads may run.static intThe capacity given to each gateway pumper's queue.static doubleThe pumper pool utilization as a ratio (0.0-1.0).static longThe delay before an idle gateway pumper is requeued.static intThe current bandwidth share in KBps.static floatgetTransitThrottleFactor(RouterContext ctx, float def) The transit throttle factor in effect, tuned value if set else config.booleanWhether an outbound gateway exists for the given TunnelId.booleanWe are the inbound endpoint - we created this tunnel.booleanWe are the inbound gateway in this tunnel, and did not create it.booleanWe are the outbound gateway - we created this tunnel.booleanWe are the outbound endpoint in this tunnel, and did not create it.booleanjoinParticipant(HopConfig cfg) We are a participant in this tunnel, but not as the endpoint or gateway.The participating tunnels for console display.(package private) static voidDeclare the rate stats emitted byFragmentHandleron the endpoint side.voidRemove a tunnel we're participating in.voidRemove a tunnel we created.voidRemove a tunnel from the expiration queue.voidrenderStatusHTML(Writer out) Required byService; status rendering moved to routerconsole.static voidresizePumperQueue(int value) Apply a new capacity to the running pumper instance's queue.voidrestart()Restart the TunnelDispatcher.static voidsetMaxIbMsgsPerPump(int val) The cap on messages a single inbound pump pass may handle.static voidsetMaxObMsgsPerPump(int val) The cap on messages a single outbound pump pass may handle.static voidsetPerTunnelBweDivisor(int div) Set the per-tunnel bandwidth divisor (called by Tuner).static voidsetPumperMaxThreads(int value) The cap on how many gateway pumper threads may run.static voidsetPumperQueueCapacity(int value) The capacity given to each gateway pumper's queue.static voidsetRequeueTime(long ms) The delay before an idle gateway pumper is requeued.static voidsetTransitThrottleFactor(float f) Set the transit throttle factor (called by Tuner).(package private) booleanshouldDropParticipatingInboundMessage(TunnelDispatcher.Location loc, int type, int length, SyntheticREDQueue bwe) Check if we should drop an inbound participating tunnel message.(package private) booleanshouldDropParticipatingMessage(TunnelDispatcher.Location loc, int type, int length, SyntheticREDQueue bwe) Implement RED (Random Early Discard) to enforce bandwidth limits.voidshutdown()Shut down TunnelDispatcher.voidstartup()Start up the TunnelDispatcher.voidupdateParticipatingStats(int ms) Update stats for participating tunnels.(package private) voidUpdate cached transit throttle factors from router properties.
Constructor Details
TunnelDispatcher
Creates a new instance of TunnelDispatcher.- Parameters:
ctx- the router context
Method Details
hasOutboundGateway
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
The transit throttle factor in effect, tuned value if set else config.- Parameters:
ctx- the router contextdef- 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
The per-tunnel bandwidth divisor in effect, tuned value if set elserouter.tunnel.perTunnelBweDivisorconfig, else the derived default of min(max tunnels, 100).- Parameters:
ctx- the router context- Returns:
- the per-tunnel bandwidth divisor
getIVValidator
The tunnel IV validator, so the Tuner can retune its size. Null before setup and after shutdown.- Returns:
- the validator, or null
registerFragmentStats
Declare the rate stats emitted byFragmentHandleron the endpoint side. They must be declared as required:createRateStatis a no-op unlessstat.fullis set, and StatManager discardsaddRateDatafor 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
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
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
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
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
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
A random send tunnel ID that isn't a duplicate.- Returns:
- the new o b g w i d
getNewIBEPID
A random receive tunnel ID that isn't a duplicate.- Returns:
- the new i b e p i d
getNewIBZeroHopID
A random receive tunnel ID that isn't a duplicate (zero hop).- Returns:
- the new i b zero hop i d
remove
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
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
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
Dispatch a TunnelDataMessage to the appropriate participant or endpoint.- Parameters:
msg- transit message to deliver, routed by its tunnel IDrecvFrom- hash of the peer that sent it, recorded in the dispatch log and passed on for profile accounting
dispatch
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
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 transitoutboundTunnel- send tunnel to hand the message to, which must exist or the message is droppedtargetPeer- 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 transitoutboundTunnel- send tunnel to hand the message to, which must exist or the message is droppedtargetTunnel- 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 statstargetPeer- 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
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 onlytype- message type, used for logging onlylength- message size in bytes; 0 or less is never droppedbwe- 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 onlylength- message size in bytesbwe- per-tunnel bandwidth estimator (may be null)- Returns:
- true to drop, false to accept
getMaxPerTunnelBandwidth
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
shutdown
restart
renderStatusHTML
Required byService; status rendering moved to routerconsole.- Specified by:
renderStatusHTMLin interfaceService- Parameters:
out- the writer to write to- Throws:
IOException- if an error occurs writing
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]