All Implemented Interfaces:
I2NPMessage

public class TunnelDataMessageextends FastI2NPMessageImpl
Defines the message sent between routers as part of the tunnel delivery

The tunnel ID is changed in-place by TunnelParticipant.send(), so we can't reuse the checksum on output, but we still subclass FastI2NPMessageImpl so we don't verify the checksum on input... because this is a high-usage class.

  • Field Details

    • _tunnelId

      private long _tunnelId
      The tunnel this message is routed on.
    • _tunnelIdObj

      private TunnelId _tunnelIdObj
      The tunnel id in object form.
    • _data

      private byte[] _data
      The message's payload bytes.
    • _dataBuf

      private ByteArray _dataBuf
      The payload as a buffer, for reuse.
    • MESSAGE_TYPE

      public static final int MESSAGE_TYPE
      Message type ID for this I2NP message.
      See Also:
    • DATA_SIZE

      public static final int DATA_SIZE
      Size of the data payload in bytes.
      See Also:
    • EXPIRATION_PERIOD

      private static final int EXPIRATION_PERIOD
      If we can't deliver a tunnel message in 10s, forget it.
      See Also:
    • _cache

      private static final ByteCache _cache
      Pooled buffers for message payloads.
    • PIPELINED_CACHE

      private static final boolean PIPELINED_CACHE
      When true, this tunnelDataMessage is used as part of a tunnel processing pipeline. The byte array is acquired during the TunnelDataMessage's creation (per readMessage), held onto through several transitions (updating and moving that array between different TunnelDataMessage instances or the fragment handler's cache, etc.), until it is finally released back into the cache when written to the next peer (or explicitly by the fragment handler's completion). Setting this to false just increases memory churn.

      This is tricky to get right and avoid data corruption.

      See Also:
    • _hadCache

      private boolean _hadCache
      For use-after-free checks. Always false if PIPELINED_CACHE is false.
  • Constructor Details

    • TunnelDataMessage

      public TunnelDataMessage(I2PAppContext context)
      Constructor with 10-second message expiration from context clock.
      Parameters:
      context - the context whose clock supplies the expiration stamp
  • Method Details

    • getTunnelId

      public long getTunnelId()
      Numeric form of the tunnel ID, for callers that cannot use a TunnelId.
      Returns:
      the tunnel this data message is addressed to
    • setTunnelId

      public void setTunnelId(long id)
      (correctly) Invalidates stored checksum.
      Parameters:
      id - the tunnel to address; assigning it invalidates the cached checksum
    • getTunnelIdObj

      public TunnelId getTunnelIdObj()
      The TunnelId form of the tunnel ID, built once and then cached.
      Returns:
      the cached TunnelId object for this message's tunnel
    • setTunnelId

      public void setTunnelId(TunnelId id)
      (correctly) Invalidates stored checksum.
      Parameters:
      id - the tunnel to address; assigning it invalidates the cached checksum
    • getData

      public byte[] getData()
      The payload this message carries, for a message already read or written.
      Returns:
      the tunnel payload bytes
    • setData

      public void setData(byte[] data)
      Tunnel payload; may only be set once.
      Parameters:
      data - the payload to carry; must be non-empty and may only be assigned once
      Throws:
      IllegalStateException - if data previously set, to protect saved checksum
    • readMessage

      public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException
      Read and parse the message from raw data into fields.
      Parameters:
      data - data to read from
      offset - where to start in the data array
      dataSize - how long into the data to read
      type - I2NP message type
      Throws:
      I2NPMessageException - if the stream doesn't contain a valid message that this class can read.
    • calculateWrittenLength

      protected int calculateWrittenLength()
      Calculate the message body's length (not including the header and footer).
      Specified by:
      calculateWrittenLength in class I2NPMessageImpl
      Returns:
      the number of bytes the body will occupy once serialized
    • writeMessageBody

      protected int writeMessageBody(byte[] out, int curIndex) throws I2NPMessageException
      Write the message body to the output array, starting at the given index.
      Specified by:
      writeMessageBody in class I2NPMessageImpl
      Parameters:
      out - the buffer to serialize the body into
      curIndex - the offset into out at which to begin writing; leave room for the signature where the header format calls for one
      Returns:
      the index into the array after the last byte written (NOT the length)
      Throws:
      I2NPMessageException - if the body cannot be serialized into out, because it is too small or a field is unserializable
    • getType

      public int getType()
      Return the type.
      Returns:
      the message type number, as defined in the I2NP spec
    • hashCode

      public int hashCode()
      Hash based on tunnel ID and data payload.
      Overrides:
      hashCode in class Object
      Returns:
      whether h code is present
    • equals

      public boolean equals(Object object)
      Two TunnelDataMessages are equal if they have the same tunnel ID and data.
      Overrides:
      equals in class Object
    • toByteArray

      public byte[] toByteArray()
      Serialized message bytes with header and footer.
      Specified by:
      toByteArray in interface I2NPMessage
      Overrides:
      toByteArray in class I2NPMessageImpl
      Returns:
      a new array holding the whole message, full 16 byte header included
    • toString

      public String toString()
      Label with unique ID for logging.
      Overrides:
      toString in class Object