public class I2PTunnelServer extends I2PTunnelTask implements Runnable
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:
Connection Flow:
Subclasses: I2PTunnelHTTPServer, I2PTunnelIRCServer, and others extend this class to provide protocol-specific handling while reusing the core connection management infrastructure.
I2PTunnelHTTPServer,
I2PTunnelIRCServer,
I2PSocketManager| 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 |
open, tunnel| 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
|
| 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.
|
connected, disconnected, errorOccurred, getBooleanOption, getId, getTunnel, isOpen, reportAbuse, routerDisconnected, setId, setName, setTunnel, toStringattachEventDispatcher, detachEventDispatcher, getEventDispatcher, getEvents, getEventValue, ignoreEvents, notifyEvent, unIgnoreEvents, waitEventValueprotected static volatile long __serverId
protected volatile ThreadPoolExecutor _clientExecutor
protected final Log _log
protected boolean bidir
protected volatile I2PServerSocket i2pss
protected final Logging l
protected int localPort
public static final String PROP_ALT_PKF
public static final String PROP_UNIQUE_LOCAL
public static final String PROP_USE_SSL
protected long readTimeout
protected InetAddress remoteHost
protected int remotePort
protected final Object slock
protected final I2PSocketManager sockMgr
protected final Object sslLock
protected I2PTunnelTask task
public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)
privkey - file containing the private key data,
format is specified in PrivateKeyFileprivkeyname - the name of the privKey file, just for loggingIllegalArgumentException - if the I2CP configuration is b0rked so
badly that we cant create a socketManagerpublic I2PTunnelServer(InetAddress host, int port, I2PSocketManager sktMgr, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)
sktMgr - the existing socket managerpublic I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)
privData - stream containing the private key data,
format is specified in PrivateKeyFileprivkeyname - the name of the privKey file, just for loggingIllegalArgumentException - if the I2CP configuration is b0rked so
badly that we cant create a socketManagerpublic I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel)
privData - Base64-encoded private key data,
format is specified in PrivateKeyFileIllegalArgumentException - if the I2CP configuration is b0rked so
badly that we cant create a socketManagerprotected void blockingHandle(I2PSocket socket)
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:
Error Handling: SocketException and IOException are caught and logged, with the socket being reset to notify the peer of the failure.
socket - the incoming I2P connection from a remote peer; never nullgetSocket(Hash, int),
I2PTunnelRunnerpublic boolean close(boolean forced)
close in class I2PTunnelTaskpublic boolean destroy()
destroy in class I2PTunnelTaskpublic long getReadTimeout()
protected Socket getSocket(Hash from, InetAddress remoteHost, int remotePort) throws IOException
This convenience method delegates to getSocket() with forceNonSSL=false, allowing SSL configuration to be controlled by client options.
from - the hash of the peer's destinationremoteHost - the target InetAddress to connect toremotePort - the target port to connect toIOException - if the socket cannot be created or connectedgetSocket(Hash, int)protected Socket getSocket(Hash from, int incomingPort) throws IOException
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.
from - the hash of the peer's destination; used for local address bindingincomingPort - the port on which the I2P connection was receivedIOException - if the socket cannot be created or connectedgetSocket(Hash, InetAddress, int)protected String getSocketString(int incomingPort)
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.
incomingPort - the incoming I2P connection port for lookupgetSocket(Hash, int)public void optionsUpdated(I2PTunnel tunnel)
optionsUpdated in class I2PTunnelTaskpublic void run()
public void setReadTimeout(long ms)
ms - in msvoid shutdownAndAwaitTermination(ExecutorService executor)
public void startRunning()
IllegalArgumentException - if the I2CP configuration is b0rked so
badly that we cant create a socketManager