All Implemented Interfaces:
Serializable, DataStructure

public class RouterInfoextends DatabaseEntry
Defines the data that a router either publishes to the global routing table or provides to trusted peers.

For efficiency, the methods and structures here are now unsynchronized. Initialize the RI with readBytes(InputStream), or call the setters and then sign() in a single thread. Don't change it after that.

To ensure integrity of the RouterInfo, methods that change an element of the RouterInfo will throw an IllegalStateException after the RouterInfo is signed.

See Also:
  • Field Details

    • ctx

      private final I2PAppContext ctx
      Router context.
    • log

      private final Log log
      Class logger.
    • _identity

      private RouterIdentity _identity
      This router's identity (router key + certificate).
    • _published

      private volatile long _published
      Last published time in ms since epoch.
    • _addresses

      private final List<RouterAddress> _addresses
      Save addresses in the order received so the signature works.
    • _peers

      private Set<Hash> _peers
      May be null to save memory, no longer final.
    • _options

      private final Properties _options
      Config properties for this router info.
    • _validated

      private volatile boolean _validated
      Whether the signature has been verified.
    • _isValid

      private volatile boolean _isValid
      Whether this router info is valid.
    • _byteified

      private volatile byte[] _byteified
      Cached serialized byte form.
    • _hashCode

      private volatile int _hashCode
      Cached hash code.
    • _hashCodeInitialized

      private volatile boolean _hashCodeInitialized
      Whether the hash code has been initialized.
    • _shouldCache

      private volatile boolean _shouldCache
      Whether to cache the byte and string versions of this router info.
    • CACHE_ALL

      private static final boolean CACHE_ALL
      Maybe we should check if we are floodfill? If we do bring this back, don't do on ARM or Android. The disabled initializer below uses the max memory.
      See Also:
    • PROP_NETWORK_ID

      public static final String PROP_NETWORK_ID
      Property key for network id.
      See Also:
    • PROP_CAPABILITIES

      public static final String PROP_CAPABILITIES
      Property key for capabilities.
      See Also:
    • CAPABILITY_HIDDEN

      public static final char CAPABILITY_HIDDEN
      Capability flag for hidden.
      See Also:
    • MAX_ADDRESSES

      private static final int MAX_ADDRESSES
      Most addresses one router info may carry.
      See Also:
    • MAX_INTRODUCERS

      private static final int MAX_INTRODUCERS
      Most introducers a floodfill will return.
      See Also:
    • MAX_UNCOMPRESSED_SIZE

      public static final int MAX_UNCOMPRESSED_SIZE
      All legit RIs are currently under 2KB. May need to be adjusted if we add a huge new enctype or sigtype. Enforced in DatabaseStoreMessage, the transports, and reseed.
      See Also:
    • BW_CAPABILITY_CHARS

      public static final String BW_CAPABILITY_CHARS
      Public string of chars which serve as bandwidth capacity markers NOTE: individual chars defined in Router.java.
      See Also:
    • CONGESTION_CAPABILITY_CHARS

      public static final String CONGESTION_CAPABILITY_CHARS
      Public string of chars which serve as bandwidth congestion markers NOTE: individual chars defined in Router.java.
      See Also:
  • Constructor Details

    • RouterInfo

      public RouterInfo()
      Constructor with default address list and options properties.
    • RouterInfo

      public RouterInfo(RouterInfo old)
      Used only by Router and PublishLocalRouterInfoJob. Copies ONLY the identity and peers. Does not copy published, addresses, options, or signature.
      Parameters:
      old - the RouterInfo to copy the identity and peer set from
  • Method Details

    • getDate

      public long getDate()
      Return the date.
      Specified by:
      getDate in class DatabaseEntry
      Returns:
      the date this entry takes effect, in milliseconds since the epoch: the expiration of the earliest lease for a LeaseSet, the publication time for a RouterInfo
    • getKeysAndCert

      public KeysAndCert getKeysAndCert()
      Return the keysAndCert.
      Specified by:
      getKeysAndCert in class DatabaseEntry
      Returns:
      KAC or null
    • getType

      public int getType()
      Return the type.
      Specified by:
      getType in class DatabaseEntry
      Returns:
      KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET or LS2 types
    • getIdentity

      public RouterIdentity getIdentity()
      Retrieve the identity of the router represented.
      Returns:
      the RouterIdentity holding the public key and certificate
    • setIdentity

      public void setIdentity(RouterIdentity ident)
      Configure the identity of the router represented.
      Parameters:
      ident - the RouterIdentity whose public key and certificate describe this router
      Throws:
      IllegalStateException - if RouterInfo is already signed
    • getPublished

      public long getPublished()
      Retrieve the timestamp on which the info was published, essentially a version number for the RouterInfo. This should be used to expire old RouterInfo structures.
      Returns:
      the publication date in milliseconds since the epoch
    • setPublished

      public void setPublished(long published)
      Date on which it was published, in milliseconds since Midnight GMT on Jan 01, 1970.
      Parameters:
      published - the publication time in milliseconds since the epoch
      Throws:
      IllegalStateException - if RouterInfo is already signed
    • getAddressCount

      public int getAddressCount()
      Return the number of router addresses. More efficient than getAddresses().size().
      Returns:
      the address count
    • getAddresses

      public Collection<RouterAddress> getAddresses()
      Retrieve the set of RouterAddress structures at which this router can be contacted.
      Returns:
      unmodifiable view, non-null
    • setAddresses

      public void setAddresses(Collection<RouterAddress> addresses)
      Specify a set of RouterAddress structures at which this router can be contacted.
      Parameters:
      addresses - may be null
      Throws:
      IllegalStateException - if RouterInfo is already signed or addresses previously set
      IllegalArgumentException - if too many addresses
    • getPeers

      public Set<Hash> getPeers()
      Retrieve a set of SHA-256 hashes of RouterIdentities from routers this router can be reached through. Obsolete — peer set is typically empty.
      Returns:
      an unmodifiable set of the peer hashes, empty if there are none
    • setPeers

      public void setPeers(Set<Hash> peers)
      Specify a set of SHA-256 hashes of RouterIdentities from routers this router can be reached through. Obsolete — peer set is typically empty.
      Parameters:
      peers - SHA-256 hashes of the peers this router can be reached through; null or empty clears the set
      Throws:
      IllegalStateException - if RouterInfo is already signed
    • getOptions

      public Properties getOptions()
      Retrieve a set of options or statistics that the router can expose. Prefer getOptionsMap() for an unmodifiable view.
      Returns:
      sorted, non-null, NOT a copy, do not modify!!!
    • getOptionsMap

      public Map<Object,Object> getOptionsMap()
      Retrieve a set of options or statistics that the router can expose.
      Returns:
      an unmodifiable view, non-null, sorted
    • getOption

      public String getOption(String opt)
      Return the value of a single option.
      Parameters:
      opt - the name of the option to look up
      Returns:
      the option's value, or null if that option is not set
    • getVersion

      public String getVersion()
      For convenience, the same as getOption("router.version"), but returns "0" if unset.
      Returns:
      non-null, "0" if unknown.
    • setOptions

      public void setOptions(Properties options)
      Configure a set of options or statistics that the router can expose. Makes a copy.

      Warning, clears all capabilities.

      Parameters:
      options - if null, clears current options
      Throws:
      IllegalStateException - if RouterInfo is already signed
    • getBytes

      protected byte[] getBytes() throws DataFormatException
      Write out the raw payload of the routerInfo, excluding the signature. This caches the data in memory if possible.
      Specified by:
      getBytes in class DatabaseEntry
      Returns:
      the serialized payload excluding the signature
      Throws:
      DataFormatException - if the data is somehow b0rked (missing props, etc)
    • writeDataBytes

      private void writeDataBytes(OutputStream out) throws DataFormatException, IOException
      Write out the raw payload of the routerInfo, excluding the signature. This caches the data in memory if possible.
      Parameters:
      out - the stream to write to
      Throws:
      DataFormatException - if the data is somehow b0rked (missing props, etc)
      IOException - if writing to the stream fails
    • isValid

      public boolean isValid()
      Determine whether this router info is authorized with a valid signature.
      Returns:
      true if the signature verifies, false otherwise
    • verifySignature

      public boolean verifySignature()
      Return true if the signature is valid, as isValid() does.
      Overrides:
      verifySignature in class DatabaseEntry
      Returns:
      true if the entry carries a signature that verifies over its own data
    • getNetworkId

      public int getNetworkId()
      Which network this router info is a part of, configured through the property PROP_NETWORK_ID.
      Returns:
      -1 if unknown
    • getCapabilities

      public String getCapabilities()
      What special capabilities this router offers.
      Returns:
      non-null, empty string if none
    • isHidden

      public boolean isHidden()
      Is this a hidden node?
      Returns:
      true if either 'H' is in the capabilities, or router identity contains a hidden cert.
    • getBandwidthTier

      public String getBandwidthTier()
      Return a string representation of this node's bandwidth tier, or "Unknown".
      Returns:
      the bandwidth tier
    • getCongestionCap

      public String getCongestionCap()
      Return a string representation of this node's congestion cap, or "Unknown".
      Returns:
      the congestion cap
    • isCurrent

      public boolean isCurrent(long maxAgeMs)
      Determine whether the router was published recently (within the given age milliseconds). The age should be large enough to take into consideration any clock fudge factor, so values such as 1 or 2 hours are probably reasonable.
      Parameters:
      maxAgeMs - milliseconds between the current time and publish date to check
      Returns:
      true if it was published recently, false otherwise
    • getTargetAddress

      public RouterAddress getTargetAddress(String transportStyle)
      Pull the first workable target address for the given transport. Use to check for any address. For all addresses, use getTargetAddresses(String), which you probably want if you care about IPv6.
      Parameters:
      transportStyle - the transport style to match, e.g. NTCP2 or SSU2
      Returns:
      the target address, or null if this router advertises none for that style
    • getTargetAddresses

      public List<RouterAddress> getTargetAddresses(String transportStyle)
      For multiple addresses per-transport (IPv4 or IPv6).
      Parameters:
      transportStyle - the transport style to match, e.g. NTCP2 or SSU2
      Returns:
      a mutable list of the advertised addresses in that style, never null
    • getTargetAddresses

      public List<RouterAddress> getTargetAddresses(String transportStyle1, String transportStyle2)
      For multiple addresses per-transport (IPv4 or IPv6) Return addresses matching either of two styles.
      Parameters:
      transportStyle1 - the first transport style to match, e.g. NTCP2
      transportStyle2 - the second transport style to match, e.g. SSU2
      Returns:
      a mutable list of the advertised addresses in either style, never null
    • doValidate

      private void doValidate()
      Actually validate the signature.
    • readBytes

      public void readBytes(InputStream in) throws DataFormatException, IOException
      This does NOT validate the signature.
      Parameters:
      in - stream to read from
      Throws:
      IllegalStateException - if RouterInfo was already read in
      DataFormatException - if the data is improperly formatted
      IOException - if there was a problem reading the stream
    • readBytes

      public void readBytes(InputStream in, boolean verifySig) throws DataFormatException, IOException
      If verifySig is true, this validates the signature while reading in, and throws a DataFormatException if the sig is invalid. This is faster than reserializing to validate later.
      Parameters:
      in - the stream to read the RouterInfo from
      verifySig - if true, validate the signature as the bytes are read
      Throws:
      DataFormatException - if the data cannot be parsed, or if verifySig is true and the signature does not validate
      IllegalStateException - if RouterInfo was already read in
      IOException - if the stream cannot be read
    • writeBytes

      public void writeBytes(OutputStream out) throws DataFormatException, IOException
      This does NOT validate the signature.
      Parameters:
      out - stream to write to
      Throws:
      DataFormatException - if the data was incomplete or not yet ready to be written
      IOException - if there was a problem writing to the stream
    • equals

      public boolean equals(Object object)
      Compare the published time, signature, identity, addresses, options, and peers for equality.
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Hash code based on the identity and published time.
      Overrides:
      hashCode in class Object
      Returns:
      whether h code is present
    • toString

      public String toString()
      String form for debugging, showing all router info fields.
      Overrides:
      toString in class Object