java.lang.Object
net.i2p.router.transport.TransportManager
All Implemented Interfaces:
TransportEventListener

public class TransportManagerextends Object implements TransportEventListener
Central coordinator for all I2P transport protocols.

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.

  • Field Details

    • _log

      private final Log _log
      Logger for the transports.
    • _banLogger

      private final BanLogger _banLogger
      Records why routers were banned.
    • _transports

      private final Map<String, Transport> _transports
      Converted from List to prevent concurrent modification exceptions. If we want more than one transport with the same style we will have to change this.
    • _pluggableTransports

      private final Map<String, Transport> _pluggableTransports
      Locking: this.
    • _context

      private final RouterContext _context
      The router context.
    • _upnpManager

      private final UPnPManager _upnpManager
      The UPnP port forwarding manager.
    • _upnpRefresher

      private final SimpleTimer2.TimedEvent _upnpRefresher
      Timer refreshing the UPnP mappings.
    • _xdhThread

      private final X25519KeyFactory _xdhThread
      Factory for the NTCP2 and SSU2 key agreements.
    • _enableUDP

      private final boolean _enableUDP
      True if UDP transports are enabled.
    • _upnpUpdateQueued

      private boolean _upnpUpdateQueued
      True while a UPnP update is queued.
    • _establishedCache

      private volatile TransportManager.EstablishedSnapshot _establishedCache
      Cached getEstablished() 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_TTL
      How long a getEstablished() snapshot is reused, in ms. @since 0.9.71+.
      See Also:
    • PROP_ENABLE_UDP

      public static final String PROP_ENABLE_UDP
      Property enabling the UDP transport; defaults to true.
      See Also:
    • PROP_ENABLE_NTCP

      public static final String PROP_ENABLE_NTCP
      Property enabling the NTCP transport; defaults to true.
      See Also:
    • PROP_ENABLE_UPNP

      public static final String PROP_ENABLE_UPNP
      Property enabling UPnP port forwarding; defaults to true.
      See Also:
    • PROP_ENABLE_UPNP_IPV6

      public static final String PROP_ENABLE_UPNP_IPV6
      Enable UPnP for IPv6.
      See Also:
    • DEFAULT_ENABLE_UPNP_IPV6

      public static final boolean DEFAULT_ENABLE_UPNP_IPV6
      Default UPnP IPv6 enable.
      See Also:
    • PROP_JAVA_PROXY1

      private static final String PROP_JAVA_PROXY1
      Java property naming a SOCKS proxy.
      See Also:
    • PROP_JAVA_PROXY2

      private static final String PROP_JAVA_PROXY2
      Java property enabling the system proxies.
      See Also:
    • PROP_JAVA_PROXY3

      private static final String PROP_JAVA_PROXY3
      Java property naming the HTTP proxy.
      See Also:
    • PROP_JAVA_PROXY4

      private static final String PROP_JAVA_PROXY4
      Java property naming the HTTPS proxy.
      See Also:
    • SIGTYPE_BANLIST_DURATION

      private static final long SIGTYPE_BANLIST_DURATION
      Not forever, since they may update.
      See Also:
    • UPNP_REFRESH_TIME

      private static final long UPNP_REFRESH_TIME
      Interval between UPnP mapping refreshes.
      See Also:
    • _msgIDBloomXor

      private final long _msgIDBloomXor
      XOR value randomizing the message id bloom filter.
    • RATES

      private static final long[] RATES
      Rate stat periods for the transport statistics.
    • MAINTAINER_INTERVAL

      private static final long MAINTAINER_INTERVAL
      Interval 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_CYCLE
      Maximum per-cycle establishments to avoid flooding the network.
      See Also:
    • MAINTAINER_MIN_OUTBOUND

      private static final int MAINTAINER_MIN_OUTBOUND
      Minimum outbound Fast connections to maintain (below this, we establish more).
      See Also:
    • _outboundMaintainer

      private TransportManager.OutboundMaintainerEvent _outboundMaintainer
      Timer maintaining the outbound capacity.
    • HIGH_CAPACITY_PCT

      private static final int HIGH_CAPACITY_PCT
      Share of capacity counted as high.
      See Also:
    • BUNDLE_NAME

      private static final String BUNDLE_NAME
      Bundle holding the translated console strings.
      See Also:
  • Constructor Details

    • TransportManager

      public TransportManager(RouterContext context)
      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

      void registerAndStart(Transport t)
      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 type
      IllegalStateException - if transport style already exists
    • stopAndUnregister

      void stopAndUnregister(Transport t)
      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

      private void addTransport(Transport transport)
      Adds a started transport to the lists.
      Parameters:
      transport - the transport to add
    • removeTransport

      private void removeTransport(Transport transport)
      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

      public static boolean isNTCPEnabled(RouterContext ctx)
      Whether the NTCP transport is enabled.
      Parameters:
      ctx - the context to read the NTCP enable property from
      Returns:
      true if NTCP enabled
    • initializeAddress

      private void initializeAddress(Transport t)
      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

      private void initializeAddress(Collection<Transport> ts)
      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

      void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)
      Initialize from interfaces, and callback from UPnP or SSU. See CSFI.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 address
      ip - the new external address, 4 bytes for IPv4 or 16 for IPv6
      port - the external port, or 0 when the source did not report one
    • externalAddressRemoved

      void externalAddressRemoved(Transport.AddressSource source, boolean ipv6)
      Remove all ipv4 or ipv6 addresses. See CSFI.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 address
      ipv6 - 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. SSU
      ip - the local address the mapping was requested on
      port - the local port the mapping was requested for
      externalPort - the external port the router mapped it to
      success - true if the mapping is now in place, false if it was refused
      reason - 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

      Transport getTransport(String style)
      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

      SortedMap<String, Transport> getTransports()
      The registered transports by style, for the console pages that enumerate them.
      Returns:
      SortedMap of style to Transport (a copy)
    • getTuner

      public Tuner 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_PCT of 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

      List<Long> 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

      boolean isBacklogged(Hash peer)
      Whether any transport is backlogged to the given peer.
      Parameters:
      peer - the peer's RouterIdentity hash
      Returns:
      true if any transport is backlogged to peer
    • isEstablished

      boolean isEstablished(Hash peer)
      Whether any transport has an established connection to the given peer.
      Parameters:
      peer - the peer's RouterIdentity hash
      Returns:
      true if any transport has an established connection
    • wasFailsafeClosed

      boolean wasFailsafeClosed(Hash peer, long withinMs)
      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 about
      withinMs - 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

      boolean isConnecting(Hash peer)
      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

      public List<Hash> 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_TTL ms. 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

      void mayDisconnect(Hash peer)
      Tell the transports that we may disconnect from this peer. This is advisory only.
      Parameters:
      peer - the peer that may be dropped
    • forceDisconnect

      void forceDisconnect(Hash peer)
      Tell the transports to disconnect from this peer.
      Parameters:
      peer - the peer to disconnect from
    • forceDisconnect

      void forceDisconnect(Hash peer, String reason)
      Tell the transports to disconnect from this peer with a reason for logging.
      Parameters:
      peer - the peer hash
      reason - reason for disconnection (for logging), may be null
    • wasUnreachable

      boolean wasUnreachable(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. 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

      byte[] getIP(Hash peer)
      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

      private Set<TransportManager.Port> getPorts()
      Include the published port, or the requested port, for each transport which we will pass along to UPnP.
      Returns:
      one TransportManager.Port per 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

      TransportBid getNextBid(OutNetMessage msg)
      The best bid, skipping failed transports and unreachable peers.
      Parameters:
      msg - the message to bid on
      Returns:
      the winning bid or null
    • peerIPFromRI

      static String peerIPFromRI(RouterInfo ri)
      Build the host:port string 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

      public void messageReceived(I2NPMessage message, RouterIdentity fromRouter, Hash fromRouterHash)
      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:
      messageReceived in interface TransportEventListener
      Parameters:
      message - the received I2NP message to be processed
      fromRouter - identity of the sending router
      fromRouterHash - 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:
      transportAddressChanged in interface TransportEventListener
    • getMostRecentErrorMessages

      List<String> getMostRecentErrorMessages()
      Recent error messages from all the transports.
      Returns:
      the messages, aggregated and de-duplicated
    • renderStatusHTML

      public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException
      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 to
      urlBase - base URL for generating links
      sortFlags - flags controlling sorting and display options
      Throws:
      IOException - if writing to output fails
    • _x

      private static final String _x(String s)
      Mark a string for extraction by xgettext and translation. Use this only in static initializers. It does not translate!
      Parameters:
      s - the literal string to mark for extraction
      Returns:
      s, unchanged; the marker works by naming the literal
    • _t

      private final String _t(String s)
      Looks up a localised string in the console bundle.
      Parameters:
      s - the string to translate
      Returns:
      the localised string, or s itself when no translation exists
    • maintainOutboundConnections

      private void maintainOutboundConnections()
      Check outbound connection count and establish new ones if below threshold.
    • establishTo

      private void establishTo(Hash peer)
      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