net.i2p.data.i2np

## Class I2NPMessageImpl

- java.lang.Object
- - net.i2p.data.i2np.I2NPMessageImpl

- All Implemented Interfaces:
    I2NPMessage
  Direct Known Subclasses:
    FastI2NPMessageImpl, TunnelBuildMessageBase

      public abstract class I2NPMessageImpl
      extends Object
      implements I2NPMessage

  Defines the base message implementation. Note: No longer extends DataStructureImpl as of 0.9.48

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `I2NPMessageImpl.Builder` interface for extending the types of messages handled - unused

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected I2PAppContext` | `_context`
    `protected long` | `_expiration`
    `protected Log` | `_log`
    `static int` | `CHECKSUM_LENGTH`
    `static long` | `DEFAULT_EXPIRATION_MS`
    `static int` | `HEADER_LENGTH` 16

    - ### Fields inherited from interface net.i2p.data.i2np.I2NPMessage

      `MAX_ID_VALUE, MAX_SIZE`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2NPMessageImpl(I2PAppContext context)`

  - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected abstract int` | `calculateWrittenLength()` calculate the message body's length (not including the header and footer
    `static I2NPMessage` | `createMessage(I2PAppContext context, int type)` Yes, this is fairly ugly, but its the only place it ever happens.
    `static I2NPMessage` | `fromRawByteArray(I2PAppContext ctx, byte[] buffer, int offset, int len, I2NPMessageHandler handler)` Read the message with a short 5-byte header.
    `static I2NPMessage` | `fromRawByteArrayNTCP2(I2PAppContext ctx, byte[] buffer, int offset, int len, I2NPMessageHandler handler)` Read the message with a short 9-byte header.
    `long` | `getMessageExpiration()` Date after which the message should be dropped (and the associated uniqueId forgotten)
    `int` | `getMessageSize()` How large the message is, including any checksums, i.e.
    `int` | `getRawMessageSize()` The raw header consists of a one-byte type and a 4-byte expiration in seconds only.
    `long` | `getUniqueId()`
    `long` | `getUniqueId(long msgIDBloomXor)` Replay resistant message Id
    `int` | `readBytes(byte[] data, int type, int offset)` Read the header, then read the rest into buffer, then call readMessage in the implemented message type
    `int` | `readBytes(byte[] data, int type, int offset, int maxLen)` Set a limit on the max to read from the data buffer, so that we can use a large buffer but prevent the reader from reading off the end.
    `void` | `readMessage(byte[] data, int offset, int dataSize, int type, I2NPMessageHandler handler)`
    `void` | `setMessageExpiration(long exp)` The expiration is set to one minute from now in the constructor but it can be overridden here.
    `void` | `setUniqueId(long id)` The ID is set to a random value when written but it can be overridden here.
    `byte[]` | `toByteArray()`
    `int` | `toByteArray(byte[] buffer)` write the message to the buffer, returning the number of bytes written.
    `int` | `toByteArray(byte[] buffer, int off)` Write the message to the buffer, returning the new offset (NOT the length).
    `int` | `toRawByteArray(byte[] buffer)` Write the message with a short 5-byte header.
    `int` | `toRawByteArrayNTCP2(byte[] buffer, int off)` Write the message to the buffer, returning the new offset (NOT the length).
    `protected abstract int` | `writeMessageBody(byte[] out, int curIndex)` write the message body to the output array, starting at the given index.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

    - ### Methods inherited from interface net.i2p.data.i2np.I2NPMessage

      `getType, readMessage`

- - ### Field Detail

    - #### _context

          protected final I2PAppContext _context

    - #### _expiration

          protected long _expiration

    - #### _log

          protected final Log _log

    - #### CHECKSUM_LENGTH

          public static final int CHECKSUM_LENGTH

      See Also:
        Constant Field Values

    - #### DEFAULT_EXPIRATION_MS

          public static final long DEFAULT_EXPIRATION_MS

      See Also:
        Constant Field Values

    - #### HEADER_LENGTH

          public static final int HEADER_LENGTH

      16
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### I2NPMessageImpl

          public I2NPMessageImpl(I2PAppContext context)

  - ### Method Detail

    - #### calculateWrittenLength

          protected abstract int calculateWrittenLength()

      calculate the message body's length (not including the header and footer

    - #### createMessage

          public static I2NPMessage createMessage(I2PAppContext context,
                                                  int type)
                                           throws I2NPMessageException

      Yes, this is fairly ugly, but its the only place it ever happens.
      Returns:
        non-null, returns an UnknownI2NPMessage if unknown type
      Throws:
        `I2NPMessageException`

    - #### fromRawByteArray

          public static I2NPMessage fromRawByteArray(I2PAppContext ctx,
                                                     byte[] buffer,
                                                     int offset,
                                                     int len,
                                                     I2NPMessageHandler handler)
                                              throws I2NPMessageException

      Read the message with a short 5-byte header. THe header consists of a one-byte type and a 4-byte expiration in seconds only. Used by SSU only!
      Throws:
        `I2NPMessageException`

    - #### fromRawByteArrayNTCP2

          public static I2NPMessage fromRawByteArrayNTCP2(I2PAppContext ctx,
                                                          byte[] buffer,
                                                          int offset,
                                                          int len,
                                                          I2NPMessageHandler handler)
                                                   throws I2NPMessageException

      Read the message with a short 9-byte header. THe header consists of a one-byte type, 4-byte ID, and a 4-byte expiration in seconds only. Used by NTCP2 and SSU2 only!
      Parameters:
        `handler` - ignored, may be null
      Throws:
        `I2NPMessageException`

    - #### getMessageExpiration

          public long getMessageExpiration()

      Date after which the message should be dropped (and the associated uniqueId forgotten)
      Specified by:
        `getMessageExpiration` in interface `I2NPMessage`

    - #### getMessageSize

          public int getMessageSize()

      Description copied from interface: `I2NPMessage`
      How large the message is, including any checksums, i.e. full 16 byte header
      Specified by:
        `getMessageSize` in interface `I2NPMessage`

    - #### getRawMessageSize

          public int getRawMessageSize()

      The raw header consists of a one-byte type and a 4-byte expiration in seconds only. Used by SSU only!
      Specified by:
        `getRawMessageSize` in interface `I2NPMessage`

    - #### getUniqueId

          public long getUniqueId()

      Specified by:
        `getUniqueId` in interface `I2NPMessage`

    - #### getUniqueId

          public long getUniqueId(long msgIDBloomXor)

      Replay resistant message Id
      Specified by:
        `getUniqueId` in interface `I2NPMessage`

    - #### readBytes

          public int readBytes(byte[] data,
                               int type,
                               int offset)
                        throws I2NPMessageException

      Read the header, then read the rest into buffer, then call readMessage in the implemented message type

            Specifically:
              1 byte type (if caller didn't read already, as specified by the type param
              4 byte ID
              8 byte expiration
              2 byte size
              1 byte checksum
              size bytes of payload (read by readMessage() in implementation)

      Specified by:
        `readBytes` in interface `I2NPMessage`
      Parameters:
        `type` - the message type or -1 if we should read it here
        `data` - the data
        `offset` - where to start starting at type if type is < 0 (16 byte header) starting at ID if type is >= 0 (15 byte header)
      Returns:
        total length of the message
      Throws:
        `I2NPMessageException` - if there is no valid message

    - #### readBytes

          public int readBytes(byte[] data,
                               int type,
                               int offset,
                               int maxLen)
                        throws I2NPMessageException

      Set a limit on the max to read from the data buffer, so that we can use a large buffer but prevent the reader from reading off the end.
      Specified by:
        `readBytes` in interface `I2NPMessage`
      Parameters:
        `type` - the message type or -1 if we should read it here
        `maxLen` - read no more than this many bytes from data starting at offset, even if it is longer This includes the type byte only if type < 0
        `data` - the data, may or may not include the type
        `offset` - where to start starting at type if type is < 0 (16 byte header) starting at ID if type is >= 0 (15 byte header)
      Returns:
        total length of the message
      Throws:
        `I2NPMessageException` - if there is no valid message

    - #### readMessage

          public void readMessage(byte[] data,
                                  int offset,
                                  int dataSize,
                                  int type,
                                  I2NPMessageHandler handler)
                           throws I2NPMessageException

      Specified by:
        `readMessage` in interface `I2NPMessage`
      Throws:
        `I2NPMessageException`

    - #### setMessageExpiration

          public void setMessageExpiration(long exp)

      The expiration is set to one minute from now in the constructor but it can be overridden here.
      Specified by:
        `setMessageExpiration` in interface `I2NPMessage`

    - #### setUniqueId

          public void setUniqueId(long id)

      The ID is set to a random value when written but it can be overridden here.
      Specified by:
        `setUniqueId` in interface `I2NPMessage`

    - #### toByteArray

          public byte[] toByteArray()

      Specified by:
        `toByteArray` in interface `I2NPMessage`

    - #### toByteArray

          public int toByteArray(byte[] buffer)

      write the message to the buffer, returning the number of bytes written. the data is formatted so as to be self contained, with the type, size, expiration, unique id, as well as a checksum bundled along. Full 16 byte header for NTCP 1.
      Specified by:
        `toByteArray` in interface `I2NPMessage`
      Returns:
        the length written

    - #### toByteArray

          public int toByteArray(byte[] buffer,
                                 int off)

      Write the message to the buffer, returning the new offset (NOT the length). the data is formatted so as to be self contained, with the type, size, expiration, unique id, as well as a checksum bundled along. Full 16 byte header for NTCP 1.
      Specified by:
        `toByteArray` in interface `I2NPMessage`
      Parameters:
        `off` - the offset to start writing at
      Returns:
        the new offset (NOT the length)

    - #### toRawByteArray

          public int toRawByteArray(byte[] buffer)

      Write the message with a short 5-byte header. THe header consists of a one-byte type and a 4-byte expiration in seconds only. Used by SSU only!
      Specified by:
        `toRawByteArray` in interface `I2NPMessage`
      Returns:
        the new offset (NOT the length)

    - #### toRawByteArrayNTCP2

          public int toRawByteArrayNTCP2(byte[] buffer,
                                         int off)

      Write the message to the buffer, returning the new offset (NOT the length). the data is is not self contained - it does not include the size, unique id, or any checksum, but does include the type and expiration. Short 9 byte header for NTCP2 and SSU2.
      Specified by:
        `toRawByteArrayNTCP2` in interface `I2NPMessage`
      Parameters:
        `off` - the offset to start writing at
      Returns:
        the new offset (NOT the length)

    - #### writeMessageBody

          protected abstract int writeMessageBody(byte[] out,
                                                  int curIndex)
                                           throws I2NPMessageException

      write the message body to the output array, starting at the given index.
      Returns:
        the index into the array after the last byte written (NOT the length)
      Throws:
        `I2NPMessageException`