I2PTunnel: Add delay-open option for clients
This commit is contained in:
@ -126,26 +126,28 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
// be looked up
|
// be looked up
|
||||||
tunnel.getClientOptions().setProperty("i2cp.dontPublishLeaseSet", "true");
|
tunnel.getClientOptions().setProperty("i2cp.dontPublishLeaseSet", "true");
|
||||||
|
|
||||||
while (sockMgr == null) {
|
boolean openNow = !Boolean.valueOf(tunnel.getClientOptions().getProperty("i2cp.delayOpen")).booleanValue();
|
||||||
synchronized (sockLock) {
|
if (openNow) {
|
||||||
if (ownDest) {
|
while (sockMgr == null) {
|
||||||
sockMgr = buildSocketManager();
|
synchronized (sockLock) {
|
||||||
} else {
|
if (ownDest) {
|
||||||
sockMgr = getSocketManager();
|
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) {
|
if (sockMgr == null) {
|
||||||
_log.log(Log.CRIT, "Unable to create socket manager (our own? " + ownDest + ")");
|
l.log("Invalid I2CP configuration");
|
||||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
throw new IllegalArgumentException("Socket manager could not be created");
|
||||||
}
|
}
|
||||||
}
|
l.log("I2P session created");
|
||||||
if (sockMgr == null) {
|
|
||||||
l.log("Invalid I2CP configuration");
|
|
||||||
throw new IllegalArgumentException("Socket manager could not be created");
|
|
||||||
}
|
|
||||||
l.log("I2P session created");
|
|
||||||
|
|
||||||
getTunnel().addSession(sockMgr.getSession());
|
} // else delay creating session until createI2PSocket() is called
|
||||||
|
|
||||||
Thread t = new I2PThread(this);
|
Thread t = new I2PThread(this);
|
||||||
t.setName("Client " + _clientId);
|
t.setName("Client " + _clientId);
|
||||||
@ -165,7 +167,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
configurePool(tunnel);
|
configurePool(tunnel);
|
||||||
|
|
||||||
if (open && listenerReady) {
|
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");
|
notifyEvent("openBaseClientResult", "ok");
|
||||||
} else {
|
} else {
|
||||||
l.log("Error listening - please see the logs!");
|
l.log("Error listening - please see the logs!");
|
||||||
@ -217,6 +222,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
I2PSession s = socketManager.getSession();
|
I2PSession s = socketManager.getSession();
|
||||||
if ( (s == null) || (s.isClosed()) ) {
|
if ( (s == null) || (s.isClosed()) ) {
|
||||||
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
|
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
|
||||||
|
if (s != null)
|
||||||
|
tunnel.removeSession(s);
|
||||||
socketManager = buildSocketManager(tunnel, pkf);
|
socketManager = buildSocketManager(tunnel, pkf);
|
||||||
} else {
|
} else {
|
||||||
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
|
_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
|
* @return a new I2PSocket
|
||||||
*/
|
*/
|
||||||
public I2PSocket createI2PSocket(Destination dest) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
|
public I2PSocket createI2PSocket(Destination dest) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
|
||||||
|
if (sockMgr == null) {
|
||||||
|
// we need this before getDefaultOptions()
|
||||||
|
sockMgr = getSocketManager();
|
||||||
|
}
|
||||||
return createI2PSocket(dest, getDefaultOptions());
|
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 {
|
public I2PSocket createI2PSocket(Destination dest, I2PSocketOptions opt) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
|
||||||
I2PSocket i2ps;
|
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) {
|
synchronized(sockMgr) {
|
||||||
I2PSocketManager oldSockMgr = sockMgr;
|
I2PSocketManager oldSockMgr = sockMgr;
|
||||||
// This will build a new socket manager and a new dest if the session is closed.
|
// This will build a new socket manager and a new dest if the session is closed.
|
||||||
|
@ -161,6 +161,10 @@ public class EditBean extends IndexBean {
|
|||||||
return getBooleanProperty(tunnel, "persistentClientKey");
|
return getBooleanProperty(tunnel, "persistentClientKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDelayOpen(int tunnel) {
|
||||||
|
return getBooleanProperty(tunnel, "i2cp.delayOpen");
|
||||||
|
}
|
||||||
|
|
||||||
private int getProperty(int tunnel, String prop, int def) {
|
private int getProperty(int tunnel, String prop, int def) {
|
||||||
TunnelController tun = getController(tunnel);
|
TunnelController tun = getController(tunnel);
|
||||||
if (tun != null) {
|
if (tun != null) {
|
||||||
|
@ -614,6 +614,9 @@ public class IndexBean {
|
|||||||
public void setAccess(String moo) {
|
public void setAccess(String moo) {
|
||||||
_booleanOptions.add("i2cp.enableAccessList");
|
_booleanOptions.add("i2cp.enableAccessList");
|
||||||
}
|
}
|
||||||
|
public void setDelayOpen(String moo) {
|
||||||
|
_booleanOptions.add("i2cp.delayOpen");
|
||||||
|
}
|
||||||
public void setNewDest(String val) {
|
public void setNewDest(String val) {
|
||||||
if ("1".equals(val))
|
if ("1".equals(val))
|
||||||
_booleanOptions.add("i2cp.newDestOnResume");
|
_booleanOptions.add("i2cp.newDestOnResume");
|
||||||
@ -820,7 +823,7 @@ public class IndexBean {
|
|||||||
"inbound.nickname", "outbound.nickname", "i2p.streaming.connectDelay", "i2p.streaming.maxWindowSize"
|
"inbound.nickname", "outbound.nickname", "i2p.streaming.connectDelay", "i2p.streaming.maxWindowSize"
|
||||||
};
|
};
|
||||||
private static final String _booleanClientOpts[] = {
|
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[] = {
|
private static final String _booleanServerOpts[] = {
|
||||||
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", "i2cp.enableAccessList"
|
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", "i2cp.enableAccessList"
|
||||||
|
@ -351,6 +351,22 @@
|
|||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="optionsField" class="rowItem">
|
||||||
|
<label for="reduce" accesskey="c">
|
||||||
|
<span class="accessKey">D</span>elay tunnel open until required:
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="portField" class="rowItem">
|
||||||
|
<label for="access" accesskey="c">
|
||||||
|
Enable:
|
||||||
|
</label>
|
||||||
|
<input value="1" type="checkbox" id="startOnLoad" name="delayOpen" title="Delay Tunnel Open"<%=(editBean.getDelayOpen(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="subdivider">
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
|
||||||
<% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType)) { %>
|
<% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType)) { %>
|
||||||
<div id="optionsField" class="rowItem">
|
<div id="optionsField" class="rowItem">
|
||||||
<label for="privKeyFile" accesskey="k">
|
<label for="privKeyFile" accesskey="k">
|
||||||
|
Reference in New Issue
Block a user