forked from I2P_Developers/i2p.i2p
* I2CP/I2PTunnel locking fixes (partial fixes for tickets 650. 815, 946, 947, 953):
- I2PSocketManagerFactory: New createDisconnectedManager(), javadocs
- I2PSessionImpl: Rewrite state management and locking, prevent multiple
connect() calls, but allow disconnect() to interrupt connect()
- I2PSimpleSession: Changes to match I2PSessionImpl
- I2PTunnelServer: Don't connect in constructor, use createDisconnectedManager()
for a final manager, finals and cleanups
Lightly tested.
Todo: I2PTunnelClientBase
This commit is contained in:
@@ -26,7 +26,6 @@ import net.i2p.util.Log;
|
||||
public class I2PSocketManagerFactory {
|
||||
|
||||
public static final String PROP_MANAGER = "i2p.streaming.manager";
|
||||
//public static final String DEFAULT_MANAGER = "net.i2p.client.streaming.I2PSocketManagerImpl";
|
||||
public static final String DEFAULT_MANAGER = "net.i2p.client.streaming.I2PSocketManagerFull";
|
||||
|
||||
/**
|
||||
@@ -47,7 +46,7 @@ public class I2PSocketManagerFactory {
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param opts I2CP options
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(Properties opts) {
|
||||
@@ -60,8 +59,8 @@ public class I2PSocketManagerFactory {
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param host I2CP host
|
||||
* @param port I2CP port
|
||||
* @param host I2CP host null to use default
|
||||
* @param port I2CP port <= 0 to use default
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String host, int port) {
|
||||
@@ -74,9 +73,9 @@ public class I2PSocketManagerFactory {
|
||||
*
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param i2cpHost I2CP host
|
||||
* @param i2cpPort I2CP port
|
||||
* @param opts I2CP options
|
||||
* @param i2cpHost I2CP host null to use default
|
||||
* @param i2cpPort I2CP port <= 0 to use default
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(String i2cpHost, int i2cpPort, Properties opts) {
|
||||
@@ -102,6 +101,7 @@ public class I2PSocketManagerFactory {
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream) {
|
||||
@@ -115,7 +115,8 @@ public class I2PSocketManagerFactory {
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* @param opts I2CP options
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream, Properties opts) {
|
||||
@@ -130,13 +131,73 @@ public class I2PSocketManagerFactory {
|
||||
* Blocks for a long time while the router builds tunnels.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* @param i2cpHost I2CP host
|
||||
* @param i2cpPort I2CP port
|
||||
* @param opts I2CP options
|
||||
* or null for a transient destination. Caller must close.
|
||||
* @param i2cpHost I2CP host null to use default
|
||||
* @param i2cpPort I2CP port <= 0 to use default
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @return the newly created socket manager, or null if there were errors
|
||||
*/
|
||||
public static I2PSocketManager createManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort,
|
||||
Properties opts) {
|
||||
try {
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, true);
|
||||
} 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.
|
||||
*
|
||||
* 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
|
||||
* @param i2cpPort I2CP port <= 0 to use default
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @return the newly created socket manager, non-null (throws on error)
|
||||
* @since 0.9.8
|
||||
*/
|
||||
public static I2PSocketManager createDisconnectedManager(InputStream myPrivateKeyStream, String i2cpHost,
|
||||
int i2cpPort, Properties opts) throws I2PSessionException {
|
||||
if (myPrivateKeyStream == null) {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
client.createDestination(keyStream);
|
||||
} catch (Exception e) {
|
||||
throw new I2PSessionException("Error creating keys", e);
|
||||
}
|
||||
myPrivateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
|
||||
}
|
||||
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 if connect is true.
|
||||
*
|
||||
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
|
||||
* non-null. Caller must close.
|
||||
* @param i2cpHost I2CP host null to use default
|
||||
* @param i2cpPort I2CP port <= 0 to use default
|
||||
* @param opts Streaming and I2CP options, may be null
|
||||
* @param connect true to connect (blocking)
|
||||
* @return the newly created socket manager, non-null (throws on error)
|
||||
* @since 0.9.7
|
||||
*/
|
||||
private static I2PSocketManager createManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort,
|
||||
Properties opts, boolean connect) throws I2PSessionException {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
if (opts == null)
|
||||
opts = new Properties();
|
||||
@@ -146,34 +207,20 @@ public class I2PSocketManagerFactory {
|
||||
if (!opts.containsKey(name))
|
||||
opts.setProperty(name, (String) e.getValue());
|
||||
}
|
||||
//boolean oldLib = DEFAULT_MANAGER.equals(opts.getProperty(PROP_MANAGER, DEFAULT_MANAGER));
|
||||
//if (oldLib && false) {
|
||||
// for the old streaming lib
|
||||
// opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_GUARANTEED);
|
||||
//opts.setProperty("tunnels.depthInbound", "0");
|
||||
//} else {
|
||||
// for new streaming lib:
|
||||
//opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
|
||||
// as of 0.8.1 (I2CP default is BestEffort)
|
||||
if (!opts.containsKey(I2PClient.PROP_RELIABILITY))
|
||||
opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
|
||||
//p.setProperty("tunnels.depthInbound", "0");
|
||||
//}
|
||||
// as of 0.8.1 (I2CP default is BestEffort)
|
||||
if (!opts.containsKey(I2PClient.PROP_RELIABILITY))
|
||||
opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
|
||||
|
||||
if (i2cpHost != null)
|
||||
opts.setProperty(I2PClient.PROP_TCP_HOST, i2cpHost);
|
||||
if (i2cpPort > 0)
|
||||
opts.setProperty(I2PClient.PROP_TCP_PORT, "" + i2cpPort);
|
||||
|
||||
try {
|
||||
I2PSession session = client.createSession(myPrivateKeyStream, opts);
|
||||
I2PSession session = client.createSession(myPrivateKeyStream, opts);
|
||||
if (connect)
|
||||
session.connect();
|
||||
I2PSocketManager sockMgr = createManager(session, opts, "manager");
|
||||
return sockMgr;
|
||||
} catch (I2PSessionException ise) {
|
||||
getLog().error("Error creating session for socket manager", ise);
|
||||
return null;
|
||||
}
|
||||
I2PSocketManager sockMgr = createManager(session, opts, "manager");
|
||||
return sockMgr;
|
||||
}
|
||||
|
||||
private static I2PSocketManager createManager(I2PSession session, Properties opts, String name) {
|
||||
|
||||
Reference in New Issue
Block a user