net.i2p.router.transport

## Interface Transport

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

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Interface and Description
    --- | ---
    `static class` | `Transport.AddressSource` Source of transport address configuration.

  - ### Method Summary

    All Methods Instance Methods Abstract Methods
    Modifier and Type | Method and Description
    --- | ---
    `TransportBid` | `bid(RouterInfo toAddress, int dataSize)` Request to send a message to the specified router.
    `int` | `countActivePeers()`
    `int` | `countActiveSendPeers()`
    `int` | `countPeers()`
    `void` | `externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)` Notify transport of an external address change event.
    `void` | `externalAddressRemoved(Transport.AddressSource source, boolean ipv6)` Notify a transport of an external address change.
    `void` | `forceDisconnect(Hash peer)` Force immediate disconnection from specified peer.
    `void` | `forwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason)` Notify a transport of the results of trying to forward a port.
    `List<Long>` | `getClockSkews()` Get list of clock skew measurements from peer communications.
    `RouterAddress` | `getCurrentAddress(boolean ipv6)` Get the first currently listening address of specified IP version.
    `List<RouterAddress>` | `getCurrentAddresses()` Get all addresses this transport is currently listening on.
    `List<Hash>` | `getEstablished()` Get list of peers that this transport has established connections with.
    `TransportUtil.IPv6Config` | `getIPv6Config()`
    `List<String>` | `getMostRecentErrorMessages()`
    `int[]` | `getPeerCounts()` Get detailed peer count statistics by IP version and direction.
    `CommSystemFacade.Status` | `getReachabilityStatus()` Get the current reachability status of this transport.
    `int` | `getRequestedPort()` Get the internal port that transport wants forwarded via UPnP.
    `String` | `getStyle()` Get the unique style identifier for this transport.
    `boolean` | `hasCurrentAddress()` Do we have any current address?
    `boolean` | `haveCapacity()`
    `boolean` | `haveCapacity(int pct)`
    `boolean` | `isBacklogged(Hash peer)`
    `boolean` | `isEstablished(Hash peer)`
    `boolean` | `isIPv4Firewalled()` This returns true if the force-firewalled setting is configured, false otherwise.
    `boolean` | `isIPv6Firewalled()` This returns true if the force-firewalled setting is configured, false otherwise.
    `boolean` | `isUnreachable(Hash peer)`
    `void` | `mayDisconnect(Hash peer)` Suggest that transport may disconnect from specified peer.
    `void` | `renderStatusHTML(Writer out, String urlBase, int sortFlags)`
    `void` | `send(OutNetMessage msg)` Asynchronously send a message to the specified peer.
    `void` | `setListener(TransportEventListener listener)` Set the event listener for transport-related notifications.
    `void` | `startListening()`
    `void` | `stopListening()`
    `List<RouterAddress>` | `updateAddress()` Request transport to update its addresses based on current conditions.
    `boolean` | `wasUnreachable(Hash peer)` Check if peer was unreachable on last outbound attempt.

- - ### Method Detail

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

    - #### countActivePeers

          int countActivePeers()

    - #### countActiveSendPeers

          int countActiveSendPeers()

    - #### countPeers

          int countPeers()

    - #### 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 source of this address change (UPnP, interface, config, SSU)
        `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 source of the address removal
        `ipv6` - true for IPv6, false for IPv4

    - #### 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(), 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

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

    - #### getClockSkews

          List<Long> getClockSkews()

      Get 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

    - #### getCurrentAddress

          RouterAddress getCurrentAddress(boolean ipv6)

      Get 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

    - #### getCurrentAddresses

          List<RouterAddress> getCurrentAddresses()

      Get 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() method to support multiple addresses per transport.
      Returns:
        list of all currently listening addresses, never null

    - #### getEstablished

          List<Hash> getEstablished()

      Get list of peers that 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

    - #### getIPv6Config

          TransportUtil.IPv6Config getIPv6Config()

    - #### getMostRecentErrorMessages

          List<String> getMostRecentErrorMessages()

    - #### getPeerCounts

          int[] getPeerCounts()

      Get 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]

    - #### getReachabilityStatus

          CommSystemFacade.Status getReachabilityStatus()

      Get 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

    - #### getRequestedPort

          int getRequestedPort()

      Get the internal port that 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

    - #### getStyle

          String getStyle()

      Get 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

    - #### hasCurrentAddress

          boolean hasCurrentAddress()

      Do we have any current address?

    - #### haveCapacity

          boolean haveCapacity()

    - #### haveCapacity

          boolean haveCapacity(int pct)

    - #### isBacklogged

          boolean isBacklogged(Hash peer)

    - #### isEstablished

          boolean isEstablished(Hash peer)

    - #### isIPv4Firewalled

          boolean isIPv4Firewalled()

      This returns true if the force-firewalled setting is configured, false otherwise.

    - #### isIPv6Firewalled

          boolean isIPv6Firewalled()

      This returns true if the force-firewalled setting is configured, false otherwise.

    - #### isUnreachable

          boolean isUnreachable(Hash peer)

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

    - #### renderStatusHTML

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

      Throws:
        `IOException`

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

    - #### setListener

          void setListener(TransportEventListener listener)

      Set 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

    - #### startListening

          void startListening()

    - #### stopListening

          void stopListening()

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

    - #### 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() which checks current state
      Parameters:
        `peer` - hash of the peer to check reachability for
      Returns:
        true if peer was unreachable on last outbound attempt