- All Implemented Interfaces:
Transport
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classFor PeerStateDestroyed, to kill the timers on overflow, else the memory won't be freed.private classTimer expiring idle peers and pinging the rest.(package private) static enumIPv6 external-address rebuild action for a reachability status change.private classPeriodically ping the introducers, split out since we need to do it faster than we rebuild our address.private classCreates the periodic SSU2 rebuild timer event.private classTimer removing a peer from the drop list when it ages out.private classA bid shared by all peers in one class, cached to reduce object churn.Nested classes/interfaces inherited from interface Transport
Transport.AddressSourceModifier and TypeInterfaceDescriptionstatic enumSource of transport address configuration.Field Summary
Modifier and TypeFieldDescriptionprivate final ObjectLock serializing peer adds against drop-list changes.private final BanLoggerLogger for peers banned by this transport.private final TransportBid[]Precomputed bids, indexed by the constants above.private RouterAddressWe don't publish our IP/port if introduced, so we need to store it somewhere.private RouterAddressOur current IPv6 endpoint as a router address.private final intThe MTU configured at startup, in bytes.private final Set<RemoteHostId> List of RemoteHostId for peers whose packets we want to drop outright This is only for old network IDs (pre-0.6.1.10), so it isn't really used now.private final List<UDPEndpoint> The sockets listened on, one per local address.private EstablishmentManagerRuns the SSU2 handshakes.private final UDPTransport.ExpirePeerEventTimer expiring idle peers.private longIdle time at which a peer is expired, in ms.private final OutboundMessageFragmentsQueue of outbound message fragments.private PacketHandlerThread reading packets off the sockets.private booleanDo we have a public IPv6 address?private booleanTrue once a UPnP port mapping exists.private final InboundMessageFragmentsQueue of inbound message fragments.private SessionKeyIntroduction key.private final IntroductionManagerManages introducers and introductions.private byte[]Source of the last inbound IPv4 packet.private byte[]Source of the last inbound IPv6 packet.private HashLast report from a peer of our IP.private HashHash of the last peer reached over IPv6.private longTime the last inbound IPv6 packet arrived.private longTime the last inbound packet arrived.private byte[]Local address the last outbound IPv4 packet left.private byte[]Local address the last outbound IPv6 packet left.private intLocal port the last outbound IPv4 packet left.private intLocal port the last outbound IPv6 packet left.private final LogLogger for this class.private final intFewest peers to keep connected.private final intFewest IPv6-capable peers to keep connected.private booleanTrue once the MTU mismatch has been logged.private intThe MTU in use, in bytes.private intThe SSU2 MTU in use, in bytes.private intThe SSU2 IPv6 MTU in use, in bytes.private booleanFlag indicating whether the router's external address needs to be rebuilt.private final intNetwork id of the packets we accept.private final PacketBuilder2Builds the SSU2 packets we send.private final Map<Long, PeerState2> Connected peers, by connection id.Map of known peers, keyed by their identity hash.private final Map<RemoteHostId, PeerState> Map of known peers, keyed by their remote host and port.private PacketPusherThread pushing queued packets to the sockets.private CommSystemFacade.StatusOur measured reachability.private CommSystemFacade.StatusA new reachability awaiting confirmation.private intLoops the reachability has been unchanged, logging only.private final ObjectLock serializing external-address rebuilds.private final Map<Long, PeerStateDestroyed> Recently closed peers, by connection id, for late packets.private final StringThe introducer key, base64, for the router info.private final StringThe static public key, base64, for the router info.private final byte[]Our SSU2 introducer-only static key.private final byte[]Our SSU2 static private key.private final byte[]Our SSU2 static public key.private final PeerTestEventTimer running reachability peer tests.private final PeerTestManagerManages peer reachability testing to determine if we are firewalled or reachable.private final TunerAdaptive tuner.private longTime the IPv4 introducer set was last chosen.private longTime the IPv6 introducer set was last chosen.private final X25519KeyFactoryShared X25519 factory for the handshakes.private static final intIf we have received an inbound connection in the last 2 minutes, don't allow our IP to change.private static final int[]Bid values for each peer class, worst last.private static final StringCapacity letter for a peer under testing.private static final StringCapacity letters for a testing IPv4 peer.private static final StringCapacity letters for a testing IPv6 peer.private static final StringCapacity letters for a testing introducer.static final intDefault cost value for SSU peer selection.private static final StringDefault for preferring UDP over NTCP.static final StringDefault address sources.private static final intStale drop-list entries are removed every 10 minutes.private static final longAmount the expire timeout shrinks per adjustment.private static final longAmount the expire timeout grows per adjustment.static final intDefault introducer expiration in ms.private static final intBid index for a fast peer.private static final intBid index for a fast peer we prefer.private booleanTrue once the IPv4 address has been reported, to stop repeats.private booleanTrue once the IPv6 address has been reported, to stop repeats.(package private) static final longDefault introducer expiration in ms.private static final longLoop interval while no pings are due.private static final intConsecutive send failures before considering a peer for drop (requires inactivity too).private static final intIdle time past which a peer is disconnected.private static final longIdle time past which a peer may be disconnected.private static final longWe re-key after 7 days of downtime.private static final longHidden routers re-key after 24 hours of downtime.static final intMinimum introducer expiration in ms.private static final intMinimum peers volunteering to be introducers if we need that.private static final StringOldest version whose SSU2 peer tests are trusted, SSU2 having become stable then.private static final intMinimum active peers to maintain IP detection, etc.private static final intPeer target once we are reachable over IPv6.private static final StringRI sigtypes supported in 0.9.16, but due to a bug inInboundEstablishStatefixed in 0.9.17, we cannot connect out to routers before that version.private static final intBid index for a peer near its capacity.private static final intBid index for a peer near capacity by cost.private static final longHalf of that, the time by which the ping must be sent.private static final longTime past which a ping keeps the firewall open, 30 seconds; firewalls have been seen to change ports after 40.static final StringDo we allow direct SSU connections, sans introducers?static final StringThis is rarely if ever used, default is to bind to wildcard address.private static final StringOverride the "large" (max) MTU, default is PeerState.LARGE_MTU.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 StringOverride whether we will change our advertised port no matter what our peers tell us.static final StringDo we require introducers, regardless of our status? Value sourced fromTransport.PROP_FORCE_INTRODUCERS.static final StringConfig key for the SSU internal listening port.static final StringConfig key for the SSU introducer key published in hidden-mode RouterInfos.static final StringRemember IP changes across restarts.static final StringConfig key tracking when the last IP address change occurred.static final StringLast IPv6 config.static final StringConfig key for laptop power-saving mode.static final StringConfig key to prefer UDP transport.private static final StringProperty overriding the measured reachability.static final StringAllowed sources of address updates.static final StringConfig key for the base-64 SSU2 static IV.static final StringConfig key for the base-64 SSU2 static private key.static final intHow many relays offered to us will we use at a time?(package private) static final long[]Short-term rate limits for SSU.private static final longThe router info is re-stored every 29 minutes.private static final longLoop interval while pings are due.private static final intPeer slices pinged one per loop.private static final intBid index for a slow peer.private static final intBid index for a slow peer we prefer.private static final intBid index for the slowest tier.private static final intBid index for the slowest tier by cost.private static final intRelative cost of sending via SSU, against NTCP's 10.(package private) static final intSSU2 protocol version.(package private) static final String"2".(package private) static final String"2,".private static final Set<CommSystemFacade.Status> Statuses in which either family is firewalled.private static final Set<CommSystemFacade.Status> Statuses in which our IPv4 is firewalled.private static final Set<CommSystemFacade.Status> Statuses in which we cannot be a v4 Charlie.private static final Set<CommSystemFacade.Status> Statuses in which IPv4 sits behind a symmetric NAT.private static final Set<CommSystemFacade.Status> Statuses in which our IPv4 reachability is unknown.private static final Set<CommSystemFacade.Status> Statuses in which our IPv6 is firewalled.private static final Set<CommSystemFacade.Status> Statuses treating IPv6 as firewalled, ambiguous ones included.private static final Set<CommSystemFacade.Status> Statuses in which we cannot be a v6 Charlie.private static final Set<CommSystemFacade.Status> Statuses in which our IPv6 is reachable.private static final Set<CommSystemFacade.Status> Statuses in which our IPv6 reachability is unknown.private static final Set<CommSystemFacade.Status> Statuses in which our IPv4 is reachable.static final StringStyle identifier for the SSU transport.static final StringStyle identifier for the SSU2 protocol variant.private static final intBid index for a peer with a recent failure.Fields inherited from class TransportImpl
_context, ADJUST_COST, CAP_IPV4, CAP_IPV4_IPV6, CAP_IPV6, CONGESTION_COST_ADJUSTMENT, PROP_BOOST_CONNECTION_LIMITS, PROP_IPV6_FIREWALLEDModifier and TypeFieldDescriptionprotected final RouterContextThe router context, which every subclass reads its configuration from.protected static final booleanDo we increase the advertised cost when approaching conn limits?static final StringAdvertised reachability value for a working IPv4 address.static final StringAdvertised reachability value for both address families.static final StringAdvertised reachability value for a working IPv6 address.protected static final intAdjustment factor for congestion cost.protected static final StringProperty allowing a transport to lift its connection limit.protected static final StringProperty recording the result of the last IPv6 firewall test.Fields inherited from interface Transport
PROP_I2NP_NTCP_AUTO_IP, PROP_I2NP_NTCP_AUTO_PORT, PROP_I2NP_NTCP_HOSTNAME, PROP_I2NP_NTCP_PORT, PROP_NTCP2_IV, PROP_NTCP2_SP, RTT_TIME_CURRENT, RTT_TIME_UNKNOWN, STYLE_NTCP, STYLE_NTCP2, STYLE_SSU, STYLE_SSU2Modifier and TypeFieldDescriptionstatic 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 NTCP2 static IV.static final StringConfig key for the NTCP2 static private key.static final longSentinel forTransport.getEstimatedRTTTime(Hash)meaning the transport's reading is refreshed by live traffic and is never out of date.static final longSentinel forTransport.getEstimatedRTTTime(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.Constructor Summary
ConstructorsConstructorDescriptionUDPTransport(RouterContext ctx, X25519KeyFactory xdh) Create the UDP transport for the given router context and SSU2 XDH factory.Method Summary
Modifier and TypeMethodDescription(package private) voidStart listening for packets on a destroyed connection.(package private) booleanaddRemotePeerState(PeerState peer) Adds a new peer state or replaces an existing one if the peer identity or address changes.private voidaddSSU2Options(Properties props) Add the required options to the properties for a SSU2 address.(package private) static longadjustExpireTimeout(long expireTimeout, boolean haveCap, boolean lastLoopShort) Adjust the idle-timeout towards the target as a function of spare connection capacity, ramping slowly when the loop is running short.voidDynamically adjusts MessageReceiver thread count to match the target.voidDynamically adjusts PacketHandler thread count to match the target.private voidAdjusts reachability status when IPv4 is firewalled.booleanWhether a new connection is allowed.private booleanWhether direct UDP connections to other routers are allowed; defaults to true.(package private) static StringalreadyConnectedLine(String kind, String oldPeer, String peer) The entry for a peer replaced while establishing a second session with the same router.private booleanWhether UDP is preferred in every situation.(package private) static CommSystemFacade.StatusapplyIPv6Only(CommSystemFacade.Status status, boolean isIPv6Only) Collapse a merged status when the transport runs in IPv6-only mode.(package private) static CommSystemFacade.StatusapplyNoIPv6Address(CommSystemFacade.Status status, boolean hasIPv6Address) Collapse a merged status when the router has no IPv6 address to publish.bid(RouterInfo toAddress, int dataSize) Bid on a message to the given router.(package private) booleancanIntroduce(boolean ipv6) For EstablishmentManager.(package private) booleancanTestAsCharlie(boolean ipv6) Can we be a Charlie right now?private booleanchangeAddress(byte[] ourIP, int ourPort) Updates the external IP address and/or port based on feedback from a peer.(package private) voidchangePeerAddress(PeerState2 peer, RemoteHostId newAddress) Remove and add to peersByRemoteHost map.(package private) voidchangePeerPort(PeerState peer, int newPort) Remove and add to peersByRemoteHost map.private voidconfigureExternalAddressesAndStatus(int newPort, Set<InetAddress> bindToAddrs) Configures external addresses and sets reachability status based on current state.intActive peers.intActive send peers.intCount peers.(package private) static UDPTransport.IPv6RebuilddecideIPv6Rebuild(CommSystemFacade.Status old, CommSystemFacade.Status status, boolean explicitAddressSpecified) The IPv6 external-address rebuild to perform after a committed status change.private voidSend a session destroy message to everybody.private intdeterminePort(Set<InetAddress> bindToAddrs) Determines the port to bind to based on internal, bind, or external port properties.(package private) voidThis does not send a session destroy, caller must do that if desired.(package private) voidThis does not send a session destroy, caller must do that if desired.private static final booleaneq(byte[] laddr, int lport, byte[] raddr, int rport) Compare two address and port pairs for equality; either address may be null.private StringExpands the PROP_EXTERNAL_HOST configuration into a comma-separated string of IP addresses that are local and allowed.private booleanWhether the config pins our external address.(package private) voidexternalAddressReceived(Hash from, byte[] hisIP, byte[] ourIP, int ourPort) Someone we tried to contact gave us what they think our IP address is.voidexternalAddressReceived(Transport.AddressSource source, byte[] ip, int port) From config, UPnP, local i/f, ...voidfail(UDPEndpoint endpoint) The endpoint has failed.voidfailed(OutNetMessage msg, String reason) Handle a failed outbound network message.voidHandle a failed outbound message.(package private) voidfailed(OutboundMessageState msg, boolean allowPeerFailure) Handle a failed outbound message, blaming the peer only after MAX_CONSECUTIVE_FAILED failures with no recent activity.(package private) static booleanfirewallPingSliceMatched(int runCount, int peerHash) Firewall-keepalive slice gate: roughly one peer in SLICES pings per pass, so pings are spread out over the short loop.voidforceDisconnect(Hash peer) Force disconnect a peer.voidforceDisconnect(Hash peer, String reason) Force disconnect with reason.voidforwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason) Callback from UPnP.An alternate supported style, or null.(package private) PacketBuilder2Packet builder for SSU2, or null if not configured for SSU2.Return our peer clock skews on this transport.getCurrentExternalAddress(boolean isIPv6) Simple fetch of stored IP and port, since we don't put them in the real, published RouterAddress anymore if we are firewalled.static longThe data message timeout in ms.Identities of all currently established peers.(package private) EstablishmentManagerFor IntroductionManager.intgetEstimatedRTT(Hash peer) Measured round trip time to a peer over SSU.longgetEstimatedRTTTime(Hash peer) WhengetEstimatedRTT(Hash)was measured, on the router clock.(package private) byte[]Published IP, IPv4 only.(package private) intgetExternalPort(boolean ipv6) Published or requested port.(package private) InboundMessageFragmentsThe inbound fragment reassembler.(package private) SessionKeyIntroduction key that people should use to contact us, or null if SSU1 disabled.(package private) IntroductionManagerThe introduction manager.private booleangetIsPortFixed(boolean isIPv6) Was true before 0.9.2 Now false if we need introducers (as perhaps that's why we need them, our firewall is changing our port), unless overridden by the property.private intgetListenPort(boolean ipv6) The current port of the first matching endpoint.static longThe inbound establish timeout in ms.static longThe outbound establish timeout in ms.static intThe current target MessageReceiver thread count.doubleMessage receiver pool utilization as a ratio (0.0-1.0).intgetMTU(boolean ipv6) The MTU for the socket interface.(package private) OutboundMessageFragmentsgetOMF()The OutboundMessageFragments instance.(package private) PacketHandlerThe packet handler.static intThe max packet handler threads.(package private) StringPacket handler status.doublePacket handler pool utilization as a ratio (0.0-1.0).int[]Peer counts.getPeers()For /peers UI only.(package private) PeerState2getPeerState(long rcvConnID) Peer state by SSU2 connection ID.(package private) PeerStategetPeerState(Hash remotePeer) The peer state for the peer with the given ident, or null if no state exists.(package private) PeerStategetPeerState(RemoteHostId hostInfo) Retrieves the current connection state for a peer identified by their remote host and port.(package private) PeerTestManagerThe peer test manager.private StringThe publish style.Current reachability status, possibly overridden by configuration.intReturns the maximum capacity of the MessageReceiver queue.intThe current queue depth of the MessageReceiver.(package private) PeerStateDestroyedgetRecentlyClosed(long rcvConnID) Was the state for this SSU2 receive connection ID recently closed? Lock-free single ConcurrentHashMap read.intThe current or configured internal IPv4 port.private intgetRequestedPort(boolean ipv6) The current or configured internal port.intgetSSU2MTU(boolean ipv6) The SSU2 MTU for the socket interface.(package private) byte[]The static Intro key.(package private) byte[]The static priv key.(package private) byte[]The static pub key.(package private) intgetSSUVersion(RouterAddress addr) Valid SSU version of Bob's SSU address for our outbound connections as Alice.getStyle()Transport style string "SSU".(package private) RouterAddressgetTargetAddress(RouterInfo target) First available address of the target that we can use.intTotal outbound messages queued across all UDP peers.getTuner()The transport tuner.(package private) X25519KeyFactoryXDH key factory for SSU2, or null if not configured for SSU2.(package private) booleanFor PeerTestManager.(package private) static longidleHardCutoff(long now, boolean overCapacity) Hard-cap idle cutoff: peers idle past this are dropped when the connection maximum is exceeded, otherwise the cutoff is unbounded.(package private) static booleanidleSince(long lastReceive, long lastSend, long cutoff) Whether a peer has been idle (no receive and no send) since the given cutoff.(package private) static longinactivityCutoff(long now, long timeout, boolean weAreFirewalled, long firewalledMin) Idle cutoff for a peer tier.(package private) voidinboundConnectionReceived(boolean isIPv6) Inbound connection received, which locks our IP against changing forALLOW_IP_CHANGE_INTERVAL.private voidInitializes establishment and handler managers if missing.(package private) booleanintroducersMaybeRequired(boolean ipv6) MIGHT we require introducers? This is like introducersRequired, but if we aren't sure, this returns true.private booleanintroducersRequired(boolean ipv6) Do we require introducers?(package private) static booleanisAddressChange(byte[] externalListenHost, int externalListenPort, byte[] ourIP, int ourPort) Whether the peer-reported address differs from the current external address and is worth acting on.private booleanisAlive()Check if inbound fragment handler is alive.booleanisBacklogged(Hash dest) Whether the peer for the given destination is backlogged.booleanisConnecting(Hash dest) Check if a connection attempt is in progress for the given peer.(package private) static booleanisDifferentNetwork(int nid, int ourNetworkId) Whether the target router belongs to a different network than ours.booleanisEstablished(Hash dest) Whether the given peer is established.private booleanAre we behind a firewall, with no way to accept incoming UDP?(package private) static booleanisFirewalled(CommSystemFacade.Status status) Whether a comm-system reachability status means we are firewalled for at least one address family.(package private) static booleanisIdleEstablished(long now, long lastSend, long lastRecv, long maxIdleTime) Is an established peer idle past the threshold in both directions, and so due for teardown and re-establishment rather than continued selection?(package private) booleanisIdleEstablished(PeerState peer, long now, long maxIdleTime) Is the peer idle in both directions past the threshold, disregarding send failures.(package private) booleanisInDropList(RemoteHostId peer) Is in drop list.(package private) static booleanisIPChange(byte[] externalListenHost, byte[] ourIP) Whether the reported host differs from the current external host.(package private) static booleanisLocalAddress(byte[] ip) Whether the given IP is one of this host's local addresses.(package private) booleanIs IPv4 Symmetric NATted?(package private) booleanisTooClose(byte[] ip) Is this IP too close to ours to trust it for things like relaying?(package private) static booleanisTooLarge(int dataSize) Not-a-note: the message is too large for SSU to carry at all.final booleanisValid(byte[] addr) An IPv6 address is only valid if we are configured to support IPv6 AND we have a public IPv6 address.private booleanAdds a connected peer under the add/drop lock.private voidlocked_dropPeer(PeerState peer, boolean shouldBanlist, String why) This does not send a session destroy, caller must do that if desired.private RouterAddresslocked_rebuildExternalAddress(String host, int port, boolean allowRebuildRouterInfo) Rebuild the external address from the given validated host; caller must hold the rebuild lock.private voidlocked_setReachabilityStatus(CommSystemFacade.Status newStatus, boolean isIPv6) 1) Merge IPv4 or IPv6 newStatus into the current IPv4+IPv6 status 2a) If current status changed, callrebuildExternalAddress(boolean)2b) Otherwise, If we need to retest, callPeerTestEvent.forceRunSoon(boolean).voidmayDisconnect(Hash peer) Tell the transport that we may disconnect from this peer.(package private) static booleanmayDisconnectLowTraffic(boolean haveCap, boolean inbound, boolean mayDisconnect, int messagesReceived, int messagesSent) Whether an inbound (or capacity-starved) peer with may-disconnect set and near-zero traffic is a stale candidate for the aggressive 15-second cutoff.voidmessageReceived(I2NPMessage inMsg, RouterIdentity remoteIdent, Hash remoteIdentHash, long msToReceive, int bytesReceived) Handle incoming message from transport layer.(package private) static booleanneedsMinimumSigTypeVersion(SigType ourSigType, String theirVersion) Whether we need a minimum software version on the target because we are not DSA-signed: non-DSA routers cannot be reached by pre-0.9.17 builds that do not understand their signature types.protected voidNot used for UDP, which does its own queueing.(package private) static longparseLastAddressChange(String value) Parse the stored last-IP-change timestamp, tolerating garbage.(package private) static longpickInactivityCutoff(boolean reliedOnRecently, boolean mayDisconnectLowTraffic, long longInactivityCutoff, long mayDisconCutoff, long shortInactivityCutoff) Select the inactivity tier for a peer.(package private) PeerStatepickTestPeer(PeerTestState.Role peerRole, int version, boolean isIPv6, RemoteHostId dontInclude) Pick a Bob (if we are Alice) or a Charlie (if we are Bob).private booleanWhether the config prefers UDP over NTCP.private RouterAddressrebuildEmptyAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6, boolean introducersRequired, int mtu) No direct address and no introducers available; publish an empty "4" or "6" address so peers know the address exists, and retry later.private RouterAddressrebuildExternalAddress(boolean ipv6) Rebuilds the external router address for either IPv4 or IPv6.private RouterAddressrebuildExternalAddress(boolean allowRebuildRouterInfo, boolean ipv6) Update our IPv4 address and optionally tell the router to rebuild and republish the router info.private RouterAddressrebuildExternalAddress(byte[] ip, int port, boolean allowRebuildRouterInfo) Update our IPv4 or IPv6 address and optionally tell the router to rebuild and republish the router info.private RouterAddressrebuildExternalAddress(String host, int port, boolean allowRebuildRouterInfo) Rebuilds the router address for our external endpoint.private RouterAddressrebuildHiddenExternalAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6) Rebuild the external address of a hidden router: nothing is published, so only an address with 4/6 caps is made.private RouterAddressrebuildPublishedAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6, boolean directIncluded, boolean introducersIncluded, int mtu, OrderedProperties options) Publish the fully populated address (direct and/or introducers).private voidAvoid deadlocks part 999.(package private) static booleanrejectCppBug(int cost, String version) Reject known c++ SSU disconnect bugs (through 0.9.52), which drop inbound sessions shortly after establishment.private booleanrejectFloodfill(Hash to, RouterInfo toAddress) Reject a floodfill router that we have no history with, or that has rejected tunnel creation far more often than it has agreed.(package private) static booleanreliedOnRecently(long weRelayToThemAs, long introducerTime, long pingCutoff) Whether we have recently relied on this peer as a relay or introducer, in which case it gets the long inactivity tier.protected voidremoveAddress(boolean ipv6) Remove then tell NTCP that we changed.protected voidremoveAddress(RouterAddress address) Remove then tell NTCP that we changed.(package private) voidStop listening for packets on a destroyed connection.protected voidreplaceAddress(RouterAddress address) Replace then tell NTCP that we changed.private voidreplaceCurrentExternalAddress(RouterAddress ra, boolean isIPv6) Simple storage of IP and port, since we don't put them in the real, published RouterAddress anymore if we are firewalled.(package private) static booleanrequiresConfirmation(CommSystemFacade.Status old, CommSystemFacade.Status status, boolean isIPv6) Whether the status transition must be confirmed by a second test before it is committed, to prevent thrashing between OK and firewalled.private Set<InetAddress> Resolves bind addresses from configuration properties, expanding hostnames if necessary.private TransportBidselectBid(RouterAddress addr, int cost, boolean weAreFirewalled) Select the bid tier for a message to an unestablished peer.private StringselectCapacity(boolean isIPv6, boolean directIncluded, boolean introducersRequired) Select the address capacity string for the given state.private booleanselectIntroducers(boolean isIPv6, RouterAddress current, OrderedProperties options) Pick inbound introducers for the address options.(package private) voidsend(List<I2NPMessage> msgs, PeerState peer) "injected" messages from the EstablishmentManager.(package private) voidsend(I2NPMessage msg, List<OutNetMessage> msgs, PeerState peer) "injected" message from the EstablishmentManager, plus pending messages to send, so the messages may be bundled efficiently.(package private) voidsend(I2NPMessage msg, PeerState peer) "injected" message from the EstablishmentManager.voidsend(OutNetMessage msg) Asynchronously send the message as requested in the message and, if the send is successful, queue up any msg.getOnSendJob job, and register it with the OutboundMessageRegistry (if it has a reply selector).(package private) voidThis sends it directly out, bypassing OutboundMessageFragments.(package private) voidsendDestroy(PeerState peer, int reasonCode) Send a session destroy message, bypassing OMF and PacketPusher.(package private) voidSend only if established, otherwise fail immediately.static voidsetDataMessageTimeout(long ms) Data message timeout.static voidsetMaxIbEstablishTime(long ms) Inbound establish timeout.static voidsetMaxObEstablishTime(long ms) Outbound establish timeout.static voidsetMessageReceiverThreads(int threads) Target MessageReceiver thread count.private intsetMTU(InetAddress addr) MTU for the socket interface at addr.static voidsetPacketHandlerMaxThreads(int handlers) Max packet handler threads.private voidIPv4 only.(package private) voidsetReachabilityStatus(CommSystemFacade.Status status, boolean isIPv6) Update the reachability status of this router, optionally for an IPv6 change.private voidsetupEndpoints(Set<InetAddress> bindToAddrs, int port) Create UDP endpoints for the given bind addresses and port.private voidPick a port if not previously configured, so that TransportManager may callgetRequestedPort()before we've started to get a best-guess of what our port is going to be, and pass that to NTCP.(package private) static booleanshouldFirewallPing(boolean shouldPingFirewall, boolean sliceMatched, long lastSendOrPing, long lastReceive, long pingFirewallCutoff) Whether a firewall keepalive ping should be sent to this peer: ping mode on, peer in this pass's slice, and no send-or-ping or receive in the PING_FIREWALL_CUTOFF window.(package private) static booleanshouldOverrideReportedPort(boolean fixedPort, int externalListenPort, int reportedPort) Whether the reported (peer-observed) port should be discarded in favour of the currently configured external listen port.(package private) static booleanshouldRerunStatusTest(CommSystemFacade.Status old, boolean isIPv6) Whether an UNKNOWN reachability update should reschedule a peer test.(package private) static booleanshouldRestartForLaptopMode(String oldIP, boolean hasWrapper, boolean laptopMode, long lastChanged, long now, long uptime) Whether the configured IP change rate and startup window require a hard restart with a fresh identity (laptop mode).(package private) static booleanshouldSaveExternalPort(int externalListenPort, int ourPort, int configuredExternalPort) Whether a peer-reported external port change should be persisted to the configuration.(package private) static booleanshouldStoreRI(long uptime, long loopTime) Whether the peer session key is old enough to warrant re-publishing our RouterInfo.voidshutdown()Stop all UDP endpoints, handlers, and background threads.private voidShutdown components and clear endpoints safely.(package private) static booleansigTypeUnsupported(SigType type) Whether the target identity uses a signature type we cannot verify.private intStarts all endpoints, returns the listen port of the first IPv4 endpoint started or -1 if none.voidStart the transport listener.private voidstartup()Starts up the SSU transport listener, configuring and binding UDP endpoints, initializing components, and setting reachability status.private voidStarts fragment and packet components.voidStop listening.voidHandle a successful outbound message.Rebuild to get updated cost and introducers.private voidupdatePortsInConfig(int port, int newPort) Updates internal and external port config after successful endpoint startup.Methods inherited from class TransportImpl
_t, _t, afterSend, afterSend, afterSend, afterSend, allowLocal, externalAddressRemoved, formatIPPort, getContext, getCurrentAddress, getCurrentAddresses, getCurrentIPv4, getIP, getIPv6Config, getMaxConnections, getMostRecentErrorMessages, getNextMessage, getRouterIPPort, getSavedLocalAddresses, getSendPool, getSendPoolCapacity, getTargetAddresses, getTransportMaxConnections, hasCurrentAddress, haveCapacity, haveCapacity, isCurrentIPv4, isIPv4Firewalled, isIPv6Firewalled, isPubliclyRoutable, isUnreachable, markReachable, markUnreachable, ngettext, renderStatusHTML, renderStatusHTML, resizeSendPool, saveLocalAddress, sendPoolCapacityMax, sendPoolCapacityMin, setIP, setListener, setSendPoolCapacity, stopCleanupJob, wasFailsafeClosed, wasUnreachableModifier and TypeMethodDescriptionprotected StringLooks the string up in the web messages bundle, returning s itself if there is no translation.protected StringTranslate and substitute one parameter.protected voidafterSend(OutNetMessage msg, boolean sendSuccessful) The transport is done sending this message.protected voidafterSend(OutNetMessage msg, boolean sendSuccessful, boolean allowRequeue) The transport is done sending this message.protected voidafterSend(OutNetMessage msg, boolean sendSuccessful, boolean allowRequeue, long msToSend) The transport is done sending this message.protected voidafterSend(OutNetMessage msg, boolean sendSuccessful, long msToSend) The transport is done sending this message.booleanAre we allowed to connect to local addresses?voidexternalAddressRemoved(Transport.AddressSource source, boolean ipv6) Notify a transport of an external address change.static StringformatIPPort(byte[] ip, int port) Format an IP byte array (4 or 16 bytes) as host:port, for logging.The context this transport runs in.getCurrentAddress(boolean ipv6) What address are we currently listening to? Replaces getCurrentAddress()What addresses are we currently listening to? ReplacesTransportImpl.getCurrentAddress(boolean).protected byte[]IP of the current IPv4 address, from the cache maintained by the address mutators.static byte[]IP of the peer from the last connection (in or out, any transport).The IPv6 configuration for this transport.intPer-transport connection limit.Recent error messages from this transport.protected OutNetMessageNonblocking call to pull the next outbound message off the queue.static StringgetRouterIPPort(RouterInfo router) Best IP:port for a router, for ban logging: the direct connection IP from the transport layer, else a compatible address, else any announced address.protected Collection<InetAddress> Return and then clear all saved local addresses.The send pool instance, for stat access.static intCapacity of the NTCP send pool.getTargetAddresses(RouterInfo target) All available addresses we can use, shuffled and then sorted by cost/preference.static intgetTransportMaxConnections(RouterContext ctx, String style) The transport max connections for the given context and style.booleanDo we have any current address?booleanCan we initiate or accept a connection to another peer, saving some margin.booleanhaveCapacity(int pct) Whether we are under the given capacity level.booleanisCurrentIPv4(byte[] ip) Is the given IP the current external IPv4 address?booleanThis returns true if the force-firewalled setting is configured, false otherwise.booleanThis returns true if the force-firewalled setting is configured, false otherwise.protected booleanisPubliclyRoutable(byte[] addr) Allows IPv6 only if the transport is configured for it.booleanisUnreachable(Hash peer) Whether the given peer is unreachable.voidmarkReachable(Hash peer, boolean isInbound) Called when we establish a peer connection (outbound or inbound).voidmarkUnreachable(Hash peer) Called when we can't reach a peer.protected StringTranslate, choosing between the singular and the plural form.voidrenderStatusHTML(Writer out) Make this stuff pretty.voidrenderStatusHTML(Writer out, String urlBase, int sortFlags) Render the transport status HTML to the given writer.voidResize the NTCP send pool if needed.protected voidsaveLocalAddress(InetAddress address) Save a local address we were notified about before we started.static intThe largest capacityTransportImpl.setSendPoolCapacity(int)accepts.static intThe smallest capacityTransportImpl.setSendPoolCapacity(int)accepts.voidIP of the peer from the last connection (in or out, any transport).voidsetListener(TransportEventListener listener) Who to notify on message availability.static voidsetSendPoolCapacity(int capacity) The NTCP send pool capacity (called by Tuner).voidCancel the unreachable-entry cleanup, if one is scheduled.booleanwasFailsafeClosed(Hash peer, long withinMs) Whether this transport closed a session to the peer for idleness recently.booleanwasUnreachable(Hash peer) Was the peer unreachable (outbound only) the last time we tried it? This is NOT reset if the peer contacts us.
Field Details
_log
Logger for this class._banLogger
Logger for peers banned by this transport._endpoints
The sockets listened on, one per local address._addDropLock
Lock serializing peer adds against drop-list changes._peersByIdent
_peersByRemoteHost
Map of known peers, keyed by their remote host and port. Used to identify peers based on source address in incoming packets._peersByConnID
Connected peers, by connection id._recentlyClosedConnIDs
Recently closed peers, by connection id, for late packets._handler
Thread reading packets off the sockets._establisher
Runs the SSU2 handshakes._fragments
Queue of outbound message fragments._pusher
Thread pushing queued packets to the sockets._inboundFragments
Queue of inbound message fragments._testManager
Manages peer reachability testing to determine if we are firewalled or reachable._introManager
Manages introducers and introductions._expireEvent
Timer expiring idle peers._testEvent
Timer running reachability peer tests._reachabilityStatus
Our measured reachability._reachabilityStatusPending
A new reachability awaiting confirmation._reachabilityStatusUnchanged
private volatile int _reachabilityStatusUnchangedLoops the reachability has been unchanged, logging only._v4IntroducersSelectedOn
private long _v4IntroducersSelectedOnTime the IPv4 introducer set was last chosen._v6IntroducersSelectedOn
private long _v6IntroducersSelectedOnTime the IPv6 introducer set was last chosen._lastInboundReceivedOn
private volatile long _lastInboundReceivedOnTime the last inbound packet arrived._mtu
private int _mtuThe MTU in use, in bytes._mtu_ssu2
private int _mtu_ssu2The SSU2 MTU in use, in bytes._mtu_ssu2_ipv6
private int _mtu_ssu2_ipv6The SSU2 IPv6 MTU in use, in bytes._defaultMTU
private final int _defaultMTUThe MTU configured at startup, in bytes._mismatchLogged
private boolean _mismatchLoggedTrue once the MTU mismatch has been logged._networkID
private final int _networkIDNetwork id of the packets we accept._haveIPv6Address
private volatile boolean _haveIPv6AddressDo we have a public IPv6 address?_lastInboundIPv6
private volatile long _lastInboundIPv6Time the last inbound IPv6 packet arrived._min_peers
private final int _min_peersFewest peers to keep connected._min_v6_peers
private final int _min_v6_peersFewest IPv6-capable peers to keep connected._needsRebuild
private volatile boolean _needsRebuildFlag indicating whether the router's external address needs to be rebuilt. This is typically set after significant network changes or reachability updates._rebuildLock
Lock serializing external-address rebuilds._introKey
Introduction key._dropList
List of RemoteHostId for peers whose packets we want to drop outright This is only for old network IDs (pre-0.6.1.10), so it isn't really used now._expireTimeout
private volatile long _expireTimeoutIdle time at which a peer is expired, in ms._lastFromv4
Last report from a peer of our IP._lastFromv6
Hash of the last peer reached over IPv6._lastFromIPv4
private byte[] _lastFromIPv4Source of the last inbound IPv4 packet._lastFromIPv6
private byte[] _lastFromIPv6Source of the last inbound IPv6 packet._lastOurIPv4
private byte[] _lastOurIPv4Local address the last outbound IPv4 packet left._lastOurIPv6
private byte[] _lastOurIPv6Local address the last outbound IPv6 packet left._lastOurPortv4
private int _lastOurPortv4Local port the last outbound IPv4 packet left._lastOurPortv6
private int _lastOurPortv6Local port the last outbound IPv6 packet left._haveUPnP
private boolean _haveUPnPTrue once a UPnP port mapping exists._currentOurV4Address
We don't publish our IP/port if introduced, so we need to store it somewhere._currentOurV6Address
Our current IPv6 endpoint as a router address._tuner
Adaptive tuner.STYLE2
Style identifier for the SSU2 protocol variant. Value sourced fromTransport.STYLE_SSU2.- See Also:
SSU2_INT_VERSION
SSU2_VERSION
"2".SSU2_VERSION_ALT
"2,"._packetBuilder2
Builds the SSU2 packets we send._xdhFactory
Shared X25519 factory for the handshakes._ssu2StaticPubKey
private final byte[] _ssu2StaticPubKeyOur SSU2 static public key._ssu2StaticPrivKey
private final byte[] _ssu2StaticPrivKeyOur SSU2 static private key._ssu2StaticIntroKey
private final byte[] _ssu2StaticIntroKeyOur SSU2 introducer-only static key._ssu2B64StaticPubKey
The static public key, base64, for the router info._ssu2B64StaticIntroKey
The introducer key, base64, for the router info.PROP_SSU2_SP
Config key for the base-64 SSU2 static private key. Value sourced fromTransport.PROP_SSU2_SP.- See Also:
PROP_SSU2_IKEY
Config key for the base-64 SSU2 static IV. Value sourced fromTransport.PROP_SSU2_IKEY.- See Also:
MIN_DOWNTIME_TO_REKEY_HIDDEN
private static final long MIN_DOWNTIME_TO_REKEY_HIDDENHidden routers re-key after 24 hours of downtime.- See Also:
DROPLIST_PERIOD
private static final int DROPLIST_PERIODStale drop-list entries are removed every 10 minutes.- See Also:
STYLE
Style identifier for the SSU transport. Value sourced fromTransport.STYLE_SSU.- See Also:
PROP_INTERNAL_PORT
Config key for the SSU internal listening port. Value sourced fromTransport.PROP_INTERNAL_PORT.- See Also:
PROP_EXTERNAL_HOST
Config key to force advertising a fixed external IP address. Value sourced fromTransport.PROP_EXTERNAL_HOST.- See Also:
PROP_EXTERNAL_PORT
Config key to force advertising a fixed external port. Value sourced fromTransport.PROP_EXTERNAL_PORT.- See Also:
PROP_PREFER_UDP
Config key to prefer UDP transport.- See Also:
DEFAULT_PREFER_UDP
Default for preferring UDP over NTCP.- See Also:
PROP_FIXED_PORT
Override whether we will change our advertised port no matter what our peers tell us. SeegetIsPortFixed(boolean)for default behaviour. Value sourced fromTransport.PROP_FIXED_PORT.- See Also:
PROP_SOURCES
Allowed sources of address updates. Value sourced fromTransport.PROP_SOURCES.- See Also:
DEFAULT_SOURCES
Default address sources. Value sourced fromTransport.DEFAULT_SOURCES.PROP_IP
Remember IP changes across restarts. Value sourced fromTransport.PROP_IP.- See Also:
PROP_IP_CHANGE
Config key tracking when the last IP address change occurred.- See Also:
PROP_LAPTOP_MODE
Config key for laptop power-saving mode. Value sourced fromTransport.PROP_LAPTOP_MODE.- See Also:
PROP_IPV6
Last IPv6 config. Value sourced fromTransport.PROP_IPV6.- See Also:
PROP_FORCE_INTRODUCERS
Do we require introducers, regardless of our status? Value sourced fromTransport.PROP_FORCE_INTRODUCERS.- See Also:
PROP_ALLOW_DIRECT
Do we allow direct SSU connections, sans introducers?- See Also:
PROP_BIND_INTERFACE
This is rarely if ever used, default is to bind to wildcard address.- See Also:
PROP_DEFAULT_MTU
Override the "large" (max) MTU, default is PeerState.LARGE_MTU.- See Also:
PROP_INTRO_KEY
Config key for the SSU introducer key published in hidden-mode RouterInfos. Value sourced fromTransport.PROP_INTRO_KEY.- See Also:
CAP_TESTING
Capacity letter for a peer under testing.CAP_TESTING_INTRO
Capacity letters for a testing introducer.CAP_TESTING_4
Capacity letters for a testing IPv4 peer.CAP_TESTING_6
Capacity letters for a testing IPv6 peer.PUBLIC_RELAY_COUNT
public static final int PUBLIC_RELAY_COUNTHow many relays offered to us will we use at a time?- See Also:
MAX_CONSECUTIVE_FAILED
private static final int MAX_CONSECUTIVE_FAILEDConsecutive send failures before considering a peer for drop (requires inactivity too).- See Also:
DEFAULT_COST
public static final int DEFAULT_COSTDefault cost value for SSU peer selection.- See Also:
SSU_OUTBOUND_COST
private static final int SSU_OUTBOUND_COSTRelative cost of sending via SSU, against NTCP's 10.- See Also:
RATES
static final long[] RATESShort-term rate limits for SSU.MIN_PEERS
private static final int MIN_PEERSMinimum active peers to maintain IP detection, etc.- See Also:
MIN_PEERS_IF_HAVE_V6
private static final int MIN_PEERS_IF_HAVE_V6Peer target once we are reachable over IPv6.- See Also:
MIN_INTRODUCER_POOL
private static final int MIN_INTRODUCER_POOLMinimum peers volunteering to be introducers if we need that.- See Also:
INTRODUCER_EXPIRATION_MARGIN
static final long INTRODUCER_EXPIRATION_MARGINDefault introducer expiration in ms.- See Also:
MIN_DOWNTIME_TO_REKEY
private static final long MIN_DOWNTIME_TO_REKEYWe re-key after 7 days of downtime.- See Also:
BID_VALUES
private static final int[] BID_VALUESBid values for each peer class, worst last.FAST_PREFERRED_BID
private static final int FAST_PREFERRED_BIDBid index for a fast peer we prefer.- See Also:
SLOW_PREFERRED_BID
private static final int SLOW_PREFERRED_BIDBid index for a slow peer we prefer.- See Also:
FAST_BID
SLOW_BID
SLOWEST_BID
SLOWEST_COST_BID
private static final int SLOWEST_COST_BIDBid index for the slowest tier by cost.- See Also:
NEAR_CAPACITY_BID
private static final int NEAR_CAPACITY_BIDBid index for a peer near its capacity.- See Also:
NEAR_CAPACITY_COST_BID
private static final int NEAR_CAPACITY_COST_BIDBid index for a peer near capacity by cost.- See Also:
TRANSIENT_FAIL_BID
private static final int TRANSIENT_FAIL_BIDBid index for a peer with a recent failure.- See Also:
_cachedBid
Precomputed bids, indexed by the constants above.MIN_SIGTYPE_VERSION
RI sigtypes supported in 0.9.16, but due to a bug inInboundEstablishStatefixed in 0.9.17, we cannot connect out to routers before that version.- See Also:
MIN_PEER_TEST_VERSION
Oldest version whose SSU2 peer tests are trusted, SSU2 having become stable then.- See Also:
STATUS_IPV4_UNK
Statuses in which our IPv4 reachability is unknown.STATUS_IPV6_UNK
Statuses in which our IPv6 reachability is unknown.STATUS_IPV4_FW
Statuses in which our IPv4 is firewalled.STATUS_IPV6_FW
Statuses in which our IPv6 is firewalled.STATUS_FW
Statuses in which either family is firewalled.STATUS_IPV6_FW_2
Statuses treating IPv6 as firewalled, ambiguous ones included.STATUS_IPV6_OK
Statuses in which our IPv6 is reachable.STATUS_OK
Statuses in which our IPv4 is reachable.STATUS_IPV4_SYMNAT
Statuses in which IPv4 sits behind a symmetric NAT.STATUS_IPV4_NO_TEST
Statuses in which we cannot be a v4 Charlie.STATUS_IPV6_NO_TEST
Statuses in which we cannot be a v6 Charlie.ALLOW_IP_CHANGE_INTERVAL
private static final int ALLOW_IP_CHANGE_INTERVALIf we have received an inbound connection in the last 2 minutes, don't allow our IP to change.- See Also:
gotIPv4Addr
private boolean gotIPv4AddrTrue once the IPv4 address has been reported, to stop repeats.gotIPv6Addr
private boolean gotIPv6AddrTrue once the IPv6 address has been reported, to stop repeats.EXPIRE_TIMEOUT
public static final int EXPIRE_TIMEOUTDefault introducer expiration in ms.- See Also:
MAX_IDLE_TIME
private static final int MAX_IDLE_TIMEIdle time past which a peer is disconnected.- See Also:
MIN_EXPIRE_TIMEOUT
public static final int MIN_EXPIRE_TIMEOUTMinimum introducer expiration in ms.- See Also:
PING_FIREWALL_TIME
private static final long PING_FIREWALL_TIMETime past which a ping keeps the firewall open, 30 seconds; firewalls have been seen to change ports after 40.- See Also:
PING_FIREWALL_CUTOFF
private static final long PING_FIREWALL_CUTOFFHalf of that, the time by which the ping must be sent.- See Also:
SLICES
SHORT_LOOP_TIME
private static final long SHORT_LOOP_TIMELoop interval while pings are due.- See Also:
LONG_LOOP_TIME
private static final long LONG_LOOP_TIMELoop interval while no pings are due.- See Also:
EXPIRE_INCREMENT
private static final long EXPIRE_INCREMENTAmount the expire timeout grows per adjustment.- See Also:
EXPIRE_DECREMENT
private static final long EXPIRE_DECREMENTAmount the expire timeout shrinks per adjustment.- See Also:
MAY_DISCON_TIMEOUT
private static final long MAY_DISCON_TIMEOUTIdle time past which a peer may be disconnected.- See Also:
RI_STORE_INTERVAL
private static final long RI_STORE_INTERVALThe router info is re-stored every 29 minutes.- See Also:
PROP_REACHABILITY_STATUS_OVERRIDE
Property overriding the measured reachability.- See Also:
Constructor Details
UDPTransport
Create the UDP transport for the given router context and SSU2 XDH factory.- Parameters:
ctx- the router contextxdh- non-null
Method Details
getTuner
getMaxObEstablishTime
public static long getMaxObEstablishTime()The outbound establish timeout in ms.- Returns:
- the timeout, in ms
setMaxObEstablishTime
public static void setMaxObEstablishTime(long ms) Outbound establish timeout.- Parameters:
ms- the outbound establish timeout, bounded 1500-5000ms
getMaxIbEstablishTime
public static long getMaxIbEstablishTime()The inbound establish timeout in ms.- Returns:
- the timeout, in ms
setMaxIbEstablishTime
public static void setMaxIbEstablishTime(long ms) Inbound establish timeout.- Parameters:
ms- the inbound establish timeout, bounded 1500-5000ms
getDataMessageTimeout
public static long getDataMessageTimeout()The data message timeout in ms.- Returns:
- the timeout, in ms
setDataMessageTimeout
public static void setDataMessageTimeout(long ms) Data message timeout.- Parameters:
ms- the data message timeout, bounded 15000-120000ms
getOMF
OutboundMessageFragments getOMF()The OutboundMessageFragments instance.- Returns:
- the instance of OutboundMessageFragments
setupPort
private void setupPort()Pick a port if not previously configured, so that TransportManager may callgetRequestedPort()before we've started to get a best-guess of what our port is going to be, and pass that to NTCP.startup
private void startup()Starts up the SSU transport listener, configuring and binding UDP endpoints, initializing components, and setting reachability status. This method is synchronized to prevent concurrent startup attempts.shutdownComponents
private void shutdownComponents()Shutdown components and clear endpoints safely.resolveBindAddresses
Resolves bind addresses from configuration properties, expanding hostnames if necessary.- Returns:
- set of InetAddress to bind to, empty if none specified
expandExternalHostToBind
Expands the PROP_EXTERNAL_HOST configuration into a comma-separated string of IP addresses that are local and allowed.- Returns:
- expanded bind string or null if no resolved addresses
determinePort
Determines the port to bind to based on internal, bind, or external port properties.- Parameters:
bindToAddrs- set of addresses to bind; used for logging- Returns:
- the port to bind to
setupEndpoints
Create UDP endpoints for the given bind addresses and port.- Parameters:
bindToAddrs- addresses to bind, empty means wildcardport- port to bind endpoints on
initializeManagers
private void initializeManagers()Initializes establishment and handler managers if missing.startEndpointsAndGetPort
private int startEndpointsAndGetPort()Starts all endpoints, returns the listen port of the first IPv4 endpoint started or -1 if none.- Returns:
- new port that endpoints are listening on or -1
updatePortsInConfig
private void updatePortsInConfig(int port, int newPort) Updates internal and external port config after successful endpoint startup.- Parameters:
port- previously requested portnewPort- actual port endpoints listen on
startupComponentServices
private void startupComponentServices()Starts fragment and packet components.configureExternalAddressesAndStatus
Configures external addresses and sets reachability status based on current state.- Parameters:
newPort- port that endpoints are listening onbindToAddrs- bind addresses provided
adjustReachabilityForFirewalled
private void adjustReachabilityForFirewalled()Adjusts reachability status when IPv4 is firewalled.shutdown
public void shutdown()Stop all UDP endpoints, handlers, and background threads.fail
The endpoint has failed. Remove it.- Parameters:
endpoint- the failed endpoint; dropping it rebuilds the external address advertisement
isAlive
private boolean isAlive()Check if inbound fragment handler is alive.- Returns:
- true if the inbound fragment handler job is still running
getIntroKey
SessionKey getIntroKey()Introduction key that people should use to contact us, or null if SSU1 disabled.- Returns:
- the SSU1 introduction key, or null if SSU1 is disabled
getSSU2StaticIntroKey
byte[] getSSU2StaticIntroKey()The static Intro key.- Returns:
- null if not configured for SSU2
getSSU2StaticPubKey
byte[] getSSU2StaticPubKey()The static pub key.- Returns:
- null if not configured for SSU2
getSSU2StaticPrivKey
byte[] getSSU2StaticPrivKey()The static priv key.- Returns:
- null if not configured for SSU2
getSSUVersion
Valid SSU version of Bob's SSU address for our outbound connections as Alice.- Parameters:
addr- the remote RouterAddress, whose transport style selects the version- Returns:
- the valid version 1 or 2, or 0 if unusable
addSSU2Options
Add the required options to the properties for a SSU2 address. Host/port must already be set in props if they are going to be. Must only be called if SSU2 is enabled.- Parameters:
props- the address options to add the SSU2 intro key, static key and version entries to
getExternalPort
int getExternalPort(boolean ipv6) Published or requested port.- Parameters:
ipv6-truefor the IPv6 socket- Returns:
- the published port, else the requested port
getExternalIP
byte[] getExternalIP()Published IP, IPv4 only.Reads the cached IPv4 address rather than scanning _currentAddresses, so this does not take the address-list monitor. For the per-packet comparison, prefer
TransportImpl.isCurrentIPv4(byte[])over copying the array.- Returns:
- a copy of the IP, or null if we have no IPv4 address
hasIPv6Address
boolean hasIPv6Address()For PeerTestManager.- Returns:
trueif we have a published IPv6 address
isTooClose
boolean isTooClose(byte[] ip) Is this IP too close to ours to trust it for things like relaying?- Parameters:
ip- IPv4 or IPv6- Returns:
trueif it shares our subnet prefix (2 bytes IPv4, 4 bytes IPv6)
getListenPort
private int getListenPort(boolean ipv6) The current port of the first matching endpoint. To be enhanced to handle multiple endpoints of the same type.- Parameters:
ipv6- true to match an IPv6 endpoint, false for IPv4- Returns:
- port or -1
getRequestedPort
public int getRequestedPort()The current or configured internal IPv4 port. UDPEndpoint should always be instantiated (and a random port picked if not configured) before this is called, so the returned value should be > 0 unless the endpoint failed to bind.- Specified by:
getRequestedPortin interfaceTransport- Overrides:
getRequestedPortin classTransportImpl- Returns:
- the requested port
getRequestedPort
private int getRequestedPort(boolean ipv6) The current or configured internal port. UDPEndpoint should always be instantiated (and a random port picked if not configured) before this is called, so the returned value should be > 0 unless the endpoint failed to bind.- Parameters:
ipv6- true to return the IPv6 port, false for IPv4- Returns:
- the requested port
setMTU
MTU for the socket interface at addr.- Parameters:
addr- null ok- Returns:
- the MTU in bytes
getMTU
public int getMTU(boolean ipv6) The MTU for the socket interface. To be used as the "large" MTU.- Parameters:
ipv6- true for IPv6, false for IPv4- Returns:
- limited to range PeerState.MIN_MTU to PeerState.LARGE_MTU.
getSSU2MTU
public int getSSU2MTU(boolean ipv6) The SSU2 MTU for the socket interface. To be used as the "large" MTU.- Parameters:
ipv6- true for IPv6, false for IPv4- Returns:
- limited to range PeerState2.MIN_MTU to PeerState2.LARGE_MTU, or 0 if unavailable
inboundConnectionReceived
void inboundConnectionReceived(boolean isIPv6) Inbound connection received, which locks our IP against changing forALLOW_IP_CHANGE_INTERVAL.- Parameters:
isIPv6-truefor the IPv6 socket
externalAddressReceived
From config, UPnP, local i/f, ... Not for info received from peers - see externalAddressReceived(Hash, ip, port).- Specified by:
externalAddressReceivedin interfaceTransport- Specified by:
externalAddressReceivedin classTransportImpl- Parameters:
source- as defined in Transport.SOURCE_xxxip- publicly routable IPv4 or IPv6, null okport- 0 if unknown
forwardPortStatus
public void forwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason) Callback from UPnP. If we we have an IP address and UPnP claims success, believe it. If this is wrong, the peer test will figure it out and change the status. Don't do anything if UPnP claims failure.- Specified by:
forwardPortStatusin interfaceTransport- Overrides:
forwardPortStatusin classTransportImpl- 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
externalAddressReceived
Someone we tried to contact gave us what they think our IP address is. Right now, we just blindly trust them, changing our IP and port on a whim. this is not good ;)Slight enhancement - require two different peers in a row to agree
Todo: - Much better tracking of troublemakers - Disable if we have good local address or UPnP - This gets harder if and when we publish multiple addresses, or IPv6.
- Parameters:
from- Hash of inbound destinationhisIP- the IP of the peer telling usourIP- publicly routable IPv4 or IPv6 only, non-nullourPort- >= 1024
changeAddress
private boolean changeAddress(byte[] ourIP, int ourPort) Updates the external IP address and/or port based on feedback from a peer. This is used when a peer reports our external address, or when we detect a change.- Parameters:
ourIP- the new IP address (IPv4 or IPv6)ourPort- the new port number, or 0 to keep the current port- Returns:
- true if the address was successfully updated
shouldOverrideReportedPort
static boolean shouldOverrideReportedPort(boolean fixedPort, int externalListenPort, int reportedPort) Whether the reported (peer-observed) port should be discarded in favour of the currently configured external listen port.The port is pinned when the operator fixed it (
fixedPortwith a known listen port) or when the peer reported no port at all.- Parameters:
fixedPort- true if the transport runs with a fixed portexternalListenPort- current external listen portreportedPort- port reported by the peer (may be <= 0)- Returns:
- true if
reportedPortmust be discarded
isAddressChange
static boolean isAddressChange(byte[] externalListenHost, int externalListenPort, byte[] ourIP, int ourPort) Whether the peer-reported address differs from the current external address and is worth acting on. A reported port of 0 means "keep the current port", so a zero port is never an address change.- Parameters:
externalListenHost- current external host, may be nullexternalListenPort- current external portourIP- reported host (IPv4 or IPv6)ourPort- reported port, 0 = keep current- Returns:
- true if the address pair should be updated
isIPChange
static boolean isIPChange(byte[] externalListenHost, byte[] ourIP) Whether the reported host differs from the current external host.- Parameters:
externalListenHost- current external host, may be nullourIP- host address the peer reported for us- Returns:
- true if the host differs
shouldSaveExternalPort
static boolean shouldSaveExternalPort(int externalListenPort, int ourPort, int configuredExternalPort) Whether a peer-reported external port change should be persisted to the configuration. The configured external port (explicit operator setting) takes precedence over any report and is never overwritten.- Parameters:
externalListenPort- current external listen portourPort- port the peer reported for usconfiguredExternalPort- externally configured port, 0 if none- Returns:
- true if the reported port must be persisted
shouldRestartForLaptopMode
static boolean shouldRestartForLaptopMode(String oldIP, boolean hasWrapper, boolean laptopMode, long lastChanged, long now, long uptime) Whether the configured IP change rate and startup window require a hard restart with a fresh identity (laptop mode).- Parameters:
oldIP- the previously configured IP, null if never sethasWrapper- true if running under the service wrapperlaptopMode- true if thei2np.laptopModeproperty is setlastChanged- ms of the previous IP change, 0 if unknownnow- current time msuptime- router uptime ms- Returns:
- true if the router should restart with a new identity
parseLastAddressChange
Parse the stored last-IP-change timestamp, tolerating garbage.- Parameters:
value- the property value, may be null or non-numeric- Returns:
- the timestamp in ms, or 0 when unset or unparsable
isLocalAddress
static boolean isLocalAddress(byte[] ip) Whether the given IP is one of this host's local addresses.- Parameters:
ip- absolute IPv4 or IPv6 address bytes, may be null- Returns:
- true if it matches a local interface address
eq
private static final boolean eq(byte[] laddr, int lport, byte[] raddr, int rport) Compare two address and port pairs for equality; either address may be null.- Parameters:
laddr- local address, may be nulllport- local port, 0-65535raddr- remote address, may be nullrport- remote port, 0-65535- Returns:
- true if the ports are equal and the addresses are equal, with null addresses equal only when both are null
isValid
public final boolean isValid(byte[] addr) An IPv6 address is only valid if we are configured to support IPv6 AND we have a public IPv6 address.- Parameters:
addr- may be null, returns false- Returns:
- true if valid
getIsPortFixed
private boolean getIsPortFixed(boolean isIPv6) Was true before 0.9.2 Now false if we need introducers (as perhaps that's why we need them, our firewall is changing our port), unless overridden by the property. We must have an accurate external port when firewalled, or else our signature of the SessionCreated packet will be invalid.As of 0.9.58, returns false if status is UNKNOWN.
- Parameters:
isIPv6- true to evaluate the IPv6 reachability status, false for IPv4- Returns:
- true if our port is fixed and stable, false if we are firewalled or the status for that family is unknown
getPeerState
Retrieves the current connection state for a peer identified by their remote host and port.- Parameters:
hostInfo- the remote host and port of the peer- Returns:
- the peer state, or null if not found
getPeerState
getEstimatedRTT
Measured round trip time to a peer over SSU.PeerState seeds its RTT at 0 and only assigns a real value from an observed round trip, so 0 here means the session has not measured yet. Callers treat that as unknown, not as an impossibly good peer.
- Parameters:
peer- the peer to measure- Returns:
- the measured RTT in ms, or 0 if there is no session or none measured
getEstimatedRTTTime
WhengetEstimatedRTT(Hash)was measured, on the router clock.Always
Transport.RTT_TIME_CURRENT: SSU refreshes a session's RTT on every acknowledgement, so whatever this returns was measured by traffic the session is carrying now. There is no reading here that can go stale while a session is alive, which is the property NTCP2 lacks.- Parameters:
peer- the peer to report on- Returns:
Transport.RTT_TIME_CURRENT, always
getPeerState
Peer state by SSU2 connection ID.- Parameters:
rcvConnID- the receive connection ID of the session- Returns:
- the peer state, or null if none exists
getRecentlyClosed
Was the state for this SSU2 receive connection ID recently closed? Lock-free single ConcurrentHashMap read. Hits the per-packet receive path on a connection-ID miss (attacker-triggerable), so the shared add/drop lock must not be taken here.- Parameters:
rcvConnID- the receive connection ID of the closed session- Returns:
- the destroyed state, or null if the ID is not in the recent list
addRecentlyClosed
Start listening for packets on a destroyed connection.- Parameters:
peer- the destroyed session to keep reachable
removeRecentlyClosed
Stop listening for packets on a destroyed connection.- Parameters:
peer- the destroyed session to stop tracking
getPeers
For /peers UI only. Not a public API, not for external use.- Returns:
- not a copy, do not modify
getEstablished
changePeerPort
Remove and add to peersByRemoteHost map.- Parameters:
peer- the peer whose port changednewPort- the peer's new port
changePeerAddress
Remove and add to peersByRemoteHost map.- Parameters:
peer- the peer whose address changednewAddress- the peer's new IP and port
getEstablisher
addRemotePeerState
Adds a new peer state or replaces an existing one if the peer identity or address changes. This method ensures thread-safe updates to internal peer tracking maps.- Parameters:
peer- the peer state to add or update- Returns:
- true if the peer was successfully added or updated
locked_addRemotePeerState
Adds a connected peer under the add/drop lock.- Parameters:
peer- the peer to add- Returns:
- true if it was added
alreadyConnectedLine
The entry for a peer replaced while establishing a second session with the same router. The tag says which map held the previous peer - PBID for the remote router hash, PBRH for the remote host id. Each peer goes on its own continuation line so the entry stays readable.- Parameters:
kind- PBID or PBRHoldPeer- the peer being replaced, as its own short stringpeer- the peer taking its place, as its own short string- Returns:
- the log entry, never null
messageReceived
public void messageReceived(I2NPMessage inMsg, RouterIdentity remoteIdent, Hash remoteIdentHash, long msToReceive, int bytesReceived) Handle incoming message from transport layer.- Overrides:
messageReceivedin classTransportImpl- Parameters:
inMsg- non-nullremoteIdent- may be nullremoteIdentHash- may be null, calculated from remoteIdent if nullmsToReceive- milliseconds the read took, for the debug logbytesReceived- how many bytes of the message arrived, for the debug log
isInDropList
Is in drop list.- Parameters:
peer- the peer to look for- Returns:
trueif a delayed drop is still pending for the peer
dropPeer
dropPeer
This does not send a session destroy, caller must do that if desired.- Parameters:
peer- the session to drop, recursing if another session shares its ident or hostshouldBanlist- doesn't really, only sets unreachablewhy- cause, for the debug log only, may be null
locked_dropPeer
This does not send a session destroy, caller must do that if desired.- Parameters:
peer- the peer state to remove from all peer maps and dropshouldBanlist- doesn't really, only sets unreachablewhy- unused, the reason for the drop given at the call site
send
This sends it directly out, bypassing OutboundMessageFragments. The only queueing is for the bandwidth limiter. BLOCKING if OB queue is full.- Parameters:
packet- already built, addressed, and encrypted
sendDestroy
Send a session destroy message, bypassing OMF and PacketPusher. BLOCKING if OB queue is full.- Parameters:
peer- the session to tear down, SSU1 peers are ignoredreasonCode- SSU2 only, ignored for SSU1
destroyAll
private void destroyAll()Send a session destroy message to everybody. BLOCKING for at least 1 sec per 1K peers, more if BW is very low or if OB queue is full.bid
Bid on a message to the given router.- Parameters:
toAddress- target router infodataSize- message size in bytes- Returns:
- the bid, or null if we can't (or shouldn't) send via UDP
isTooLarge
static boolean isTooLarge(int dataSize) Not-a-note: the message is too large for SSU to carry at all.- Parameters:
dataSize- message size in bytes- Returns:
- true if the message exceeds the maximum SSU message size
isDifferentNetwork
static boolean isDifferentNetwork(int nid, int ourNetworkId) Whether the target router belongs to a different network than ours.- Parameters:
nid- the target router's network idourNetworkId- this router's network id- Returns:
- true when the network ids differ
rejectCppBug
Reject known c++ SSU disconnect bugs (through 0.9.52), which drop inbound sessions shortly after establishment.- Parameters:
cost- the target's address cost (10 = SSU1, 9 = SSU2)version- the target's router software version- Returns:
- true when the target may exhibit the disconnect bug
sigTypeUnsupported
Whether the target identity uses a signature type we cannot verify.- Parameters:
type- the target identity's signature type- Returns:
- true when the type is missing or unsupported by this build
needsMinimumSigTypeVersion
Whether we need a minimum software version on the target because we are not DSA-signed: non-DSA routers cannot be reached by pre-0.9.17 builds that do not understand their signature types.- Parameters:
ourSigType- this router's signature typetheirVersion- the target's router software version- Returns:
- true when our non-DSA signature requires a 0.9.17+ target
rejectFloodfill
Reject a floodfill router that we have no history with, or that has rejected tunnel creation far more often than it has agreed.Be less aggressive about rejecting floodfills when firewalled, as we need more peers. Temporary - let NTCP2 deal with them (prop. 165).
- Parameters:
to- target identity hashtoAddress- target router info- Returns:
- true to skip bidding on this router
isFirewalled
private boolean isFirewalled()Are we behind a firewall, with no way to accept incoming UDP?- Returns:
- true if any firewall state is active
selectBid
Select the bid tier for a message to an unestablished peer.Try to maintain at least 5 peers (30 for v6) so we can determine our IP address and we have a selection to run peer tests with. If we are firewalled, and we don't have enough peers that volunteered to also introduce us, also bid aggressively so we are preferred over NTCP - otherwise we only talk UDP to those that are firewalled, and we will never get any introducers.
- Parameters:
addr- validated target SSU addresscost- the target's address costweAreFirewalled- status computed byisFirewalled()- Returns:
- the bid to send, higher values being preferred by the peer
getTargetAddress
First available address of the target that we can use.- Parameters:
target- the remote RouterInfo whose addresses are scanned in order- Returns:
- address or null
preferUDP
private boolean preferUDP()Whether the config prefers UDP over NTCP.- Returns:
- true to prefer UDP
alwaysPreferUDP
private boolean alwaysPreferUDP()Whether UDP is preferred in every situation.- Returns:
- true to always prefer UDP
getStyle
getAltStyle
An alternate supported style, or null.- Overrides:
getAltStylein classTransportImpl- Returns:
- the alt style, always "SSU2"
getPublishStyle
isIdleEstablished
static boolean isIdleEstablished(long now, long lastSend, long lastRecv, long maxIdleTime) Is an established peer idle past the threshold in both directions, and so due for teardown and re-establishment rather than continued selection?Pure decision, extracted from
send(OutNetMessage)so the truth table can be pinned in a test without a router.This predicate is deliberately time-only, where the code it replaces also required
getConsecutiveFailedSends() > 2. That counter is incremented from exactly one place,failed(OutboundMessageState, boolean), and only once a message has exhausted its retransmits or expired. A half-open session therefore never accumulates it — the peer still ACKs enough traffic to keep messages alive, or we stop sending and never reachfailed()at all. Either way the session stays in_peersByIdentindefinitely and keeps answeringisEstablished(Hash)true, so peer selection keeps choosing peers we have not heard from in days. Of the hop records on expired builds, 85% had this shape and only 15% had been heard from within 3 seconds.The slack is intentional.
MAX_IDLE_TIMEisEXPIRE_TIMEOUT, 20 minutes, which already governed this drop and which the consecutive-failure path relaxes toward. A peer silent in both directions for twenty minutes is not carrying traffic, and a false positive costs one re-establishment, not a lost session.- Parameters:
now- current time in mslastSend- time of the last fully sent message, or 0 if neverlastRecv- time of the last receive, or 0 if nevermaxIdleTime- idle threshold in ms- Returns:
- true if the session is idle in both directions past the threshold
isIdleEstablished
Is the peer idle in both directions past the threshold, disregarding send failures.- Parameters:
peer- the peer state, may be nullnow- current time in msmaxIdleTime- idle threshold in ms- Returns:
- true if the peer should be dropped and re-established
send
Description copied from class:TransportImplAsynchronously send the message as requested in the message and, if the send is successful, queue up any msg.getOnSendJob job, and register it with the OutboundMessageRegistry (if it has a reply selector). If the send fails, queue up any msg.getOnFailedSendJobOnly used by NTCP. SSU overrides.
Non-blocking: uses priority eviction when the pool is full. Higher-priority messages (client data) evict lower-priority (transit).
- Specified by:
sendin interfaceTransport- Overrides:
sendin classTransportImpl- Parameters:
msg- the message to send, containing destination, payload, and callbacks
sendIfEstablished
Send only if established, otherwise fail immediately. Never queue with the establisher.- Parameters:
msg- the message to send, which must have an established peer
send
"injected" message from the EstablishmentManager. If you have multiple messages, use the list variant, so the messages may be bundled efficiently.- Parameters:
msg- the message to send, which must have an established peerpeer- the message MUST be going to this peer
send
"injected" message from the EstablishmentManager, plus pending messages to send, so the messages may be bundled efficiently. Called at end of outbound establishment.- Parameters:
msg- may be null if nothing to injectmsgs- pending messages to bundle withmsg, non-null, may be emptypeer- all messages MUST be going to this peer
send
"injected" messages from the EstablishmentManager. Called at end of inbound establishment.- Parameters:
msgs- the messages to bundle, non-null, may be emptypeer- all messages MUST be going to this peer
outboundMessageReady
protected void outboundMessageReady()Not used for UDP, which does its own queueing.- Specified by:
outboundMessageReadyin classTransportImpl
startListening
public void startListening()Start the transport listener.stopListening
public void stopListening()Stop listening.explicitAddressSpecified
private boolean explicitAddressSpecified()Whether the config pins our external address.- Returns:
- true if a host or port is configured
updateAddress
Rebuild to get updated cost and introducers. IPv4 only, unless configured as IPv6 only. Do not tell the router (he is the one calling this).- Specified by:
updateAddressin interfaceTransport- Overrides:
updateAddressin classTransportImpl- Returns:
- the current router addresses
rebuildExternalAddress
Rebuilds the external router address for either IPv4 or IPv6. This is called when the router needs to update its published address, typically after a reachability change or IP update.- Parameters:
ipv6- true to rebuild the IPv6 address, false for IPv4- Returns:
- the new router address if changed, otherwise null
rebuildExternalAddress
Update our IPv4 address and optionally tell the router to rebuild and republish the router info.If PROP_EXTERNAL_HOST is set, use those addresses (comma/space separated). If a hostname is configured in that property, use it. As of 0.9.32, a hostname is resolved here into one or more addresses and the IPs are published, to implement proposal 141.
A max of one v4 and one v6 address will be set. Significant changes both here and in NTCP would be required to publish multiple v4 or v6 addresses.
- Parameters:
allowRebuildRouterInfo- whether to tell the routeripv6- true to rebuild the IPv6 address, false for IPv4- Returns:
- the new address if changed, else null
rebuildExternalAddress
Update our IPv4 or IPv6 address and optionally tell the router to rebuild and republish the router info.- Parameters:
ip- new ip valid IPv4 or IPv6 or nullport- new valid port or -1allowRebuildRouterInfo- whether to tell the router- Returns:
- the new address if changed, else null
rebuildExternalAddress
Rebuilds the router address for our external endpoint.- Parameters:
host- the external hostport- the external portallowRebuildRouterInfo- true to publish the change- Returns:
- the new address, null if unchanged
locked_rebuildExternalAddress
private RouterAddress locked_rebuildExternalAddress(String host, int port, boolean allowRebuildRouterInfo) Rebuild the external address from the given validated host; caller must hold the rebuild lock.- Parameters:
host- new validated IPv4 or IPv6 or DNS hostname or null or ":" to force IPv6 introducer rebuildport- the port to publish, 0 or less if unknownallowRebuildRouterInfo- whether to rebuild and republish the router info- Returns:
- the new RouterAddress, or null if it equals the current one
rebuildHiddenExternalAddress
private RouterAddress rebuildHiddenExternalAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6) Rebuild the external address of a hidden router: nothing is published, so only an address with 4/6 caps is made.- Parameters:
host- new validated host or nullport- new validated port or 0/-1allowRebuildRouterInfo- whether to tell the routerisIPv6- true for an IPv6 address- Returns:
- the new address if changed, else null
selectIntroducers
Pick inbound introducers for the address options. The intro manager now sorts introducers, so deepEquals() will not fail even with the same introducers (was only a problem when we had very very few peers to pick from).- Parameters:
isIPv6- true for an IPv6 addresscurrent- current address, used as the introducer pool sourceoptions- address options to fill in- Returns:
- true if introducers were selected
selectCapacity
Select the address capacity string for the given state.- Parameters:
isIPv6- true for an IPv6 addressdirectIncluded- whether a direct address is in the optionsintroducersRequired- whether this address must have introducers- Returns:
- the capacity string
rebuildPublishedAddress
private RouterAddress rebuildPublishedAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6, boolean directIncluded, boolean introducersIncluded, int mtu, OrderedProperties options) Publish the fully populated address (direct and/or introducers).- Parameters:
host- new validated host or nullport- new validated port or 0/-1allowRebuildRouterInfo- whether to tell the routerisIPv6- true for an IPv6 addressdirectIncluded- whether a direct address is in the optionsintroducersIncluded- whether introducers are in the optionsmtu- the MTU for this addressoptions- address options (host, port, caps, mtu, introducers)- Returns:
- the new address if changed, else null
rebuildEmptyAddress
private RouterAddress rebuildEmptyAddress(String host, int port, boolean allowRebuildRouterInfo, boolean isIPv6, boolean introducersRequired, int mtu) No direct address and no introducers available; publish an empty "4" or "6" address so peers know the address exists, and retry later.- Parameters:
host- new validated host or nullport- new validated port or 0/-1allowRebuildRouterInfo- whether to tell the routerisIPv6- true for an IPv6 addressintroducersRequired- whether this address must have introducersmtu- the MTU for this address- Returns:
- the new address if changed, else null
replaceCurrentExternalAddress
Simple storage of IP and port, since we don't put them in the real, published RouterAddress anymore if we are firewalled.Side effect: Sets our MTU
Caller must sync on _rebuildLock.
- Parameters:
ra- the new external address to store, with host and port optionsisIPv6- true to store it as the current IPv6 address, false for IPv4
rebuildRouterInfo
private void rebuildRouterInfo()Avoid deadlocks part 999.getCurrentExternalAddress
Simple fetch of stored IP and port, since we don't put them in the real, published RouterAddress anymore if we are firewalled.- Parameters:
isIPv6- true for IPv6, false for IPv4- Returns:
- the external address or null
replaceAddress
Replace then tell NTCP that we changed.- Overrides:
replaceAddressin classTransportImpl- Parameters:
address- the new address or null to remove all
removeAddress
Remove then tell NTCP that we changed.- Overrides:
removeAddressin classTransportImpl- Parameters:
address- the address to remove
removeAddress
protected void removeAddress(boolean ipv6) Remove then tell NTCP that we changed.- Overrides:
removeAddressin classTransportImpl- Parameters:
ipv6- true to remove the IPv6 address, false for IPv4
introducersRequired
private boolean introducersRequired(boolean ipv6) Do we require introducers?- Parameters:
ipv6- true to test the IPv6 side of our reachability, false for IPv4- Returns:
- true if we cannot accept unsolicited UDP packets on that side, or direct connections are disallowed, so outbound introducers are needed
introducersMaybeRequired
boolean introducersMaybeRequired(boolean ipv6) MIGHT we require introducers? This is like introducersRequired, but if we aren't sure, this returns true. Used only byEstablishmentManager.- Parameters:
ipv6-trueto test the IPv6 side of our reachability- Returns:
trueif introducers may be required
canIntroduce
boolean canIntroduce(boolean ipv6) For EstablishmentManager.- Parameters:
ipv6-trueto test the IPv6 side of our reachability- Returns:
trueif we are eligible to offer relay introductions
allowDirectUDP
private boolean allowDirectUDP()Whether direct UDP connections to other routers are allowed; defaults to true.- Returns:
- false only if i2np.udp.allowDirect is explicitly set to false
getPacketHandlerStatus
String getPacketHandlerStatus()Packet handler status.- Returns:
- the handler's status string, or empty if not yet started
getPacketHandler
failed
Handle a failed outbound message.- Parameters:
msg- the outbound message
failed
Handle a failed outbound message, blaming the peer only after MAX_CONSECUTIVE_FAILED failures with no recent activity.- Parameters:
msg- the outbound messageallowPeerFailure-falseto count the failure without blaming the peer
failed
Handle a failed outbound network message.- Parameters:
msg- the outbound network messagereason- the failure reason
succeeded
Handle a successful outbound message.- Parameters:
msg- the outbound message
countPeers
public int countPeers()Count peers.- Specified by:
countPeersin interfaceTransport- Specified by:
countPeersin classTransportImpl- Returns:
- the number of peers this transport knows of, established or not
getPeerCounts
public int[] getPeerCounts()Peer 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]
countActivePeers
public int countActivePeers()Active peers.- Specified by:
countActivePeersin interfaceTransport- Specified by:
countActivePeersin classTransportImpl- Returns:
- the number of such peers
countActiveSendPeers
public int countActiveSendPeers()Active send peers.- Returns:
- active send peer count
isEstablished
Description copied from class:TransportImplWhether the given peer is established.- Specified by:
isEstablishedin interfaceTransport- Overrides:
isEstablishedin classTransportImpl- Parameters:
dest- hash of the peer to check- Returns:
- false; only a real transport reports established sessions
isBacklogged
Whether the peer for the given destination is backlogged.- Specified by:
isBackloggedin interfaceTransport- Overrides:
isBackloggedin classTransportImpl- Parameters:
dest- hash of the peer to check- Returns:
- true if messages are queued for the peer, awaiting responses
isConnecting
Description copied from class:TransportImplCheck if a connection attempt is in progress for the given peer. Default returns false. NTCP2 and SSU2 transports that have an async handshake phase should override to report in-progress connections.- Specified by:
isConnectingin interfaceTransport- Overrides:
isConnectingin classTransportImpl- Parameters:
dest- hash of the peer to check- Returns:
- true if a connection attempt is in progress but not yet established
mayDisconnect
Tell the transport that we may disconnect from this peer. This is advisory only.- Specified by:
mayDisconnectin interfaceTransport- Overrides:
mayDisconnectin classTransportImpl- Parameters:
peer- the peer to consider
forceDisconnect
Force disconnect a peer.- Parameters:
peer- hash of the peer to forcefully disconnect from
forceDisconnect
allowConnection
public boolean allowConnection()Whether a new connection is allowed.- Returns:
- true if connection is allowed
getClockSkews
Return our peer clock skews on this transport. List composed of Long, each element representing a peer skew in seconds. A positive number means our clock is ahead of theirs.- Specified by:
getClockSkewsin interfaceTransport- Overrides:
getClockSkewsin classTransportImpl- Returns:
- the clock skews
getXDHFactory
X25519KeyFactory getXDHFactory()XDH key factory for SSU2, or null if not configured for SSU2.- Returns:
- null if not configured for SSU2
getBuilder2
PacketBuilder2 getBuilder2()Packet builder for SSU2, or null if not configured for SSU2.- Returns:
- null if not configured for SSU2
getIntroManager
IntroductionManager getIntroManager()The introduction manager.- Returns:
- the manager, or null if not started
getPeerTestManager
PeerTestManager getPeerTestManager()The peer test manager.- Returns:
- the manager, or null if not started
getInboundFragments
InboundMessageFragments getInboundFragments()The inbound fragment reassembler.- Returns:
- the reassembler, or null if not started
isFirewalled
Whether a comm-system reachability status means we are firewalled for at least one address family.- Parameters:
status- the current comm-system status- Returns:
- true for any of the six firewalled statuses
adjustExpireTimeout
static long adjustExpireTimeout(long expireTimeout, boolean haveCap, boolean lastLoopShort) Adjust the idle-timeout towards the target as a function of spare connection capacity, ramping slowly when the loop is running short.- Parameters:
expireTimeout- current idle-expire timeouthaveCap- true when connection capacity remainslastLoopShort- true if the previous loop was a short (fast) pass- Returns:
- the adjusted timeout, clamped to [MIN_EXPIRE_TIMEOUT, EXPIRE_TIMEOUT]
idleHardCutoff
static long idleHardCutoff(long now, boolean overCapacity) Hard-cap idle cutoff: peers idle past this are dropped when the connection maximum is exceeded, otherwise the cutoff is unbounded.- Parameters:
now- current time msoverCapacity- true when peer count exceeds the connection max- Returns:
- the idle cutoff (30s before now), or Long.MIN_VALUE when not over capacity
inactivityCutoff
static long inactivityCutoff(long now, long timeout, boolean weAreFirewalled, long firewalledMin) Idle cutoff for a peer tier. Firewalled routers keep peers much longer by flooring the cutoff atfirewalledMin.- Parameters:
now- current time mstimeout- idle timeout for this tier, in msweAreFirewalled- true for lenient firewalled behaviorfirewalledMin- minimum timeout when firewalled- Returns:
- the inactivity cutoff; peers idle before it are expirable
reliedOnRecently
static boolean reliedOnRecently(long weRelayToThemAs, long introducerTime, long pingCutoff) Whether we have recently relied on this peer as a relay or introducer, in which case it gets the long inactivity tier.- Parameters:
weRelayToThemAs- nonzero when we offer this peer as introducerintroducerTime- ms since this peer was used as introducerpingCutoff- the 2-hour reference cutoff- Returns:
- true if the peer was relied on recently
mayDisconnectLowTraffic
static boolean mayDisconnectLowTraffic(boolean haveCap, boolean inbound, boolean mayDisconnect, int messagesReceived, int messagesSent) Whether an inbound (or capacity-starved) peer with may-disconnect set and near-zero traffic is a stale candidate for the aggressive 15-second cutoff.- Parameters:
haveCap- true when connection capacity remainsinbound- true if the peer connected inboundmayDisconnect- peer's may-disconnect flagmessagesReceived- messages received from the peermessagesSent- messages sent to the peer- Returns:
- true when the peer qualifies for the stale-cutoff tier
pickInactivityCutoff
static long pickInactivityCutoff(boolean reliedOnRecently, boolean mayDisconnectLowTraffic, long longInactivityCutoff, long mayDisconCutoff, long shortInactivityCutoff) Select the inactivity tier for a peer.- Parameters:
reliedOnRecently- peer acted as relay/introducer recentlymayDisconnectLowTraffic- peer is stale and may disconnectlongInactivityCutoff- lenient tier cutoffmayDisconCutoff- aggressive stale-peer cutoffshortInactivityCutoff- default tier cutoff- Returns:
- the cutoff to compare both last-send and last-receive against
idleSince
static boolean idleSince(long lastReceive, long lastSend, long cutoff) Whether a peer has been idle (no receive and no send) since the given cutoff.- Parameters:
lastReceive- last receive time mslastSend- last send time mscutoff- inactivity cutoff ms- Returns:
- true if both activity stamps precede the cutoff
firewallPingSliceMatched
static boolean firewallPingSliceMatched(int runCount, int peerHash) Firewall-keepalive slice gate: roughly one peer in SLICES pings per pass, so pings are spread out over the short loop.- Parameters:
runCount- current expire-loop run counterpeerHash- the peer's hashCode, to place it in a slice- Returns:
- true if this peer is scheduled for a keepalive ping
shouldFirewallPing
static boolean shouldFirewallPing(boolean shouldPingFirewall, boolean sliceMatched, long lastSendOrPing, long lastReceive, long pingFirewallCutoff) Whether a firewall keepalive ping should be sent to this peer: ping mode on, peer in this pass's slice, and no send-or-ping or receive in the PING_FIREWALL_CUTOFF window.- Parameters:
shouldPingFirewall- ping mode is activesliceMatched- peer selected for this passlastSendOrPing- last send-or-ping time mslastReceive- last receive time mspingFirewallCutoff- ping-due cutoff ms- Returns:
- true when the keepalive ping should be sent
shouldStoreRI
static boolean shouldStoreRI(long uptime, long loopTime) Whether the peer session key is old enough to warrant re-publishing our RouterInfo. Publishes on the first loop at/after each RI_STORE_INTERVAL boundary.- Parameters:
uptime- ms since the peer session key was establishedloopTime- ms of the current loop interval- Returns:
- true when a periodic RouterInfo store is due
setReachabilityStatus
IPv4 only.- Parameters:
status- the new IPv4 reachability status
setReachabilityStatus
Update the reachability status of this router, optionally for an IPv6 change.- Parameters:
status- the merged IPv4/IPv6 reachability statusisIPv6- Is the change an IPv6 change?
locked_setReachabilityStatus
1) Merge IPv4 or IPv6 newStatus into the current IPv4+IPv6 status 2a) If current status changed, callrebuildExternalAddress(boolean)2b) Otherwise, If we need to retest, callPeerTestEvent.forceRunSoon(boolean).- Parameters:
newStatus- the new IPv4 or IPv6 status to merge into the combined statusisIPv6- Is the change an IPv6 change?
shouldRerunStatusTest
Whether an UNKNOWN reachability update should reschedule a peer test.UNKNOWN is only a click-flag, never stored; any UNKNOWN result against UNKNOWN always repeats the test. States with an unknown IPv6 component also repeat on an IPv6 test (independent of the IPv4 component), while the remaining statuses are unchanged and just bump the counter.
- Parameters:
old- the current reachability statusisIPv6- true if the update concerns IPv6- Returns:
- true if a peer test should be run immediately
applyIPv6Only
Collapse a merged status when the transport runs in IPv6-only mode.The IPv4 component cannot be tested, so any merged state with an IPv4 UNKNOWN component becomes the matching DISABLED state.
- Parameters:
status- the merged IPv4+IPv6 statusisIPv6Only- true if the transport is configured IPv6-only- Returns:
- the status to store
applyNoIPv6Address
static CommSystemFacade.Status applyNoIPv6Address(CommSystemFacade.Status status, boolean hasIPv6Address) Collapse a merged status when the router has no IPv6 address to publish.The IPv6 component of the status is dropped and only the IPv4 result matters; in particular a firewalled-or-ok v6 component cannot turn the IPv4 result into a paradox (firewalled->OK->firewalled+OK thrash), so the *_IPV6_OK states map down to the plain IPv4 equivalents.
- Parameters:
status- the merged IPv4+IPv6 statushasIPv6Address- true if the router has an IPv6 address to publish- Returns:
- the status to store
requiresConfirmation
static boolean requiresConfirmation(CommSystemFacade.Status old, CommSystemFacade.Status status, boolean isIPv6) Whether the status transition must be confirmed by a second test before it is committed, to prevent thrashing between OK and firewalled.Any jump into, out of, or between the firewalled group is staged as pending confirmation; for IPv4, leaving the IPv4-unknown group is also staged (an IPv6-unrelated UNKNOWN result must not flip IPv4 flapping).
- Parameters:
old- the current reachability statusstatus- the (possibly adjusted) merged new statusisIPv6- true if the update concerns IPv6- Returns:
- true if the new status must be confirmed by a second test
decideIPv6Rebuild
static UDPTransport.IPv6Rebuild decideIPv6Rebuild(CommSystemFacade.Status old, CommSystemFacade.Status status, boolean explicitAddressSpecified) The IPv6 external-address rebuild to perform after a committed status change.- Parameters:
old- the previous reachability statusstatus- the new committed reachability statusexplicitAddressSpecified- true if the operator configured an explicit IPv6 address- Returns:
- the rebuild action to take
getReachabilityStatus
Current reachability status, possibly overridden by configuration.- Specified by:
getReachabilityStatusin interfaceTransport- Specified by:
getReachabilityStatusin classTransportImpl- Returns:
- the reachability status
isSymNatted
boolean isSymNatted()Is IPv4 Symmetric NATted?- Returns:
trueif the IPv4 status is one of the SYMNAT states
canTestAsCharlie
boolean canTestAsCharlie(boolean ipv6) Can we be a Charlie right now?- Parameters:
ipv6-trueto test the IPv6 side of our reachability- Returns:
- true if we can participate
pickTestPeer
PeerState pickTestPeer(PeerTestState.Role peerRole, int version, boolean isIPv6, RemoteHostId dontInclude) Pick a Bob (if we are Alice) or a Charlie (if we are Bob).For Bob (as called from
PeerTestEventbelow), returns an established IPv4/v6 peer. While the protocol allows Alice to select an unestablished Bob, we don't support that.For Charlie (as called from
PeerTestManager), returns an established IPv4 or IPv6 peer. (doesn't matter how Bob and Charlie communicate)Any returned peer must advertise an IPv4 address to prove it is IPv4-capable. Ditto for v6.
- Parameters:
peerRole- The role of the peer we are looking for, BOB or CHARLIE only (NOT our role)version- 1 or 2 for role CHARLIE; ignored for role BOBisIPv6- true to get a v6-capable peer backdontInclude- may be null- Returns:
- peer or null
getPacketHandlerMaxThreads
public static int getPacketHandlerMaxThreads()The max packet handler threads.- Returns:
- the current ceiling on SSU2 packet handler threads
setPacketHandlerMaxThreads
public static void setPacketHandlerMaxThreads(int handlers) Max packet handler threads.- Parameters:
handlers- max packet handler threads
adjustPacketHandlerThreads
public void adjustPacketHandlerThreads()Dynamically adjusts PacketHandler thread count to match the target.getMessageReceiverThreads
public static int getMessageReceiverThreads()The current target MessageReceiver thread count.- Returns:
- message receiver thread count
setMessageReceiverThreads
public static void setMessageReceiverThreads(int threads) Target MessageReceiver thread count.- Parameters:
threads- message receiver thread count
adjustMessageReceiverThreads
public void adjustMessageReceiverThreads()Dynamically adjusts MessageReceiver thread count to match the target.getReceiverQueueSize
public int getReceiverQueueSize()The current queue depth of the MessageReceiver.- Returns:
- receiver queue size
getReceiverQueueCapacity
public int getReceiverQueueCapacity()Returns the maximum capacity of the MessageReceiver queue.- Returns:
- receiver queue capacity
getTotalOutboundQueueDepth
public int getTotalOutboundQueueDepth()Total outbound messages queued across all UDP peers. Unsynchronized — usesConcurrentHashMap.valueswhich is weakly consistent. For Tuner cross-references on outbound pressure.- Returns:
- total outbound queue depth
getPacketHandlerUtilization
public double getPacketHandlerUtilization()Packet handler pool utilization as a ratio (0.0-1.0). Returns NaN if not started.- Returns:
- packet handler utilization
getMessageReceiverUtilization
public double getMessageReceiverUtilization()Message receiver pool utilization as a ratio (0.0-1.0). Returns NaN if not started.- Returns:
- message receiver utilization