java.lang.Object
net.i2p.router.transport.udp.PacketPusher
All Implemented Interfaces:
Runnable

class PacketPusherextends Object implements Runnable
Blocking thread to grab new packets off the outbound fragment pool and toss them onto the outbound packet queues.

This class runs a dedicated thread that continuously pulls batches of UDP packets from the OutboundMessageFragments pool and sends them out through appropriate UDPEndpoints based on the packet IP version.

Thread safety is improved by using concurrent safe collections and volatile flag visibility.

Endpoint selection currently picks the first matching endpoint for IPv4 or IPv6.

  • Field Details

    • _log

      private final Log _log
      Logger for this class.
    • _fragments

      private final OutboundMessageFragments _fragments
      Where outgoing messages are fragmented.
    • _endpoints

      private final List<UDPEndpoint> _endpoints
      Endpoints to push to, in a thread-safe copy-on-write list, for safe concurrent iterations with minimal locking.
    • _alive

      private volatile boolean _alive
      False once the job has been cancelled.
    • _thread

      private volatile Thread _thread
      The thread running the push loop.
    • IDLE_BACKOFF_MS

      private static final long IDLE_BACKOFF_MS
      Idle backoff, used only if the fragment pool ever comes back empty while alive.
      See Also:
  • Constructor Details

    • PacketPusher

      public PacketPusher(RouterContext ctx, OutboundMessageFragments fragments, List<UDPEndpoint> endpoints)
      Creates the packet pusher.
      Parameters:
      ctx - the router context used to get the logger
      fragments - the outbound message fragment pool to pull packets from
      endpoints - a thread-safe or effectively immutable list of UDPEndpoints
  • Method Details

    • startup

      public void startup()
      Starts the packet pusher thread. This method is synchronized to prevent concurrent startups/shutdowns.

      Left at Thread.NORM_PRIORITY, which is what I2PThread sets. This was the only router thread at MAX_PRIORITY, so when the pool had nothing to send its spin preempted every other router thread; a local inefficiency became a router-wide latency problem.

    • shutdown

      public void shutdown()
      Stops the packet pusher thread. This method is synchronized to prevent concurrent shutdown/startup races.
    • run

      public void run()
      The main loop for the packet pusher thread. Continuously pulls packets from the fragment pool and sends them out via endpoints. Includes a blocking wait if no packets are currently available.
      Specified by:
      run in interface Runnable
    • send

      public void send(UDPPacket packet)
      Sends a single UDP packet directly out by selecting an appropriate UDPEndpoint. This bypasses the outbound fragment pool's queue and only blocks if the endpoint queue is full.

      Endpoint selection tries to match the packet's IP version to an endpoint's IP version.

      Tracked limitation: the first endpoint of the matching family wins, so packets to different peers on the same family can leave over different sockets. A per-peer endpoint affinity would keep a session on one socket for its lifetime; nothing here depends on that today, because the reply path keys off the peer's RouterIdentity rather than the local socket.

      Parameters:
      packet - the non-null UDPPacket to send