diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
index a3280ac446..886ba6abb6 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
@@ -10,17 +10,21 @@ import net.i2p.router.RouterContext;
public class NetDbHelper extends HelperBase {
private String _routerPrefix;
private boolean _full = false;
+ private boolean _lease = false;
public NetDbHelper() {}
public void setRouter(String r) { _routerPrefix = r; }
- public void setFull(String f) { _full = "1".equals(f); };
+ public void setFull(String f) { _full = "1".equals(f); }
+ public void setLease(String l) { _lease = "1".equals(l); }
public String getNetDbSummary() {
try {
if (_out != null) {
if (_routerPrefix != null)
_context.netDb().renderRouterInfoHTML(_out, _routerPrefix);
+ else if (_lease)
+ _context.netDb().renderLeaseSetHTML(_out);
else
_context.netDb().renderStatusHTML(_out, _full);
return "";
@@ -28,6 +32,8 @@ public class NetDbHelper extends HelperBase {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
if (_routerPrefix != null)
_context.netDb().renderRouterInfoHTML(new OutputStreamWriter(baos), _routerPrefix);
+ else if (_lease)
+ _context.netDb().renderLeaseSetHTML(new OutputStreamWriter(baos));
else
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos), _full);
return new String(baos.toByteArray());
diff --git a/apps/routerconsole/jsp/netdb.jsp b/apps/routerconsole/jsp/netdb.jsp
index 08a1377d37..392888bc67 100644
--- a/apps/routerconsole/jsp/netdb.jsp
+++ b/apps/routerconsole/jsp/netdb.jsp
@@ -16,6 +16,7 @@
" />
" />
+ " />
diff --git a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java
index e1169b455a..ded9bee26a 100644
--- a/router/java/src/net/i2p/router/NetworkDatabaseFacade.java
+++ b/router/java/src/net/i2p/router/NetworkDatabaseFacade.java
@@ -58,5 +58,6 @@ public abstract class NetworkDatabaseFacade implements Service {
public int getKnownRouters() { return 0; }
public int getKnownLeaseSets() { return 0; }
public void renderRouterInfoHTML(Writer out, String s) throws IOException {}
+ public void renderLeaseSetHTML(Writer out) throws IOException {}
public void renderStatusHTML(Writer out, boolean b) throws IOException {}
}
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index a4a707926e..c9a95dd552 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -685,6 +685,7 @@ public class Router {
out.write("\n
\n");
+ _context.netDb().renderLeaseSetHTML(out);
_context.netDb().renderStatusHTML(out);
buf.setLength(0);
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 9b1a1c7acd..b980170227 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
@@ -115,11 +115,13 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
protected final static int MIN_REMAINING_ROUTERS = 25;
/**
- * dont accept any dbDtore of a router over 24 hours old (unless we dont
- * know anyone or just started up)
+ * limits for accepting a dbDtore of a router (unless we dont
+ * know anyone or just started up) -- see validate() below
*/
private final static long ROUTER_INFO_EXPIRATION = 3*24*60*60*1000l;
+ private final static long ROUTER_INFO_EXPIRATION_MIN = 3*60*60*1000l;
private final static long ROUTER_INFO_EXPIRATION_SHORT = 90*60*1000l;
+ private final static long ROUTER_INFO_EXPIRATION_FLOODFILL = 45*60*1000l;
private final static long EXPLORE_JOB_DELAY = 10*60*1000l;
private final static long PUBLISH_JOB_DELAY = 5*60*1000l;
@@ -624,7 +626,22 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
*/
String validate(Hash key, RouterInfo routerInfo) throws IllegalArgumentException {
long now = _context.clock().now();
-
+ boolean upLongEnough = _context.router().getUptime() > 60*60*1000;
+ // Once we're over 300 routers, reduce the expiration time down from the default,
+ // as a crude way of limiting memory usage.
+ // i.e. at 600 routers the expiration time will be about half the default, etc.
+ // And if we're floodfill, we can keep the expiration really short, since
+ // we are always getting the latest published to us.
+ // As the net grows this won't be sufficient, and we'll have to implement
+ // flushing some from memory, while keeping all on disk.
+ long adjustedExpiration;
+ if (FloodfillNetworkDatabaseFacade.floodfillEnabled(_context))
+ adjustedExpiration = ROUTER_INFO_EXPIRATION_FLOODFILL;
+ else
+ adjustedExpiration = Math.min(ROUTER_INFO_EXPIRATION,
+ ROUTER_INFO_EXPIRATION_MIN +
+ ((ROUTER_INFO_EXPIRATION - ROUTER_INFO_EXPIRATION_MIN) * 300 / (_kb.size() + 1)));
+
if (!key.equals(routerInfo.getIdentity().getHash())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid store attempt! key does not match routerInfo.identity! key = " + key + ", router = " + routerInfo);
@@ -633,7 +650,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid routerInfo signature! forged router structure! router = " + routerInfo);
return "Invalid routerInfo signature on " + key.toBase64();
- } else if (!routerInfo.isCurrent(ROUTER_INFO_EXPIRATION) && (_context.router().getUptime() > 60*60*1000) ) {
+ } else if (upLongEnough && !routerInfo.isCurrent(adjustedExpiration)) {
if (routerInfo.getNetworkId() != Router.NETWORK_ID) {
_context.shitlist().shitlistRouter(key, "Peer is not in our network");
return "Peer is not in our network (" + routerInfo.getNetworkId() + ", wants "
@@ -661,10 +678,10 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
String rv = "Peer " + key.toBase64() + " is from another network, not accepting it (id="
+ routerInfo.getNetworkId() + ", want " + Router.NETWORK_ID + ")";
return rv;
- } else if ( (_context.router().getUptime() > 60*60*1000) && (routerInfo.getPublished() < now - 2*24*60*60*1000l) ) {
+ } else if (upLongEnough && (routerInfo.getPublished() < now - 2*24*60*60*1000l) ) {
long age = _context.clock().now() - routerInfo.getPublished();
return "Peer " + key.toBase64() + " published " + DataHelper.formatDuration(age) + " ago";
- } else if (!routerInfo.isCurrent(ROUTER_INFO_EXPIRATION_SHORT) && (_context.router().getUptime() > 60*60*1000) ) {
+ } else if (upLongEnough && !routerInfo.isCurrent(ROUTER_INFO_EXPIRATION_SHORT)) {
if (routerInfo.getAddresses().size() <= 0)
return "Peer " + key.toBase64() + " published > 90m ago with no addresses";
RouterAddress ra = routerInfo.getTargetAddress("SSU");
@@ -901,23 +918,13 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
}
@Override
- public void renderStatusHTML(Writer out, boolean full) throws IOException {
- int size = getKnownRouters() * 512;
- if (full)
- size *= 4;
- StringBuffer buf = new StringBuffer(size);
+ public void renderLeaseSetHTML(Writer out) throws IOException {
+ StringBuffer buf = new StringBuffer(4*1024);
buf.append("Network Database Contents
\n");
- if (!_initialized) {
- buf.append("Not initialized\n");
- out.write(buf.toString());
- out.flush();
- return;
- }
+ buf.append("View RouterInfo");
+ buf.append("LeaseSets
\n");
Set leases = new TreeSet(new LeaseSetComparator());
leases.addAll(getLeases());
- buf.append("Leases
\n");
- out.write(buf.toString());
- buf.setLength(0);
long now = _context.clock().now();
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
LeaseSet ls = (LeaseSet)iter.next();
@@ -957,7 +964,25 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
out.write(buf.toString());
buf.setLength(0);
}
+ out.write(buf.toString());
+ out.flush();
+ }
+
+ @Override
+ public void renderStatusHTML(Writer out, boolean full) throws IOException {
+ int size = getKnownRouters() * 512;
+ if (full)
+ size *= 4;
+ StringBuffer buf = new StringBuffer(size);
+ out.write("Network Database Contents
\n");
+ if (!_initialized) {
+ buf.append("Not initialized\n");
+ out.write(buf.toString());
+ out.flush();
+ return;
+ }
+ out.write("View LeaseSets");
Hash us = _context.routerHash();
out.write("Routers (