Changeset efff25a


Ignore:
Timestamp:
Dec 14, 2013 2:38:00 PM (7 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
8cb503d
Parents:
6e2583a
Message:

NetDB:

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java

    r6e2583a refff25a  
    196196            buf.append("</b></p><p><b>Mod Data: \"").append(DataHelper.getUTF8(_context.routingKeyGenerator().getModData()))
    197197               .append("\" Last Changed: ").append(new Date(_context.routingKeyGenerator().getLastChanged()));
     198            buf.append("</b></p><p><b>Next Mod Data: \"").append(DataHelper.getUTF8(_context.routingKeyGenerator().getNextModData()))
     199               .append("\" Change in: ").append(DataHelper.formatDuration(_context.routingKeyGenerator().getTimeTillMidnight()));
    198200            int ff = _context.peerManager().getPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL).size();
    199201            buf.append("</b></p><p><b>Known Floodfills: ").append(ff);
  • core/java/src/net/i2p/data/DatabaseEntry.java

    r6e2583a refff25a  
    108108    public Hash getRoutingKey() {
    109109        RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance();
    110         if ((gen.getModData() == null) || (_routingKeyGenMod == null)
    111             || (!DataHelper.eq(gen.getModData(), _routingKeyGenMod))) {
     110        byte[] mod = gen.getModData();
     111        if (!DataHelper.eq(mod, _routingKeyGenMod)) {
    112112            _currentRoutingKey = gen.getRoutingKey(getHash());
    113             _routingKeyGenMod = gen.getModData();
     113            _routingKeyGenMod = mod;
    114114        }
    115115        return _currentRoutingKey;
    116116    }
    117117
    118 
     118    /**
     119     * @deprecated unused
     120     */
    119121    public void setRoutingKey(Hash key) {
    120122        _currentRoutingKey = key;
  • core/java/src/net/i2p/data/RoutingKeyGenerator.java

    r6e2583a refff25a  
    1818import net.i2p.I2PAppContext;
    1919import net.i2p.crypto.SHA256Generator;
     20import net.i2p.util.HexDump;
    2021import net.i2p.util.Log;
    2122
     
    3839 * once per day to generate the correct routing keys!
    3940 *
     41 * Warning - API subject to change. Not for use outside the router.
     42 *
    4043 */
    4144public class RoutingKeyGenerator {
     
    5558   
    5659    private volatile byte _currentModData[];
     60    private volatile byte _nextModData[];
     61    private volatile long _nextMidnight;
    5762    private volatile long _lastChanged;
    5863
     
    6267    private final static SimpleDateFormat _fmt = new SimpleDateFormat(FORMAT);
    6368
     69    /**
     70     *  The current (today's) mod data.
     71     *  Warning - not a copy, do not corrupt.
     72     *
     73     *  @return non-null, 8 bytes
     74     */
    6475    public byte[] getModData() {
    6576        return _currentModData;
    6677    }
    6778
     79    /**
     80     *  Tomorrow's mod data.
     81     *  Warning - not a copy, do not corrupt.
     82     *  For debugging use only.
     83     *
     84     *  @return non-null, 8 bytes
     85     *  @since 0.9.10
     86     */
     87    public byte[] getNextModData() {
     88        return _nextModData;
     89    }
     90
    6891    public long getLastChanged() {
    6992        return _lastChanged;
     
    7194
    7295    /**
    73      * Update the current modifier data with some bytes derived from the current
    74      * date (yyyyMMdd in GMT)
    75      *
    76      * @return true if changed
    77      */
    78     public synchronized boolean generateDateBasedModData() {
    79         long now = _context.clock().now();
     96     *  How long until midnight (ms)
     97     *
     98     *  @return could be slightly negative
     99     *  @since 0.9.10 moved from UpdateRoutingKeyModifierJob
     100     */
     101    public long getTimeTillMidnight() {
     102        return _nextMidnight - _context.clock().now();
     103    }
     104
     105    /**
     106     *  Set _cal to midnight for the time given.
     107     *  Caller must synch.
     108     *  @since 0.9.10
     109     */
     110    private void setCalToPreviousMidnight(long now) {
    80111            _cal.setTime(new Date(now));
    81112            _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR));               // gcj <= 4.0 workaround
     
    85116            _cal.set(Calendar.SECOND, 0);
    86117            _cal.set(Calendar.MILLISECOND, 0);
     118    }
     119
     120    /**
     121     *  Generate mod data from _cal.
     122     *  Caller must synch.
     123     *  @since 0.9.10
     124     */
     125    private byte[] generateModDataFromCal() {
    87126        Date today = _cal.getTime();
    88127       
     
    93132        for (int i = 0; i < LENGTH; i++)
    94133            mod[i] = (byte)(modVal.charAt(i) & 0xFF);
     134        return mod;
     135    }
     136
     137    /**
     138     * Update the current modifier data with some bytes derived from the current
     139     * date (yyyyMMdd in GMT)
     140     *
     141     * @return true if changed
     142     */
     143    public synchronized boolean generateDateBasedModData() {
     144        long now = _context.clock().now();
     145        setCalToPreviousMidnight(now);
     146        byte[] mod = generateModDataFromCal();
    95147        boolean changed = !DataHelper.eq(_currentModData, mod);
    96148        if (changed) {
     149            // add a day and store next midnight and mod data for convenience
     150            _cal.add(Calendar.DATE, 1);
     151            _nextMidnight = _cal.getTime().getTime();
     152            byte[] next = generateModDataFromCal();
    97153            _currentModData = mod;
     154            _nextModData = next;
    98155            _lastChanged = now;
    99156            if (_log.shouldLog(Log.INFO))
    100                 _log.info("Routing modifier generated: " + modVal);
     157                _log.info("Routing modifier generated: " + HexDump.dump(mod));
    101158        }
    102159        return changed;
     
    105162    /**
    106163     * Generate a modified (yet consistent) hash from the origKey by generating the
    107      * SHA256 of the targetKey with the current modData appended to it, *then*
     164     * SHA256 of the targetKey with the current modData appended to it
    108165     *
    109166     * This makes Sybil's job a lot harder, as she needs to essentially take over the
     
    113170     */
    114171    public Hash getRoutingKey(Hash origKey) {
     172        return getKey(origKey, _currentModData);
     173    }
     174   
     175    /**
     176     * Get the routing key using tomorrow's modData, not today's
     177     *
     178     * @since 0.9.10
     179     */
     180    public Hash getNextRoutingKey(Hash origKey) {
     181        return getKey(origKey, _nextModData);
     182    }
     183   
     184    /**
     185     * Generate a modified (yet consistent) hash from the origKey by generating the
     186     * SHA256 of the targetKey with the specified modData appended to it
     187     *
     188     * @throws IllegalArgumentException if origKey is null
     189     */
     190    private static Hash getKey(Hash origKey, byte[] modData) {
    115191        if (origKey == null) throw new IllegalArgumentException("Original key is null");
    116192        byte modVal[] = new byte[Hash.HASH_LENGTH + LENGTH];
    117193        System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH);
    118         System.arraycopy(_currentModData, 0, modVal, Hash.HASH_LENGTH, LENGTH);
     194        System.arraycopy(modData, 0, modVal, Hash.HASH_LENGTH, LENGTH);
    119195        return SHA256Generator.getInstance().calculateHash(modVal);
    120196    }
  • history.txt

    r6e2583a refff25a  
     12013-12-14 zzz
     2* NetDB:
     3 - Just before midnight, flood to new location too so lookups
     4   don't fail after keyspace rotation (ticket #510)
     5 - Refactor RoutingKeyGenerator and UpdateRoutingKeyModifierJob
     6   in support of the above
     7
    182013-12-13 zzz
    29 * i2ptunnel: Show destination for persistent client key only if available;
  • router/java/src/net/i2p/router/RouterVersion.java

    r6e2583a refff25a  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 2;
     21    public final static long BUILD = 3;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java

    r6e2583a refff25a  
    4444    private static final int FLOOD_PRIORITY = OutNetMessage.PRIORITY_NETDB_FLOOD;
    4545    private static final int FLOOD_TIMEOUT = 30*1000;
     46    private static final long NEXT_RKEY_RI_ADVANCE_TIME = 45*60*1000;
     47    private static final long NEXT_RKEY_LS_ADVANCE_TIME = 10*60*1000;
     48    private static final int NEXT_FLOOD_QTY = 2;
    4649   
    4750    public FloodfillNetworkDatabaseFacade(RouterContext context) {
     
    198201        FloodfillPeerSelector sel = (FloodfillPeerSelector)getPeerSelector();
    199202        List<Hash> peers = sel.selectFloodfillParticipants(rkey, MAX_TO_FLOOD, getKBuckets());
     203        long until = _context.routingKeyGenerator().getTimeTillMidnight();
     204        if (until < NEXT_RKEY_LS_ADVANCE_TIME ||
     205            (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && until < NEXT_RKEY_RI_ADVANCE_TIME)) {
     206            // to avoid lookup failures after midnight, also flood to some closest to the
     207            // next routing key for a period of time before midnight.
     208            Hash nkey = _context.routingKeyGenerator().getNextRoutingKey(key);
     209            List<Hash> nextPeers = sel.selectFloodfillParticipants(nkey, NEXT_FLOOD_QTY, getKBuckets());
     210            int i = 0;
     211            for (Hash h : nextPeers) {
     212                if (!peers.contains(h)) {
     213                    peers.add(h);
     214                    i++;
     215                }
     216            }
     217            if (i > 0 && _log.shouldLog(Log.INFO))
     218                _log.info("Flooding the entry for " + key + " to " + i + " more, just before midnight");
     219        }
    200220        int flooded = 0;
    201221        for (int i = 0; i < peers.size(); i++) {
  • router/java/src/net/i2p/router/tasks/UpdateRoutingKeyModifierJob.java

    r6e2583a refff25a  
    99 */
    1010
    11 import java.util.Calendar;
    12 import java.util.Date;
    13 import java.util.GregorianCalendar;
    14 import java.util.TimeZone;
    15 
     11import net.i2p.data.RoutingKeyGenerator;
    1612import net.i2p.router.JobImpl;
    1713import net.i2p.router.RouterContext;
     
    2723public class UpdateRoutingKeyModifierJob extends JobImpl {
    2824    private final Log _log;
    29     private final Calendar _cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    3025    // Run every 15 minutes in case of time zone change, clock skew, etc.
    3126    private static final long MAX_DELAY_FAILSAFE = 15*60*1000;
     
    3934
    4035    public void runJob() {
     36        RoutingKeyGenerator gen = getContext().routingKeyGenerator();
    4137        // make sure we requeue quickly if just before midnight
    42         long delay = Math.min(MAX_DELAY_FAILSAFE, getTimeTillMidnight());
     38        long delay = Math.max(5, Math.min(MAX_DELAY_FAILSAFE, gen.getTimeTillMidnight()));
    4339        // TODO tell netdb if mod data changed?
    44         getContext().routingKeyGenerator().generateDateBasedModData();
     40        gen.generateDateBasedModData();
    4541        requeue(delay);
    4642    }
    47 
    48     private long getTimeTillMidnight() {
    49         long now = getContext().clock().now();
    50         _cal.setTime(new Date(now));
    51         _cal.set(Calendar.YEAR, _cal.get(Calendar.YEAR));               // gcj <= 4.0 workaround
    52         _cal.set(Calendar.DAY_OF_YEAR, _cal.get(Calendar.DAY_OF_YEAR)); // gcj <= 4.0 workaround
    53         _cal.add(Calendar.DATE, 1);
    54         _cal.set(Calendar.HOUR_OF_DAY, 0);
    55         _cal.set(Calendar.MINUTE, 0);
    56         _cal.set(Calendar.SECOND, 0);
    57         _cal.set(Calendar.MILLISECOND, 0);
    58         long then = _cal.getTime().getTime();
    59         long howLong = then - now;
    60         if (howLong < 0) // hi kaffe
    61             howLong = 24*60*60*1000l + howLong;
    62         if (_log.shouldLog(Log.DEBUG))
    63             _log.debug("Time till midnight: " + howLong + "ms");
    64         return howLong;
    65     }
    6643}
Note: See TracChangeset for help on using the changeset viewer.