Class UDPTransport

java.lang.Object
net.i2p.router.transport.TransportImpl
net.i2p.router.transport.udp.UDPTransport
All Implemented Interfaces:
Transport, TimedWeightedPriorityMessageQueue.FailedListener

public class UDPTransport extends TransportImpl implements TimedWeightedPriorityMessageQueue.FailedListener
The SSU transport
  • Field Details

    • STYLE2

      public static final String STYLE2
      See Also:
    • SSU2_INT_VERSION

      static final int SSU2_INT_VERSION
      See Also:
    • SSU2_VERSION

      static final String SSU2_VERSION
      "2"
    • SSU2_VERSION_ALT

      static final String SSU2_VERSION_ALT
      "2,"
    • PROP_SSU2_SP

      public static final String PROP_SSU2_SP
      b64 static private key
      See Also:
    • PROP_SSU2_IKEY

      public static final String PROP_SSU2_IKEY
      b64 static IV
      See Also:
    • STYLE

      public static final String STYLE
      See Also:
    • PROP_INTERNAL_PORT

      public static final String PROP_INTERNAL_PORT
      See Also:
    • DEFAULT_INTERNAL_PORT

      @Deprecated public static final int DEFAULT_INTERNAL_PORT
      Deprecated.
      unused
      now unused, we pick a random port
      See Also:
    • PROP_EXTERNAL_HOST

      public static final String PROP_EXTERNAL_HOST
      define this to explicitly set an external IP address
      See Also:
    • PROP_EXTERNAL_PORT

      public static final String PROP_EXTERNAL_PORT
      define this to explicitly set an external port
      See Also:
    • PROP_PREFER_UDP

      public static final String PROP_PREFER_UDP
      If i2np.udp.preferred is set to "always", the UDP bids will always be under the bid from the TCP transport - even if a TCP connection already exists. If it is set to "true", it will prefer UDP unless no UDP session exists and a TCP connection already exists. If it is set to "false" (the default), it will prefer TCP unless no TCP session exists and a UDP connection already exists.
      See Also:
    • PROP_SOURCES

      public static final String PROP_SOURCES
      allowed sources of address updates
      See Also:
    • DEFAULT_SOURCES

      public static final String DEFAULT_SOURCES
    • PROP_IP

      public static final String PROP_IP
      remember IP changes
      See Also:
    • PROP_IP_CHANGE

      public static final String PROP_IP_CHANGE
      See Also:
    • PROP_LAPTOP_MODE

      public static final String PROP_LAPTOP_MODE
      See Also:
    • PROP_IPV6

      public static final String PROP_IPV6
      Since:
      0.9.43
      See Also:
    • PROP_FORCE_INTRODUCERS

      public static final String PROP_FORCE_INTRODUCERS
      do we require introducers, regardless of our status?
      See Also:
    • PROP_ALLOW_DIRECT

      public static final String PROP_ALLOW_DIRECT
      do we allow direct SSU connections, sans introducers?
      See Also:
    • PROP_BIND_INTERFACE

      public static final String PROP_BIND_INTERFACE
      this is rarely if ever used, default is to bind to wildcard address
      See Also:
    • PROP_INTRO_KEY

      public static final String PROP_INTRO_KEY
      Since:
      0.9.48
      See Also:
    • PUBLIC_RELAY_COUNT

      public static final int PUBLIC_RELAY_COUNT
      how many relays offered to us will we use at a time?
      See Also:
    • DEFAULT_COST

      public static final int DEFAULT_COST
      See Also:
    • RATES

      static final long[] RATES
    • INTRODUCER_EXPIRATION_MARGIN

      static final long INTRODUCER_EXPIRATION_MARGIN
      See Also:
    • EXPIRE_TIMEOUT

      public static final int EXPIRE_TIMEOUT
      We used to have MAX_IDLE_TIME = 5m, but this causes us to drop peers and lose the old introducer tags, causing introduction fails, so we keep the max time long to give the introducer keepalive code in the IntroductionManager a chance to work.
      See Also:
    • MIN_EXPIRE_TIMEOUT

      public static final int MIN_EXPIRE_TIMEOUT
      See Also:
  • Constructor Details

  • Method Details

    • getOMF

      Returns:
      the instance of OutboundMessageFragments
      Since:
      0.9.48
    • shutdown

      public void shutdown()
    • fail

      public void fail(UDPEndpoint endpoint)
      The endpoint has failed. Remove it.
      Since:
      0.9.16
    • getIntroKey

      SessionKey getIntroKey()
      Introduction key that people should use to contact us
    • getSSU2StaticIntroKey

      byte[] getSSU2StaticIntroKey()
      The static Intro key
      Returns:
      null if not configured for SSU2
      Since:
      0.9.54
    • getSSU2StaticPubKey

      byte[] getSSU2StaticPubKey()
      The static pub key
      Returns:
      null if not configured for SSU2
      Since:
      0.9.54
    • getSSU2StaticPrivKey

      byte[] getSSU2StaticPrivKey()
      The static priv key
      Returns:
      null if not configured for SSU2
      Since:
      0.9.54
    • getSSUVersion

      int getSSUVersion(RouterAddress addr)
      Get the valid SSU version of Bob's SSU address for our outbound connections as Alice.
      Returns:
      the valid version 1 or 2, or 0 if unusable
      Since:
      0.9.54
    • getExternalPort

      int getExternalPort(boolean ipv6)
      Published or requested port
    • getExternalIP

      byte[] getExternalIP()
      Published IP, IPv4 only
      Returns:
      IP or null
      Since:
      0.9.2
    • hasIPv6Address

      boolean hasIPv6Address()
      For PeerTestManager
      Since:
      0.9.30
    • isTooClose

      boolean isTooClose(byte[] ip)
      Is this IP too close to ours to trust it for things like relaying?
      Parameters:
      ip - IPv4 or IPv6
      Since:
      IPv6
    • 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:
      getRequestedPort in interface Transport
      Overrides:
      getRequestedPort in class TransportImpl
      Returns:
      port or -1 for none or 0 for any
    • getMTU

      public int getMTU(boolean ipv6)
      The MTU for the socket interface. To be used as the "large" MTU.
      Returns:
      limited to range PeerState.MIN_MTU to PeerState.LARGE_MTU.
      Since:
      0.9.2, public since 0.9.31
    • getSSU2MTU

      public int getSSU2MTU(boolean ipv6)
      The SSU2 MTU for the socket interface. To be used as the "large" MTU.
      Returns:
      limited to range PeerState2.MIN_MTU to PeerState2.LARGE_MTU, or 0 if unavailable
      Since:
      0.9.55
    • inboundConnectionReceived

      void inboundConnectionReceived(boolean isIPv6)
    • externalAddressReceived

      public void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)
      From config, UPnP, local i/f, ... Not for info received from peers - see externalAddressReceived(Hash, ip, port)
      Specified by:
      externalAddressReceived in interface Transport
      Specified by:
      externalAddressReceived in class TransportImpl
      Parameters:
      source - as defined in Transport.SOURCE_xxx
      ip - publicly routable IPv4 or IPv6, null ok
      port - 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:
      forwardPortStatus in interface Transport
      Overrides:
      forwardPortStatus in class TransportImpl
      Parameters:
      ip - may be null
      port - the internal port
      externalPort - the external port, which for now should always be the same as the internal port if the forwarding was successful.
    • externalAddressReceived

      void externalAddressReceived(Hash from, byte[] ourIP, int ourPort)
      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 destination
      ourIP - publicly routable IPv4 or IPv6 only, non-null
      ourPort - >= 1024
    • 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
    • getPeerState

      PeerState getPeerState(RemoteHostId hostInfo)
      get the state for the peer at the given remote host/port, or null if no state exists
    • getPeerStatesByIP

      List<PeerState> getPeerStatesByIP(RemoteHostId hostInfo)
      Get the states for all peers at the given remote host, ignoring port. Used for a last-chance search for a peer that changed port, by PacketHandler. Always returns empty list for IPv6 hostInfo.
      Since:
      0.9.3
    • getPeerState

      PeerState getPeerState(Hash remotePeer)
      get the state for the peer with the given ident, or null if no state exists
    • getPeerState

      PeerState2 getPeerState(long rcvConnID)
      Get the state by SSU2 connection ID
      Since:
      0.9.55
    • wasRecentlyClosed

      boolean wasRecentlyClosed(long rcvConnID)
      Was the state for this SSU2 receive connection ID recently closed?
      Since:
      0.9.56
    • getPeers

      public Collection<PeerState> getPeers()
      For /peers UI only. Not a public API, not for external use.
      Returns:
      not a copy, do not modify
      Since:
      0.9.31
    • getEstablished

      public Set<Hash> getEstablished()
      Connected peers.
      Specified by:
      getEstablished in interface Transport
      Returns:
      not a copy, do not modify
      Since:
      0.9.34
    • changePeerPort

      void changePeerPort(PeerState peer, int newPort)
      Remove and add to peersByRemoteHost map
      Since:
      0.9.3
    • changePeerAddress

      void changePeerAddress(PeerState2 peer, RemoteHostId newAddress)
      Remove and add to peersByRemoteHost map
      Since:
      0.9.56
    • getEstablisher

      EstablishmentManager getEstablisher()
      For IntroductionManager
      Returns:
      may be null if not started
      Since:
      0.9.2
    • addRemotePeerState

      boolean addRemotePeerState(PeerState peer)
      add the peer info, returning true if it went in properly, false if it was rejected (causes include peer ident already connected, or no remote host info known
    • messageReceived

      public void messageReceived(I2NPMessage inMsg, RouterIdentity remoteIdent, Hash remoteIdentHash, long msToReceive, int bytesReceived)
      infinite loop public RouterAddress getCurrentAddress() { if (needsRebuild()) rebuildExternalAddress(false); return super.getCurrentAddress(); }
      Overrides:
      messageReceived in class TransportImpl
      Parameters:
      inMsg - non-null
      remoteIdent - may be null
      remoteIdentHash - may be null, calculated from remoteIdent if null
    • isInDropList

      boolean isInDropList(RemoteHostId peer)
    • dropPeer

      void dropPeer(Hash peer, boolean shouldBanlist, String why)
      This does not send a session destroy, caller must do that if desired.
      Parameters:
      shouldBanlist - doesn't really, only sets unreachable
    • dropPeer

      void dropPeer(PeerState peer, boolean shouldBanlist, String why)
      This does not send a session destroy, caller must do that if desired.
      Parameters:
      shouldBanlist - doesn't really, only sets unreachable
    • send

      void send(UDPPacket packet)
      This sends it directly out, bypassing OutboundMessageFragments. The only queueing is for the bandwidth limiter. BLOCKING if OB queue is full.
    • sendDestroy

      void sendDestroy(PeerState peer, int reasonCode)
      Send a session destroy message, bypassing OMF and PacketPusher. BLOCKING if OB queue is full.
      Parameters:
      reasonCode - SSU2 only, ignored for SSU1
      Since:
      0.8.9
    • bid

      public TransportBid bid(RouterInfo toAddress, int dataSize)
      Specified by:
      bid in interface Transport
      Parameters:
      dataSize - assumes full 16-byte header, transports should adjust as necessary
      Returns:
      a bid or null if unwilling to send
    • getTargetAddress

      RouterAddress getTargetAddress(RouterInfo target)
      Get first available address we can use.
      Returns:
      address or null
      Since:
      0.9.6
    • getStyle

      public String getStyle()
      Description copied from interface: Transport
      The unique identity of this Transport
      Specified by:
      getStyle in interface Transport
    • getAltStyle

      public String getAltStyle()
      An alternate supported style, or null.
      Overrides:
      getAltStyle in class TransportImpl
      Returns:
      null, override to add support
      Since:
      0.9.54
    • send

      public void send(OutNetMessage msg)
      Description copied from class: TransportImpl
      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). If the send fails, queue up any msg.getOnFailedSendJob Only used by NTCP. SSU overrides. Note that this adds to the queue and then takes it back off in the same thread, so it actually blocks, and we don't need a big queue. TODO: Override in NTCP also and get rid of queue?
      Specified by:
      send in interface Transport
      Overrides:
      send in class TransportImpl
    • sendIfEstablished

      void sendIfEstablished(OutNetMessage msg)
      Send only if established, otherwise fail immediately. Never queue with the establisher.
      Since:
      0.9.2
    • send

      void send(I2NPMessage msg, PeerState peer)
      "injected" message from the EstablishmentManager. If you have multiple messages, use the list variant, so the messages may be bundled efficiently.
      Parameters:
      peer - all messages MUST be going to this peer
    • send

      void send(I2NPMessage msg, List<OutNetMessage> msgs, PeerState peer)
      "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 inject
      msgs - non-null, may be empty
      peer - all messages MUST be going to this peer
      Since:
      0.9.24
    • send

      void send(List<I2NPMessage> msgs, PeerState peer)
      "injected" messages from the EstablishmentManager. Called at end of inbound establishment.
      Parameters:
      peer - all messages MUST be going to this peer
      Since:
      0.9.24
    • outboundMessageReady

      protected void outboundMessageReady()
      Description copied from class: TransportImpl
      This message is called whenever a new message is added to the send pool, and it should not block Only used by NTCP. SSU throws UOE.
      Specified by:
      outboundMessageReady in class TransportImpl
    • startListening

      public void startListening()
      Specified by:
      startListening in interface Transport
    • stopListening

      public void stopListening()
      Specified by:
      stopListening in interface Transport
    • updateAddress

      public List<RouterAddress> 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:
      updateAddress in interface Transport
      Overrides:
      updateAddress in class TransportImpl
      Returns:
      all addresses, non-null
      Since:
      0.7.12
    • getCurrentExternalAddress

      public RouterAddress 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.
      Since:
      0.9.18, public for PacketBuilder and TransportManager since 0.9.50
    • replaceAddress

      protected void replaceAddress(RouterAddress address)
      Replace then tell NTCP that we changed.
      Overrides:
      replaceAddress in class TransportImpl
      Parameters:
      address - the new address or null to remove all
    • removeAddress

      protected void removeAddress(RouterAddress address)
      Remove then tell NTCP that we changed.
      Overrides:
      removeAddress in class TransportImpl
      Since:
      0.9.20
    • removeAddress

      protected void removeAddress(boolean ipv6)
      Remove then tell NTCP that we changed.
      Overrides:
      removeAddress in class TransportImpl
      Parameters:
      ipv6 - true to remove all IPv6 addresses, false to remove all IPv4 addresses
      Since:
      0.9.20
    • introducersMaybeRequired

      boolean introducersMaybeRequired(boolean ipv6)
      MIGHT we require introducers? This is like introducersRequired, but if we aren't sure, this returns true. Used only by EstablishmentManager.
      Since:
      0.9.24
    • canIntroduce

      boolean canIntroduce(boolean ipv6)
      For EstablishmentManager.
      Since:
      0.9.3
    • getPacketHandlerStatus

      String getPacketHandlerStatus()
    • getPacketHandler

      PacketHandler getPacketHandler()
      Since:
      IPv6
    • failed

      public void failed(OutboundMessageState msg)
    • failed

      void failed(OutboundMessageState msg, boolean allowPeerFailure)
    • failed

      public void failed(OutNetMessage msg, String reason)
      Specified by:
      failed in interface TimedWeightedPriorityMessageQueue.FailedListener
    • succeeded

      public void succeeded(OutboundMessageState msg)
    • countPeers

      public int countPeers()
      Description copied from class: TransportImpl
      How many peers are we connected to?
      Specified by:
      countPeers in interface Transport
      Specified by:
      countPeers in class TransportImpl
    • getPeerCounts

      public int[] getPeerCounts()
      Specified by:
      getPeerCounts in interface Transport
      Returns:
      8 bytes: version 1 ipv4 in/out, ipv6 in/out version 2 ipv4 in/out, ipv6 in/out
      Since:
      0.9.57
    • countActivePeers

      public int countActivePeers()
      Description copied from class: TransportImpl
      How many peers are we currently connected to, that we have sent a message to or received a message from in the last five minutes.
      Specified by:
      countActivePeers in interface Transport
      Specified by:
      countActivePeers in class TransportImpl
    • countActiveSendPeers

      public int countActiveSendPeers()
      Description copied from class: TransportImpl
      How many peers are we currently connected to, that we have sent a message to in the last minute. Unused for anything, to be removed.
      Specified by:
      countActiveSendPeers in interface Transport
      Specified by:
      countActiveSendPeers in class TransportImpl
    • isEstablished

      public boolean isEstablished(Hash dest)
      Specified by:
      isEstablished in interface Transport
      Overrides:
      isEstablished in class TransportImpl
    • isBacklogged

      public boolean isBacklogged(Hash dest)
      Specified by:
      isBacklogged in interface Transport
      Overrides:
      isBacklogged in class TransportImpl
      Since:
      0.9.3
    • mayDisconnect

      public void mayDisconnect(Hash peer)
      Tell the transport that we may disconnect from this peer. This is advisory only.
      Specified by:
      mayDisconnect in interface Transport
      Overrides:
      mayDisconnect in class TransportImpl
      Since:
      0.9.24
    • forceDisconnect

      public void forceDisconnect(Hash peer)
      Tell the transport to disconnect from this peer.
      Specified by:
      forceDisconnect in interface Transport
      Since:
      0.9.38
    • allowConnection

      public boolean allowConnection()
    • getClockSkews

      public List<Long> 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:
      getClockSkews in interface Transport
      Overrides:
      getClockSkews in class TransportImpl
    • getDHBuilder

      DHSessionKeyBuilder getDHBuilder()
      Returns:
      a new DHSessionKeyBuilder
      Since:
      0.9
    • getDHFactory

      Returns:
      the factory
      Since:
      0.9.2
    • getXDHFactory

      X25519KeyFactory getXDHFactory()
      Returns:
      null if not configured for SSU2
      Since:
      0.9.54
    • getHMAC

      HMACGenerator getHMAC()
      Returns:
      the SSU HMAC
      Since:
      0.9.42
    • getBuilder

      PacketBuilder getBuilder()
      Returns:
      the PacketBuilder
      Since:
      0.9.52
    • getBuilder2

      PacketBuilder2 getBuilder2()
      Returns:
      null if not configured for SSU2
      Since:
      0.9.54
    • getIntroManager

      IntroductionManager getIntroManager()
      Since:
      0.9.54
    • getPeerTestManager

      PeerTestManager getPeerTestManager()
      Since:
      0.9.54
    • getInboundFragments

      InboundMessageFragments getInboundFragments()
      Since:
      0.9.54
    • renderStatusHTML

      @Deprecated public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException
      Deprecated.
      as of 0.9.31
      Does nothing
      Specified by:
      renderStatusHTML in interface Transport
      Overrides:
      renderStatusHTML in class TransportImpl
      Throws:
      IOException
    • setReachabilityStatus

      void setReachabilityStatus(CommSystemFacade.Status status, boolean isIPv6)
      Parameters:
      isIPv6 - Is the change an IPv6 change?
      Since:
      0.9.27
    • getReachabilityStatus

      public CommSystemFacade.Status getReachabilityStatus()
      Previously returned short, now enum as of 0.9.20
      Specified by:
      getReachabilityStatus in interface Transport
      Specified by:
      getReachabilityStatus in class TransportImpl
    • recheckReachability

      @Deprecated public void recheckReachability()
      Deprecated.
      unused
      Specified by:
      recheckReachability in interface Transport
      Overrides:
      recheckReachability in class TransportImpl
    • 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 PeerTestEvent below), 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 BOB
      isIPv6 - true to get a v6-capable peer back
      dontInclude - may be null
      Returns:
      peer or null