Hooks into streaming for filtering of incoming connections

This commit is contained in:
zab2
2019-03-26 15:34:15 +00:00
parent 64039ee3c2
commit a5e568ffa1
4 changed files with 243 additions and 20 deletions

View File

@@ -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,9 +117,26 @@ 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);
}
/**
* Create a socket manager using a brand new destination connected to the
* I2CP router on the given machine reachable through the given port.
@@ -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,14 +273,38 @@ 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;
}
}
}
/**
* Create a disconnected socket manager using the destination loaded from the given private key
* stream, or null for a transient destination.
@@ -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,9 +369,9 @@ public class I2PSocketManagerFactory {
}
myPrivateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
}
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false);
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false, filter);
}
/**
* 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
@@ -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);

View File

@@ -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;
}
};
}