net.i2p.i2ptunnel

## Class I2PTunnelServer

- java.lang.Object
- - net.i2p.util.EventDispatcherImpl
  - - net.i2p.i2ptunnel.I2PTunnelTask
    - - net.i2p.i2ptunnel.I2PTunnelServer

- All Implemented Interfaces:
    Runnable, EventDispatcher
  Direct Known Subclasses:
    I2PTunnelDCCServer, I2PTunnelHTTPServer, I2PTunnelIRCServer

      public class I2PTunnelServer
      extends I2PTunnelTask
      implements Runnable

  Base I2P tunnel server for handling incoming connections.

  I2PTunnelServer is the foundation for all I2P server tunnels that accept incoming I2P connections and forward them to local TCP services. It manages the lifecycle of I2PSocketManager, handles connection acceptance, and provides connection forwarding to configured local destinations.

  Key Features:

  - Accepts incoming I2P connections via I2PServerSocket
  - Forwards connections to configurable local TCP destinations
  - Supports SSL/TLS connections via I2PSSLSocketFactory
  - Provides port-based destination mapping (targetForPort.xx)
  - Implements connection filtering via StatefulConnectionFilter
  - Uses thread pool for concurrent connection handling

  Connection Flow:

  1. Client connects to I2P destination via I2PServerSocket
  2. blockingHandle() is called with the I2PSocket
  3. Local TCP socket is created via getSocket()
  4. I2PTunnelRunner handles bidirectional data streaming

  Subclasses: I2PTunnelHTTPServer, I2PTunnelIRCServer, and others extend this class to provide protocol-specific handling while reusing the core connection management infrastructure.

  See Also:
    `I2PTunnelHTTPServer`, `I2PTunnelIRCServer`, `I2PSocketManager`

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected static long` | `__serverId`
    `protected ThreadPoolExecutor` | `_clientExecutor`
    `protected Log` | `_log`
    `protected boolean` | `bidir`
    `protected I2PServerSocket` | `i2pss`
    `protected Logging` | `l`
    `protected int` | `localPort`
    `static String` | `PROP_ALT_PKF`
    `static String` | `PROP_UNIQUE_LOCAL`
    `static String` | `PROP_USE_SSL`
    `protected long` | `readTimeout` default timeout - override if desired
    `protected InetAddress` | `remoteHost`
    `protected int` | `remotePort`
    `protected Object` | `slock`
    `protected I2PSocketManager` | `sockMgr`
    `protected Object` | `sslLock`
    `protected I2PTunnelTask` | `task`

    - ### Fields inherited from class net.i2p.i2ptunnel.I2PTunnelTask

      `open, tunnel`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)` Non-blocking
    `I2PTunnelServer(InetAddress host, int port, I2PSocketManager sktMgr, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)` Non-blocking
    `I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)` Non-blocking
    `I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)` Non-blocking

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected void` | `blockingHandle(I2PSocket socket)` This is run in a thread from a limited-size thread pool via Handler.run(), except for a standard server (this class, no extension, as determined in getUsePool()), it is run directly in the acceptor thread (see run()).
    `boolean` | `close(boolean forced)` Note that the tunnel can be reopened after this by calling startRunning().
    `boolean` | `destroy()` Note that the tunnel cannot be reopened after this by calling startRunning(), as it will destroy the underlying socket manager.
    `long` | `getReadTimeout()` Get the read idle timeout for newly-created connections (in milliseconds).
    `protected Socket` | `getSocket(Hash from, InetAddress remoteHost, int remotePort)` Creates a TCP socket connection to the specified destination.
    `protected Socket` | `getSocket(Hash from, int incomingPort)` Creates a TCP socket connection to the configured destination.
    `protected String` | `getSocketString(int incomingPort)` Gets a human-readable string representation of the target socket.
    `void` | `optionsUpdated(I2PTunnel tunnel)` Update the I2PSocketManager.
    `void` | `run()` Runs the I2PTunnelServer to accept and handle incoming connections asynchronously.
    `void` | `setReadTimeout(long ms)` Set the read idle timeout for newly-created connections (in milliseconds).
    `(package private) void` | `shutdownAndAwaitTermination(ExecutorService executor)`
    `void` | `startRunning()` Start running the I2PTunnelServer.

    - ### Methods inherited from class net.i2p.i2ptunnel.I2PTunnelTask

      `connected, disconnected, errorOccurred, getBooleanOption, getId, getTunnel, isOpen, reportAbuse, routerDisconnected, setId, setName, setTunnel, toString`

    - ### Methods inherited from class net.i2p.util.EventDispatcherImpl

      `attachEventDispatcher, detachEventDispatcher, getEventDispatcher, getEvents, getEventValue, ignoreEvents, notifyEvent, unIgnoreEvents, waitEventValue`

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

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

- - ### Field Detail

    - #### __serverId

          protected static volatile long __serverId

    - #### _clientExecutor

          protected volatile ThreadPoolExecutor _clientExecutor

    - #### _log

          protected final Log _log

    - #### bidir

          protected boolean bidir

    - #### i2pss

          protected volatile I2PServerSocket i2pss

    - #### l

          protected final Logging l

    - #### localPort

          protected int localPort

    - #### PROP_ALT_PKF

          public static final String PROP_ALT_PKF

      See Also:
        Constant Field Values

    - #### PROP_UNIQUE_LOCAL

          public static final String PROP_UNIQUE_LOCAL

      See Also:
        Constant Field Values

    - #### PROP_USE_SSL

          public static final String PROP_USE_SSL

      See Also:
        Constant Field Values

    - #### readTimeout

          protected long readTimeout

      default timeout - override if desired

    - #### remoteHost

          protected InetAddress remoteHost

    - #### remotePort

          protected int remotePort

    - #### slock

          protected final Object slock

    - #### sockMgr

          protected final I2PSocketManager sockMgr

    - #### sslLock

          protected final Object sslLock

    - #### task

          protected I2PTunnelTask task

  - ### Constructor Detail

    - #### I2PTunnelServer

          public I2PTunnelServer(InetAddress host,
                                 int port,
                                 File privkey,
                                 String privkeyname,
                                 Logging l,
                                 EventDispatcher notifyThis,
                                 I2PTunnel tunnel)

      Non-blocking
      Parameters:
        `privkey` - file containing the private key data, format is specified in `PrivateKeyFile`
        `privkeyname` - the name of the privKey file, just for logging
      Throws:
        `IllegalArgumentException` - if the I2CP configuration is b0rked so badly that we cant create a socketManager

    - #### I2PTunnelServer

          public I2PTunnelServer(InetAddress host,
                                 int port,
                                 I2PSocketManager sktMgr,
                                 Logging l,
                                 EventDispatcher notifyThis,
                                 I2PTunnel tunnel)

      Non-blocking
      Parameters:
        `sktMgr` - the existing socket manager

    - #### I2PTunnelServer

          public I2PTunnelServer(InetAddress host,
                                 int port,
                                 InputStream privData,
                                 String privkeyname,
                                 Logging l,
                                 EventDispatcher notifyThis,
                                 I2PTunnel tunnel)

      Non-blocking
      Parameters:
        `privData` - stream containing the private key data, format is specified in `PrivateKeyFile`
        `privkeyname` - the name of the privKey file, just for logging
      Throws:
        `IllegalArgumentException` - if the I2CP configuration is b0rked so badly that we cant create a socketManager

    - #### I2PTunnelServer

          public I2PTunnelServer(InetAddress host,
                                 int port,
                                 String privData,
                                 Logging l,
                                 EventDispatcher notifyThis,
                                 I2PTunnel tunnel)

      Non-blocking
      Parameters:
        `privData` - Base64-encoded private key data, format is specified in `PrivateKeyFile`
      Throws:
        `IllegalArgumentException` - if the I2CP configuration is b0rked so badly that we cant create a socketManager

  - ### Method Detail

    - #### blockingHandle

          protected void blockingHandle(I2PSocket socket)

      This is run in a thread from a limited-size thread pool via Handler.run(), except for a standard server (this class, no extension, as determined in getUsePool()), it is run directly in the acceptor thread (see run()). Handles an incoming I2P connection by forwarding it to the local TCP destination.

      This method is called by the server socket's acceptance thread when a new I2P connection arrives. It creates a local TCP socket connection and spawns an I2PTunnelRunner to handle bidirectional data streaming between the I2P and TCP connections.

      Implementation Notes:

      - Subclasses that override this must call super.blockingHandle() or implement
      full connection handling themselves
    - For protocol-specific handling (HTTP, IRC), spawn a handler thread and return
    - For simple forwarding, this base implementation handles all cases
    - Performance: local connections are fast enough to handle synchronously

    Error Handling: SocketException and IOException are caught and logged, with the socket being reset to notify the peer of the failure.

Parameters:
  `socket` - the incoming I2P connection from a remote peer; never null
See Also:
  `getSocket(Hash, int)`, `I2PTunnelRunner`

- #### close

      public boolean close(boolean forced)

  Note that the tunnel can be reopened after this by calling startRunning(). This does not release all resources. In particular, the I2PSocketManager remains and it may have timer threads that continue running. To release all resources permanently, call destroy().
  Specified by:
    `close` in class `I2PTunnelTask`
  Returns:
    true if the tunnel was closed successfully, false if connections exist and forced is false

- #### destroy

      public boolean destroy()

  Note that the tunnel cannot be reopened after this by calling startRunning(), as it will destroy the underlying socket manager. This releases all resources.
  Overrides:
    `destroy` in class `I2PTunnelTask`
  Returns:
    success

- #### getReadTimeout

      public long getReadTimeout()

  Get the read idle timeout for newly-created connections (in milliseconds). Less than or equal to 0 means forever. Default -1 (forever) as of 0.9.36 for standard tunnels, but extending classes may override. Prior to that, default was 5 minutes, but did not work due to streaming bugs.
  Returns:
    The read timeout used for connections

- #### getSocket

      protected Socket getSocket(Hash from,
                                 InetAddress remoteHost,
                                 int remotePort)
                          throws IOException

  Creates a TCP socket connection to the specified destination.

  This convenience method delegates to getSocket() with forceNonSSL=false, allowing SSL configuration to be controlled by client options.

  Parameters:
    `from` - the hash of the peer's destination
    `remoteHost` - the target InetAddress to connect to
    `remotePort` - the target port to connect to
  Returns:
    a connected TCP Socket
  Throws:
    `IOException` - if the socket cannot be created or connected
  See Also:
    `getSocket(Hash, int)`

- #### getSocket

      protected Socket getSocket(Hash from,
                                 int incomingPort)
                          throws IOException

  Creates a TCP socket connection to the configured destination.

  This method resolves the target host and port for the incoming connection, supporting port-based destination mapping via the client options. If a port has a specific mapping (targetForPort.xx=host:port), that destination is used; otherwise, the default remoteHost and remotePort are used.

  Port Mapping Configuration:

       targetForPort.80=localhost:8080
       targetForPort.443=localhost:8443

  Special Ports: Ports 443 and 22 are automatically flagged for non-SSL handling to prevent SSL-over-SSL issues.

  Parameters:
    `from` - the hash of the peer's destination; used for local address binding
    `incomingPort` - the port on which the I2P connection was received
  Returns:
    a connected TCP Socket to the appropriate local destination
  Throws:
    `IOException` - if the socket cannot be created or connected
  See Also:
    `getSocket(Hash, InetAddress, int)`

- #### getSocketString

      protected String getSocketString(int incomingPort)

  Gets a human-readable string representation of the target socket.

  This method is used for logging and error messages when socket creation fails. It returns the configured destination address, taking into account any port-specific mappings that may have been configured.

  The returned string is formatted as "host:port" without any protocol prefix.

  Parameters:
    `incomingPort` - the incoming I2P connection port for lookup
  Returns:
    the target host and port as a string, or default if not configured
  See Also:
    `getSocket(Hash, int)`

- #### optionsUpdated

      public void optionsUpdated(I2PTunnel tunnel)

  Update the I2PSocketManager. And since 0.9.15, the target host and port.
  Overrides:
    `optionsUpdated` in class `I2PTunnelTask`

- #### run

      public void run()

  Runs the I2PTunnelServer to accept and handle incoming connections asynchronously. Accepts connections in a loop, submitting each to the thread pool via CompletableFuture. Handles expected exceptions with retries and logs errors. On shutdown, gracefully terminates the pool.
  Specified by:
    `run` in interface `Runnable`

- #### setReadTimeout

      public void setReadTimeout(long ms)

  Set the read idle timeout for newly-created connections (in milliseconds). After this time expires without data being reached from the I2P network, the connection itself will be closed. Less than or equal to 0 means forever. Default -1 (forever) as of 0.9.36 for standard tunnels, but extending classes may override. Prior to that, default was 5 minutes, but did not work due to streaming bugs. Applies only to future connections; calling this does not affect existing connections.
  Parameters:
    `ms` - in ms

- #### shutdownAndAwaitTermination

      void shutdownAndAwaitTermination(ExecutorService executor)

- #### startRunning

      public void startRunning()

  Start running the I2PTunnelServer. Warning, blocks while connecting to router and building tunnels;
  Throws:
    `IllegalArgumentException` - if the I2CP configuration is b0rked so badly that we cant create a socketManager