diff --git a/history.txt b/history.txt index 59aa2af21efe78fe578cff015e104465c4eaba3a..a3964357547f3cf693868dc072fb24d7142f0205 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,10 @@ +2012-11-16 zzz + * i2psnark: Fix rare IOOBE (ticket #777) + * NetDB: + - Implement automatic reseeding (ticket #521) + - Increase minimum routers + * Tunnels: Fix outbound tunnel message priority (ticket #719) + 2012-11-13 zzz * Bandwidth Limiter: Fix stats broken in -1 * HTTP Proxy: Store referrer of new addresses in address book diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index c10128fe6223a59f4fa2320e38c3309487438a87..fecba78d6973d87e9930d631de787e05fec2a510 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 = 6; + public final static long BUILD = 7; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java index 633dbeff1a1a3111530a4f39e40b6f8c421ae0c9..9dcd9231805e78b377be05c3c21945752b2dcda3 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -105,10 +105,17 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade { public final static String PROP_DB_DIR = "router.networkDatabase.dbDir"; public final static String DEFAULT_DB_DIR = "netDb"; + /** Reseed if below this. + * @since 0.9.4 + */ + static final int MIN_RESEED = ReseedChecker.MINIMUM; + /** if we have less than this many routers left, don't drop any more, * even if they're failing or doing bad stuff. + * As of 0.9.4, we make this LOWER than the min for reseeding, so + * a reseed will be forced if necessary. */ - protected final static int MIN_REMAINING_ROUTERS = 25; + protected final static int MIN_REMAINING_ROUTERS = MIN_RESEED - 10; /** * limits for accepting a dbDtore of a router (unless we dont diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index dc44e1345f78992b368dbfc7f8e7d3e7ef481bb2..e59ad6b31aa0e23cb9e7ea5c58bb02ee05df40a7 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -46,9 +46,9 @@ class PersistentDataStore extends TransientDataStore { private final KademliaNetworkDatabaseFacade _facade; private final Writer _writer; private final ReadJob _readJob; - private boolean _initialized; + private volatile boolean _initialized; - private final static int READ_DELAY = 60*1000; + private final static int READ_DELAY = 2*60*1000; /** * @param dbDir relative path @@ -319,14 +319,21 @@ class PersistentDataStore extends TransientDataStore { return data.getDate(); } - /** This is only for manual reseeding? Why bother every 60 sec??? */ + /** + * This is mostly for manual reseeding, i.e. the user manually + * copies RI files to the directory. Nobody does this, + * so this is run way too often. + * Reseed task calls wakeup() on completion. + * As of 0.9.4, also initiates an automatic reseed if necessary. + */ private class ReadJob extends JobImpl { - private boolean _alreadyWarned; private long _lastModified; + private long _lastReseed; + private static final int MIN_ROUTERS = KademliaNetworkDatabaseFacade.MIN_RESEED; + private static final long MIN_RESEED_INTERVAL = 90*60*1000; public ReadJob() { super(PersistentDataStore.this._context); - _alreadyWarned = false; } public String getName() { return "DB Read Job"; } @@ -334,7 +341,8 @@ class PersistentDataStore extends TransientDataStore { public void runJob() { // check directory mod time to save a lot of object churn in scanning all the file names long lastMod = _dbDir.lastModified(); - if (lastMod > _lastModified) { + // if size() (= RI + LS) is too low, call anyway to check for reseed + if (lastMod > _lastModified || size() < MIN_ROUTERS + 10) { _lastModified = lastMod; _log.info("Rereading new files"); // synch with the writer job @@ -354,9 +362,7 @@ class PersistentDataStore extends TransientDataStore { File routerInfoFiles[] = _dbDir.listFiles(RouterInfoFilter.getInstance()); if (routerInfoFiles != null) { - routerCount += routerInfoFiles.length; - if (routerInfoFiles.length > 5) - _alreadyWarned = false; + routerCount = routerInfoFiles.length; for (int i = 0; i < routerInfoFiles.length; i++) { // drop out if the router gets killed right after startup if (!_context.router().isAlive()) @@ -373,10 +379,16 @@ class PersistentDataStore extends TransientDataStore { } } - if (!_alreadyWarned) { - _facade.reseedChecker().checkReseed(routerCount); - _alreadyWarned = true; + if (!_initialized) { + if (_facade.reseedChecker().checkReseed(routerCount)) + _lastReseed = _context.clock().now(); _initialized = true; + } else if (_lastReseed < _context.clock().now() - MIN_RESEED_INTERVAL) { + int count = Math.min(routerCount, size()); + if (count < MIN_ROUTERS) { + if (_facade.reseedChecker().checkReseed(count)) + _lastReseed = _context.clock().now(); + } } } } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java index efb9b33e2120fdf1d9b91d9a783d6ede1f76c0da..2023452a8bd3ab677579a0e8b0dbf538a1976585 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java @@ -4,6 +4,7 @@ import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.router.RouterContext; +import net.i2p.util.Addresses; import net.i2p.util.Log; /** @@ -23,10 +24,10 @@ public class ReseedChecker { private final RouterContext _context; private final Log _log; private final AtomicBoolean _inProgress = new AtomicBoolean(); - private String _lastStatus = ""; - private String _lastError = ""; + private volatile String _lastStatus = ""; + private volatile String _lastError = ""; - private static final int MINIMUM = 15; + public static final int MINIMUM = 50; /** * All reseeding must be done through this instance. @@ -64,6 +65,10 @@ public class ReseedChecker { File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed"); File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p"); if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { + if (!Addresses.isConnected()) { + _log.logAlways(Log.WARN, "Cannot reseed, no network connection"); + return false; + } if (count <= 1) _log.logAlways(Log.INFO, "Downloading peer router information for a new I2P installation"); else @@ -96,7 +101,7 @@ public class ReseedChecker { } } else { if (_log.shouldLog(Log.WARN)) - _log.warn("Reseed already in prgress"); + _log.warn("Reseed already in progress"); return false; } }