- All Implemented Interfaces:
TransportEventListener
This class manages the lifecycle, configuration, and coordination of all enabled transport protocols (NTCP, UDP, SSU, etc.). It provides unified access to transport functionality and handles transport-specific operations like address management, peer discovery, and message routing.
Core Responsibilities:
- Transport lifecycle management (start/stop/restart)
- Address discovery and configuration
- Peer connection management and statistics
- Message routing between transports
- UPnP integration for NAT traversal
- Bandwidth allocation and coordination
- Transport event handling and notifications
Transport Support:
- Built-in transports: NTCP, UDP, SSU
- Pluggable transport support (incomplete)
- IPv4 and IPv6 addressing
- Automatic transport selection and failover
UPnP Integration: Automatically starts and manages UPnP service for NAT traversal and port forwarding discovery.
API Access: This class is primarily internal to the router. Only a few methods are public for console and Android integration. External components should use CommSystemFacadeImpl for transport access rather than calling this class directly.
Note: This is not intended as a public API for external use. Implementation details may change without notice.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final classImmutable getEstablished() snapshot plus its expiry, holding an unmodifiable peer hash list and the wall-clock ms after which the snapshot is stale.private classPeriodically ensures we have enough outbound connections to Fast peers.(package private) static classPort configuration for transport protocols.private classDelayed update of UPnP ports.private classPeriodic refresh of UPnP ports.Field Summary
Modifier and TypeFieldDescriptionprivate final BanLoggerRecords why routers were banned.private final RouterContextThe router context.private final booleanTrue if UDP transports are enabled.CachedgetEstablished()result.private final LogLogger for the transports.private final longXOR value randomizing the message id bloom filter.Timer maintaining the outbound capacity.Locking: this.Converted from List to prevent concurrent modification exceptions.private final UPnPManagerThe UPnP port forwarding manager.private final SimpleTimer2.TimedEventTimer refreshing the UPnP mappings.private booleanTrue while a UPnP update is queued.private final X25519KeyFactoryFactory for the NTCP2 and SSU2 key agreements.private static final StringBundle holding the translated console strings.static final booleanDefault UPnP IPv6 enable.private static final longHow long a getEstablished() snapshot is reused, in ms.private static final intShare of capacity counted as high.private static final longInterval for the outbound connection maintainer (60 seconds).private static final intMaximum per-cycle establishments to avoid flooding the network.private static final intMinimum outbound Fast connections to maintain (below this, we establish more).static final StringProperty enabling the NTCP transport; defaults to true.static final StringProperty enabling the UDP transport; defaults to true.static final StringProperty enabling UPnP port forwarding; defaults to true.static final StringEnable UPnP for IPv6.private static final StringJava property naming a SOCKS proxy.private static final StringJava property enabling the system proxies.private static final StringJava property naming the HTTP proxy.private static final StringJava property naming the HTTPS proxy.private static final long[]Rate stat periods for the transport statistics.private static final longNot forever, since they may update.private static final longInterval between UPnP mapping refreshes.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionprivate final StringLooks up a localised string in the console bundle.private static final StringMark a string for extraction by xgettext and translation.private voidaddTransport(Transport transport) Adds a started transport to the lists.private voidApplies the current config to the running transports.(package private) intHow many peers are we currently connected to, that we have sent a message to or received a message from in the last five minutes.(package private) intHow many peers we have sent to in the last minute, summed across transports.private voidestablishTo(Hash peer) Trigger transport connection establishment to a peer.(package private) voidexternalAddressReceived(Transport.AddressSource source, byte[] ip, int port) Initialize from interfaces, and callback from UPnP or SSU.(package private) voidexternalAddressRemoved(Transport.AddressSource source, boolean ipv6) Remove all ipv4 or ipv6 addresses.(package private) voidforceDisconnect(Hash peer) Tell the transports to disconnect from this peer.(package private) voidforceDisconnect(Hash peer, String reason) Tell the transports to disconnect from this peer with a reason for logging.(package private) voidforwardPortStatus(String style, byte[] ip, int port, int externalPort, boolean success, String reason) Callback from UPnP, reporting whether the port mapping was established.(package private) List<RouterAddress> This forces a rebuild.(package private) TransportBidgetBid(OutNetMessage msg) The best bid for a message across all transports.(package private) List<TransportBid> getBids(OutNetMessage msg) All bids for a message across all transports.Return our peer clock skews on all transports.The list of peer hashes with established connections, may be empty.(package private) byte[]IP of the peer from the last connection (in or out, any transport).Recent error messages from all the transports.(package private) TransportBidgetNextBid(OutNetMessage msg) The best bid, skipping failed transports and unreachable peers.private Set<TransportManager.Port> getPorts()Include the published port, or the requested port, for each transport which we will pass along to UPnP.(package private) CommSystemFacade.StatusPreviously returned short, now enum as of 0.9.20.(package private) TransportgetTransport(String style) The registered transport for the given style.(package private) intCount of the registered transports.The registered transports by style, for the console pages that enumerate them.getTuner()Adaptive tuner from the UDP transport.(package private) X25519KeyFactoryThe X25519 key factory used by transports.(package private) booleanAre all transports well below their outbound connection limit Use for throttling in the router.(package private) booleanhaveInboundCapacity(int pct) Is at least one transport below its inbound connection limit + some margin Use for throttling in the router.(package private) booleanhaveOutboundCapacity(int pct) Is at least one transport below its outbound connection limit + some margin Use for throttling in the router.(package private) voidNotify all transports of ALL routable interface addresses, including IPv6.private voidNotify transports of ALL routable interface addresses, including IPv6.private voidNotify transport of ALL routable interface addresses, including IPv6.(package private) booleanisBacklogged(Hash peer) Whether any transport is backlogged to the given peer.(package private) booleanisConnecting(Hash peer) Check if any transport has a connection attempt in progress for the peer.(package private) booleanisEstablished(Hash peer) Whether any transport has an established connection to the given peer.static booleanWhether the NTCP transport is enabled.private booleanDetect system settings and log warnings.private voidCheck outbound connection count and establish new ones if below threshold.(package private) voidmayDisconnect(Hash peer) Tell the transports that we may disconnect from this peer.voidmessageReceived(I2NPMessage message, RouterIdentity fromRouter, Hash fromRouterHash) Handle incoming I2NP message from a peer.(package private) static StringBuild thehost:portstring for a peer's first usable transport address, for ban/ghost logging.(package private) voidRegister and start a pluggable transport.private voidremoveTransport(Transport transport) Removes a stopped transport from the lists.voidrenderStatusHTML(Writer out, String urlBase, int sortFlags) Render transport status information as HTML for console display.(package private) voidrestart()Restart all transports (stop, wait, start).(package private) voidshutdown()Cannot be restarted.(package private) voidStart listening on all configured transports.(package private) voidStop and unregister a pluggable transport.(package private) voidCan be restarted.voidHandle transport address change notifications.(package private) booleanwasFailsafeClosed(Hash peer, long withinMs) Whether any transport closed a session to this peer for idleness recently.(package private) booleanwasUnreachable(Hash peer) Was the peer unreachable (outbound only) on every transport, based on the last time we tried it for each transport? This is NOT reset if the peer contacts us.
Field Details
_log
Logger for the transports._banLogger
Records why routers were banned._transports
_pluggableTransports
_context
The router context._upnpManager
The UPnP port forwarding manager._upnpRefresher
Timer refreshing the UPnP mappings._xdhThread
Factory for the NTCP2 and SSU2 key agreements._enableUDP
private final boolean _enableUDPTrue if UDP transports are enabled._upnpUpdateQueued
private boolean _upnpUpdateQueuedTrue while a UPnP update is queued._establishedCache
CachedgetEstablished()result. Held as a single immutable holder so that publishing the list and its deadline is one volatile write — two separate volatiles would let a reader pair a fresh deadline with the previous list.ESTABLISHED_CACHE_TTL
private static final long ESTABLISHED_CACHE_TTLHow long a getEstablished() snapshot is reused, in ms. @since 0.9.71+.- See Also:
PROP_ENABLE_UDP
Property enabling the UDP transport; defaults to true.- See Also:
PROP_ENABLE_NTCP
Property enabling the NTCP transport; defaults to true.- See Also:
PROP_ENABLE_UPNP
Property enabling UPnP port forwarding; defaults to true.- See Also:
PROP_ENABLE_UPNP_IPV6
DEFAULT_ENABLE_UPNP_IPV6
public static final boolean DEFAULT_ENABLE_UPNP_IPV6Default UPnP IPv6 enable.- See Also:
PROP_JAVA_PROXY1
Java property naming a SOCKS proxy.- See Also:
PROP_JAVA_PROXY2
Java property enabling the system proxies.- See Also:
PROP_JAVA_PROXY3
Java property naming the HTTP proxy.- See Also:
PROP_JAVA_PROXY4
Java property naming the HTTPS proxy.- See Also:
SIGTYPE_BANLIST_DURATION
private static final long SIGTYPE_BANLIST_DURATIONNot forever, since they may update.- See Also:
UPNP_REFRESH_TIME
private static final long UPNP_REFRESH_TIMEInterval between UPnP mapping refreshes.- See Also:
_msgIDBloomXor
private final long _msgIDBloomXorXOR value randomizing the message id bloom filter.RATES
private static final long[] RATESRate stat periods for the transport statistics.MAINTAINER_INTERVAL
private static final long MAINTAINER_INTERVALInterval for the outbound connection maintainer (60 seconds). Periodically checks whether we have enough outbound connections to Fast peers and proactively establishes new ones.- See Also:
MAINTAINER_MAX_PER_CYCLE
private static final int MAINTAINER_MAX_PER_CYCLEMaximum per-cycle establishments to avoid flooding the network.- See Also:
MAINTAINER_MIN_OUTBOUND
private static final int MAINTAINER_MIN_OUTBOUNDMinimum outbound Fast connections to maintain (below this, we establish more).- See Also:
_outboundMaintainer
Timer maintaining the outbound capacity.HIGH_CAPACITY_PCT
private static final int HIGH_CAPACITY_PCTShare of capacity counted as high.- See Also:
BUNDLE_NAME
Bundle holding the translated console strings.- See Also:
Constructor Details
TransportManager
Manager for all enabled transports.- Parameters:
context- the context whose transports this manager will create and own
Method Details
isProxied
private boolean isProxied()Detect system settings and log warnings. ref: https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html- Returns:
- true if a system proxy is configured, which disables UPnP; also logs the warning explaining why
registerAndStart
Register and start a pluggable transport.This method registers a new pluggable transport (not NTCP or SSU) with the transport manager and starts it if this is the first transport being registered. The method handles validation, initialization, and lifecycle management.
Process:
- Validates transport is not built-in (NTCP/UDP)
- Checks for duplicate transport styles
- Adds to pluggable transport registry
- Sets transport event listener
- Initializes transport addresses
- Starts transport listening if first transport
- Rebuilds router info with new addresses
- Parameters:
t- the transport to register and start- Throws:
IllegalArgumentException- if transport is built-in typeIllegalStateException- if transport style already exists
stopAndUnregister
Stop and unregister a pluggable transport.This method gracefully shuts down a pluggable transport (not NTCP or SSU) and removes it from the transport registry. The method handles cleanup, listener removal, and address updates.
Process:
- Validates transport is not built-in (NTCP/UDP)
- Removes transport event listener
- Removes from pluggable transport registry
- Stops transport listening
- Removes from main transport registry
- Rebuilds router info without transport addresses
- Parameters:
t- the transport to stop and unregister- Throws:
IllegalArgumentException- if transport is built-in type
getXDHFactory
X25519KeyFactory getXDHFactory()The X25519 key factory used by transports.This method returns the key factory that provides X25519 key pairs for transport encryption operations. The factory is used by NTCP and UDP transports for ephemeral key generation in session establishment.
- Returns:
- X25519KeyFactory instance for transport cryptography
addTransport
Adds a started transport to the lists.- Parameters:
transport- the transport to add
removeTransport
Removes a stopped transport from the lists.- Parameters:
transport- the transport to remove
configTransports
private void configTransports()Applies the current config to the running transports.isNTCPEnabled
Whether the NTCP transport is enabled.- Parameters:
ctx- the context to read the NTCP enable property from- Returns:
- true if NTCP enabled
initializeAddress
Notify transport of ALL routable interface addresses, including IPv6. It's the transport's job to ignore what it can't handle.- Parameters:
t- the transport to notify
initializeAddress
void initializeAddress()Notify all transports of ALL routable interface addresses, including IPv6. It's the transport's job to ignore what it can't handle.initializeAddress
Notify transports of ALL routable interface addresses, including IPv6. It's the transport's job to ignore what it can't handle.- Parameters:
ts- the transports to notify
externalAddressReceived
Initialize from interfaces, and callback from UPnP or SSU. SeeCSFI.notifyReplaceAddress(). Tell all transports... but don't loop.- Parameters:
source- where the address came from, so the transport that reported it is not told about its own addressip- the new external address, 4 bytes for IPv4 or 16 for IPv6port- the external port, or 0 when the source did not report one
externalAddressRemoved
Remove all ipv4 or ipv6 addresses. SeeCSFI.notifyRemoveAddress(). Tell all transports... but don't loop.- Parameters:
source- where the removal came from, so the transport that reported it is not told to drop its own addressipv6- true to remove the IPv6 addresses, false for the IPv4 ones
forwardPortStatus
void forwardPortStatus(String style, byte[] ip, int port, int externalPort, boolean success, String reason) Callback from UPnP, reporting whether the port mapping was established.- Parameters:
style- the transport style the mapping was requested for, e.g. SSUip- the local address the mapping was requested onport- the local port the mapping was requested forexternalPort- the external port the router mapped it tosuccess- true if the mapping is now in place, false if it was refusedreason- the router's explanation, used when success is false
startListening
void startListening()Start listening on all configured transports.restart
void restart()Restart all transports (stop, wait, start).stopListening
void stopListening()Can be restarted.shutdown
void shutdown()Cannot be restarted.getTransport
The registered transport for the given style.- Parameters:
style- a transport style, e.g.Transport.STYLE_SSU- Returns:
- the transport for the given style or null
getTransportCount
int getTransportCount()Count of the registered transports.- Returns:
- the number in the list
getTransports
getTuner
Adaptive tuner from the UDP transport.- Returns:
- the adaptive tuner, or null if not available
countActivePeers
int countActivePeers()How many peers are we currently connected to, that we have sent a message to or received a message from in the last five minutes.- Returns:
- the summed count across every transport
countActiveSendPeers
int countActiveSendPeers()How many peers we have sent to in the last minute, summed across transports.Each transport owns the window, so this is a strict sum and not a union: a peer reachable over both NTCP and UDP counts on each. The transports maintain this by summing two such counts, matching how
countActivePeers()is built, so the two are directly comparable.- Returns:
- the number of peers sent to in the last minute, summed across every transport, and so a peer reachable over two of them counted twice
haveOutboundCapacity
boolean haveOutboundCapacity(int pct) Is at least one transport below its outbound connection limit + some margin Use for throttling in the router.- Parameters:
pct- percent of limit 0-100- Returns:
- true if at least one transport is under pct of its outbound limit
haveHighOutboundCapacity
boolean haveHighOutboundCapacity()Are all transports well below their outbound connection limit Use for throttling in the router.- Returns:
- true if every transport is under
HIGH_CAPACITY_PCTof its outbound limit; false if there are no transports at all
haveInboundCapacity
boolean haveInboundCapacity(int pct) Is at least one transport below its inbound connection limit + some margin Use for throttling in the router.- Parameters:
pct- percent of limit 0-100- Returns:
- true if at least one transport with a current address is under pct of its inbound limit
getClockSkews
Return our peer clock skews on all transports. List composed of Long, each element representing a peer skew in seconds. A positive number means our clock is ahead of theirs. Note: this method returns them in whimsical order.- Returns:
- the skews in seconds collected from every transport, never null
getReachabilityStatus
CommSystemFacade.Status getReachabilityStatus()Previously returned short, now enum as of 0.9.20.- Returns:
- the best status of any transport
isBacklogged
Whether any transport is backlogged to the given peer.- Parameters:
peer- the peer'sRouterIdentityhash- Returns:
- true if any transport is backlogged to peer
isEstablished
Whether any transport has an established connection to the given peer.- Parameters:
peer- the peer'sRouterIdentityhash- Returns:
- true if any transport has an established connection
wasFailsafeClosed
Whether any transport closed a session to this peer for idleness recently. True when at least one transport remembers such a close, which is enough to attribute a connectivity loss to this router rather than to the peer.- Parameters:
peer- the peer to ask aboutwithinMs- how far back counts as recent; non-positive means nothing is- Returns:
- true when some transport closed a session to the peer that recently
isConnecting
Check if any transport has a connection attempt in progress for the peer.- Parameters:
peer- hash of the peer to check- Returns:
- true if at least one transport is currently establishing
getEstablished
The list of peer hashes with established connections, may be empty.The result is an unmodifiable snapshot shared across callers for up to
ESTABLISHED_CACHE_TTLms. Merging cost two list allocations plus two full traversals of the NTCP and SSU connection tables, and BuildRequestor alone calls this up to five times per tunnel build. Every caller (ProfileOrganizer selection, BuildRequestor logging and hop checks, ConnectChecker, ExploratoryPeerSelector, KademliaNetworkDatabaseFacade, and our own outbound maintainer) only reads the list, so sharing is safe; the TTL is well under the 60s maintainer interval, so the only possible effect is a momentarily stale view of which peers are connected.- Returns:
- unmodifiable list of peer hashes with established connections, may be empty
mayDisconnect
Tell the transports that we may disconnect from this peer. This is advisory only.- Parameters:
peer- the peer that may be dropped
forceDisconnect
Tell the transports to disconnect from this peer.- Parameters:
peer- the peer to disconnect from
forceDisconnect
wasUnreachable
Was the peer unreachable (outbound only) on every transport, based on the last time we tried it for each transport? This is NOT reset if the peer contacts us. A single transport that reached the peer makes this false, and with no transports registered at all it is vacuously true.- Parameters:
peer- the peer to test- Returns:
- true only if no transport has reached the peer since its last attempt
getIP
IP of the peer from the last connection (in or out, any transport). This may be different from that advertised in the netDb, as the peer may be hidden, or connect from a different IP, or change his netDb later, in an attempt to avoid restrictions.For blocking purposes, etc. it's worth checking both the netDb addresses and this address.
- Parameters:
peer- the peer whose last known address is wanted- Returns:
- IPv4 or IPv6 or null
getAddresses
List<RouterAddress> getAddresses()This forces a rebuild.- Returns:
- the addresses every transport currently publishes, after asking each to refresh
getPorts
Include the published port, or the requested port, for each transport which we will pass along to UPnP.- Returns:
- one
TransportManager.Portper transport style and address family that is listening, un-firewalled and not disabled; empty when we are hidden
getBid
The best bid for a message across all transports.- Parameters:
msg- the message to bid on- Returns:
- the winning bid or null
getBids
All bids for a message across all transports.- Parameters:
msg- the message to bid on- Returns:
- list of bids, never null
getNextBid
The best bid, skipping failed transports and unreachable peers.- Parameters:
msg- the message to bid on- Returns:
- the winning bid or null
peerIPFromRI
Build thehost:portstring for a peer's first usable transport address, for ban/ghost logging. Returns "" if the RouterInfo has no usable address. Only called on the rare unreachable/ban path, not per message.- Parameters:
ri- the target RouterInfo- Returns:
- the peer IP:port, or "" if none
messageReceived
Handle incoming I2NP message from a peer.This method is called by transports when they receive an I2NP message that needs to be processed by the router. The TransportManager acts as a central message dispatcher and routes messages to appropriate handlers.
- Specified by:
messageReceivedin interfaceTransportEventListener- Parameters:
message- the received I2NP message to be processedfromRouter- identity of the sending routerfromRouterHash- hash of the sending router for quick lookup
transportAddressChanged
public void transportAddressChanged()Handle transport address change notifications.This method is called when any transport reports a change in its advertised addresses. The TransportManager coordinates address updates across all transports and updates the router's published information accordingly.
This method is typically called by transports in response to:
- UPnP address discovery
- Interface address changes
- Configuration updates
- Network topology changes
- Specified by:
transportAddressChangedin interfaceTransportEventListener
getMostRecentErrorMessages
renderStatusHTML
Render transport status information as HTML for console display.As of 0.9.31, only outputs UPnP status.
This method generates detailed HTML status for all transports, including connection counts, peer information, bandwidth usage, and transport-specific statistics. The output is used by the router console for transport monitoring.
Warning - blocking, very slow, queries the active UPnP router, will take many seconds if it has vanished.
- Parameters:
out- writer to write HTML output tourlBase- base URL for generating linkssortFlags- flags controlling sorting and display options- Throws:
IOException- if writing to output fails
_x
_t
maintainOutboundConnections
private void maintainOutboundConnections()Check outbound connection count and establish new ones if below threshold.establishTo
Trigger transport connection establishment to a peer. Uses a DatabaseLookupMessage to warm the connection, which triggers a real handshake and keeps the session alive (peer replies with its RouterInfo). NTCP crashes on null messages, so we always provide a real payload.- Parameters:
peer- the peer to connect to