forked from I2P_Developers/i2p.i2p
Hooks into streaming for filtering of incoming connections
This commit is contained in:
@ -55,7 +55,24 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager() {
|
||||
return createManager(getHost(), getPort(), (Properties) System.getProperties().clone());
|
||||
return createManager(getHost(), getPort(), (Properties) System.getProperties().clone(),
|
||||
IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using a brand new destination connected to the
|
||||
* I2CP router on the local machine on the default port (7654) with the
|
||||
* specified incoming connection filter.
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @since 0.9.40
|
||||
* @param filter The filter for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(IncomingConnectionFilter filter) {
|
||||
return createManager(getHost(), getPort(), (Properties) System.getProperties().clone(), filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +86,23 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(Properties opts) {
|
||||
return createManager(getHost(), getPort(), opts);
|
||||
return createManager(getHost(), getPort(), opts, IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using a brand new destination connected to the
|
||||
* I2CP router on the local machine on the default port (7654).
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @since 0.9.40
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(Properties opts, IncomingConnectionFilter filter) {
|
||||
return createManager(getHost(), getPort(), opts, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,7 +117,24 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String host, int port) {
|
||||
return createManager(host, port, (Properties) System.getProperties().clone());
|
||||
return createManager(host, port, (Properties) System.getProperties().clone(),
|
||||
IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using a brand new destination connected to the
|
||||
* I2CP router on the specified host and port with the specified connection filter
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @param host I2CP host null to use default, ignored if in router context
|
||||
* @param port I2CP port <= 0 to use default, ignored if in router context
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String host, int port, IncomingConnectionFilter filter) {
|
||||
return createManager(host, port, (Properties) System.getProperties().clone(), filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,12 +150,32 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String i2cpHost, int i2cpPort, Properties opts) {
|
||||
return createManager(i2cpHost, i2cpPort, opts, IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using a brand new destination connected to the
|
||||
* I2CP router on the given machine reachable through the given port with
|
||||
* the specified connection filter
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @since 0.9.40
|
||||
* @param i2cpHost I2CP host null to use default, ignored if in router context
|
||||
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String i2cpHost, int i2cpPort, Properties opts,
|
||||
IncomingConnectionFilter filter) {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
client.createDestination(keyStream, getSigType(opts));
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(keyStream.toByteArray());
|
||||
return createManager(in, i2cpHost, i2cpPort, opts);
|
||||
return createManager(in, i2cpHost, i2cpPort, opts, filter);
|
||||
} catch (IOException ioe) {
|
||||
getLog().error("Error creating the destination for socket manager", ioe);
|
||||
return null;
|
||||
@ -127,7 +197,28 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream) {
|
||||
return createManager(myPrivateKeyStream, getHost(), getPort(), (Properties) System.getProperties().clone());
|
||||
return createManager(myPrivateKeyStream, IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using the destination loaded from the given private key
|
||||
* stream and connected to the default I2CP host and port with the specified connection filter
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @since 0.9.40
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream,
|
||||
IncomingConnectionFilter filter) {
|
||||
return createManager(myPrivateKeyStream, getHost(), getPort(),
|
||||
(Properties) System.getProperties().clone(),
|
||||
filter);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,7 +234,26 @@ public class I2PSocketManagerFactory {
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream, Properties opts) {
|
||||
return createManager(myPrivateKeyStream, getHost(), getPort(), opts);
|
||||
return createManager(myPrivateKeyStream, opts, IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using the destination loaded from the given private key
|
||||
* stream and connected to the default I2CP host and port.
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream,
|
||||
Properties opts,
|
||||
IncomingConnectionFilter filter) {
|
||||
return createManager(myPrivateKeyStream, getHost(), getPort(), opts, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,8 +273,32 @@ public class I2PSocketManagerFactory {
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort,
|
||||
Properties opts) {
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a socket manager using the destination loaded from the given private key
|
||||
* stream and connected to the I2CP router on the specified machine on the given
|
||||
* port.
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
* The nonblocking createDisconnectedManager() is preferred.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param i2cpHost I2CP host null to use default, ignored if in router context
|
||||
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream,
|
||||
String i2cpHost,
|
||||
int i2cpPort,
|
||||
Properties opts,
|
||||
IncomingConnectionFilter filter) {
|
||||
try {
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, true);
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, true, filter);
|
||||
} catch (I2PSessionException ise) {
|
||||
getLog().error("Error creating session for socket manager", ise);
|
||||
return null;
|
||||
@ -191,6 +325,38 @@ public class I2PSocketManagerFactory {
|
||||
*/
|
||||
public static I2PSocketManager createDisconnectedManager(InputStream myPrivateKeyStream, String i2cpHost,
|
||||
int i2cpPort, Properties opts) throws I2PSessionException {
|
||||
return createDisconnectedManager(myPrivateKeyStream,
|
||||
i2cpHost,
|
||||
i2cpPort,
|
||||
opts,
|
||||
IncomingConnectionFilter.ALLOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a disconnected socket manager using the destination loaded from the given private key
|
||||
* stream, or null for a transient destination.
|
||||
*
|
||||
* Non-blocking. Does not connect to the router or build tunnels.
|
||||
* For servers, caller MUST call getSession().connect() to build tunnels and start listening.
|
||||
* For clients, caller may do that to build tunnels in advance;
|
||||
* otherwise, the first call to connect() will initiate a connection to the router,
|
||||
* with significant delay for tunnel building.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param i2cpHost I2CP host null to use default, ignored if in router context
|
||||
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, non-null (throws on error)
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public static I2PSocketManager createDisconnectedManager(InputStream myPrivateKeyStream,
|
||||
String i2cpHost,
|
||||
int i2cpPort,
|
||||
Properties opts,
|
||||
IncomingConnectionFilter filter)
|
||||
throws I2PSessionException {
|
||||
if (myPrivateKeyStream == null) {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
|
||||
@ -203,7 +369,7 @@ public class I2PSocketManagerFactory {
|
||||
}
|
||||
myPrivateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
|
||||
}
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false);
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,11 +385,13 @@ public class I2PSocketManagerFactory {
|
||||
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param connect true to connect (blocking)
|
||||
* @param filter The filter to use for incoming connections
|
||||
* @return the newly created socket manager, non-null (throws on error)
|
||||
* @since 0.9.7
|
||||
* @since 0.9.40
|
||||
*/
|
||||
private static I2PSocketManager createManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort,
|
||||
Properties opts, boolean connect) throws I2PSessionException {
|
||||
Properties opts, boolean connect,
|
||||
IncomingConnectionFilter filter) throws I2PSessionException {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
if (opts == null)
|
||||
opts = new Properties();
|
||||
@ -245,11 +413,12 @@ public class I2PSocketManagerFactory {
|
||||
I2PSession session = client.createSession(myPrivateKeyStream, opts);
|
||||
if (connect)
|
||||
session.connect();
|
||||
I2PSocketManager sockMgr = createManager(session, opts, "manager");
|
||||
I2PSocketManager sockMgr = createManager(session, opts, "manager", filter);
|
||||
return sockMgr;
|
||||
}
|
||||
|
||||
private static I2PSocketManager createManager(I2PSession session, Properties opts, String name) {
|
||||
private static I2PSocketManager createManager(I2PSession session, Properties opts, String name,
|
||||
IncomingConnectionFilter filter) {
|
||||
I2PAppContext context = I2PAppContext.getGlobalContext();
|
||||
// As of 0.9.12, ignore this setting, as jwebcache and i2phex set it to the old value.
|
||||
// There is no other valid manager.
|
||||
@ -260,8 +429,13 @@ public class I2PSocketManagerFactory {
|
||||
if (!I2PSocketManager.class.isAssignableFrom(cls))
|
||||
throw new IllegalArgumentException(classname + " is not an I2PSocketManager");
|
||||
Constructor<?> con =
|
||||
cls.getConstructor(I2PAppContext.class, I2PSession.class, Properties.class, String.class);
|
||||
I2PSocketManager mgr = (I2PSocketManager) con.newInstance(new Object[] {context, session, opts, name});
|
||||
cls.getConstructor(I2PAppContext.class,
|
||||
I2PSession.class,
|
||||
Properties.class,
|
||||
String.class,
|
||||
IncomingConnectionFilter.class);
|
||||
I2PSocketManager mgr = (I2PSocketManager) con.newInstance(
|
||||
new Object[] {context, session, opts, name, filter});
|
||||
return mgr;
|
||||
} catch (Throwable t) {
|
||||
getLog().log(Log.CRIT, "Error loading " + classname, t);
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
|
||||
/**
|
||||
* Something that filters incoming streaming connections.
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public interface IncomingConnectionFilter {
|
||||
|
||||
/**
|
||||
* @param d the destination that wants to establish an
|
||||
* incoming connection
|
||||
* @return true if the connection should be allowed.
|
||||
*/
|
||||
public boolean allowDestination(Destination d);
|
||||
|
||||
/**
|
||||
* Utility implementation that allows all incoming connections
|
||||
*/
|
||||
public static final IncomingConnectionFilter ALLOW =
|
||||
new IncomingConnectionFilter() {
|
||||
public boolean allowDestination(Destination d) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility implementation that denies all incoming connections
|
||||
*/
|
||||
public static final IncomingConnectionFilter DENY =
|
||||
new IncomingConnectionFilter() {
|
||||
public boolean allowDestination(Destination d) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
@ -21,6 +21,7 @@ import net.i2p.util.ConvertToHash;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
import net.i2p.client.streaming.IncomingConnectionFilter;
|
||||
|
||||
/**
|
||||
* Coordinate all of the connections for a single local destination.
|
||||
@ -38,6 +39,7 @@ class ConnectionManager {
|
||||
private final SchedulerChooser _schedulerChooser;
|
||||
private final ConnectionPacketHandler _conPacketHandler;
|
||||
private final TCBShare _tcbShare;
|
||||
private final IncomingConnectionFilter _connectionFilter;
|
||||
/** Inbound stream ID (Long) to Connection map */
|
||||
private final ConcurrentHashMap<Long, Connection> _connectionByInboundId;
|
||||
/** Ping ID (Long) to PingRequest */
|
||||
@ -81,10 +83,14 @@ class ConnectionManager {
|
||||
/**
|
||||
* Manage all conns for this session
|
||||
*/
|
||||
public ConnectionManager(I2PAppContext context, I2PSession session, ConnectionOptions defaultOptions) {
|
||||
public ConnectionManager(I2PAppContext context,
|
||||
I2PSession session,
|
||||
ConnectionOptions defaultOptions,
|
||||
IncomingConnectionFilter connectionFilter) {
|
||||
_context = context;
|
||||
_session = session;
|
||||
_defaultOptions = defaultOptions;
|
||||
_connectionFilter = connectionFilter;
|
||||
_log = _context.logManager().getLog(ConnectionManager.class);
|
||||
_connectionByInboundId = new ConcurrentHashMap<Long,Connection>(32);
|
||||
_pendingPings = new ConcurrentHashMap<Long,PingRequest>(4);
|
||||
@ -655,6 +661,10 @@ class ConnectionManager {
|
||||
" per minute";
|
||||
}
|
||||
|
||||
if (!_connectionFilter.allowDestination(from)) {
|
||||
return "not allowed by filter";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
import net.i2p.client.streaming.IncomingConnectionFilter;
|
||||
import net.i2p.crypto.SigAlgo;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.Certificate;
|
||||
@ -191,7 +192,8 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
* @param opts may be null
|
||||
* @param name non-null
|
||||
*/
|
||||
public I2PSocketManagerFull(I2PAppContext context, I2PSession session, Properties opts, String name) {
|
||||
public I2PSocketManagerFull(I2PAppContext context, I2PSession session, Properties opts, String name,
|
||||
IncomingConnectionFilter connectionFilter) {
|
||||
_context = context;
|
||||
_session = session;
|
||||
_subsessions = new ConcurrentHashSet<I2PSession>(4);
|
||||
@ -200,7 +202,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
_name = name + " " + (__managerId.incrementAndGet());
|
||||
_acceptTimeout = ACCEPT_TIMEOUT_DEFAULT;
|
||||
_defaultOptions = new ConnectionOptions(opts);
|
||||
_connectionManager = new ConnectionManager(_context, _session, _defaultOptions);
|
||||
_connectionManager = new ConnectionManager(_context, _session, _defaultOptions, connectionFilter);
|
||||
_serverSocket = new I2PServerSocketFull(this);
|
||||
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
|
Reference in New Issue
Block a user