* I2CP: Implement optional reduce tunnels on idle - not hooked
in to i2ptunnel GUI yet - still needs tweaks
This commit is contained in:
@ -150,6 +150,10 @@ public class EditBean extends IndexBean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getCloseTime(int tunnel) {
|
||||||
|
return getProperty(tunnel, "closeIdleTime", 30);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getNewDest(int tunnel) {
|
public boolean getNewDest(int tunnel) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -289,9 +289,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="portField" class="rowItem">
|
<div id="portField" class="rowItem">
|
||||||
<label for="reduceTime" accesskey="c">
|
<label for="reduceTime" accesskey="c">
|
||||||
Reduce when idle (minutes):
|
Close when idle (minutes):
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="port" name="reduceTime" size="4" maxlength="4" title="Reduced Tunnel Idle Time" value="<%=editBean.getReduceTime(curTunnel)%>" class="freetext" />
|
<input type="text" id="port" name="closeTime" size="4" maxlength="4" title="Reduced Tunnel Idle Time" value="<%=editBean.getCloseTime(curTunnel)%>" class="freetext" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="subdivider">
|
<div class="subdivider">
|
||||||
|
@ -49,7 +49,9 @@ public class ConfigTunnelsHelper extends HelperBase {
|
|||||||
|
|
||||||
private static final int WARN_LENGTH = 4;
|
private static final int WARN_LENGTH = 4;
|
||||||
private static final int MAX_LENGTH = 4;
|
private static final int MAX_LENGTH = 4;
|
||||||
private static final int MAX_QUANTITY = 3;
|
private static final int WARN_QUANTITY = 5;
|
||||||
|
private static final int MAX_QUANTITY = 6;
|
||||||
|
private static final int MAX_BACKUP_QUANTITY = 3;
|
||||||
private static final int MAX_VARIANCE = 2;
|
private static final int MAX_VARIANCE = 2;
|
||||||
private static final int MIN_NEG_VARIANCE = -1;
|
private static final int MIN_NEG_VARIANCE = -1;
|
||||||
private void renderForm(StringBuffer buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
private void renderForm(StringBuffer buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
||||||
@ -64,6 +66,9 @@ public class ConfigTunnelsHelper extends HelperBase {
|
|||||||
if (in.getLength() + Math.abs(in.getLengthVariance()) >= WARN_LENGTH ||
|
if (in.getLength() + Math.abs(in.getLengthVariance()) >= WARN_LENGTH ||
|
||||||
out.getLength() + Math.abs(out.getLengthVariance()) >= WARN_LENGTH)
|
out.getLength() + Math.abs(out.getLengthVariance()) >= WARN_LENGTH)
|
||||||
buf.append("<tr><td colspan=\"3\"><font color=\"red\">PERFORMANCE WARNING - Settings include very long tunnels</font></td></tr>");
|
buf.append("<tr><td colspan=\"3\"><font color=\"red\">PERFORMANCE WARNING - Settings include very long tunnels</font></td></tr>");
|
||||||
|
if (in.getQuantity() + in.getBackupQuantity() >= WARN_QUANTITY ||
|
||||||
|
out.getQuantity() + out.getBackupQuantity() >= WARN_QUANTITY)
|
||||||
|
buf.append("<tr><td colspan=\"3\"><font color=\"red\">PERFORMANCE WARNING - Settings include high tunnel quantities</font></td></tr>");
|
||||||
|
|
||||||
|
|
||||||
buf.append("<tr><td></td><td><b>Inbound</b></td><td><b>Outbound</b></td></tr>\n");
|
buf.append("<tr><td></td><td><b>Inbound</b></td><td><b>Outbound</b></td></tr>\n");
|
||||||
@ -130,15 +135,15 @@ public class ConfigTunnelsHelper extends HelperBase {
|
|||||||
buf.append("<tr><td>Backup quantity</td>\n");
|
buf.append("<tr><td>Backup quantity</td>\n");
|
||||||
buf.append("<td><select name=\"").append(index).append(".backupInbound\">\n");
|
buf.append("<td><select name=\"").append(index).append(".backupInbound\">\n");
|
||||||
now = in.getBackupQuantity();
|
now = in.getBackupQuantity();
|
||||||
renderOptions(buf, 0, MAX_QUANTITY, now, "", "tunnel");
|
renderOptions(buf, 0, MAX_BACKUP_QUANTITY, now, "", "tunnel");
|
||||||
if (now > MAX_QUANTITY)
|
if (now > MAX_BACKUP_QUANTITY)
|
||||||
renderOptions(buf, now, now, now, "", "tunnel");
|
renderOptions(buf, now, now, now, "", "tunnel");
|
||||||
buf.append("</select></td>\n");
|
buf.append("</select></td>\n");
|
||||||
|
|
||||||
buf.append("<td><select name=\"").append(index).append(".backupOutbound\">\n");
|
buf.append("<td><select name=\"").append(index).append(".backupOutbound\">\n");
|
||||||
now = out.getBackupQuantity();
|
now = out.getBackupQuantity();
|
||||||
renderOptions(buf, 0, MAX_QUANTITY, now, "", "tunnel");
|
renderOptions(buf, 0, MAX_BACKUP_QUANTITY, now, "", "tunnel");
|
||||||
if (now > MAX_QUANTITY)
|
if (now > MAX_BACKUP_QUANTITY)
|
||||||
renderOptions(buf, now, now, now, "", "tunnel");
|
renderOptions(buf, now, now, now, "", "tunnel");
|
||||||
buf.append("</select></td>\n");
|
buf.append("</select></td>\n");
|
||||||
buf.append("</tr>\n");
|
buf.append("</tr>\n");
|
||||||
|
@ -10,6 +10,7 @@ package net.i2p.client;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
@ -27,6 +28,7 @@ import net.i2p.data.i2cp.CreateLeaseSetMessage;
|
|||||||
import net.i2p.data.i2cp.CreateSessionMessage;
|
import net.i2p.data.i2cp.CreateSessionMessage;
|
||||||
import net.i2p.data.i2cp.DestroySessionMessage;
|
import net.i2p.data.i2cp.DestroySessionMessage;
|
||||||
import net.i2p.data.i2cp.MessageId;
|
import net.i2p.data.i2cp.MessageId;
|
||||||
|
import net.i2p.data.i2cp.ReconfigureSessionMessage;
|
||||||
import net.i2p.data.i2cp.ReportAbuseMessage;
|
import net.i2p.data.i2cp.ReportAbuseMessage;
|
||||||
import net.i2p.data.i2cp.SendMessageMessage;
|
import net.i2p.data.i2cp.SendMessageMessage;
|
||||||
import net.i2p.data.i2cp.SendMessageExpiresMessage;
|
import net.i2p.data.i2cp.SendMessageExpiresMessage;
|
||||||
@ -188,4 +190,33 @@ class I2CPMessageProducer {
|
|||||||
msg.setSessionId(session.getSessionId());
|
msg.setSessionId(session.getSessionId());
|
||||||
session.sendMessage(msg);
|
session.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update number of tunnels
|
||||||
|
*
|
||||||
|
* @param tunnels 0 for original configured number
|
||||||
|
*/
|
||||||
|
public void updateTunnels(I2PSessionImpl session, int tunnels) throws I2PSessionException {
|
||||||
|
ReconfigureSessionMessage msg = new ReconfigureSessionMessage();
|
||||||
|
SessionConfig cfg = new SessionConfig(session.getMyDestination());
|
||||||
|
Properties props = session.getOptions();
|
||||||
|
if (tunnels > 0) {
|
||||||
|
Properties newprops = new Properties();
|
||||||
|
newprops.putAll(props);
|
||||||
|
props = newprops;
|
||||||
|
props.setProperty("inbound.quantity", "" + tunnels);
|
||||||
|
props.setProperty("outbound.quantity", "" + tunnels);
|
||||||
|
props.setProperty("inbound.backupQuantity", "0");
|
||||||
|
props.setProperty("outbound.backupQuantity", "0");
|
||||||
|
}
|
||||||
|
cfg.setOptions(props);
|
||||||
|
try {
|
||||||
|
cfg.signSessionConfig(session.getPrivateKey());
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
throw new I2PSessionException("Unable to sign the session config", dfe);
|
||||||
|
}
|
||||||
|
msg.setSessionConfig(cfg);
|
||||||
|
msg.setSessionId(session.getSessionId());
|
||||||
|
session.sendMessage(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,9 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
*/
|
*/
|
||||||
protected AvailabilityNotifier _availabilityNotifier;
|
protected AvailabilityNotifier _availabilityNotifier;
|
||||||
|
|
||||||
|
private long _lastActivity;
|
||||||
|
private boolean _isReduced;
|
||||||
|
|
||||||
void dateUpdated() {
|
void dateUpdated() {
|
||||||
_dateReceived = true;
|
_dateReceived = true;
|
||||||
synchronized (_dateReceivedLock) {
|
synchronized (_dateReceivedLock) {
|
||||||
@ -290,6 +293,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
_log.info(getPrefix() + "Lease set created with inbound tunnels after "
|
_log.info(getPrefix() + "Lease set created with inbound tunnels after "
|
||||||
+ (connected - startConnect)
|
+ (connected - startConnect)
|
||||||
+ "ms - ready to participate in the network!");
|
+ "ms - ready to participate in the network!");
|
||||||
|
startIdleMonitor();
|
||||||
} catch (UnknownHostException uhe) {
|
} catch (UnknownHostException uhe) {
|
||||||
_closed = true;
|
_closed = true;
|
||||||
throw new I2PSessionException(getPrefix() + "Invalid session configuration", uhe);
|
throw new I2PSessionException(getPrefix() + "Invalid session configuration", uhe);
|
||||||
@ -316,6 +320,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
_log.error("Receive message " + msgId + " had no matches, remaining=" + remaining);
|
_log.error("Receive message " + msgId + " had no matches, remaining=" + remaining);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
updateActivity();
|
||||||
return msg.getPayload().getUnencryptedData();
|
return msg.getPayload().getUnencryptedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,4 +673,34 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
public Destination lookupDest(Hash h) throws I2PSessionException {
|
public Destination lookupDest(Hash h) throws I2PSessionException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateActivity() {
|
||||||
|
_lastActivity = _context.clock().now();
|
||||||
|
if (_isReduced) {
|
||||||
|
_isReduced = false;
|
||||||
|
try {
|
||||||
|
_producer.updateTunnels(this, 0);
|
||||||
|
} catch (I2PSessionException ise) {
|
||||||
|
_log.error(getPrefix() + "bork restore from reduced");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long lastActivity() {
|
||||||
|
return _lastActivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReduced() {
|
||||||
|
_isReduced = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startIdleMonitor() {
|
||||||
|
_isReduced = false;
|
||||||
|
boolean reduce = Boolean.valueOf(_options.getProperty("i2cp.reduceOnIdle")).booleanValue();
|
||||||
|
boolean close = Boolean.valueOf(_options.getProperty("i2cp.closeOnIdle")).booleanValue();
|
||||||
|
if (reduce || close) {
|
||||||
|
updateActivity();
|
||||||
|
SimpleScheduler.getInstance().addEvent(new SessionIdleTimer(_context, this, reduce, close), SessionIdleTimer.MINIMUM_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
|||||||
throws I2PSessionException {
|
throws I2PSessionException {
|
||||||
if (_log.shouldLog(Log.DEBUG)) _log.debug("sending message");
|
if (_log.shouldLog(Log.DEBUG)) _log.debug("sending message");
|
||||||
if (isClosed()) throw new I2PSessionException("Already closed");
|
if (isClosed()) throw new I2PSessionException("Already closed");
|
||||||
|
updateActivity();
|
||||||
|
|
||||||
// Sadly there is no way to send something completely uncompressed in a backward-compatible way,
|
// Sadly there is no way to send something completely uncompressed in a backward-compatible way,
|
||||||
// so we have to still send it in a gzip format, which adds 23 bytes (2.4% for a 960-byte msg)
|
// so we have to still send it in a gzip format, which adds 23 bytes (2.4% for a 960-byte msg)
|
||||||
|
106
core/java/src/net/i2p/client/SessionIdleTimer.java
Normal file
106
core/java/src/net/i2p/client/SessionIdleTimer.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package net.i2p.client;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free (adj.): unencumbered; not under the control of others
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.SimpleScheduler;
|
||||||
|
import net.i2p.util.SimpleTimer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduce tunnels or shutdown the session on idle if so configured
|
||||||
|
*
|
||||||
|
* @author zzz
|
||||||
|
*/
|
||||||
|
public class SessionIdleTimer implements SimpleTimer.TimedEvent {
|
||||||
|
public static final long MINIMUM_TIME = 5*60*1000;
|
||||||
|
private static final long DEFAULT_REDUCE_TIME = 20*60*1000;
|
||||||
|
private static final long DEFAULT_CLOSE_TIME = 30*60*1000;
|
||||||
|
private final static Log _log = new Log(SessionIdleTimer.class);
|
||||||
|
private I2PAppContext _context;
|
||||||
|
private I2PSessionImpl _session;
|
||||||
|
private boolean _reduceEnabled;
|
||||||
|
private int _reduceQuantity;
|
||||||
|
private long _reduceTime;
|
||||||
|
private boolean _shutdownEnabled;
|
||||||
|
private long _shutdownTime;
|
||||||
|
private long _minimumTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reduce, shutdown, or both must be true
|
||||||
|
*/
|
||||||
|
public SessionIdleTimer(I2PAppContext context, I2PSessionImpl session, boolean reduce, boolean shutdown) {
|
||||||
|
_context = context;
|
||||||
|
_session = session;
|
||||||
|
_reduceEnabled = reduce;
|
||||||
|
_shutdownEnabled = shutdown;
|
||||||
|
if (! (reduce || shutdown))
|
||||||
|
throw new IllegalArgumentException("At least one must be enabled");
|
||||||
|
Properties props = session.getOptions();
|
||||||
|
_minimumTime = Long.MAX_VALUE;
|
||||||
|
if (reduce) {
|
||||||
|
_reduceQuantity = 1;
|
||||||
|
String p = props.getProperty("i2cp.reduceQuantity");
|
||||||
|
if (p != null) {
|
||||||
|
try {
|
||||||
|
_reduceQuantity = Math.max(Integer.parseInt(p), 1);
|
||||||
|
// also check vs. configured quantities?
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
_reduceTime = DEFAULT_REDUCE_TIME;
|
||||||
|
p = props.getProperty("i2cp.reduceTime");
|
||||||
|
if (p != null) {
|
||||||
|
try {
|
||||||
|
_reduceTime = Math.max(Long.parseLong(p), MINIMUM_TIME);
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
_minimumTime = _reduceTime;
|
||||||
|
}
|
||||||
|
if (shutdown) {
|
||||||
|
_shutdownTime = DEFAULT_CLOSE_TIME;
|
||||||
|
String p = props.getProperty("i2cp.closeTime");
|
||||||
|
if (p != null) {
|
||||||
|
try {
|
||||||
|
_shutdownTime = Math.max(Long.parseLong(p), MINIMUM_TIME);
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
_minimumTime = Math.min(_minimumTime, _shutdownTime);
|
||||||
|
if (reduce && _shutdownTime <= _reduceTime)
|
||||||
|
reduce = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void timeReached() {
|
||||||
|
if (_session.isClosed())
|
||||||
|
return;
|
||||||
|
long now = _context.clock().now();
|
||||||
|
long lastActivity = _session.lastActivity();
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Fire idle timer, last activity: " + DataHelper.formatDuration(now - lastActivity) + " ago ");
|
||||||
|
if (_shutdownEnabled && now - lastActivity >= _shutdownTime) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Closing on idle " + _session);
|
||||||
|
_session.destroySession();
|
||||||
|
} else if (_reduceEnabled && now - lastActivity >= _reduceTime) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Reducing quantity on idle " + _session);
|
||||||
|
try {
|
||||||
|
_session.getProducer().updateTunnels(_session, _reduceQuantity);
|
||||||
|
} catch (I2PSessionException ise) {
|
||||||
|
_log.error("bork idle reduction " + ise);
|
||||||
|
}
|
||||||
|
_session.setReduced();
|
||||||
|
if (_shutdownEnabled)
|
||||||
|
SimpleScheduler.getInstance().addEvent(this, _shutdownTime - (now - lastActivity));
|
||||||
|
// else sessionimpl must reschedule??
|
||||||
|
} else {
|
||||||
|
SimpleScheduler.getInstance().addEvent(this, _minimumTime - (now - lastActivity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -69,6 +69,8 @@ public class I2CPMessageHandler {
|
|||||||
return new ReceiveMessageBeginMessage();
|
return new ReceiveMessageBeginMessage();
|
||||||
case ReceiveMessageEndMessage.MESSAGE_TYPE:
|
case ReceiveMessageEndMessage.MESSAGE_TYPE:
|
||||||
return new ReceiveMessageEndMessage();
|
return new ReceiveMessageEndMessage();
|
||||||
|
case ReconfigureSessionMessage.MESSAGE_TYPE:
|
||||||
|
return new ReconfigureSessionMessage();
|
||||||
case ReportAbuseMessage.MESSAGE_TYPE:
|
case ReportAbuseMessage.MESSAGE_TYPE:
|
||||||
return new ReportAbuseMessage();
|
return new ReportAbuseMessage();
|
||||||
case RequestLeaseSetMessage.MESSAGE_TYPE:
|
case RequestLeaseSetMessage.MESSAGE_TYPE:
|
||||||
|
@ -8,6 +8,8 @@ package net.i2p.router.client;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.i2p.data.Payload;
|
import net.i2p.data.Payload;
|
||||||
import net.i2p.data.i2cp.CreateLeaseSetMessage;
|
import net.i2p.data.i2cp.CreateLeaseSetMessage;
|
||||||
import net.i2p.data.i2cp.CreateSessionMessage;
|
import net.i2p.data.i2cp.CreateSessionMessage;
|
||||||
@ -27,6 +29,7 @@ import net.i2p.data.i2cp.SendMessageExpiresMessage;
|
|||||||
import net.i2p.data.i2cp.SessionId;
|
import net.i2p.data.i2cp.SessionId;
|
||||||
import net.i2p.data.i2cp.SessionStatusMessage;
|
import net.i2p.data.i2cp.SessionStatusMessage;
|
||||||
import net.i2p.data.i2cp.SetDateMessage;
|
import net.i2p.data.i2cp.SetDateMessage;
|
||||||
|
import net.i2p.router.ClientTunnelSettings;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.RandomSource;
|
import net.i2p.util.RandomSource;
|
||||||
@ -87,6 +90,9 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
|||||||
case DestLookupMessage.MESSAGE_TYPE:
|
case DestLookupMessage.MESSAGE_TYPE:
|
||||||
handleDestLookup(reader, (DestLookupMessage)message);
|
handleDestLookup(reader, (DestLookupMessage)message);
|
||||||
break;
|
break;
|
||||||
|
case ReconfigureSessionMessage.MESSAGE_TYPE:
|
||||||
|
handleReconfigureSession(reader, (ReconfigureSessionMessage)message);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Unhandled I2CP type received: " + message.getType());
|
_log.error("Unhandled I2CP type received: " + message.getType());
|
||||||
@ -138,24 +144,13 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionStatusMessage msg = new SessionStatusMessage();
|
|
||||||
SessionId sessionId = new SessionId();
|
SessionId sessionId = new SessionId();
|
||||||
sessionId.setSessionId(getNextSessionId());
|
sessionId.setSessionId(getNextSessionId());
|
||||||
_runner.setSessionId(sessionId);
|
_runner.setSessionId(sessionId);
|
||||||
msg.setSessionId(sessionId);
|
sendStatusMessage(SessionStatusMessage.STATUS_CREATED);
|
||||||
msg.setStatus(SessionStatusMessage.STATUS_CREATED);
|
_runner.sessionEstablished(message.getSessionConfig());
|
||||||
try {
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
_log.debug("after sessionEstablished for " + message.getSessionConfig().getDestination().calculateHash().toBase64());
|
||||||
_log.debug("before sending sessionStatusMessage for " + message.getSessionConfig().getDestination().calculateHash().toBase64());
|
|
||||||
_runner.doSend(msg);
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("after sending sessionStatusMessage for " + message.getSessionConfig().getDestination().calculateHash().toBase64());
|
|
||||||
_runner.sessionEstablished(message.getSessionConfig());
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("after sessionEstablished for " + message.getSessionConfig().getDestination().calculateHash().toBase64());
|
|
||||||
} catch (I2CPMessageException ime) {
|
|
||||||
_log.error("Error writing out the session status message", ime);
|
|
||||||
}
|
|
||||||
|
|
||||||
_context.jobQueue().addJob(new CreateSessionJob(_context, _runner));
|
_context.jobQueue().addJob(new CreateSessionJob(_context, _runner));
|
||||||
}
|
}
|
||||||
@ -249,8 +244,34 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
|||||||
*/
|
*/
|
||||||
private void handleReconfigureSession(I2CPMessageReader reader, ReconfigureSessionMessage message) {
|
private void handleReconfigureSession(I2CPMessageReader reader, ReconfigureSessionMessage message) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Updating options - session " + _runner.getSessionId());
|
_log.info("Updating options - old: " + _runner.getConfig() + " new: " + message.getSessionConfig());
|
||||||
|
if (!message.getSessionConfig().getDestination().equals(_runner.getConfig().getDestination())) {
|
||||||
|
_log.error("Dest mismatch");
|
||||||
|
sendStatusMessage(SessionStatusMessage.STATUS_INVALID);
|
||||||
|
_runner.stopRunning();
|
||||||
|
return;
|
||||||
|
}
|
||||||
_runner.getConfig().getOptions().putAll(message.getSessionConfig().getOptions());
|
_runner.getConfig().getOptions().putAll(message.getSessionConfig().getOptions());
|
||||||
|
ClientTunnelSettings settings = new ClientTunnelSettings();
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.putAll(_runner.getConfig().getOptions());
|
||||||
|
settings.readFromProperties(props);
|
||||||
|
_context.tunnelManager().setInboundSettings(_runner.getConfig().getDestination().calculateHash(),
|
||||||
|
settings.getInboundSettings());
|
||||||
|
_context.tunnelManager().setOutboundSettings(_runner.getConfig().getDestination().calculateHash(),
|
||||||
|
settings.getOutboundSettings());
|
||||||
|
sendStatusMessage(SessionStatusMessage.STATUS_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendStatusMessage(int status) {
|
||||||
|
SessionStatusMessage msg = new SessionStatusMessage();
|
||||||
|
msg.setSessionId(_runner.getSessionId());
|
||||||
|
msg.setStatus(status);
|
||||||
|
try {
|
||||||
|
_runner.doSend(msg);
|
||||||
|
} catch (I2CPMessageException ime) {
|
||||||
|
_log.error("Error writing out the session status message", ime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this *should* be mod 65536, but UnsignedInteger is still b0rked. FIXME
|
// this *should* be mod 65536, but UnsignedInteger is still b0rked. FIXME
|
||||||
|
Reference in New Issue
Block a user