* NetDb: Tweak some logging on lease problems

* Shitlist:
      - Add shitlistForever() and isShitlistedForever(), unused for now
      - Sort the HTML output by router hash
    * config.jsp: Add another warning
    * netdb.jsp:
      - Sort the lease HTML output by dest hash, local first
      - Sort the router HTML output by router hash
This commit is contained in:
zzz
2008-06-07 17:44:13 +00:00
parent 88e26224c2
commit f3b8c73e96
4 changed files with 101 additions and 35 deletions

View File

@ -1,3 +1,13 @@
2008-06-07 zzz
* NetDb: Tweak some logging on lease problems
* Shitlist:
- Add shitlistForever() and isShitlistedForever(), unused for now
- Sort the HTML output by router hash
* config.jsp: Add another warning
* netdb.jsp:
- Sort the lease HTML output by dest hash, local first
- Sort the router HTML output by router hash
2008-06-06 zzz
* LeaseSet:
- Sort the leases by expiration date in TunnelPool.locked_buildNewLeaseSet()

View File

@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
public class RouterVersion {
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
public final static String VERSION = "0.6.1.33";
public final static long BUILD = 2003;
public final static long BUILD = 2004;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -11,8 +11,8 @@ package net.i2p.router;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import net.i2p.data.DataHelper;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.router.peermanager.PeerProfile;
import net.i2p.util.Log;
@ -38,6 +38,8 @@ public class Shitlist {
}
public final static long SHITLIST_DURATION_MS = 40*60*1000; // 40 minute shitlist
public final static long SHITLIST_DURATION_MAX = 60*60*1000;
public final static long SHITLIST_DURATION_FOREVER = 181l*24*60*60*1000; // will get rounded down to 180d on console
public Shitlist(RouterContext context) {
_context = context;
@ -91,6 +93,12 @@ public class Shitlist {
}
public boolean shitlistRouter(Hash peer, String reason) { return shitlistRouter(peer, reason, null); }
public boolean shitlistRouter(Hash peer, String reason, String transport) {
return shitlistRouter(peer, reason, null, false);
}
public boolean shitlistRouterForever(Hash peer, String reason) {
return shitlistRouter(peer, reason, null, true);
}
public boolean shitlistRouter(Hash peer, String reason, String transport, boolean forever) {
if (peer == null) {
_log.error("wtf, why did we try to shitlist null?", new Exception("shitfaced"));
return false;
@ -103,18 +111,21 @@ public class Shitlist {
if (_log.shouldLog(Log.INFO))
_log.info("Shitlisting router " + peer.toBase64(), new Exception("Shitlist cause: " + reason));
long period = SHITLIST_DURATION_MS + _context.random().nextLong(SHITLIST_DURATION_MS);
PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) {
period = SHITLIST_DURATION_MS << prof.incrementShitlists();
period += _context.random().nextLong(period);
}
if (period > 60*60*1000)
period = 60*60*1000;
Entry e = new Entry();
e.expireOn = _context.clock().now() + period;
if (forever) {
e.expireOn = _context.clock().now() + SHITLIST_DURATION_FOREVER;
} else {
long period = SHITLIST_DURATION_MS + _context.random().nextLong(SHITLIST_DURATION_MS);
PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) {
period = SHITLIST_DURATION_MS << prof.incrementShitlists();
period += _context.random().nextLong(period);
}
if (period > SHITLIST_DURATION_MAX)
period = SHITLIST_DURATION_MAX;
e.expireOn = _context.clock().now() + period;
}
e.cause = reason;
e.transports = null;
if (transport != null) {
@ -123,17 +134,22 @@ public class Shitlist {
}
synchronized (_entries) {
Entry old = (Entry)_entries.put(peer, e);
Entry old = (Entry)_entries.get(peer);
if (old != null) {
wasAlready = true;
_entries.put(peer, old);
if (e.transports == null) {
old.transports = null;
} else if (old.transports != null) {
old.transports.addAll(e.transports);
// take the oldest expiration and cause, combine transports
if (old.expireOn > e.expireOn) {
e.expireOn = old.expireOn;
e.cause = old.cause;
}
if (e.transports != null) {
if (old.transports != null)
e.transports.addAll(old.transports);
else
e.transports = null;
}
e = old;
}
_entries.put(peer, e);
}
if (transport == null) {
@ -222,13 +238,27 @@ public class Shitlist {
return rv;
}
public boolean isShitlistedForever(Hash peer) {
Entry entry;
synchronized (_entries) {
entry = (Entry)_entries.get(peer);
}
return entry != null && entry.expireOn > _context.clock().now() + SHITLIST_DURATION_MAX;
}
class HashComparator implements Comparator {
public int compare(Object l, Object r) {
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
}
}
public void renderStatusHTML(Writer out) throws IOException {
StringBuffer buf = new StringBuffer(1024);
buf.append("<h2>Shitlist</h2>");
Map entries = null;
Map entries = new TreeMap(new HashComparator());
synchronized (_entries) {
entries = new HashMap(_entries);
entries.putAll(_entries);
}
buf.append("<ul>");
@ -241,7 +271,7 @@ public class Shitlist {
continue;
}
buf.append("<li><b>").append(key.toBase64()).append("</b>");
buf.append(" <a href=\"netdb.jsp#").append(key.toBase64().substring(0, 6)).append("\">(?)</a>");
buf.append(" (<a href=\"netdb.jsp#").append(key.toBase64().substring(0, 6)).append("\">netdb</a>)");
buf.append(" expiring in ");
buf.append(DataHelper.formatDuration(entry.expireOn-_context.clock().now()));
Set transports = entry.transports;
@ -251,12 +281,16 @@ public class Shitlist {
buf.append("<br />\n");
buf.append(entry.cause);
}
// future
// buf.append(" (<a href=\"configblock.jsp?peer=").append(key.toBase64()).append("#unsh\">unshitlist now</a>)");
buf.append("</li>\n");
}
buf.append("</ul>\n");
buf.append("<i>Partial shitlisted peers (only blocked on some transports): ");
buf.append(partial);
buf.append("</i>\n");
if (partial > 0) {
buf.append("<i>Partial shitlisted peers (only blocked on some transports): ");
buf.append(partial);
buf.append("</i>\n");
}
out.write(buf.toString());
out.flush();
}

View File

@ -13,6 +13,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@ -20,6 +21,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
@ -579,13 +581,13 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
*/
String validate(Hash key, LeaseSet leaseSet) {
if (!key.equals(leaseSet.getDestination().calculateHash())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid store attempt! key does not match leaseSet.destination! key = "
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid store attempt! key does not match leaseSet.destination! key = "
+ key + ", leaseSet = " + leaseSet);
return "Key does not match leaseSet.destination - " + key.toBase64();
} else if (!leaseSet.verifySignature()) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid leaseSet signature! leaseSet = " + leaseSet);
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid leaseSet signature! leaseSet = " + leaseSet);
return "Invalid leaseSet signature on " + leaseSet.getDestination().calculateHash().toBase64();
} else if (leaseSet.getEarliestLeaseDate() <= _context.clock().now() - 2*Router.CLOCK_FUDGE_FACTOR) {
long age = _context.clock().now() - leaseSet.getEarliestLeaseDate();
@ -597,8 +599,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
+ " expired " + DataHelper.formatDuration(age) + " ago";
} else if (leaseSet.getEarliestLeaseDate() > _context.clock().now() + Router.CLOCK_FUDGE_FACTOR + MAX_LEASE_FUTURE) {
long age = leaseSet.getEarliestLeaseDate() - _context.clock().now();
if (_log.shouldLog(Log.WARN))
_log.warn("LeaseSet to expire too far in the future: "
if (_log.shouldLog(Log.ERROR))
_log.error("LeaseSet to expire too far in the future: "
+ leaseSet.getDestination().calculateHash().toBase64()
+ " expires on " + new Date(leaseSet.getEarliestLeaseDate()), new Exception("Rejecting store"));
return "Expired leaseSet for " + leaseSet.getDestination().calculateHash().toBase64()
@ -924,6 +926,24 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
_context.jobQueue().addJob(new StoreJob(_context, this, key, ds, onSuccess, onFailure, sendTimeout, toIgnore));
}
class LeaseSetComparator implements Comparator {
public int compare(Object l, Object r) {
Destination dl = ((LeaseSet)l).getDestination();
Destination dr = ((LeaseSet)r).getDestination();
boolean locall = _context.clientManager().isLocal(dl);
boolean localr = _context.clientManager().isLocal(dr);
if (locall && !localr) return -1;
if (localr && !locall) return 1;
return dl.calculateHash().toBase64().compareTo(dr.calculateHash().toBase64());
}
}
class RouterInfoComparator implements Comparator {
public int compare(Object l, Object r) {
return ((RouterInfo)l).getIdentity().getHash().toBase64().compareTo(((RouterInfo)r).getIdentity().getHash().toBase64());
}
}
public void renderStatusHTML(Writer out) throws IOException {
StringBuffer buf = new StringBuffer(10*1024);
buf.append("<h2>Kademlia Network DB Contents</h2>\n");
@ -933,7 +953,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
out.flush();
return;
}
Set leases = getLeases();
Set leases = new TreeSet(new LeaseSetComparator());
leases.addAll(getLeases());
buf.append("<h3>Leases</h3>\n");
out.write(buf.toString());
buf.setLength(0);
@ -978,7 +999,6 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
}
Hash us = _context.routerHash();
Set routers = getRouters();
out.write("<h3>Routers</h3>\n");
RouterInfo ourInfo = _context.router().getRouterInfo();
@ -989,6 +1009,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
/* coreVersion to Map of routerVersion to Integer */
Map versions = new TreeMap();
Set routers = new TreeSet(new RouterInfoComparator());
routers.addAll(getRouters());
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
@ -1038,7 +1060,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
String hash = info.getIdentity().getHash().toBase64();
if (isUs) {
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
buf.append("<a name=\"our-info\" /a><b>Our info (").append(hash).append(") : </b><br />\n");
buf.append("<a name=\"our-info\" /a><b>Our info: ").append(hash).append("</b><br />\n");
} else {
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
buf.append("<b>Peer info for:</b> ").append(hash).append("<br />\n");