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 b669f1447c17cbfef7f0f629b552dc621870f865..712830f59a8c0cca05d73d9ed35ef66a2f4cd299 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java @@ -199,10 +199,10 @@ public class NetDbRenderer { FloodfillNetworkDatabaseFacade netdb = (FloodfillNetworkDatabaseFacade)_context.netDb(); buf.append("<p><b>Total Leasesets: ").append(leases.size()); buf.append("</b></p><p><b>Published (RAP) Leasesets: ").append(netdb.getKnownLeaseSets()); - buf.append("</b></p><p><b>Mod Data: \"").append(DataHelper.getUTF8(_context.routingKeyGenerator().getModData())) - .append("\" Last Changed: ").append(new Date(_context.routingKeyGenerator().getLastChanged())); - buf.append("</b></p><p><b>Next Mod Data: \"").append(DataHelper.getUTF8(_context.routingKeyGenerator().getNextModData())) - .append("\" Change in: ").append(DataHelper.formatDuration(_context.routingKeyGenerator().getTimeTillMidnight())); + buf.append("</b></p><p><b>Mod Data: \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData())) + .append("\" Last Changed: ").append(new Date(_context.routerKeyGenerator().getLastChanged())); + buf.append("</b></p><p><b>Next Mod Data: \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData())) + .append("\" Change in: ").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())); int ff = _context.peerManager().getPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL).size(); buf.append("</b></p><p><b>Known Floodfills: ").append(ff); buf.append("</b></p><p><b>Currently Floodfill? "); diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index 8357a485ac14110622603bf06e90e7c1153c3942..79c3108f78d9c4b27d530056819aa8ce053129b5 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -86,7 +86,6 @@ public class I2PAppContext { private SHA256Generator _sha; protected Clock _clock; // overridden in RouterContext private DSAEngine _dsa; - private RoutingKeyGenerator _routingKeyGenerator; private RandomSource _random; private KeyGenerator _keyGenerator; protected KeyRing _keyRing; // overridden in RouterContext @@ -106,7 +105,6 @@ public class I2PAppContext { private volatile boolean _shaInitialized; protected volatile boolean _clockInitialized; // used in RouterContext private volatile boolean _dsaInitialized; - private volatile boolean _routingKeyGeneratorInitialized; private volatile boolean _randomInitialized; private volatile boolean _keyGeneratorInitialized; protected volatile boolean _keyRingInitialized; // used in RouterContext @@ -126,7 +124,7 @@ public class I2PAppContext { private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(), _lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(), _lock9 = new Object(), _lock10 = new Object(), _lock11 = new Object(), _lock12 = new Object(), - _lock13 = new Object(), _lock14 = new Object(), _lock15 = new Object(), _lock16 = new Object(), + _lock13 = new Object(), _lock14 = new Object(), _lock16 = new Object(), _lock17 = new Object(), _lock18 = new Object(), _lock19 = new Object(), _lock20 = new Object(); /** @@ -851,19 +849,13 @@ public class I2PAppContext { * may want to test out how things react when peers don't agree on * how to skew. * + * As of 0.9.16, returns null in I2PAppContext. + * You must be in RouterContext to get a generator. + * + * @return null always */ public RoutingKeyGenerator routingKeyGenerator() { - if (!_routingKeyGeneratorInitialized) - initializeRoutingKeyGenerator(); - return _routingKeyGenerator; - } - - private void initializeRoutingKeyGenerator() { - synchronized (_lock15) { - if (_routingKeyGenerator == null) - _routingKeyGenerator = new RoutingKeyGenerator(this); - _routingKeyGeneratorInitialized = true; - } + return null; } /** diff --git a/core/java/src/net/i2p/data/DatabaseEntry.java b/core/java/src/net/i2p/data/DatabaseEntry.java index 4b84ed106e0775a620f2b112794a1486ac384968..2adc066bfee05f4b1243e3030cbcfb7e992cd9c4 100644 --- a/core/java/src/net/i2p/data/DatabaseEntry.java +++ b/core/java/src/net/i2p/data/DatabaseEntry.java @@ -11,6 +11,7 @@ package net.i2p.data; import java.util.Arrays; +import net.i2p.I2PAppContext; import net.i2p.crypto.DSAEngine; /** @@ -47,7 +48,7 @@ public abstract class DatabaseEntry extends DataStructureImpl { protected volatile Signature _signature; protected volatile Hash _currentRoutingKey; - protected volatile byte[] _routingKeyGenMod; + protected volatile long _routingKeyGenMod; /** * A common interface to the timestamp of the two subclasses. @@ -106,11 +107,15 @@ public abstract class DatabaseEntry extends DataStructureImpl { * Get the routing key for the structure using the current modifier in the RoutingKeyGenerator. * This only calculates a new one when necessary though (if the generator's key modifier changes) * + * @throws IllegalStateException if not in RouterContext */ public Hash getRoutingKey() { - RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance(); - byte[] mod = gen.getModData(); - if (!Arrays.equals(mod, _routingKeyGenMod)) { + I2PAppContext ctx = I2PAppContext.getGlobalContext(); + if (!ctx.isRouterContext()) + throw new IllegalStateException("Not in router context"); + RoutingKeyGenerator gen = ctx.routingKeyGenerator(); + long mod = gen.getLastChanged(); + if (mod != _routingKeyGenMod) { _currentRoutingKey = gen.getRoutingKey(getHash()); _routingKeyGenMod = mod; } @@ -124,9 +129,16 @@ public abstract class DatabaseEntry extends DataStructureImpl { _currentRoutingKey = key; } + /** + * @throws IllegalStateException if not in RouterContext + */ public boolean validateRoutingKey() { + I2PAppContext ctx = I2PAppContext.getGlobalContext(); + if (!ctx.isRouterContext()) + throw new IllegalStateException("Not in router context"); + RoutingKeyGenerator gen = ctx.routingKeyGenerator(); Hash destKey = getHash(); - Hash rk = RoutingKeyGenerator.getInstance().getRoutingKey(destKey); + Hash rk = gen.getRoutingKey(destKey); return rk.equals(getRoutingKey()); } diff --git a/core/java/src/net/i2p/data/RoutingKeyGenerator.java b/core/java/src/net/i2p/data/RoutingKeyGenerator.java index 367089442a8fcda8346a039709d9947bd0323318..20e2218ee5548421c2011319ee1ecfb887b7110a 100644 --- a/core/java/src/net/i2p/data/RoutingKeyGenerator.java +++ b/core/java/src/net/i2p/data/RoutingKeyGenerator.java @@ -9,215 +9,40 @@ package net.i2p.data; * */ -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Arrays; -import java.util.GregorianCalendar; -import java.util.Locale; -import java.util.TimeZone; - import net.i2p.I2PAppContext; -import net.i2p.crypto.SHA256Generator; -import net.i2p.util.HexDump; -import net.i2p.util.Log; /** * Component to manage the munging of hashes into routing keys - given a hash, * perform some consistent transformation against it and return the result. * This transformation is fed by the current "mod data". * - * Right now the mod data is the current date (GMT) as a string: "yyyyMMdd", - * and the transformation takes the original hash, appends the bytes of that mod data, - * then returns the SHA256 of that concatenation. - * - * Do we want this to simply do the XOR of the SHA256 of the current mod data and - * the key? does that provide the randomization we need? It'd save an SHA256 op. - * Bah, too much effort to think about for so little gain. Other algorithms may come - * into play layer on about making periodic updates to the routing key for data elements - * to mess with Sybil. This may be good enough though. - * - * Also - the method generateDateBasedModData() should be called after midnight GMT - * once per day to generate the correct routing keys! - * - * Warning - API subject to change. Not for use outside the router. + * As of 0.9.16, this is essentially just an interface. + * Implementation moved to net.i2p.data.router.RouterKeyGenerator. + * No generator is available in I2PAppContext; you must be in RouterContext. * */ -public class RoutingKeyGenerator { - private final Log _log; - private final I2PAppContext _context; - - 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 volatile byte _currentModData[]; - private volatile byte _nextModData[]; - private volatile long _nextMidnight; - private volatile long _lastChanged; - - private final static Calendar _cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); - private static final String FORMAT = "yyyyMMdd"; - private static final int LENGTH = FORMAT.length(); - private final static SimpleDateFormat _fmt = new SimpleDateFormat(FORMAT, Locale.US); - static { - // make sure GMT is set, azi2phelper Vuze plugin is disabling static JVM TZ setting in Router.java - _fmt.setCalendar(_cal); - } - - /** - * The current (today's) mod data. - * Warning - not a copy, do not corrupt. - * - * @return non-null, 8 bytes - */ - public byte[] getModData() { - return _currentModData; - } - - /** - * Tomorrow's mod data. - * Warning - not a copy, do not corrupt. - * For debugging use only. - * - * @return non-null, 8 bytes - * @since 0.9.10 - */ - public byte[] getNextModData() { - return _nextModData; - } - - public long getLastChanged() { - return _lastChanged; - } +public abstract class RoutingKeyGenerator { /** - * How long until midnight (ms) + * Get the generator for this context. * - * @return could be slightly negative - * @since 0.9.10 moved from UpdateRoutingKeyModifierJob + * @return null in I2PAppContext; non-null in RouterContext. */ - public long getTimeTillMidnight() { - return _nextMidnight - _context.clock().now(); - } - - /** - * Set _cal to midnight for the time given. - * Caller must synch. - * @since 0.9.10 - */ - private void setCalToPreviousMidnight(long now) { - _cal.setTime(new Date(now)); - _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR)); // gcj <= 4.0 workaround - _cal.set(Calendar.DAY_OF_YEAR, _cal.get(Calendar.DAY_OF_YEAR)); // gcj <= 4.0 workaround - _cal.set(Calendar.HOUR_OF_DAY, 0); - _cal.set(Calendar.MINUTE, 0); - _cal.set(Calendar.SECOND, 0); - _cal.set(Calendar.MILLISECOND, 0); + public static RoutingKeyGenerator getInstance() { + return I2PAppContext.getGlobalContext().routingKeyGenerator(); } /** - * Generate mod data from _cal. - * Caller must synch. - * @since 0.9.10 + * The version of the current (today's) mod data. + * Use to determine if the routing key should be regenerated. */ - private byte[] generateModDataFromCal() { - Date today = _cal.getTime(); - - String modVal = _fmt.format(today); - if (modVal.length() != LENGTH) - throw new IllegalStateException(); - byte[] mod = new byte[LENGTH]; - for (int i = 0; i < LENGTH; i++) - mod[i] = (byte)(modVal.charAt(i) & 0xFF); - return mod; - } + public abstract long getLastChanged(); /** - * Update the current modifier data with some bytes derived from the current - * date (yyyyMMdd in GMT) - * - * @return true if changed - */ - public synchronized boolean generateDateBasedModData() { - long now = _context.clock().now(); - setCalToPreviousMidnight(now); - byte[] mod = generateModDataFromCal(); - boolean changed = !Arrays.equals(_currentModData, mod); - if (changed) { - // add a day and store next midnight and mod data for convenience - _cal.add(Calendar.DATE, 1); - _nextMidnight = _cal.getTime().getTime(); - byte[] next = generateModDataFromCal(); - _currentModData = mod; - _nextModData = next; - _lastChanged = now; - if (_log.shouldLog(Log.INFO)) - _log.info("Routing modifier generated: " + HexDump.dump(mod)); - } - return changed; - } - - /** - * Generate a modified (yet consistent) hash from the origKey by generating the - * SHA256 of the targetKey with the current modData appended to it - * - * This makes Sybil's job a lot harder, as she needs to essentially take over the - * whole keyspace. - * - * @throws IllegalArgumentException if origKey is null - */ - public Hash getRoutingKey(Hash origKey) { - return getKey(origKey, _currentModData); - } - - /** - * Get the routing key using tomorrow's modData, not today's - * - * @since 0.9.10 - */ - public Hash getNextRoutingKey(Hash origKey) { - return getKey(origKey, _nextModData); - } - - /** - * Generate a modified (yet consistent) hash from the origKey by generating the - * SHA256 of the targetKey with the specified modData appended to it + * Get the routing key for a key. * * @throws IllegalArgumentException if origKey is null */ - private static Hash getKey(Hash origKey, byte[] modData) { - if (origKey == null) throw new IllegalArgumentException("Original key is null"); - byte modVal[] = new byte[Hash.HASH_LENGTH + LENGTH]; - System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH); - System.arraycopy(modData, 0, modVal, Hash.HASH_LENGTH, LENGTH); - return SHA256Generator.getInstance().calculateHash(modVal); - } - -/**** - public static void main(String args[]) { - Hash k1 = new Hash(); - byte k1d[] = new byte[Hash.HASH_LENGTH]; - RandomSource.getInstance().nextBytes(k1d); - k1.setData(k1d); + public abstract Hash getRoutingKey(Hash origKey); - for (int i = 0; i < 10; i++) { - System.out.println("K1: " + k1); - Hash k1m = RoutingKeyGenerator.getInstance().getRoutingKey(k1); - System.out.println("MOD: " + new String(RoutingKeyGenerator.getInstance().getModData())); - System.out.println("K1M: " + k1m); - } - try { - Thread.sleep(2000); - } catch (Throwable t) { // nop - } - } -****/ } diff --git a/router/java/src/net/i2p/data/router/RouterKeyGenerator.java b/router/java/src/net/i2p/data/router/RouterKeyGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..69e6aaceca317488cce3034b2d7e705dc5d7740a --- /dev/null +++ b/router/java/src/net/i2p/data/router/RouterKeyGenerator.java @@ -0,0 +1,224 @@ +package net.i2p.data.router; + +/* + * free (adj.): unencumbered; not under the control of others + * Written by jrandom in 2003 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + * + */ + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Arrays; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +import net.i2p.I2PAppContext; +import net.i2p.crypto.SHA256Generator; +import net.i2p.data.Hash; +import net.i2p.data.RoutingKeyGenerator; +import net.i2p.util.HexDump; +import net.i2p.util.Log; + +/** + * Component to manage the munging of hashes into routing keys - given a hash, + * perform some consistent transformation against it and return the result. + * This transformation is fed by the current "mod data". + * + * Right now the mod data is the current date (GMT) as a string: "yyyyMMdd", + * and the transformation takes the original hash, appends the bytes of that mod data, + * then returns the SHA256 of that concatenation. + * + * Do we want this to simply do the XOR of the SHA256 of the current mod data and + * the key? does that provide the randomization we need? It'd save an SHA256 op. + * Bah, too much effort to think about for so little gain. Other algorithms may come + * into play layer on about making periodic updates to the routing key for data elements + * to mess with Sybil. This may be good enough though. + * + * Also - the method generateDateBasedModData() should be called after midnight GMT + * once per day to generate the correct routing keys! + * + * @since 0.9.16 moved from net.i2p.data.RoutingKeyGenerator.. + * + */ +public class RouterKeyGenerator extends RoutingKeyGenerator { + private final Log _log; + private final I2PAppContext _context; + + public RouterKeyGenerator(I2PAppContext context) { + _log = context.logManager().getLog(RoutingKeyGenerator.class); + _context = context; + // ensure non-null mod data + generateDateBasedModData(); + } + + private volatile byte _currentModData[]; + private volatile byte _nextModData[]; + private volatile long _nextMidnight; + private volatile long _lastChanged; + + private final static Calendar _cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); + private static final String FORMAT = "yyyyMMdd"; + private static final int LENGTH = FORMAT.length(); + private final static SimpleDateFormat _fmt = new SimpleDateFormat(FORMAT, Locale.US); + static { + // make sure GMT is set, azi2phelper Vuze plugin is disabling static JVM TZ setting in Router.java + _fmt.setCalendar(_cal); + } + + /** + * The current (today's) mod data. + * Warning - not a copy, do not corrupt. + * + * @return non-null, 8 bytes + */ + public byte[] getModData() { + return _currentModData; + } + + /** + * Tomorrow's mod data. + * Warning - not a copy, do not corrupt. + * For debugging use only. + * + * @return non-null, 8 bytes + * @since 0.9.10 + */ + public byte[] getNextModData() { + return _nextModData; + } + + public long getLastChanged() { + return _lastChanged; + } + + /** + * How long until midnight (ms) + * + * @return could be slightly negative + * @since 0.9.10 moved from UpdateRoutingKeyModifierJob + */ + public long getTimeTillMidnight() { + return _nextMidnight - _context.clock().now(); + } + + /** + * Set _cal to midnight for the time given. + * Caller must synch. + * @since 0.9.10 + */ + private void setCalToPreviousMidnight(long now) { + _cal.setTime(new Date(now)); + _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR)); // gcj <= 4.0 workaround + _cal.set(Calendar.DAY_OF_YEAR, _cal.get(Calendar.DAY_OF_YEAR)); // gcj <= 4.0 workaround + _cal.set(Calendar.HOUR_OF_DAY, 0); + _cal.set(Calendar.MINUTE, 0); + _cal.set(Calendar.SECOND, 0); + _cal.set(Calendar.MILLISECOND, 0); + } + + /** + * Generate mod data from _cal. + * Caller must synch. + * @since 0.9.10 + */ + private byte[] generateModDataFromCal() { + Date today = _cal.getTime(); + + String modVal = _fmt.format(today); + if (modVal.length() != LENGTH) + throw new IllegalStateException(); + byte[] mod = new byte[LENGTH]; + for (int i = 0; i < LENGTH; i++) + mod[i] = (byte)(modVal.charAt(i) & 0xFF); + return mod; + } + + /** + * Update the current modifier data with some bytes derived from the current + * date (yyyyMMdd in GMT) + * + * @return true if changed + */ + public synchronized boolean generateDateBasedModData() { + long now = _context.clock().now(); + setCalToPreviousMidnight(now); + byte[] mod = generateModDataFromCal(); + boolean changed = !Arrays.equals(_currentModData, mod); + if (changed) { + // add a day and store next midnight and mod data for convenience + _cal.add(Calendar.DATE, 1); + _nextMidnight = _cal.getTime().getTime(); + byte[] next = generateModDataFromCal(); + _currentModData = mod; + _nextModData = next; + // ensure version is bumped + if (_lastChanged == now) + now++; + _lastChanged = now; + if (_log.shouldLog(Log.INFO)) + _log.info("Routing modifier generated: " + HexDump.dump(mod)); + } + return changed; + } + + /** + * Generate a modified (yet consistent) hash from the origKey by generating the + * SHA256 of the targetKey with the current modData appended to it + * + * This makes Sybil's job a lot harder, as she needs to essentially take over the + * whole keyspace. + * + * @throws IllegalArgumentException if origKey is null + */ + public Hash getRoutingKey(Hash origKey) { + return getKey(origKey, _currentModData); + } + + /** + * Get the routing key using tomorrow's modData, not today's + * + * @since 0.9.10 + */ + public Hash getNextRoutingKey(Hash origKey) { + return getKey(origKey, _nextModData); + } + + /** + * Generate a modified (yet consistent) hash from the origKey by generating the + * SHA256 of the targetKey with the specified modData appended to it + * + * @throws IllegalArgumentException if origKey is null + */ + private static Hash getKey(Hash origKey, byte[] modData) { + if (origKey == null) throw new IllegalArgumentException("Original key is null"); + byte modVal[] = new byte[Hash.HASH_LENGTH + LENGTH]; + System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH); + System.arraycopy(modData, 0, modVal, Hash.HASH_LENGTH, LENGTH); + return SHA256Generator.getInstance().calculateHash(modVal); + } + +/**** + public static void main(String args[]) { + Hash k1 = new Hash(); + byte k1d[] = new byte[Hash.HASH_LENGTH]; + RandomSource.getInstance().nextBytes(k1d); + k1.setData(k1d); + + for (int i = 0; i < 10; i++) { + System.out.println("K1: " + k1); + Hash k1m = RoutingKeyGenerator.getInstance().getRoutingKey(k1); + System.out.println("MOD: " + new String(RoutingKeyGenerator.getInstance().getModData())); + System.out.println("K1M: " + k1m); + } + try { + Thread.sleep(2000); + } catch (Throwable t) { // nop + } + } +****/ +} diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 3afd99de260102de22a4d4a1cabb21e59f1c7a20..8fd08eb795f47e7cfb797fd6cc349754543b1aab 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -1070,7 +1070,7 @@ public class Router implements RouterClock.ClockShiftListener { return; _eventLog.addEvent(EventLog.CLOCK_SHIFT, Long.toString(delta)); // update the routing key modifier - _context.routingKeyGenerator().generateDateBasedModData(); + _context.routerKeyGenerator().generateDateBasedModData(); if (_context.commSystem().countActivePeers() <= 0) return; if (delta > 0) diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index 20b2fe9b7d10ba643854210e13693fc03103142f..fd5c65775953215c6623473f4d9979c3e6e1a55b 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -10,7 +10,9 @@ import java.util.concurrent.CopyOnWriteArrayList; import net.i2p.I2PAppContext; import net.i2p.app.ClientAppManager; import net.i2p.data.Hash; +import net.i2p.data.RoutingKeyGenerator; import net.i2p.data.router.RouterInfo; +import net.i2p.data.router.RouterKeyGenerator; import net.i2p.internal.InternalClientManager; import net.i2p.router.client.ClientManagerFacadeImpl; import net.i2p.router.crypto.TransientSessionKeyManager; @@ -65,6 +67,7 @@ public class RouterContext extends I2PAppContext { //private MessageStateMonitor _messageStateMonitor; private RouterThrottle _throttle; private RouterAppManager _appManager; + private RouterKeyGenerator _routingKeyGenerator; private final Set<Runnable> _finalShutdownTasks; // split up big lock on this to avoid deadlocks private volatile boolean _initialized; @@ -183,6 +186,7 @@ public class RouterContext extends I2PAppContext { _messageHistory = new MessageHistory(this); _messageRegistry = new OutboundMessageRegistry(this); //_messageStateMonitor = new MessageStateMonitor(this); + _routingKeyGenerator = new RouterKeyGenerator(this); if (!getBooleanProperty("i2p.dummyNetDb")) _netDb = new FloodfillNetworkDatabaseFacade(this); // new KademliaNetworkDatabaseFacade(this); else @@ -582,4 +586,35 @@ public class RouterContext extends I2PAppContext { _sessionKeyManagerInitialized = true; } } + + /** + * Determine how much do we want to mess with the keys to turn them + * into something we can route. This is context specific because we + * may want to test out how things react when peers don't agree on + * how to skew. + * + * Returns same thing as routerKeyGenerator() + * + * @return non-null + * @since 0.9.16 Overrides I2PAppContext. Returns non-null in RouterContext and null in I2PAppcontext. + */ + @Override + public RoutingKeyGenerator routingKeyGenerator() { + return _routingKeyGenerator; + } + + /** + * Determine how much do we want to mess with the keys to turn them + * into something we can route. This is context specific because we + * may want to test out how things react when peers don't agree on + * how to skew. + * + * Returns same thing as routingKeyGenerator() + * + * @return non-null + * @since 0.9.16 + */ + public RouterKeyGenerator routerKeyGenerator() { + return _routingKeyGenerator; + } } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java index e8a80368c4946514496c7ece8ebc3c0183c7e85a..9358092260ea0e75d9e0f2c3b72718096d18129c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java @@ -13,6 +13,7 @@ import net.i2p.data.TunnelId; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.router.RouterInfo; +import net.i2p.data.router.RouterKeyGenerator; import net.i2p.router.Job; import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; @@ -176,16 +177,17 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad */ public void flood(DatabaseEntry ds) { Hash key = ds.getHash(); - Hash rkey = _context.routingKeyGenerator().getRoutingKey(key); + RouterKeyGenerator gen = _context.routerKeyGenerator(); + Hash rkey = gen.getRoutingKey(key); FloodfillPeerSelector sel = (FloodfillPeerSelector)getPeerSelector(); List<Hash> peers = sel.selectFloodfillParticipants(rkey, MAX_TO_FLOOD, getKBuckets()); // todo key cert skip? - long until = _context.routingKeyGenerator().getTimeTillMidnight(); + long until = gen.getTimeTillMidnight(); if (until < NEXT_RKEY_LS_ADVANCE_TIME || (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && until < NEXT_RKEY_RI_ADVANCE_TIME)) { - // to avoid lookup failures after midnight, also flood to some closest to the + // to avoid lookup faulures after midnight, also flood to some closest to the // next routing key for a period of time before midnight. - Hash nkey = _context.routingKeyGenerator().getNextRoutingKey(key); + Hash nkey = gen.getNextRoutingKey(key); List<Hash> nextPeers = sel.selectFloodfillParticipants(nkey, NEXT_FLOOD_QTY, getKBuckets()); int i = 0; for (Hash h : nextPeers) { diff --git a/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java b/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java index 2952c2eda430fc37df6a487414ea52a48995e838..5b367620be13d277279258cbc486b23c67d3239f 100644 --- a/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java +++ b/router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java @@ -8,7 +8,7 @@ package net.i2p.router.tasks; * */ -import net.i2p.data.RoutingKeyGenerator; +import net.i2p.data.router.RouterKeyGenerator; import net.i2p.router.JobImpl; import net.i2p.router.RouterContext; import net.i2p.util.Log; @@ -33,7 +33,7 @@ public class UpdateRoutingKeyModifierJob extends JobImpl { public String getName() { return "Update Routing Key Modifier"; } public void runJob() { - RoutingKeyGenerator gen = getContext().routingKeyGenerator(); + RouterKeyGenerator gen = getContext().routerKeyGenerator(); // make sure we requeue quickly if just before midnight long delay = Math.max(5, Math.min(MAX_DELAY_FAILSAFE, gen.getTimeTillMidnight())); // TODO tell netdb if mod data changed?