java.lang.Object
net.i2p.client.streaming.impl.PacketHandler

class PacketHandlerextends Object
Handles incoming packets by dispatching them to the appropriate connection, server socket, or responding with a reset (RST) packet if no valid connection is found.

Packet flow: I2PSession -> MessageHandler -> PacketHandler -> ConnectionPacketHandler -> MessageInputStream.

  • Field Details

    • manager

      private final ConnectionManager manager
      The manager whose packets are handled.
    • context

      private final I2PAppContext context
      The context the handler runs in.
    • log

      private final Log log
      Logger for this class.
    • cache

      private final ByteCache cache
      Pooled buffers for incoming packets.
    • PROP_RECEIVE_WORKERS

      static final String PROP_RECEIVE_WORKERS
      Property limiting the number of inbound packet receive workers per connection manager. Unset or invalid values fall back to the platform core count.
      See Also:
    • MAX_RECEIVE_WORKERS

      static final int MAX_RECEIVE_WORKERS
      Upper bound on inbound receive workers per manager.
      See Also:
    • RECEIVE_QUEUE_CAPACITY

      static final int RECEIVE_QUEUE_CAPACITY
      Per-shard inbound queue capacity. A full queue back-pressures the session notifier thread rather than dropping or reordering packets.
      See Also:
    • _dispatcher

      private volatile PacketDispatcher _dispatcher
      Sharded dispatcher for known-connection packets, created lazily on the first inbound packet and shut down with the manager. Guarded by the volatile field + double-checked locking in getDispatcher().
    • DATE_FORMAT

      private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT
      Formatter for the date in packet options.
  • Constructor Details

    • PacketHandler

      public PacketHandler(I2PAppContext ctx, ConnectionManager mgr)
      Stores the context and manager, and opens the logger for the class.
      Parameters:
      ctx - the app context used for logging, properties and packet verification
      mgr - the connection manager whose connections dispatch inbound packets
  • Method Details

    • receivePacket

      void receivePacket(Packet packet)
      Receives a packet and dispatches it to the appropriate handler.
      Parameters:
      packet - the packet to process
    • receivePacketDirect

      void receivePacketDirect(Packet packet, boolean queueIfNoConn)
      Processes the packet immediately, optionally queuing if no connection is found.
      Parameters:
      packet - the packet to process
      queueIfNoConn - queue the packet if no matching connection exists
    • dispatchKnownConnection

      private void dispatchKnownConnection(Connection con, Packet packet, long sendId)
      Offload (con, packet) to the shard owning the connection. Per-connection FIFO ordering is preserved (a connection always maps to one worker) while packets for different connections run in parallel, so a slow connection or signature work no longer stalls the session notifier thread for all other connections on the same destination. If the shard's queue is full the notifier waits for space (the same blocking behaviour as processing the packet synchronously), so a packet is never dropped for want of queue space, and a connection always maps to the same shard, so it is never reordered.

      Two exits do drop a packet, both rare and both releasing the payload rather than leaking it: the interrupt handled below, and a worker-set resize - an entry handed to a worker between that worker idling out and being retired is freed when the retiring worker drains its queue. The peer recovers either way by retransmission.

      Parameters:
      con - the connection, indexed by sendId
      packet - the packet; ownership passes to the receiving shard
      sendId - the connection's inbound stream id (shard key)
    • getDispatcher

      private PacketDispatcher getDispatcher()
      Lazily create the sharded dispatcher. Worker count comes from the Tuner's global default (ConnectionOptions.getReceiveWorkerThreads()) when armed, else PROP_RECEIVE_WORKERS when set, else the platform core count, all clamped to MAX_RECEIVE_WORKERS.
      Returns:
      the shared dispatcher, never null
    • shutdownDispatcher

      void shutdownDispatcher()
      Shut down the receive workers, if any were created, releasing queued packets. Called from ConnectionManager.shutdown(); idempotent.
    • workerCountFor

      static int workerCountFor(int cores, String configured, int override)
      Clamped inbound receive worker count for a manager.

      The Tuner's live default wins when positive, so runtime tuning applies to managers created after the adjustment; otherwise a positive configured property value wins (capped at MAX_RECEIVE_WORKERS); otherwise the platform core count is used, floored at 2 for low-core hosts. Package-visible for unit tests.

      Parameters:
      cores - available processors at startup
      configured - raw property value, may be null
      override - Tuner global default, 0 = not armed
      Returns:
      the worker count, in 1..MAX_RECEIVE_WORKERS
    • displayPacket

      void displayPacket(Packet packet, String prefix, String suffix)
      Logs the provided packet at debug level with a timestamp.
      Parameters:
      packet - the packet to log
      prefix - text prefix (e.g., "RECV" or "UNKN")
      suffix - additional info appended after the packet string, may be null
    • receiveKnownConnection

      private void receiveKnownConnection(Connection con, Packet packet)
      Process a packet that matches a known connection.
      Parameters:
      con - the connection this packet belongs to
      packet - the incoming packet, matched to an established connection
    • handleEchoPacket

      private void handleEchoPacket(Connection con, Packet packet)
      Handles echo packets on known connections.
      Parameters:
      con - the connection the ECHO packet arrived on
      packet - the received ECHO packet
    • handleMisroutedPacket

      private void handleMisroutedPacket(Connection con, Packet packet)
      Handles a packet that appears on a known connection, but with stream ID mismatches or other anomalies.
      Parameters:
      con - the connection the packet arrived on
      packet - the misrouted packet to reclassify
    • sendReset

      private void sendReset(Packet packet)
      Sends a reset packet back to the sender if the incoming packet is verified.
      Parameters:
      packet - the received packet to answer, whose FROM option names the peer
    • sendResetUnverified

      public void sendResetUnverified(Packet packet)
      Sends a reset packet back to the sender without verifying the packet signature. Packet MUST have a FROM option.
      Parameters:
      packet - the received packet to answer; must carry a FROM option
    • receiveUnknownConnection

      private void receiveUnknownConnection(Packet packet, long sendId, boolean queueIfNoConn)
      Processes a packet that does not match any known connection.
      Parameters:
      packet - the unmatched packet
      sendId - stream ID of the sender
      queueIfNoConn - whether to queue the packet if connection is not found
    • handleEchoOnUnknown

      private void handleEchoOnUnknown(Packet packet)
      Handles an echo packet received on an unknown connection.
      Parameters:
      packet - the echo packet
    • receivePing

      private void receivePing(Connection con, Packet packet)
      Verifies and processes an incoming ping packet.
      Parameters:
      con - the connection from which ping originated, or null if unknown
      packet - the ping packet
    • receivePong

      private void receivePong(Packet packet)
      Processes an incoming pong packet.
      Parameters:
      packet - the pong packet
    • isValidMatch

      private static boolean isValidMatch(long conStreamId, long packetStreamId)
      Validates that the connection's stream ID matches the packet's stream ID and is non-zero.
      Parameters:
      conStreamId - the connection's send stream ID
      packetStreamId - the packet's receive stream ID
      Returns:
      true if stream IDs match and are non-zero, false otherwise