forked from I2P_Developers/i2p.i2p
Util: New getEstimatedDowntime() method
This commit is contained in:
@ -1006,4 +1006,22 @@ public class I2PAppContext {
|
|||||||
public ClientAppManager clientAppManager() {
|
public ClientAppManager clientAppManager() {
|
||||||
return _appManager;
|
return _appManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long this router was down before it started, or 0 if unknown.
|
||||||
|
*
|
||||||
|
* This may be used for a determination of whether to regenerate keys, for example.
|
||||||
|
* We use the timestamp of the previous ping file left behind on crash,
|
||||||
|
* as set by isOnlyRouterRunning(), if present.
|
||||||
|
* Otherwise, the last STOPPED entry in the event log.
|
||||||
|
*
|
||||||
|
* May take a while to run the first time, if it has to go through the event log.
|
||||||
|
* Once called, the result is cached.
|
||||||
|
*
|
||||||
|
* @return 0 always in app context
|
||||||
|
* @since 0.0.47
|
||||||
|
*/
|
||||||
|
public long getEstimatedDowntime() {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
|||||||
private boolean _familyKeyCryptoFail;
|
private boolean _familyKeyCryptoFail;
|
||||||
public final Object _familyKeyLock = new Object();
|
public final Object _familyKeyLock = new Object();
|
||||||
private UPnPScannerCallback _upnpScannerCallback;
|
private UPnPScannerCallback _upnpScannerCallback;
|
||||||
|
private long _downtime = -1;
|
||||||
|
|
||||||
public final static String PROP_CONFIG_FILE = "router.configLocation";
|
public final static String PROP_CONFIG_FILE = "router.configLocation";
|
||||||
|
|
||||||
@ -711,7 +712,8 @@ public class Router implements RouterClock.ClockShiftListener {
|
|||||||
synchronized(_configFileLock) {
|
synchronized(_configFileLock) {
|
||||||
// persistent key for peer ordering since 0.9.17
|
// persistent key for peer ordering since 0.9.17
|
||||||
// These will be replaced in CreateRouterInfoJob if we rekey
|
// These will be replaced in CreateRouterInfoJob if we rekey
|
||||||
if (!_config.containsKey(PROP_IB_RANDOM_KEY)) {
|
if (!_config.containsKey(PROP_IB_RANDOM_KEY) ||
|
||||||
|
getEstimatedDowntime() > 12*60*60*1000L) {
|
||||||
byte rk[] = new byte[32];
|
byte rk[] = new byte[32];
|
||||||
_context.random().nextBytes(rk);
|
_context.random().nextBytes(rk);
|
||||||
_config.put(PROP_IB_RANDOM_KEY, Base64.encode(rk));
|
_config.put(PROP_IB_RANDOM_KEY, Base64.encode(rk));
|
||||||
@ -1809,6 +1811,9 @@ public class Router implements RouterClock.ClockShiftListener {
|
|||||||
((RouterClock) _context.clock()).removeShiftListener(this);
|
((RouterClock) _context.clock()).removeShiftListener(this);
|
||||||
// Let's not stop accepting tunnels, etc
|
// Let's not stop accepting tunnels, etc
|
||||||
//_started = _context.clock().now();
|
//_started = _context.clock().now();
|
||||||
|
synchronized(_configFileLock) {
|
||||||
|
_downtime = 1;
|
||||||
|
}
|
||||||
Thread t = new I2PThread(new Restarter(_context), "Router Restart");
|
Thread t = new I2PThread(new Restarter(_context), "Router Restart");
|
||||||
t.setPriority(Thread.NORM_PRIORITY + 1);
|
t.setPriority(Thread.NORM_PRIORITY + 1);
|
||||||
t.start();
|
t.start();
|
||||||
@ -1915,7 +1920,12 @@ public class Router implements RouterClock.ClockShiftListener {
|
|||||||
File f = getPingFile();
|
File f = getPingFile();
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
long lastWritten = f.lastModified();
|
long lastWritten = f.lastModified();
|
||||||
if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) {
|
long downtime = System.currentTimeMillis() - lastWritten;
|
||||||
|
synchronized(_configFileLock) {
|
||||||
|
if (downtime > 0 && _downtime < 0)
|
||||||
|
_downtime = downtime;
|
||||||
|
}
|
||||||
|
if (downtime > LIVELINESS_DELAY) {
|
||||||
System.err.println("WARN: Old router was not shut down gracefully, deleting " + f);
|
System.err.println("WARN: Old router was not shut down gracefully, deleting " + f);
|
||||||
f.delete();
|
f.delete();
|
||||||
} else {
|
} else {
|
||||||
@ -1934,6 +1944,49 @@ public class Router implements RouterClock.ClockShiftListener {
|
|||||||
_context.simpleTimer2().addPeriodicEvent(new MarkLiveliness(this, f), 0, LIVELINESS_DELAY - (5*1000));
|
_context.simpleTimer2().addPeriodicEvent(new MarkLiveliness(this, f), 0, LIVELINESS_DELAY - (5*1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long this router was down before it started, or 0 if unknown.
|
||||||
|
*
|
||||||
|
* This may be used for a determination of whether to regenerate keys, for example.
|
||||||
|
* We use the timestamp of the previous ping file left behind on crash,
|
||||||
|
* as set by isOnlyRouterRunning(), if present.
|
||||||
|
* Otherwise, the last STOPPED entry in the event log.
|
||||||
|
*
|
||||||
|
* May take a while to run the first time, if it has to go through the event log.
|
||||||
|
* Once called, the result is cached.
|
||||||
|
*
|
||||||
|
* @since 0.0.47
|
||||||
|
*/
|
||||||
|
public long getEstimatedDowntime() {
|
||||||
|
synchronized(_configFileLock) {
|
||||||
|
if (_downtime >= 0)
|
||||||
|
return _downtime;
|
||||||
|
long begin = System.currentTimeMillis();
|
||||||
|
long stopped = _eventLog.getLastEvent(EventLog.STOPPED, _context.clock().now() - 365*24*60*60*1000L);
|
||||||
|
long downtime = stopped > 0 ? _started - stopped : 0;
|
||||||
|
if (downtime < 0)
|
||||||
|
downtime = 0;
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn("Downtime was " + DataHelper.formatDuration(downtime) +
|
||||||
|
"; calculation took " + DataHelper.formatDuration(System.currentTimeMillis() - begin));
|
||||||
|
_downtime = downtime;
|
||||||
|
return downtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only for soft restart. Not for external use.
|
||||||
|
*
|
||||||
|
* @since 0.0.47
|
||||||
|
*/
|
||||||
|
public void setEstimatedDowntime(long downtime) {
|
||||||
|
if (downtime <= 0)
|
||||||
|
downtime = 1;
|
||||||
|
synchronized(_configFileLock) {
|
||||||
|
_downtime = downtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final String PROP_BANDWIDTH_SHARE_PERCENTAGE = "router.sharePercentage";
|
public static final String PROP_BANDWIDTH_SHARE_PERCENTAGE = "router.sharePercentage";
|
||||||
public static final int DEFAULT_SHARE_PERCENTAGE = 80;
|
public static final int DEFAULT_SHARE_PERCENTAGE = 80;
|
||||||
|
|
||||||
|
@ -706,4 +706,24 @@ public class RouterContext extends I2PAppContext {
|
|||||||
public ECIESAEADEngine eciesEngine() {
|
public ECIESAEADEngine eciesEngine() {
|
||||||
return _eciesEngine;
|
return _eciesEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long this router was down before it started, or 0 if unknown.
|
||||||
|
*
|
||||||
|
* This may be used for a determination of whether to regenerate keys, for example.
|
||||||
|
* We use the timestamp of the previous ping file left behind on crash,
|
||||||
|
* as set by isOnlyRouterRunning(), if present.
|
||||||
|
* Otherwise, the last STOPPED entry in the event log.
|
||||||
|
*
|
||||||
|
* May take a while to run the first time, if it has to go through the event log.
|
||||||
|
* Once called, the result is cached.
|
||||||
|
*
|
||||||
|
* @return downtime in ms or 0 if unknown
|
||||||
|
* @since 0.0.47
|
||||||
|
*/
|
||||||
|
public long getEstimatedDowntime() {
|
||||||
|
if (_router == null)
|
||||||
|
return 0L;
|
||||||
|
return _router.getEstimatedDowntime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ public class Restarter implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Long start = System.currentTimeMillis();
|
||||||
_context.router().eventLog().addEvent(EventLog.SOFT_RESTART);
|
_context.router().eventLog().addEvent(EventLog.SOFT_RESTART);
|
||||||
Log log = _context.logManager().getLog(Router.class);
|
Log log = _context.logManager().getLog(Router.class);
|
||||||
log.error("Stopping the router for a restart...");
|
log.error("Stopping the router for a restart...");
|
||||||
@ -36,6 +37,7 @@ public class Restarter implements Runnable {
|
|||||||
|
|
||||||
log.logAlways(Log.WARN, "Router teardown complete, restarting the router...");
|
log.logAlways(Log.WARN, "Router teardown complete, restarting the router...");
|
||||||
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||||
|
_context.router().setEstimatedDowntime(System.currentTimeMillis() - start);
|
||||||
|
|
||||||
log.logAlways(Log.WARN, "Restarting the comm system");
|
log.logAlways(Log.WARN, "Restarting the comm system");
|
||||||
log.logAlways(Log.WARN, "Restarting the tunnel manager");
|
log.logAlways(Log.WARN, "Restarting the tunnel manager");
|
||||||
|
@ -252,12 +252,7 @@ public class NTCPTransport extends TransportImpl {
|
|||||||
String b64IV = null;
|
String b64IV = null;
|
||||||
String s = null;
|
String s = null;
|
||||||
// try to determine if we've been down for 30 days or more
|
// try to determine if we've been down for 30 days or more
|
||||||
// no stopping, no crashes, and only one start (this one)
|
boolean shouldRekey = _context.getEstimatedDowntime() >= MIN_DOWNTIME_TO_REKEY;
|
||||||
EventLog el = _context.router().eventLog();
|
|
||||||
long since = _context.clock().now() - MIN_DOWNTIME_TO_REKEY;
|
|
||||||
boolean shouldRekey = el.getEvents(EventLog.STOPPED, since).isEmpty() &&
|
|
||||||
el.getEvents(EventLog.CRASHED, since).isEmpty() &&
|
|
||||||
el.getEvents(EventLog.STARTED, since).size() <= 1;
|
|
||||||
if (!shouldRekey) {
|
if (!shouldRekey) {
|
||||||
s = ctx.getProperty(PROP_NTCP2_SP);
|
s = ctx.getProperty(PROP_NTCP2_SP);
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
|
@ -190,4 +190,40 @@ public class EventLog {
|
|||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timestamp of last event.
|
||||||
|
*
|
||||||
|
* @param event matching this event, case sensitive
|
||||||
|
* @param since since this time, 0 for all
|
||||||
|
* @return last event time, or 0 for none
|
||||||
|
* @since 0.9.47
|
||||||
|
*/
|
||||||
|
public synchronized long getLastEvent(String event, long since) {
|
||||||
|
long rv = 0;
|
||||||
|
BufferedReader br = null;
|
||||||
|
try {
|
||||||
|
br = new BufferedReader(new InputStreamReader(
|
||||||
|
new FileInputStream(_file), "UTF-8"));
|
||||||
|
String line = null;
|
||||||
|
while ( (line = br.readLine()) != null) {
|
||||||
|
try {
|
||||||
|
String[] s = DataHelper.split(line.trim(), " ", 3);
|
||||||
|
if (s.length < 2)
|
||||||
|
continue;
|
||||||
|
if (!s[1].equals(event))
|
||||||
|
continue;
|
||||||
|
long time = Long.parseLong(s[0]);
|
||||||
|
if (time <= since)
|
||||||
|
continue;
|
||||||
|
rv = time;
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
} finally {
|
||||||
|
if (br != null) try { br.close(); } catch (IOException ioe) {}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user