net.i2p.router.transport

## Class TransportManager

- java.lang.Object
- - net.i2p.router.transport.TransportManager

- All Implemented Interfaces:
    TransportEventListener

      public class TransportManager
      extends 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.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `(package private) static class` | `TransportManager.Port` Port configuration for transport protocols.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static boolean` | `DEFAULT_ENABLE_UPNP_IPV6`
    `static String` | `PROP_ENABLE_NTCP` default true
    `static String` | `PROP_ENABLE_UDP` default true
    `static String` | `PROP_ENABLE_UPNP` default true
    `static String` | `PROP_ENABLE_UPNP_IPV6`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `TransportManager(RouterContext context)`

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `(package private) 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.
    `(package private) int` | `countActiveSendPeers()` How many peers are we currently connected to, that we have sent a message to in the last minute.
    `(package private) void` | `externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)` Initialize from interfaces, and callback from UPnP or SSU.
    `(package private) void` | `externalAddressRemoved(Transport.AddressSource source, boolean ipv6)` Remove all ipv4 or ipv6 addresses.
    `(package private) void` | `forceDisconnect(Hash peer)` Tell the transports to disconnect from this peer.
    `(package private) void` | `forwardPortStatus(String style, byte[] ip, int port, int externalPort, boolean success, String reason)` callback from UPnP
    `(package private) List<RouterAddress>` | `getAddresses()` This forces a rebuild
    `(package private) TransportBid` | `getBid(OutNetMessage msg)`
    `(package private) List<TransportBid>` | `getBids(OutNetMessage msg)`
    `(package private) List<Long>` | `getClockSkews()` Return our peer clock skews on all transports.
    `List<Hash>` | `getEstablished()` Get list of peers with established connections across all transports.
    `byte[]` | `getIP(Hash peer)` IP of the peer from the last connection (in or out, any transport).
    `(package private) List<String>` | `getMostRecentErrorMessages()`
    `(package private) TransportBid` | `getNextBid(OutNetMessage msg)`
    `(package private) CommSystemFacade.Status` | `getReachabilityStatus()` Previously returned short, now enum as of 0.9.20
    `(package private) Transport` | `getTransport(String style)`
    `(package private) int` | `getTransportCount()`
    `(package private) SortedMap<String,Transport>` | `getTransports()`
    `(package private) X25519KeyFactory` | `getXDHFactory()` Get the X25519 key factory used by transports.
    `(package private) boolean` | `haveHighOutboundCapacity()` Are all transports well below their outbound connection limit Use for throttling in the router.
    `(package private) boolean` | `haveInboundCapacity(int pct)` Is at least one transport below its inbound connection limit + some margin Use for throttling in the router.
    `(package private) boolean` | `haveOutboundCapacity(int pct)` Is at least one transport below its outbound connection limit + some margin Use for throttling in the router.
    `(package private) void` | `initializeAddress()` Notify all transports of ALL routable interface addresses, including IPv6.
    `(package private) boolean` | `isBacklogged(Hash peer)`
    `(package private) boolean` | `isEstablished(Hash peer)`
    `static boolean` | `isNTCPEnabled(RouterContext ctx)`
    `(package private) void` | `mayDisconnect(Hash peer)` Tell the transports that we may disconnect from this peer.
    `void` | `messageReceived(I2NPMessage message, RouterIdentity fromRouter, Hash fromRouterHash)` Handle incoming I2NP message from a peer.
    `(package private) void` | `registerAndStart(Transport t)` Register and start a pluggable transport.
    `void` | `renderStatusHTML(Writer out, String urlBase, int sortFlags)` Render transport status information as HTML for console display.
    `(package private) void` | `restart()`
    `(package private) void` | `shutdown()` Cannot be restarted.
    `(package private) void` | `startListening()`
    `(package private) void` | `stopAndUnregister(Transport t)` Stop and unregister a pluggable transport.
    `(package private) void` | `stopListening()` Can be restarted.
    `void` | `transportAddressChanged()` Handle transport address change notifications.
    `(package private) boolean` | `wasUnreachable(Hash peer)` Was the peer UNreachable (outbound only) on any transport, based on the last time we tried it for each transport? This is NOT reset if the peer contacts us.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### DEFAULT_ENABLE_UPNP_IPV6

          public static final boolean DEFAULT_ENABLE_UPNP_IPV6

      See Also:
        Constant Field Values

    - #### PROP_ENABLE_NTCP

          public static final String PROP_ENABLE_NTCP

      default true
      See Also:
        Constant Field Values

    - #### PROP_ENABLE_UDP

          public static final String PROP_ENABLE_UDP

      default true
      See Also:
        Constant Field Values

    - #### PROP_ENABLE_UPNP

          public static final String PROP_ENABLE_UPNP

      default true
      See Also:
        Constant Field Values

    - #### PROP_ENABLE_UPNP_IPV6

          public static final String PROP_ENABLE_UPNP_IPV6

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### TransportManager

          public TransportManager(RouterContext context)

  - ### Method Detail

    - #### 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.

    - #### countActiveSendPeers

          int countActiveSendPeers()

      How many peers are we currently connected to, that we have sent a message to in the last minute. Unused for anything, to be removed.

    - #### 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.

    - #### externalAddressRemoved

          void externalAddressRemoved(Transport.AddressSource source,
                                      boolean ipv6)

      Remove all ipv4 or ipv6 addresses. See CSFI.notifyRemoveAddress(). Tell all transports... but don't loop.

    - #### forceDisconnect

          void forceDisconnect(Hash peer)

      Tell the transports to disconnect from this peer.

    - #### forwardPortStatus

          void forwardPortStatus(String style,
                                 byte[] ip,
                                 int port,
                                 int externalPort,
                                 boolean success,
                                 String reason)

      callback from UPnP

    - #### getAddresses

          List<RouterAddress> getAddresses()

      This forces a rebuild

    - #### getBid

          TransportBid getBid(OutNetMessage msg)

    - #### getBids

          List<TransportBid> getBids(OutNetMessage msg)

    - #### 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.

    - #### getEstablished

          public List<Hash> getEstablished()

      Get list of peers with established connections across all transports. This method aggregates established peers from all active transports (NTCP, UDP, SSU, etc.) to provide a unified view of the router's current peer connections.
      Returns:
        list of peer hashes with established connections, may be empty if no connections exist

    - #### getIP

          public 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.
      Returns:
        IPv4 or IPv6 or null

    - #### getMostRecentErrorMessages

          List<String> getMostRecentErrorMessages()

    - #### getNextBid

          TransportBid getNextBid(OutNetMessage msg)

    - #### getReachabilityStatus

          CommSystemFacade.Status getReachabilityStatus()

      Previously returned short, now enum as of 0.9.20
      Returns:
        the best status of any transport

    - #### getTransport

          Transport getTransport(String style)

    - #### getTransportCount

          int getTransportCount()

    - #### getTransports

          SortedMap<String,Transport> getTransports()

      Returns:
        SortedMap of style to Transport (a copy)

    - #### getXDHFactory

          X25519KeyFactory getXDHFactory()

      Get 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

    - #### haveHighOutboundCapacity

          boolean haveHighOutboundCapacity()

      Are all transports well below their outbound connection limit Use for throttling in the router.

    - #### 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

    - #### 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

    - #### 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.

    - #### isBacklogged

          boolean isBacklogged(Hash peer)

    - #### isEstablished

          boolean isEstablished(Hash peer)

    - #### isNTCPEnabled

          public static boolean isNTCPEnabled(RouterContext ctx)

    - #### mayDisconnect

          void mayDisconnect(Hash peer)

      Tell the transports that we may disconnect from this peer. This is advisory only.

    - #### 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

    - #### 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

    - #### renderStatusHTML

          public void renderStatusHTML(Writer out,
                                       String urlBase,
                                       int sortFlags)
                                throws IOException

      Render transport status information as HTML for console display. 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.
      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

    - #### restart

          void restart()

    - #### shutdown

          void shutdown()

      Cannot be restarted.

    - #### startListening

          void startListening()

    - #### 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

    - #### stopListening

          void stopListening()

      Can be restarted.

    - #### 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`

    - #### wasUnreachable

          boolean wasUnreachable(Hash peer)

      Was the peer UNreachable (outbound only) on any transport, based on the last time we tried it for each transport? This is NOT reset if the peer contacts us.