From 997ef73d504c37eef1f4dd72f6ff4d87f7921f86 Mon Sep 17 00:00:00 2001
From: zzz
Date: Sat, 5 Dec 2015 13:50:00 +0000
Subject: [PATCH] Sybil tool: Test tomorrow's routing keys also Add netdb stats
output Add avg. ff distance output Increase penalty for proximity to our keys
Reduce number of RIs output
---
.../src/net/i2p/router/web/SybilRenderer.java | 84 ++++++++++++++-----
1 file changed, 64 insertions(+), 20 deletions(-)
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SybilRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SybilRenderer.java
index b63993f8c..b03dbf566 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SybilRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SybilRenderer.java
@@ -21,8 +21,10 @@ import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.router.RouterAddress;
import net.i2p.data.router.RouterInfo;
+import net.i2p.data.router.RouterKeyGenerator;
import net.i2p.router.RouterContext;
import net.i2p.router.TunnelPoolSettings;
+import net.i2p.router.peermanager.DBHistory;
import net.i2p.router.peermanager.PeerProfile;
import net.i2p.router.tunnel.pool.TunnelPool;
import net.i2p.router.util.HashDistance;
@@ -43,7 +45,7 @@ class SybilRenderer {
private final RouterContext _context;
- private static final int PAIRMAX = 10;
+ private static final int PAIRMAX = 20;
private static final int MAX = 10;
// multiplied by size - 1, will also get POINTS24 added
private static final double POINTS32 = 10.0;
@@ -52,6 +54,7 @@ class SybilRenderer {
// multiplied by size - 1
private static final double POINTS16 = 0.25;
private static final double MIN_CLOSE = 242.0;
+ private static final double OUR_KEY_FACTOR = 4.0;
private static final double MIN_DISPLAY_POINTS = 3.0;
public SybilRenderer(RouterContext ctx) {
@@ -181,6 +184,10 @@ class SybilRenderer {
// Distance to our router analysis
buf.append("Closest Floodfills to Our Routing Key (Where we Store our RI)
");
renderRouterInfoHTML(out, buf, ourRKey, avgMinDist, ris, points);
+ RouterKeyGenerator rkgen = _context.routerKeyGenerator();
+ Hash nkey = rkgen.getNextRoutingKey(us);
+ buf.append("Closest Floodfills to Tomorrow's Routing Key (Where we will Store our RI)
");
+ renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
buf.append("Closest Floodfills to Our Router Hash (DHT Neighbors if we are Floodfill)
");
renderRouterInfoHTML(out, buf, us, avgMinDist, ris, points);
@@ -201,8 +208,11 @@ class SybilRenderer {
Hash rkey = ls.getRoutingKey();
TunnelPool in = clientInboundPools.get(client);
String name = (in != null) ? in.getSettings().getDestinationNickname() : client.toBase64().substring(0,4);
- buf.append("Closest floodfills to the Routing Key for Our Destination " + DataHelper.escapeHTML(name) + " (where we store our LS)
");
+ buf.append("Closest floodfills to the Routing Key for " + DataHelper.escapeHTML(name) + " (where we store our LS)
");
renderRouterInfoHTML(out, buf, rkey, avgMinDist, ris, points);
+ nkey = rkgen.getNextRoutingKey(ls.getHash());
+ buf.append("Closest floodfills to Tomorrow's Routing Key for " + DataHelper.escapeHTML(name) + " (where we store our LS)
");
+ renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
}
// TODO Profile analysis
@@ -245,9 +255,9 @@ class SybilRenderer {
}
private void renderPairDistance(Writer out, StringBuilder buf, List ris, Map points) throws IOException {
- buf.append("Closest Floodfill Pairs by Hash
");
int sz = ris.size();
List pairs = new ArrayList(PAIRMAX);
+ double total = 0;
for (int i = 0; i < sz; i++) {
RouterInfo info1 = ris.get(i);
for (int j = i + 1; j < sz; j++) {
@@ -262,22 +272,31 @@ class SybilRenderer {
pairs.set(PAIRMAX - 1, new Pair(info1, info2, dist));
Collections.sort(pairs);
}
+ total += biLog2(dist);
}
}
+
DecimalFormat fmt = new DecimalFormat("#0.00");
+ double avg = total / (sz * sz / 2);
+ buf.append("Average Floodfill Distance is ").append(fmt.format(avg)).append("
");
+
+ buf.append("Closest Floodfill Pairs by Hash
");
for (Pair p : pairs) {
double distance = biLog2(p.dist);
- buf.append("Hash Distance: ").append(fmt.format(distance)).append(": ");
- buf.append("
");
- renderRouterInfo(buf, p.r1, null, false, false);
- renderRouterInfo(buf, p.r2, null, false, false);
double point = MIN_CLOSE - distance;
- if (point > 0) {
- addPoints(points, p.r1.getHash(), point, "Very close (" + fmt.format(distance) +
- ") to other floodfill " + p.r2.getHash().toBase64());
- addPoints(points, p.r2.getHash(), point, "Very close (" + fmt.format(distance) +
- ") to other floodfill " + p.r1.getHash().toBase64());
+ if (point < 0)
+ break; // sorted;
+ if (point >= 2) {
+ // limit display
+ buf.append("Hash Distance: ").append(fmt.format(distance)).append(": ");
+ buf.append("
");
+ renderRouterInfo(buf, p.r1, null, false, false);
+ renderRouterInfo(buf, p.r2, null, false, false);
}
+ addPoints(points, p.r1.getHash(), point, "Very close (" + fmt.format(distance) +
+ ") to other floodfill " + p.r2.getHash().toBase64());
+ addPoints(points, p.r2.getHash(), point, "Very close (" + fmt.format(distance) +
+ ") to other floodfill " + p.r1.getHash().toBase64());
}
out.write(buf.toString());
out.flush();
@@ -449,7 +468,7 @@ class SybilRenderer {
int i0 = i >> 8;
int i1 = i & 0xff;
buf.append("").append(count).append(" floodfills in ").append(i0).append('.')
- .append(i1).append(".0.0/16:
");
+ .append(i1).append(".0.0/16
");
for (RouterInfo info : ris) {
byte[] ip = getIP(info);
if (ip == null)
@@ -459,7 +478,8 @@ class SybilRenderer {
if ((ip[1] & 0xff) != i1)
continue;
found = true;
- renderRouterInfo(buf, info, null, false, false);
+ // limit display
+ //renderRouterInfo(buf, info, null, false, false);
double point = POINTS16 * (count - 1);
addPoints(points, info.getHash(), point, "Same /16 IP with " + (count - 1) + " other");
}
@@ -508,7 +528,7 @@ class SybilRenderer {
median = (median + dist) / 2;
double point = MIN_CLOSE - dist;
if (point > 0) {
- point *= 2.0;
+ point *= OUR_KEY_FACTOR;
addPoints(points, ri.getHash(), point, "Very close (" + fmt.format(dist) + ") to our key " + us.toBase64());
}
if (i >= MAX - 1)
@@ -599,19 +619,43 @@ class SybilRenderer {
buf.append("Last heard from: ")
.append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
}
+ DBHistory dbh = prof.getDBHistory();
+ if (dbh != null) {
+ heard = dbh.getLastLookupSuccessful();
+ if (heard > 0) {
+ long age = Math.max(now - heard, 1);
+ buf.append("Last lookup successful: ")
+ .append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
+ }
+ heard = dbh.getLastLookupFailed();
+ if (heard > 0) {
+ long age = Math.max(now - heard, 1);
+ buf.append("Last lookup failed: ")
+ .append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
+ }
+ heard = dbh.getLastStoreSuccessful();
+ if (heard > 0) {
+ long age = Math.max(now - heard, 1);
+ buf.append("Last store successful: ")
+ .append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
+ }
+ heard = dbh.getLastStoreFailed();
+ if (heard > 0) {
+ long age = Math.max(now - heard, 1);
+ buf.append("Last store failed: ")
+ .append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
+ }
+ }
// any other profile stuff?
}
}
- long age = now - info.getPublished();
+ long age = Math.max(now - info.getPublished(), 1);
if (isUs && _context.router().isHidden()) {
buf.append("").append(_t("Hidden")).append(", ").append(_t("Updated")).append(": ")
.append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
- } else if (age > 0) {
+ } else {
buf.append("").append(_t("Published")).append(": ")
.append(_t("{0} ago", DataHelper.formatDuration2(age))).append("
\n");
- } else {
- // shouldnt happen
- buf.append("" + _t("Published") + ": in ").append(DataHelper.formatDuration2(0-age)).append("???
\n");
}
buf.append("").append(_t("Signing Key")).append(": ")
.append(info.getIdentity().getSigningPublicKey().getType().toString());