2006-10-08 Complication

* Add a framed average peer clock skew calculator
    * Add config property "router.clockOffsetSanityCheck" to determine
      if NTP-suggested clock offsets get sanity checked (default "true")
    * Reject NTP-suggested clock offsets if they'd increase peer clock skew
      by more than 5 seconds, or make it more than 20 seconds total
    * Decrease log level in getMedianPeerClockSkew()
This commit is contained in:
complication
2006-10-08 22:52:59 +00:00
committed by zzz
parent 80b0c97d72
commit 73cf3fb299
5 changed files with 90 additions and 8 deletions

View File

@ -39,6 +39,12 @@ public abstract class CommSystemFacade implements Service {
*/
public Long getMedianPeerClockSkew() { return null; }
/**
* Return framed average clock skew of connected peers in seconds, or null if we cannot answer.
* CommSystemFacadeImpl overrides this.
*/
public Long getFramedAveragePeerClockSkew(int percentToInclude) { return null; }
/**
* Determine under what conditions we are remotely reachable.
*

View File

@ -31,9 +31,6 @@ public class RouterClock extends Clock {
*/
public void setOffset(long offsetMs, boolean force) {
// To test new routines, calculate median peer clock skew
Long medianPeerClockSkew = _context.commSystem().getMedianPeerClockSkew();
if (false) return;
long delta = offsetMs - _offset;
if (!force) {
@ -56,7 +53,36 @@ public class RouterClock extends Clock {
_alreadyChanged = true;
return;
}
// If so configured, check sanity of proposed clock offset
if (Boolean.valueOf(_context.getProperty("router.clockOffsetSanityCheck","true")).booleanValue() == true) {
// Try calculating peer clock skew
Long peerClockSkew = _context.commSystem().getFramedAveragePeerClockSkew(50);
if (peerClockSkew != null) {
// Predict the effect of applying the proposed clock offset
long currentPeerClockSkew = peerClockSkew.longValue();
long predictedPeerClockSkew = currentPeerClockSkew + (delta / 1000l);
// Fail sanity check if applying the offset would increase peer clock skew
if ((Math.abs(predictedPeerClockSkew) > (Math.abs(currentPeerClockSkew) + 5)) ||
(Math.abs(predictedPeerClockSkew) > 20)) {
getLog().error("Ignoring clock offset " + offsetMs + "ms (current " + _offset +
"ms) since it would increase peer clock skew from " + currentPeerClockSkew +
"s to " + predictedPeerClockSkew + "s. Broken server in pool.ntp.org?");
return;
} else {
getLog().debug("Approving clock offset " + offsetMs + "ms (current " + _offset +
"ms) since it would decrease peer clock skew from " + currentPeerClockSkew +
"s to " + predictedPeerClockSkew + "s.");
}
}
} // check sanity
}
if (_alreadyChanged) {
if (delta > 15*1000)
getLog().log(Log.CRIT, "Updating clock offset to " + offsetMs + "ms from " + _offset + "ms");

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.464 $ $Date: 2006-09-27 01:00:37 $";
public final static String ID = "$Revision: 1.465 $ $Date: 2006-09-29 18:54:17 $";
public final static String VERSION = "0.6.1.25";
public final static long BUILD = 11;
public final static long BUILD = 12;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -84,11 +84,53 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
Collections.sort(skews);
// Pick out median
Long medianPeerClockSkew = (Long) (skews.get(skews.size() / 2));
if (_log.shouldLog(Log.WARN))
_log.warn("Our median peer clock skew is " + medianPeerClockSkew + " s.");
if (_log.shouldLog(Log.INFO))
_log.info("Our median peer clock skew is " + medianPeerClockSkew + " s.");
return medianPeerClockSkew;
}
/**
* Framed average clock skew of connected peers in seconds, or null if we cannot answer.
* Average is calculated over the middle "percentToInclude" peers.
*/
public Long getFramedAveragePeerClockSkew(int percentToInclude) {
if (_manager == null) {
if (_log.shouldLog(Log.INFO))
_log.info("Returning null for framed averege peer clock skew (no transport manager)!");
return null;
}
Vector skews = _manager.getClockSkews();
if (skews == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Returning null for framed average peer clock skew (no data)!");
return null;
}
if (skews.size() < 5) {
if (_log.shouldLog(Log.ERROR))
_log.error("Returning null for framed average peer clock skew (only " + skews.size() + " peers)!");
return null;
}
// Going to calculate, sort them
Collections.sort(skews);
// Calculate frame size
int frameSize = (skews.size() * percentToInclude / 100);
int first = (skews.size() / 2) - (frameSize / 2);
int last = (skews.size() / 2) + (frameSize / 2);
// Sum skew values
long sum = 0;
for (int i = first; i < last; i++) {
long value = ((Long) (skews.get(i))).longValue();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Adding clock skew " + i + " valued " + value + " s.");
sum = sum + value;
}
// Calculate average
Long framedAverageClockSkew = new Long(sum / frameSize);
if (_log.shouldLog(Log.INFO))
_log.info("Our framed average peer clock skew is " + framedAverageClockSkew + " s.");
return framedAverageClockSkew;
}
public List getBids(OutNetMessage msg) {
return _manager.getBids(msg);
}