From f3b8c73e96c4a5a43e44c27b704b0ff21e1de6a7 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 7 Jun 2008 17:44:13 +0000 Subject: [PATCH] * 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 --- history.txt | 10 +++ .../src/net/i2p/router/RouterVersion.java | 2 +- router/java/src/net/i2p/router/Shitlist.java | 84 +++++++++++++------ .../KademliaNetworkDatabaseFacade.java | 40 +++++++-- 4 files changed, 101 insertions(+), 35 deletions(-) diff --git a/history.txt b/history.txt index fa85b7afa..370ec2820 100644 --- a/history.txt +++ b/history.txt @@ -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() diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 16af54d82..3f2309f5f 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -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); diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index 43c24a2e6..48cadfcf4 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -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("

Shitlist

"); - Map entries = null; + Map entries = new TreeMap(new HashComparator()); synchronized (_entries) { - entries = new HashMap(_entries); + entries.putAll(_entries); } buf.append("\n"); - buf.append("Partial shitlisted peers (only blocked on some transports): "); - buf.append(partial); - buf.append("\n"); + if (partial > 0) { + buf.append("Partial shitlisted peers (only blocked on some transports): "); + buf.append(partial); + buf.append("\n"); + } out.write(buf.toString()); out.flush(); } 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 60e2b1b8b..06b2fe398 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java @@ -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("

Kademlia Network DB Contents

\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("

Leases

\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("

Routers

\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(""); - buf.append("Our info (").append(hash).append(") :
\n"); + buf.append("
Our info: ").append(hash).append("
\n"); } else { buf.append("
"); buf.append("Peer info for: ").append(hash).append("
\n");