diff --git a/history.txt b/history.txt index 0b189a9fc..ce61b302a 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2016-11-23 zzz + * NetDB: Penalize new and slow peers + * News: Add command line utility support + * Router: Support blocklist in the news feed (proposal #129) + +2016-11-21 zzz + * NetDB: Fix detection of bandwidth class with multiple values specified + 2016-11-20 zzz * NetDB: When doing lookups, don't use floodfills too close * Router: Change default family sig type to EdDSA diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 7ca1a3ec2..5a58b19bc 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 = 10; + public final static long BUILD = 11; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java index 3504e4644..dbc7b1f72 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java @@ -170,6 +170,8 @@ class FloodfillPeerSelector extends PeerSelector { private static final int NO_FAIL_LOOKUP_OK = 75*1000; private static final int NO_FAIL_LOOKUP_GOOD = NO_FAIL_LOOKUP_OK * 3; private static final int MAX_GOOD_RESP_TIME = 5*1000; + private static final long HEARD_AGE = 48*60*60*1000L; + private static final long INSTALL_AGE = HEARD_AGE + (60*60*1000L); /** * See above for description @@ -206,6 +208,8 @@ class FloodfillPeerSelector extends PeerSelector { List badff = new ArrayList(ffs.size()); int found = 0; long now = _context.clock().now(); + long installed = _context.getProperty("router.firstInstalled", 0L); + boolean enforceHeard = installed > 0 && (now - installed) > INSTALL_AGE; double maxFailRate = 100; if (_context.router().getUptime() > 60*60*1000) { @@ -249,6 +253,10 @@ class FloodfillPeerSelector extends PeerSelector { badff.add(entry); if (_log.shouldLog(Log.DEBUG)) _log.debug("Bad country: " + entry); + } else if (info != null && info.getBandwidthTier().equals("L")) { + badff.add(entry); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Slow: " + entry); } else { PeerProfile prof = _context.profileOrganizer().getProfile(entry); double maxGoodRespTime = MAX_GOOD_RESP_TIME; @@ -258,27 +266,43 @@ class FloodfillPeerSelector extends PeerSelector { if (tunnelTestTime != null && tunnelTestTime.getAverageValue() > 500) maxGoodRespTime = 2 * tunnelTestTime.getAverageValue(); } - if (prof != null && prof.getDBHistory() != null - && prof.getDbResponseTime().getRate(10*60*1000).getAverageValue() < maxGoodRespTime - && prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_GOOD - && prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_GOOD - && prof.getDBHistory().getFailedLookupRate().getRate(60*60*1000).getAverageValue() < maxFailRate) { - // good - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Good: " + entry); - rv.add(entry); - found++; - } else if (prof != null && prof.getDBHistory() != null - && (prof.getDBHistory().getLastStoreFailed() <= prof.getDBHistory().getLastStoreSuccessful() - || prof.getDBHistory().getLastLookupFailed() <= prof.getDBHistory().getLastLookupSuccessful() - || (prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_OK - && prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_OK))) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("OK: " + entry); - okff.add(entry); + if (prof != null) { + if (enforceHeard && prof.getFirstHeardAbout() > now - HEARD_AGE) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Bad (new): " + entry); + badff.add(entry); + } else if (prof.getDBHistory() != null) { + if (prof.getDbResponseTime().getRate(10*60*1000).getAverageValue() < maxGoodRespTime + && prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_GOOD + && prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_GOOD + && prof.getDBHistory().getFailedLookupRate().getRate(60*60*1000).getAverageValue() < maxFailRate) { + // good + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Good: " + entry); + rv.add(entry); + found++; + } else if (prof.getDBHistory().getLastStoreFailed() <= prof.getDBHistory().getLastStoreSuccessful() + || prof.getDBHistory().getLastLookupFailed() <= prof.getDBHistory().getLastLookupSuccessful() + || (prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_OK + && prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_OK)) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("OK: " + entry); + okff.add(entry); + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Bad (DB): " + entry); + badff.add(entry); + } + } else { + // no DBHistory + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Bad (no hist): " + entry); + badff.add(entry); + } } else { + // no profile if (_log.shouldLog(Log.DEBUG)) - _log.debug("Bad: " + entry); + _log.debug("Bad (no prof): " + entry); badff.add(entry); } }