diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java index eca8162bb..d81dcc855 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java @@ -16,6 +16,7 @@ import java.text.DecimalFormat; // debug import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -187,7 +188,8 @@ public class NetDbRenderer { FloodfillNetworkDatabaseFacade netdb = (FloodfillNetworkDatabaseFacade)_context.netDb(); buf.append("
Total Leasesets: ").append(leases.size()); buf.append("
Published (RAP) Leasesets: ").append(netdb.getKnownLeaseSets()); - //buf.append("
Mod Data: " + HexDump.dump(_context.routingKeyGenerator().getModData())); + buf.append("
Mod Data: \"").append(DataHelper.getUTF8(_context.routingKeyGenerator().getModData())) + .append("\" Last Changed: ").append(new Date(_context.routingKeyGenerator().getLastChanged())); int ff = _context.peerManager().getPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL).size(); buf.append("
Known Floodfills: ").append(ff); buf.append("
Currently Floodfill? "); @@ -201,6 +203,8 @@ public class NetDbRenderer { int total = (int) Math.round(Math.pow(2, 3 + 256 - 1 - log2)); buf.append("
Estimated total floodfills: ").append(total); buf.append("
Estimated total leasesets: ").append(total * rapCount / 8); + } else { + buf.append("
Not floodfill or no data"); } buf.append("
"); } diff --git a/core/java/src/net/i2p/data/RoutingKeyGenerator.java b/core/java/src/net/i2p/data/RoutingKeyGenerator.java index 398f579f0..b5bbc02a1 100644 --- a/core/java/src/net/i2p/data/RoutingKeyGenerator.java +++ b/core/java/src/net/i2p/data/RoutingKeyGenerator.java @@ -45,14 +45,16 @@ public class RoutingKeyGenerator { public RoutingKeyGenerator(I2PAppContext context) { _log = context.logManager().getLog(RoutingKeyGenerator.class); _context = context; + // ensure non-null mod data + generateDateBasedModData(); } public static RoutingKeyGenerator getInstance() { return I2PAppContext.getGlobalContext().routingKeyGenerator(); } - private byte _currentModData[]; - private long _lastChanged; + private volatile byte _currentModData[]; + private volatile long _lastChanged; private final static Calendar _cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); private final static SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd"); @@ -65,17 +67,13 @@ public class RoutingKeyGenerator { return _lastChanged; } - public void setModData(byte modData[]) { - _currentModData = modData; - _lastChanged = _context.clock().now(); - } - /** * Update the current modifier data with some bytes derived from the current * date (yyyyMMdd in GMT) * + * @return true if changed */ - public void generateDateBasedModData() { + public synchronized boolean generateDateBasedModData() { Date today = null; long now = _context.clock().now(); synchronized (_cal) { @@ -89,17 +87,18 @@ public class RoutingKeyGenerator { today = _cal.getTime(); } - byte mod[] = null; - String modVal = null; - synchronized (_fmt) { - modVal = _fmt.format(today); - } - mod = new byte[modVal.length()]; + String modVal = _fmt.format(today); + byte[] mod = new byte[modVal.length()]; for (int i = 0; i < modVal.length(); i++) mod[i] = (byte)(modVal.charAt(i) & 0xFF); - if (_log.shouldLog(Log.INFO)) - _log.info("Routing modifier generated: " + modVal); - setModData(mod); + boolean changed = !DataHelper.eq(_currentModData, mod); + if (changed) { + _currentModData = mod; + _lastChanged = now; + if (_log.shouldLog(Log.INFO)) + _log.info("Routing modifier generated: " + modVal); + } + return changed; } /** @@ -113,7 +112,6 @@ public class RoutingKeyGenerator { */ public Hash getRoutingKey(Hash origKey) { if (origKey == null) throw new IllegalArgumentException("Original key is null"); - if (_currentModData == null) generateDateBasedModData(); byte modVal[] = new byte[Hash.HASH_LENGTH + _currentModData.length]; System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH); System.arraycopy(_currentModData, 0, modVal, Hash.HASH_LENGTH, _currentModData.length); diff --git a/history.txt b/history.txt index 1cf1b77a4..96ab4bcb8 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,14 @@ +2012-05-20 zzz + * Console: Add full file path to thread dump message + * i2psnark: + - Create sparse files at torrent creation and delay + "ballooning" until first write (ticket #641) + - Redo clear messages button + - Concurrent message queue + * Profiles: reduce same-country bonus + * RoutingKeyModifier: Several changes to ensure the routing key + is correctly changed just after midnight. + 2012-05-19 zzz * i2psnark: - Store received chunks in temp files diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 282c18b42..0725033fa 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 2; + public final static long BUILD = 3; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java b/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java index 600292e02..ae469152e 100644 --- a/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java +++ b/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java @@ -25,19 +25,24 @@ import net.i2p.util.Log; * @since 0.8.12 moved from Router.java */ public class UpdateRoutingKeyModifierJob extends JobImpl { - private Log _log; - private Calendar _cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + private final Log _log; + private final Calendar _cal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); + // Run every 15 minutes in case of time zone change, clock skew, etc. + private static final long MAX_DELAY_FAILSAFE = 15*60*1000; public UpdateRoutingKeyModifierJob(RouterContext ctx) { super(ctx); + _log = ctx.logManager().getLog(getClass()); } public String getName() { return "Update Routing Key Modifier"; } public void runJob() { - _log = getContext().logManager().getLog(getClass()); + // make sure we requeue quickly if just before midnight + long delay = Math.min(MAX_DELAY_FAILSAFE, getTimeTillMidnight()); + // TODO tell netdb if mod data changed? getContext().routingKeyGenerator().generateDateBasedModData(); - requeue(getTimeTillMidnight()); + requeue(delay); } private long getTimeTillMidnight() {