All Known Implementing Classes:
NTCPTransport, TransportImpl, UDPTransport

public interface Transport
Core interface for I2P transport protocols.

This interface defines the contract for all transport implementations that enable I2P routers to communicate with each other. Transports handle message sending, receiving, peer management, and network address configuration.

Transport Types:

  • NTCP - Stream-based TCP transport with encryption
  • UDP - Datagram-based transport with reliability
  • SSU - Sessionless UDP for introduction

Implementation Requirements:

  • Implement all interface methods for proper functionality
  • Handle both IPv4 and IPv6 addressing
  • Support concurrent message sending and receiving
  • Provide proper error handling and logging
  • Integrate with TransportManager lifecycle

Plugin Development: To implement a new transport plugin:

  1. Implement this interface and required base classes
  2. Add transport to TransportManager.startListening()
  3. Ensure proper configuration and discovery
  4. Test with existing I2P network compatibility

Note: API is subject to change. Please contact the I2P development team if you're writing a new transport or transport plugin to ensure compatibility and guidance.

The style and config-key constants are the single source of truth; the concrete transports keep legacy aliases for them (e.g. NTCPTransport.STYLE == Transport.STYLE_NTCP).

  • Field Details

    • STYLE_NTCP

      static final String STYLE_NTCP
      Style identifier for the NTCP transport, used in RouterAddress style tags, transport map keys, and style comparisons.
      See Also:
    • STYLE_NTCP2

      static final String STYLE_NTCP2
      Style identifier for the NTCP2 protocol variant of the NTCP transport.
      See Also:
    • STYLE_SSU

      static final String STYLE_SSU
      Style identifier for the SSU transport, used in RouterAddress style tags, transport map keys, and style comparisons.
      See Also:
    • STYLE_SSU2

      static final String STYLE_SSU2
      Style identifier for the SSU2 protocol variant of the SSU transport.
      See Also:
    • PROP_I2NP_NTCP_PORT

      static final String PROP_I2NP_NTCP_PORT
      Config key for the port the NTCP transport listens for inbound connections on.
      See Also:
    • PROP_I2NP_NTCP_AUTO_PORT

      static final String PROP_I2NP_NTCP_AUTO_PORT
      Config key controlling whether NTCP may auto-update its advertised port based on peer feedback.
      See Also:
    • PROP_I2NP_NTCP_AUTO_IP

      static final String PROP_I2NP_NTCP_AUTO_IP
      Config key controlling whether NTCP may auto-update its advertised IP based on peer feedback.
      See Also:
    • PROP_I2NP_NTCP_HOSTNAME

      static final String PROP_I2NP_NTCP_HOSTNAME
      Config key for an explicitly configured hostname the NTCP transport advertises. The SSU equivalent is PROP_EXTERNAL_HOST.
      See Also:
    • PROP_NTCP2_SP

      static final String PROP_NTCP2_SP
      Config key for the NTCP2 static private key.
      See Also:
    • PROP_NTCP2_IV

      static final String PROP_NTCP2_IV
      Config key for the NTCP2 static IV.
      See Also:
    • PROP_SSU2_SP

      static final String PROP_SSU2_SP
      Config key for the SSU2 static private key.
      See Also:
    • PROP_SSU2_IKEY

      static final String PROP_SSU2_IKEY
      Config key for the SSU2 static IV.
      See Also:
    • PROP_INTERNAL_PORT

      static final String PROP_INTERNAL_PORT
      Config key for the SSU internal port, the port the SSU transport binds.
      See Also:
    • PROP_EXTERNAL_HOST

      static final String PROP_EXTERNAL_HOST
      Config key to force advertising a fixed external IP address.
      See Also:
    • PROP_EXTERNAL_PORT

      static final String PROP_EXTERNAL_PORT
      Config key to force advertising a fixed external port.
      See Also:
    • PROP_FIXED_PORT

      static final String PROP_FIXED_PORT
      Config key to keep the SSU advertised port fixed regardless of peer feedback.
      See Also:
    • PROP_SOURCES

      static final String PROP_SOURCES
      Config key naming the allowed sources of address updates, e.g. "local,upnp,ssu".
      See Also:
    • DEFAULT_SOURCES

      static final String DEFAULT_SOURCES
      Default value of PROP_SOURCES: the local interface, UPnP, and SSU-learned addresses.
    • PROP_IP

      static final String PROP_IP
      Config key remembering the last IPv4 address so IP changes can be detected across restarts.
      See Also:
    • PROP_LAPTOP_MODE

      static final String PROP_LAPTOP_MODE
      Config key enabling laptop power-saving mode, which reduces connection activity.
      See Also:
    • PROP_IPV6

      static final String PROP_IPV6
      Config key remembering the last IPv6 address.
      See Also:
    • PROP_FORCE_INTRODUCERS

      static final String PROP_FORCE_INTRODUCERS
      Config key to require SSU introducers regardless of our reachability status.
      See Also:
    • PROP_INTRO_KEY

      static final String PROP_INTRO_KEY
      Config key for the SSU introducer key published in hidden-mode RouterInfos.
      See Also:
    • RTT_TIME_CURRENT

      static final long RTT_TIME_CURRENT
      Sentinel for getEstimatedRTTTime(Hash) meaning the transport's reading is refreshed by live traffic and is never out of date.
      See Also:
    • RTT_TIME_UNKNOWN

      static final long RTT_TIME_UNKNOWN
      Sentinel for getEstimatedRTTTime(Hash) meaning the transport does not record when it measured. Callers must then treat the reading as current, which preserves the pre-existing behaviour.
      See Also:
  • Method Details

    • bid

      TransportBid bid(RouterInfo toAddress, int dataSize)
      Request to send a message to the specified router.

      This method allows the transport to evaluate whether it can and wants to send a message to the target router. The transport may decline based on current load, peer reputation, or transport-specific constraints.

      Parameters:
      toAddress - the target router's contact information
      dataSize - size of message payload, assumes full 16-byte header, transports should adjust as necessary for their overhead
      Returns:
      a TransportBid containing send details, or null if unwilling to send
    • send

      void send(OutNetMessage msg)
      Asynchronously send a message to the specified peer.

      This method handles the actual message transmission. If the send operation succeeds, it queues up any follow-up jobs defined in msg.getOnSendJob() and registers them with OutboundMessageRegistry (if the message has a reply selector). If the send fails, it queues up any failure handling jobs from msg.getOnFailedSendJob().

      The method should return immediately and perform the actual sending asynchronously to avoid blocking the calling thread.

      Parameters:
      msg - the message to send, containing destination, payload, and callbacks
    • getEstimatedRTT

      default int getEstimatedRTT(Hash peer)
      The transport's own measured round trip time to a peer.

      This is the direct link cost of reaching the peer, which is what first-hop selection needs. It is deliberately distinct from PeerProfile.getTunnelTestTimeAverage(), which is the round trip through an entire multi-hop tunnel and is not a valid measure of one hop.

      Implementations that do not track latency return 0, which callers must read as unknown rather than as zero latency. Unknown is never treated as slow.

      Parameters:
      peer - the peer to measure
      Returns:
      the estimated round trip time in ms, or 0 if not measured
    • getEstimatedRTTTime

      default long getEstimatedRTTTime(Hash peer)
      When getEstimatedRTT(Hash) last measured this peer, on the router clock.

      A transport that measures once per session and then holds the number - NTCP2, whose only round trip is its handshake - returns the handshake time, not the present. Reporting now instead would let a reading hours old pass as fresh and keep resetting the profile's staleness window, which is what stops it from ever expiring.

      A transport whose reading is refreshed by ongoing traffic, such as SSU2 on acknowledgement, has nothing to report: the value it returns is current by construction, and it returns RTT_TIME_CURRENT.

      Parameters:
      peer - the peer to look up
      Returns:
      the timestamp of the measurement in ms, RTT_TIME_CURRENT when the reading is always current, or RTT_TIME_UNKNOWN when the transport does not track one
    • startListening

      void startListening()
      Start accepting connections.
    • stopListening

      void stopListening()
      Stop accepting connections.
    • getCurrentAddresses

      List<RouterAddress> getCurrentAddresses()
      All addresses this transport is currently listening on.

      This method returns the complete list of RouterAddress objects representing all network endpoints (both IPv4 and IPv6) that this transport is actively listening for connections on.

      This method replaces the older getCurrentAddress(boolean) method to support multiple addresses per transport.

      Returns:
      list of all currently listening addresses, never null
    • getCurrentAddress

      RouterAddress getCurrentAddress(boolean ipv6)
      The first currently listening address of specified IP version.

      This method returns the first RouterAddress matching the requested IP version from the list of current addresses. This is useful when a specific address type is needed rather than all addresses.

      Note: An address without a host component is considered IPv4. This method replaces the older getCurrentAddress() method.

      Parameters:
      ipv6 - true to return IPv6 address only; false to return IPv4 address only
      Returns:
      first matching address for the specified IP version, or null if no such address exists
    • hasCurrentAddress

      boolean hasCurrentAddress()
      Do we have any current address?
      Returns:
      whether current address is present
    • updateAddress

      List<RouterAddress> updateAddress()
      Request transport to update its addresses based on current conditions.

      This method asks the transport to re-evaluate its current network configuration and update its advertised addresses accordingly. The transport should consider:

      • Current network interface status
      • UPnP discovery results
      • Configuration file settings
      • Firewall and NAT constraints
      Returns:
      updated list of all addresses the transport is now advertising, never null
    • externalAddressReceived

      void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)
      Notify transport of an external address change event.

      This method informs the transport that its external address has changed due to various sources like UPnP discovery, interface changes, or configuration updates. The transport should evaluate whether to accept this change based on the source and current state.

      Call Conditions:

      • Should NOT be called if IP didn't change from source's perspective
      • Should NOT be called for local/private addresses
      • May be called multiple times (once for IPv4, once for IPv6)
      • Transport should validate source before accepting

      Timing: Can be called before startListening() to set initial address, or after transport is already running.

      Parameters:
      source - the address source reporting the newly seen address
      ip - the new external IP address (IPv4 or IPv6), may be null to indicate IPv4 failure or port-only change
      port - the new external port number, 0 if unknown or unchanged
    • externalAddressRemoved

      void externalAddressRemoved(Transport.AddressSource source, boolean ipv6)
      Notify a transport of an external address change. This may be from a local interface, UPnP, a config change, etc. This should not be called if the ip didn't change (from that source's point of view), or is a local address. May be called multiple times for IPv4 or IPv6. The transport should also do its own checking on whether to accept notifications from this source.

      This can be called after the transport is running.

      Parameters:
      source - the address source whose address has gone away
      ipv6 - true for IPv6, false for IPv4
    • forwardPortStatus

      void forwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason)
      Notify a transport of the results of trying to forward a port.
      Parameters:
      ip - may be null
      port - the internal port
      externalPort - the external port, which for now should always be the same as the internal port if the forwarding was successful.
      success - true if the router managed to establish the mapping
      reason - the text describing the outcome, for the console and the logs
    • getRequestedPort

      int getRequestedPort()
      The internal port that the transport wants forwarded via UPnP.

      This method returns the preferred internal port that the transport would like to have mapped to an external port through UPnP port forwarding. This is different from the actual listening port because UPnP may map a different external port.

      Note: This cannot be determined from getCurrentAddress() because:

      • Transport must open the port before publishing address
      • UPnP may map different external port
      • External port is what gets advertised, not internal
      Returns:
      preferred internal port for UPnP forwarding, -1 for no preference, or 0 for any port
    • setListener

      void setListener(TransportEventListener listener)
      The event listener for transport-related notifications.

      The listener will be notified of various transport events such as message availability, peer status changes, and transport state changes. Only one listener can be active at a time.

      Parameters:
      listener - the event listener to receive transport notifications
    • getStyle

      String getStyle()
      The unique style identifier for this transport.

      This method returns a string that uniquely identifies the transport type (e.g., "NTCP", "UDP", "SSU"). This is used for configuration, logging, and transport selection.

      Returns:
      unique transport style identifier
    • getEstablished

      List<Hash> getEstablished()
      The list of peers this transport has established connections with.

      This method returns the current set of peer hashes that have successfully completed connection establishment. These are peers that the transport can actively communicate with.

      Note: The returned list may or may not be modifiable depending on implementation. Callers should not modify the returned list directly.

      Returns:
      list of established peer hashes, may be unmodifiable
    • countPeers

      int countPeers()
      Number of peers.
      Returns:
      the number of peers this transport knows of, established or not
    • countActivePeers

      int countActivePeers()
      Number of active peers.
      Returns:
      active peer count
    • countActiveSendPeers

      int countActiveSendPeers()
      Number of active send peers.
      Returns:
      active send peer count
    • getPeerCounts

      int[] getPeerCounts()
      Detailed peer count statistics by IP version and direction.

      This method returns an array containing peer counts broken down by IP version and connection direction. This provides detailed visibility into transport usage patterns and network composition.

      Array Format:

      • Version 1 (8 bytes): IPv4 inbound/outbound counts
      • Version 2 (8 bytes): IPv4 inbound/outbound, IPv6 inbound/outbound counts
      Returns:
      8-byte array with peer counts: version 1: [ipv4_in, ipv4_out, ipv6_in, ipv6_out, 0, 0, 0, 0] version 2: [ipv4_in, ipv4_out, ipv6_in, ipv6_out, 0, 0, 0, 0]
    • haveCapacity

      boolean haveCapacity()
      Whether capacity is available for a message.
      Returns:
      true if capacity available
    • haveCapacity

      boolean haveCapacity(int pct)
      Whether capacity is available for the given percentage.
      Parameters:
      pct - percent 0-100
      Returns:
      true if capacity available
    • getClockSkews

      List<Long> getClockSkews()
      The list of clock skew measurements from peer communications.

      This method returns a list of measured clock differences (in milliseconds) between this router and various peers. Clock skew is important for network time synchronization and can affect message validation and routing.

      Historical Note: This method previously returned a Vector, now returns a List as of 0.9.46.

      Returns:
      list of clock skew measurements in milliseconds, may be empty if no measurements available
    • getMostRecentErrorMessages

      List<String> getMostRecentErrorMessages()
      The most recent error messages.
      Returns:
      copy of the list of recent human-readable error strings
    • renderStatusHTML

      void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException
      Render the transport status HTML to the given writer.
      Parameters:
      out - writer the status HTML is rendered into
      urlBase - base URL for the links embedded in the HTML
      sortFlags - flags controlling sorting and display options
      Throws:
      IOException - if the status HTML cannot be written to the writer
    • getReachabilityStatus

      CommSystemFacade.Status getReachabilityStatus()
      The current reachability status of this transport.

      This method returns the transport's ability to establish and maintain connections with other peers. The status indicates whether the transport can successfully communicate through firewalls, NAT, and network restrictions.

      Historical Note: This method previously returned a short value, now returns a Status enum as of 0.9.20.

      Returns:
      current reachability status indicating transport's network accessibility
    • getIPv6Config

      TransportUtil.IPv6Config getIPv6Config()
      The current IPv6 configuration.
      Returns:
      IPv6 config
    • isIPv4Firewalled

      boolean isIPv4Firewalled()
      Whether force-firewalled for IPv4.
      Returns:
      true if force-firewalled for IPv4
    • isIPv6Firewalled

      boolean isIPv6Firewalled()
      Whether force-firewalled for IPv6.
      Returns:
      true if force-firewalled for IPv6
    • isBacklogged

      boolean isBacklogged(Hash peer)
      Whether the given peer is backlogged.
      Parameters:
      peer - hash of the peer to check
      Returns:
      true if backlogged
    • wasUnreachable

      boolean wasUnreachable(Hash peer)
      Check if peer was unreachable on last outbound attempt.

      This method determines whether the last attempt to contact the specified peer failed due to reachability issues. This is specifically for outbound connection attempts only.

      Important Notes:

      • This is NOT reset if the peer contacts us successfully
      • Status persists until peer is contacted or expires
      • Used for connection retry decisions
      • Different from isUnreachable(Hash) which checks current state
      Parameters:
      peer - hash of the peer to check reachability for
      Returns:
      true if peer was unreachable on last outbound attempt
    • isUnreachable

      boolean isUnreachable(Hash peer)
      Whether the given peer is unreachable.
      Parameters:
      peer - hash of the peer to check
      Returns:
      true if unreachable
    • isEstablished

      boolean isEstablished(Hash peer)
      Whether the given peer is established.
      Parameters:
      peer - hash of the peer to check
      Returns:
      true if established
    • wasFailsafeClosed

      boolean wasFailsafeClosed(Hash peer, long withinMs)
      Whether this transport closed a session to the given peer for idleness within the given window.

      True means this router declined to keep talking to the peer, which is not the same as the peer having gone away. Transports without a notion of closing idle sessions return false, and callers must read that as "no information" rather than as evidence about the peer.

      Parameters:
      peer - the peer to ask about, non-null
      withinMs - how far back counts as recent in ms; non-positive means nothing is recent
      Returns:
      true when this transport closed a session to the peer that recently
    • isConnecting

      boolean isConnecting(Hash peer)
      Check if a connection attempt is in progress for the given peer.

      This method returns true when the transport has accepted a message for this peer and initiated a connection handshake, but the handshake has not yet completed. Unlike isEstablished(Hash), which only returns true for fully-connected peers, this method detects connections that are still being set up.

      Used by the tunnel build system to distinguish between peers that are genuinely unreachable vs. peers that just need more time for the initial NTCP2/SSU2 handshake.

      Parameters:
      peer - hash of the peer to check
      Returns:
      true if a connection attempt is in progress
    • mayDisconnect

      void mayDisconnect(Hash peer)
      Suggest that transport may disconnect from specified peer.

      This method provides an advisory recommendation that the transport should consider disconnecting from the specified peer. The transport may choose to ignore this suggestion based on its own criteria and current state.

      Advisory Nature:

      • Transport is not required to disconnect
      • Used for peer management and load balancing
      • May be called by router or other components
      • Transport should evaluate based on its own state
      Parameters:
      peer - hash of the peer that may be disconnected
    • forceDisconnect

      void forceDisconnect(Hash peer)
      Force immediate disconnection from specified peer.

      This method commands the transport to immediately terminate the connection to the specified peer. Unlike mayDisconnect(Hash), this is not advisory - the transport must comply and disconnect as soon as possible.

      Use Cases:

      • Peer misbehavior or protocol violations
      • Router shutdown or transport shutdown
      • Network topology changes requiring disconnection
      • Administrative or manual disconnection requests
      Parameters:
      peer - hash of the peer to forcefully disconnect from
    • forceDisconnect

      void forceDisconnect(Hash peer, String reason)
      Forcefully disconnect from a peer with a reason for logging.
      Parameters:
      peer - hash of the peer to forcefully disconnect from
      reason - reason for disconnection (for logging)