net.i2p.router.tunnel

## Class FragmentHandler

- java.lang.Object
- - net.i2p.router.tunnel.FragmentHandler

-     class FragmentHandler
      extends Object

  Handle fragments at the endpoint of a tunnel, peeling off fully completed I2NPMessages when they arrive, and dropping fragments if they take too long to arrive. From tunnel-alt.html:

  When the gateway wants to deliver data through the tunnel, it first gathers zero or more I2NP messages, selects how much padding will be used, fragments it across the necessary number of 1KB tunnel messages, and decides how each I2NP message should be handled by the tunnel endpoint, encoding that data into the raw tunnel payload:

  - The 4 byte Tunnel ID
  - The 16 byte IV
  - the first 4 bytes of the SHA256 of (the remaining preprocessed data concatenated with the IV), using the IV as will be seen on the tunnel endpoint (for outbound tunnels), or the IV as was seen on the tunnel gateway (for inbound tunnels) (see below for IV processing).
  - 0 or more bytes containing random nonzero integers
  - 1 byte containing 0x00
  - a series of zero or more { instructions, message } pairs

  Note that the padding, if any, must be before the instruction/message pairs. there is no provision for padding at the end.

  The instructions are encoded with a single control byte, followed by any necessary additional information. The first bit in that control byte determines how the remainder of the header is interpreted - if it is not set, the message is either not fragmented or this is the first fragment in the message. If it is set, this is a follow on fragment.

  With the first (leftmost or MSB) bit being 0, the instructions are:

  - 1 byte control byte:

              bit 0: is follow on fragment?  (1 = true, 0 = false, must be 0)
           bits 1-2: delivery type
                     (0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER)
              bit 3: delay included?  (1 = true, 0 = false) (unimplemented)
              bit 4: fragmented?  (1 = true, 0 = false)
              bit 5: extended options?  (1 = true, 0 = false) (unimplemented)
           bits 6-7: reserved

  - if the delivery type was TUNNEL, a 4 byte tunnel ID
  - if the delivery type was TUNNEL or ROUTER, a 32 byte router hash
  - if the delay included flag is true, a 1 byte value (unimplemented):

              bit 0: type (0 = strict, 1 = randomized)
           bits 1-7: delay exponent (2^value minutes)

  - if the fragmented flag is true, a 4 byte message ID
  - if the extended options flag is true (unimplemented):

           = a 1 byte option size (in bytes)
           = that many bytes

  - 2 byte size of the I2NP message or this fragment

  If the first bit being 1, the instructions are:

  - 1 byte control byte:

              bit 0: is follow on fragment?  (1 = true, 0 = false, must be 1)
           bits 1-6: fragment number
              bit 7: is last? (1 = true, 0 = false)

  - 4 byte message ID (same one defined in the first fragment)
  - 2 byte size of this fragment

  The I2NP message is encoded in its standard form, and the preprocessed payload must be padded to a multiple of 16 bytes. The total size, including the tunnel ID and IV, is 1028 bytes.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `FragmentHandler.DefragmentedReceiver` Receive messages out of the tunnel endpoint.

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected RouterContext` | `_context`
    `protected Log` | `_log`
    `(package private) static byte` | `MASK_EXTENDED` are there follow up headers? UNIMPLEMENTED
    `(package private) static byte` | `MASK_FRAGMENTED` is this the first of a fragmented message?
    `(package private) static byte` | `MASK_IS_SUBSEQUENT` is this a follw up byte?
    `(package private) static byte` | `MASK_TYPE` how should this be delivered.
    `(package private) static long` | `MAX_DEFRAGMENT_TIME` don't wait more than this long to completely receive a fragmented message
    `(package private) static short` | `TYPE_LOCAL`
    `(package private) static short` | `TYPE_ROUTER`
    `(package private) static short` | `TYPE_TUNNEL`
    `(package private) static short` | `TYPE_UNDEF`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `FragmentHandler(RouterContext context, FragmentHandler.DefragmentedReceiver receiver, boolean isInbound)`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `int` | `getCompleteCount()`
    `int` | `getFailedCount()`
    `boolean` | `receiveTunnelMessage(byte[] preprocessed, int offset, int length)` Receive the raw preprocessed message at the endpoint, parsing out each of the fragments, using those to fill various FragmentedMessages, and sending the resulting I2NPMessages where necessary.

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

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

- - ### Field Detail

    - #### _context

          protected final RouterContext _context

    - #### _log

          protected final Log _log

    - #### MASK_EXTENDED

          static final byte MASK_EXTENDED

      are there follow up headers? UNIMPLEMENTED
      See Also:
        Constant Field Values

    - #### MASK_FRAGMENTED

          static final byte MASK_FRAGMENTED

      is this the first of a fragmented message?
      See Also:
        Constant Field Values

    - #### MASK_IS_SUBSEQUENT

          static final byte MASK_IS_SUBSEQUENT

      is this a follw up byte?
      See Also:
        Constant Field Values

    - #### MASK_TYPE

          static final byte MASK_TYPE

      how should this be delivered. shift this 5 the right and get TYPE_*
      See Also:
        Constant Field Values

    - #### MAX_DEFRAGMENT_TIME

          static long MAX_DEFRAGMENT_TIME

      don't wait more than this long to completely receive a fragmented message

    - #### TYPE_LOCAL

          static final short TYPE_LOCAL

      See Also:
        Constant Field Values

    - #### TYPE_ROUTER

          static final short TYPE_ROUTER

      See Also:
        Constant Field Values

    - #### TYPE_TUNNEL

          static final short TYPE_TUNNEL

      See Also:
        Constant Field Values

    - #### TYPE_UNDEF

          static final short TYPE_UNDEF

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### FragmentHandler

          public FragmentHandler(RouterContext context,
                                 FragmentHandler.DefragmentedReceiver receiver,
                                 boolean isInbound)

      Parameters:
        `isInbound` - true for IBEP, false for OBEP

  - ### Method Detail

    - #### getCompleteCount

          public int getCompleteCount()

    - #### getFailedCount

          public int getFailedCount()

    - #### receiveTunnelMessage

          public boolean receiveTunnelMessage(byte[] preprocessed,
                                              int offset,
                                              int length)

      Receive the raw preprocessed message at the endpoint, parsing out each of the fragments, using those to fill various FragmentedMessages, and sending the resulting I2NPMessages where necessary. The received fragments are all verified.
      Returns:
        ok (false if corrupt)