java.lang.Object
net.i2p.router.transport.ntcp.NTCP2Payload

class NTCP2Payloadextends Object
NTCP 2 payload generation and parsing utilities.
  • Field Details

    • BLOCK_HEADER_SIZE

      public static final int BLOCK_HEADER_SIZE
      Block header size in bytes.
      See Also:
    • BLOCK_DATETIME

      private static final int BLOCK_DATETIME
      Block type of the date and time.
      See Also:
    • BLOCK_OPTIONS

      private static final int BLOCK_OPTIONS
      Block type of the session options.
      See Also:
    • BLOCK_ROUTERINFO

      private static final int BLOCK_ROUTERINFO
      Block type of the router info.
      See Also:
    • BLOCK_I2NP

      private static final int BLOCK_I2NP
      Block type of the I2NP message.
      See Also:
    • BLOCK_TERMINATION

      private static final int BLOCK_TERMINATION
      Block type of the termination reason.
      See Also:
    • BLOCK_PADDING

      private static final int BLOCK_PADDING
      Block type of the padding.
      See Also:
  • Constructor Details

    • NTCP2Payload

      NTCP2Payload()
      Not instantiated - every member below is static.
  • Method Details

    • processPayload

      public static int processPayload(I2PAppContext ctx, NTCP2Payload.PayloadCallback cb, byte[] payload, int off, int length, boolean isHandshake) throws IOException, DataFormatException, I2NPMessageException
      Incoming payload. Calls the callback for each received block.
      Parameters:
      ctx - used to deserialize the RouterInfo and I2NP blocks
      cb - receives each block in the order it appears in the frame
      payload - the frame bytes, holding a sequence of blocks
      off - index in payload of the first block's type byte
      length - how many bytes of payload to parse, bounding the block walk
      isHandshake - true only for message 3 part 2, which allows only RouterInfo, options and padding
      Returns:
      number of blocks processed
      Throws:
      IOException - on major errors
      DataFormatException - on parsing of individual blocks
      I2NPMessageException - on parsing of I2NP block
    • checkBlockOrder

      private static void checkBlockOrder(boolean isHandshake, int blocks, boolean gotPadding, boolean gotTermination, int type) throws IOException
      Check the payload-wide ordering rules for the next block: no block may follow padding, only padding may follow termination, and the first block of a handshake frame must be a RouterInfo.
      Parameters:
      isHandshake - true for the handshake frame, where the block is not allowed
      blocks - blocks already processed in this frame
      gotPadding - whether padding was already seen
      gotTermination - whether termination was already seen
      type - the next block type
      Throws:
      IOException - if ordering is violated
    • checkFrameOverflow

      private static void checkFrameOverflow(int off, int length, int end, int i, int len, int blocks, int type) throws IOException
      Check that the block fits inside the frame. Called with i pointing just past the 3-byte header, so the block's offset is i - 3 - off. The frame contents are deliberately not included, they may be decrypted data; callers that want a dump log it at DEBUG.
      Parameters:
      off - index in payload of the first block's type byte, for the error message
      length - frame size in bytes, for the error message
      end - exclusive end index of the frame, i.e. off + length
      i - index of the block's first data byte, just past its 3-byte header
      len - the block's data length, as read from its header
      blocks - blocks already processed in this frame, for the error message
      type - the current block's type, for the error message
      Throws:
      IOException - if the block runs over the end of the frame
    • checkHandshakeOnly

      private static void checkHandshakeOnly(boolean isHandshake, int type) throws IOException
      Check that the block type is not allowed in a handshake frame.
      Parameters:
      isHandshake - true for the handshake frame, where the block is not allowed
      type - the block's type, for the error message
      Throws:
      IOException - if the block appears in a handshake frame
    • processDateTime

      private static void processDateTime(NTCP2Payload.PayloadCallback cb, byte[] payload, int i, int len) throws IOException, DataFormatException
      Parse a DATETIME block (exactly 4 bytes) and report it to the callback.
      Parameters:
      cb - receives the peer's clock, in milliseconds
      payload - the frame bytes
      i - index of the block's first data byte
      len - the block's data length, must be exactly 4
      Throws:
      IOException - if the length is not 4
      DataFormatException - if the callback cannot process the block
    • processOptions

      private static void processOptions(NTCP2Payload.PayloadCallback cb, byte[] payload, int i, int len, boolean isHandshake) throws DataFormatException
      Copy an OPTIONS block and report it to the callback.
      Parameters:
      cb - receives a copy of the block's data
      payload - the frame bytes
      i - index of the block's first data byte
      len - the block's data length
      isHandshake - true for the handshake frame, passed on to the callback
      Throws:
      DataFormatException - if the callback cannot process the block
    • processRouterInfo

      private static void processRouterInfo(I2PAppContext ctx, NTCP2Payload.PayloadCallback cb, byte[] payload, int i, int len, boolean isHandshake) throws IOException, DataFormatException
      Deserialize a ROUTERINFO block (a 1-byte flag then the RouterInfo) and report it to the callback.
      Parameters:
      ctx - used to deserialize the RouterInfo
      cb - receives the RouterInfo and whether the peer is a floodfill
      payload - the frame bytes
      i - index of the block's first data byte, the 1-byte flag
      len - the block's data length, including the flag byte
      isHandshake - true for the handshake frame, passed on to the callback
      Throws:
      IOException - if the RouterInfo cannot be read
      DataFormatException - if the RouterInfo is too big, or the callback rejects it
    • processI2NP

      private static void processI2NP(I2PAppContext ctx, NTCP2Payload.PayloadCallback cb, byte[] payload, int i, int len) throws IOException, I2NPMessageException
      Parse an I2NP block (at least 9 bytes) and report it to the callback.
      Parameters:
      ctx - used to deserialize the message
      cb - receives the message
      payload - the frame bytes
      i - index of the block's first data byte
      len - the block's data length, at least 9
      Throws:
      IOException - if the block is shorter than 9 bytes
      I2NPMessageException - if the message cannot be deserialized, or the callback cannot process it
    • processTermination

      private static boolean processTermination(NTCP2Payload.PayloadCallback cb, byte[] payload, int i, int len) throws IOException
      Parse a TERMINATION block (at least 9 bytes) and report it to the callback.
      Parameters:
      cb - receives the reason and the peer's last received date and time
      payload - the frame bytes
      i - index of the block's first data byte
      len - the block's data length, at least 9
      Returns:
      true, so the caller records that termination has been seen
      Throws:
      IOException - if the block is shorter than 9 bytes
    • writePayload

      public static int writePayload(byte[] payload, int off, List<NTCP2Payload.Block> blocks)
      Write the blocks out to the frame, in list order.
      Parameters:
      payload - writes to it starting at off
      off - index in payload to write the first block's header at
      blocks - each one written at the offset the previous one ended at
      Returns:
      the new offset