From 7179a64feea93bf06f0fa0058eeb0b55e8f1f944 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 9 Mar 2009 15:11:45 +0000 Subject: [PATCH] I2PTunnel: Add delay-open option for clients --- .../i2p/i2ptunnel/I2PTunnelClientBase.java | 48 ++++++++++++------- .../src/net/i2p/i2ptunnel/web/EditBean.java | 4 ++ .../src/net/i2p/i2ptunnel/web/IndexBean.java | 5 +- apps/i2ptunnel/jsp/editClient.jsp | 16 +++++++ 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index 1b308eb37..94bc959c0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -126,26 +126,28 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna // be looked up tunnel.getClientOptions().setProperty("i2cp.dontPublishLeaseSet", "true"); - while (sockMgr == null) { - synchronized (sockLock) { - if (ownDest) { - sockMgr = buildSocketManager(); - } else { - sockMgr = getSocketManager(); + boolean openNow = !Boolean.valueOf(tunnel.getClientOptions().getProperty("i2cp.delayOpen")).booleanValue(); + if (openNow) { + while (sockMgr == null) { + synchronized (sockLock) { + if (ownDest) { + sockMgr = buildSocketManager(); + } else { + sockMgr = getSocketManager(); + } + } + if (sockMgr == null) { + _log.log(Log.CRIT, "Unable to create socket manager (our own? " + ownDest + ")"); + try { Thread.sleep(10*1000); } catch (InterruptedException ie) {} } } if (sockMgr == null) { - _log.log(Log.CRIT, "Unable to create socket manager (our own? " + ownDest + ")"); - try { Thread.sleep(10*1000); } catch (InterruptedException ie) {} + l.log("Invalid I2CP configuration"); + throw new IllegalArgumentException("Socket manager could not be created"); } - } - if (sockMgr == null) { - l.log("Invalid I2CP configuration"); - throw new IllegalArgumentException("Socket manager could not be created"); - } - l.log("I2P session created"); + l.log("I2P session created"); - getTunnel().addSession(sockMgr.getSession()); + } // else delay creating session until createI2PSocket() is called Thread t = new I2PThread(this); t.setName("Client " + _clientId); @@ -165,7 +167,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna configurePool(tunnel); if (open && listenerReady) { - l.log("Ready! Port " + getLocalPort()); + if (openNow) + l.log("Ready! Port " + getLocalPort()); + else + l.log("Listening on port " + getLocalPort() + ", delaying tunnel open until required"); notifyEvent("openBaseClientResult", "ok"); } else { l.log("Error listening - please see the logs!"); @@ -217,6 +222,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna I2PSession s = socketManager.getSession(); if ( (s == null) || (s.isClosed()) ) { _log.info("Building a new socket manager since the old one closed [s=" + s + "]"); + if (s != null) + tunnel.removeSession(s); socketManager = buildSocketManager(tunnel, pkf); } else { _log.info("Not building a new socket manager since the old one is open [s=" + s + "]"); @@ -335,6 +342,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna * @return a new I2PSocket */ public I2PSocket createI2PSocket(Destination dest) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException { + if (sockMgr == null) { + // we need this before getDefaultOptions() + sockMgr = getSocketManager(); + } return createI2PSocket(dest, getDefaultOptions()); } @@ -355,7 +366,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna public I2PSocket createI2PSocket(Destination dest, I2PSocketOptions opt) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException { I2PSocket i2ps; - if (Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) { + if (sockMgr == null) { + // delayed open - call get instead of build because the locking is up there + sockMgr = getSocketManager(); + } else if (Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) { synchronized(sockMgr) { I2PSocketManager oldSockMgr = sockMgr; // This will build a new socket manager and a new dest if the session is closed. diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index 941edd0bd..004114b56 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -161,6 +161,10 @@ public class EditBean extends IndexBean { return getBooleanProperty(tunnel, "persistentClientKey"); } + public boolean getDelayOpen(int tunnel) { + return getBooleanProperty(tunnel, "i2cp.delayOpen"); + } + private int getProperty(int tunnel, String prop, int def) { TunnelController tun = getController(tunnel); if (tun != null) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index cc1c0d558..fcf45d94d 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -614,6 +614,9 @@ public class IndexBean { public void setAccess(String moo) { _booleanOptions.add("i2cp.enableAccessList"); } + public void setDelayOpen(String moo) { + _booleanOptions.add("i2cp.delayOpen"); + } public void setNewDest(String val) { if ("1".equals(val)) _booleanOptions.add("i2cp.newDestOnResume"); @@ -820,7 +823,7 @@ public class IndexBean { "inbound.nickname", "outbound.nickname", "i2p.streaming.connectDelay", "i2p.streaming.maxWindowSize" }; private static final String _booleanClientOpts[] = { - "i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey" + "i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen" }; private static final String _booleanServerOpts[] = { "i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", "i2cp.enableAccessList" diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index 178f564ef..d20c9f58d 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -351,6 +351,22 @@
+
+ +
+
+ + class="tickbox" /> +
+ +
+
+
+ <% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType)) { %>