- All Known Implementing Classes:
NTCPTransport, TransportImpl, UDPTransport
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
TransportManagerlifecycle
Plugin Development: To implement a new transport plugin:
- Implement this interface and required base classes
- Add transport to
TransportManager.startListening() - Ensure proper configuration and discovery
- 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).
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic enumSource of transport address configuration.Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringDefault value ofPROP_SOURCES: the local interface, UPnP, and SSU-learned addresses.static final StringConfig key to force advertising a fixed external IP address.static final StringConfig key to force advertising a fixed external port.static final StringConfig key to keep the SSU advertised port fixed regardless of peer feedback.static final StringConfig key to require SSU introducers regardless of our reachability status.static final StringConfig key controlling whether NTCP may auto-update its advertised IP based on peer feedback.static final StringConfig key controlling whether NTCP may auto-update its advertised port based on peer feedback.static final StringConfig key for an explicitly configured hostname the NTCP transport advertises.static final StringConfig key for the port the NTCP transport listens for inbound connections on.static final StringConfig key for the SSU internal port, the port the SSU transport binds.static final StringConfig key for the SSU introducer key published in hidden-mode RouterInfos.static final StringConfig key remembering the last IPv4 address so IP changes can be detected across restarts.static final StringConfig key remembering the last IPv6 address.static final StringConfig key enabling laptop power-saving mode, which reduces connection activity.static final StringConfig key for the NTCP2 static IV.static final StringConfig key for the NTCP2 static private key.static final StringConfig key naming the allowed sources of address updates, e.g.static final StringConfig key for the SSU2 static IV.static final StringConfig key for the SSU2 static private key.static final longSentinel forgetEstimatedRTTTime(Hash)meaning the transport's reading is refreshed by live traffic and is never out of date.static final longSentinel forgetEstimatedRTTTime(Hash)meaning the transport does not record when it measured.static final StringStyle identifier for the NTCP transport, used inRouterAddressstyle tags, transport map keys, and style comparisons.static final StringStyle identifier for the NTCP2 protocol variant of the NTCP transport.static final StringStyle identifier for the SSU transport, used in RouterAddress style tags, transport map keys, and style comparisons.static final StringStyle identifier for the SSU2 protocol variant of the SSU transport.Method Summary
Modifier and TypeMethodDescriptionbid(RouterInfo toAddress, int dataSize) Request to send a message to the specified router.intNumber of active peers.intNumber of active send peers.intNumber of peers.voidexternalAddressReceived(Transport.AddressSource source, byte[] ip, int port) Notify transport of an external address change event.voidexternalAddressRemoved(Transport.AddressSource source, boolean ipv6) Notify a transport of an external address change.voidforceDisconnect(Hash peer) Force immediate disconnection from specified peer.voidforceDisconnect(Hash peer, String reason) Forcefully disconnect from a peer with a reason for logging.voidforwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason) Notify a transport of the results of trying to forward a port.The list of clock skew measurements from peer communications.getCurrentAddress(boolean ipv6) The first currently listening address of specified IP version.All addresses this transport is currently listening on.The list of peers this transport has established connections with.default intgetEstimatedRTT(Hash peer) The transport's own measured round trip time to a peer.default longgetEstimatedRTTTime(Hash peer) WhengetEstimatedRTT(Hash)last measured this peer, on the router clock.The current IPv6 configuration.The most recent error messages.int[]Detailed peer count statistics by IP version and direction.The current reachability status of this transport.intThe internal port that the transport wants forwarded via UPnP.getStyle()The unique style identifier for this transport.booleanDo we have any current address?booleanWhether capacity is available for a message.booleanhaveCapacity(int pct) Whether capacity is available for the given percentage.booleanisBacklogged(Hash peer) Whether the given peer is backlogged.booleanisConnecting(Hash peer) Check if a connection attempt is in progress for the given peer.booleanisEstablished(Hash peer) Whether the given peer is established.booleanWhether force-firewalled for IPv4.booleanWhether force-firewalled for IPv6.booleanisUnreachable(Hash peer) Whether the given peer is unreachable.voidmayDisconnect(Hash peer) Suggest that transport may disconnect from specified peer.voidrenderStatusHTML(Writer out, String urlBase, int sortFlags) Render the transport status HTML to the given writer.voidsend(OutNetMessage msg) Asynchronously send a message to the specified peer.voidsetListener(TransportEventListener listener) The event listener for transport-related notifications.voidStart accepting connections.voidStop accepting connections.Request transport to update its addresses based on current conditions.booleanwasFailsafeClosed(Hash peer, long withinMs) Whether this transport closed a session to the given peer for idleness within the given window.booleanwasUnreachable(Hash peer) Check if peer was unreachable on last outbound attempt.
Field Details
STYLE_NTCP
Style identifier for the NTCP transport, used inRouterAddressstyle tags, transport map keys, and style comparisons.- See Also:
STYLE_NTCP2
Style identifier for the NTCP2 protocol variant of the NTCP transport.- See Also:
STYLE_SSU
Style identifier for the SSU transport, used in RouterAddress style tags, transport map keys, and style comparisons.- See Also:
STYLE_SSU2
Style identifier for the SSU2 protocol variant of the SSU transport.- See Also:
PROP_I2NP_NTCP_PORT
Config key for the port the NTCP transport listens for inbound connections on.- See Also:
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
Config key controlling whether NTCP may auto-update its advertised IP based on peer feedback.- See Also:
PROP_I2NP_NTCP_HOSTNAME
Config key for an explicitly configured hostname the NTCP transport advertises. The SSU equivalent isPROP_EXTERNAL_HOST.- See Also:
PROP_NTCP2_SP
Config key for the NTCP2 static private key.- See Also:
PROP_NTCP2_IV
PROP_SSU2_SP
Config key for the SSU2 static private key.- See Also:
PROP_SSU2_IKEY
PROP_INTERNAL_PORT
Config key for the SSU internal port, the port the SSU transport binds.- See Also:
PROP_EXTERNAL_HOST
Config key to force advertising a fixed external IP address.- See Also:
PROP_EXTERNAL_PORT
Config key to force advertising a fixed external port.- See Also:
PROP_FIXED_PORT
Config key to keep the SSU advertised port fixed regardless of peer feedback.- See Also:
PROP_SOURCES
Config key naming the allowed sources of address updates, e.g. "local,upnp,ssu".- See Also:
DEFAULT_SOURCES
Default value ofPROP_SOURCES: the local interface, UPnP, and SSU-learned addresses.PROP_IP
Config key remembering the last IPv4 address so IP changes can be detected across restarts.- See Also:
PROP_LAPTOP_MODE
Config key enabling laptop power-saving mode, which reduces connection activity.- See Also:
PROP_IPV6
Config key remembering the last IPv6 address.- See Also:
PROP_FORCE_INTRODUCERS
Config key to require SSU introducers regardless of our reachability status.- See Also:
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_CURRENTSentinel forgetEstimatedRTTTime(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_UNKNOWNSentinel forgetEstimatedRTTTime(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
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 informationdataSize- 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
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
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
WhengetEstimatedRTT(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
nowinstead 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_CURRENTwhen the reading is always current, orRTT_TIME_UNKNOWNwhen 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
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
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 addressip- the new external IP address (IPv4 or IPv6), may be null to indicate IPv4 failure or port-only changeport- the new external port number, 0 if unknown or unchanged
externalAddressRemoved
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 awayipv6- true for IPv6, false for IPv4
forwardPortStatus
Notify a transport of the results of trying to forward a port.- Parameters:
ip- may be nullport- the internal portexternalPort- 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 mappingreason- 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
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
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
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
renderStatusHTML
Render the transport status HTML to the given writer.- Parameters:
out- writer the status HTML is rendered intourlBase- base URL for the links embedded in the HTMLsortFlags- 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
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
Whether the given peer is backlogged.- Parameters:
peer- hash of the peer to check- Returns:
- true if backlogged
wasUnreachable
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
Whether the given peer is unreachable.- Parameters:
peer- hash of the peer to check- Returns:
- true if unreachable
isEstablished
Whether the given peer is established.- Parameters:
peer- hash of the peer to check- Returns:
- true if established
wasFailsafeClosed
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-nullwithinMs- 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
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
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
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