forked from I2P_Developers/i2p.i2p
Compare commits
9 Commits
master
...
i2p.i2p-2.
Author | SHA1 | Date | |
---|---|---|---|
247a6d7a24 | |||
0555f4a51d | |||
38ea29b043 | |||
ee06f9a583 | |||
6a38a11225 | |||
36387ee8b2 | |||
1cca8923fd | |||
255d2ac86d | |||
0feda7eac0 |
@ -543,7 +543,7 @@ public class SybilRenderer {
|
||||
if (p < minDisplay)
|
||||
break; // sorted
|
||||
buf.append("<p class=\"threatpoints\"><b>Threat Points: " + fmt.format(p) + "</b></p><ul>");
|
||||
List<String> reasons = pp.getReasons();
|
||||
List<String> reasons = new ArrayList<>(pp.getReasons().keySet());
|
||||
if (reasons.size() > 1)
|
||||
Collections.sort(reasons, rcomp);
|
||||
for (String s : reasons) {
|
||||
|
@ -118,10 +118,16 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
public static final long DEFAULT_FREQUENCY = 24 * 60 * 60 * 1000L;
|
||||
public static final float MIN_BLOCK_POINTS = 12.01f;
|
||||
private static final byte[] IPV6_LOCALHOST = new byte[16];
|
||||
static { IPV6_LOCALHOST[15] = 1; }
|
||||
static {
|
||||
IPV6_LOCALHOST[15] = 1;
|
||||
}
|
||||
// i2pd bug 64:ff9b::/96
|
||||
private static final byte[] IPV6_NAT64 = new byte[16];
|
||||
static { IPV6_NAT64[1] = 0x64; IPV6_NAT64[2] = (byte) 0xff; IPV6_NAT64[3] = (byte) 0x9b; }
|
||||
static {
|
||||
IPV6_NAT64[1] = 0x64;
|
||||
IPV6_NAT64[2] = (byte) 0xff;
|
||||
IPV6_NAT64[3] = (byte) 0x9b;
|
||||
}
|
||||
|
||||
/** Get via getInstance() */
|
||||
private Analysis(RouterContext ctx, ClientAppManager mgr, String[] args) {
|
||||
@ -149,7 +155,9 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
return rv;
|
||||
}
|
||||
|
||||
public PersistSybil getPersister() { return _persister; }
|
||||
public PersistSybil getPersister() {
|
||||
return _persister;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the persisted blocklist and tell the router
|
||||
@ -157,9 +165,13 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
* @since 0.9.50
|
||||
*/
|
||||
private class InitJob extends JobImpl {
|
||||
public InitJob() { super(_context); }
|
||||
public InitJob() {
|
||||
super(_context);
|
||||
}
|
||||
|
||||
public String getName() { return "Load Sybil Blocklist"; }
|
||||
public String getName() {
|
||||
return "Load Sybil Blocklist";
|
||||
}
|
||||
|
||||
public void runJob() {
|
||||
Map<String, Long> map = _persister.readBlocklist();
|
||||
@ -234,6 +246,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
/**
|
||||
* ClientApp interface
|
||||
*
|
||||
* @param args ignored
|
||||
*/
|
||||
public synchronized void shutdown(String[] args) {
|
||||
@ -289,10 +302,12 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
private static class RouterInfoRoutingKeyComparator implements Comparator<RouterInfo>, Serializable {
|
||||
private final Hash _us;
|
||||
|
||||
/** @param us ROUTING KEY */
|
||||
public RouterInfoRoutingKeyComparator(Hash us) {
|
||||
_us = us;
|
||||
}
|
||||
|
||||
public int compare(RouterInfo l, RouterInfo r) {
|
||||
return HashDistance.getDistance(_us, l.getHash()).compareTo(HashDistance.getDistance(_us, r.getHash()));
|
||||
}
|
||||
@ -303,19 +318,20 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
* points1 is unmodified.
|
||||
*/
|
||||
/****
|
||||
private void mergePoints(Map<Hash, Points> points1, Map<Hash, Points> points2) {
|
||||
for (Map.Entry<Hash, Points> e : points1.entrySet()) {
|
||||
Hash h = e.getKey();
|
||||
Points p1 = e.getValue();
|
||||
Points p2 = points2.get(h);
|
||||
if (p2 != null) {
|
||||
p2.points += p1.points;
|
||||
p2.reasons.addAll(p1.reasons);
|
||||
} else {
|
||||
points2.put(h, p1);
|
||||
}
|
||||
}
|
||||
}
|
||||
* private void mergePoints(Map<Hash, Points> points1, Map<Hash, Points>
|
||||
* points2) {
|
||||
* for (Map.Entry<Hash, Points> e : points1.entrySet()) {
|
||||
* Hash h = e.getKey();
|
||||
* Points p1 = e.getValue();
|
||||
* Points p2 = points2.get(h);
|
||||
* if (p2 != null) {
|
||||
* p2.points += p1.points;
|
||||
* p2.reasons.addAll(p1.reasons);
|
||||
* } else {
|
||||
* points2.put(h, p1);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
****/
|
||||
|
||||
/** */
|
||||
@ -330,6 +346,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
/**
|
||||
* All the floodfills, not including us
|
||||
*
|
||||
* @since 0.9.38 split out from renderRouterInfoHTML
|
||||
*/
|
||||
public List<RouterInfo> getFloodfills(Hash us) {
|
||||
@ -347,6 +364,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
/**
|
||||
* All the routers, not including us
|
||||
*
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public List<RouterInfo> getAllRouters(Hash us) {
|
||||
@ -376,6 +394,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
/**
|
||||
* Analyze threats. No output.
|
||||
* Return separate maps for each cause instead?
|
||||
*
|
||||
* @param includeAll false for floodfills only
|
||||
* @since 0.9.38
|
||||
*/
|
||||
@ -440,7 +459,8 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
continue;
|
||||
Hash rkey = ls.getRoutingKey();
|
||||
TunnelPool in = clientInboundPools.get(client);
|
||||
String name = (in != null) ? DataHelper.escapeHTML(in.getSettings().getDestinationNickname()) : client.toBase64().substring(0,4);
|
||||
String name = (in != null) ? DataHelper.escapeHTML(in.getSettings().getDestinationNickname())
|
||||
: client.toBase64().substring(0, 4);
|
||||
// closest to routing key today
|
||||
calculateRouterInfo(rkey, name, ris, points);
|
||||
// closest to routing key tomorrow
|
||||
@ -460,13 +480,19 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private static class DummyList extends ArrayList<RouterInfo> {
|
||||
public DummyList() { super(0); }
|
||||
public DummyList() {
|
||||
super(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(RouterInfo ri) { return true; }
|
||||
public boolean add(RouterInfo ri) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocklist and Banlist if configured
|
||||
*
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private void doBlocking(Map<Hash, Points> points) {
|
||||
@ -474,10 +500,12 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
long now = _context.clock().now();
|
||||
long blockUntil = _context.getProperty(Analysis.PROP_BLOCKTIME, DEFAULT_BLOCK_TIME) + now;
|
||||
try {
|
||||
threshold = Double.parseDouble(_context.getProperty(PROP_THRESHOLD, Double.toString(DEFAULT_BLOCK_THRESHOLD)));
|
||||
threshold = Double
|
||||
.parseDouble(_context.getProperty(PROP_THRESHOLD, Double.toString(DEFAULT_BLOCK_THRESHOLD)));
|
||||
if (threshold < MIN_BLOCK_POINTS)
|
||||
threshold = MIN_BLOCK_POINTS;
|
||||
} catch (NumberFormatException nfe) {}
|
||||
} catch (NumberFormatException nfe) {
|
||||
}
|
||||
String day = DataHelper.formatTime(now);
|
||||
Set<String> blocks = new HashSet<String>();
|
||||
for (Map.Entry<Hash, Points> e : points.entrySet()) {
|
||||
@ -552,10 +580,10 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
break; // sorted;
|
||||
point *= PAIR_DISTANCE_FACTOR;
|
||||
String b2 = p.r2.getHash().toBase64();
|
||||
addPoints(points, p.r1.getHash(), point, "Very close (" + fmt.format(distance) +
|
||||
addPoints(points, p.r1.getHash(), point, Points.REASON_TOO_CLOSE + " (" + fmt.format(distance) +
|
||||
") to other " + other + " <a href=\"netdb?r=" + b2 + "\">" + b2 + "</a>");
|
||||
String b1 = p.r1.getHash().toBase64();
|
||||
addPoints(points, p.r2.getHash(), point, "Very close (" + fmt.format(distance) +
|
||||
addPoints(points, p.r2.getHash(), point, Points.REASON_TOO_CLOSE + " (" + fmt.format(distance) +
|
||||
") to other " + other + " <a href=\"netdb?r=" + b1 + "\">" + b1 + "</a>");
|
||||
}
|
||||
return avg;
|
||||
@ -585,6 +613,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
/**
|
||||
* v6 only
|
||||
*
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private static byte[] getIPv6(RouterInfo ri) {
|
||||
@ -632,15 +661,15 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
String reason48;
|
||||
|
||||
if (ourIP != null) {
|
||||
reason32 = "Same IP as <a href=\"/netdb?ip=" +
|
||||
reason32 = Points.REASON_SAME_IP4 + " as <a href=\"/netdb?ip=" +
|
||||
Addresses.toString(ourIP) +
|
||||
"&sybil\">us</a>";
|
||||
reason24 = "Same IPv4 /24 as <a href=\"/netdb?ip=" +
|
||||
reason24 = Points.REASON_SAME_IP4_24 + " as <a href=\"/netdb?ip=" +
|
||||
(ourIP[0] & 0xff) + '.' +
|
||||
(ourIP[1] & 0xff) + '.' +
|
||||
(ourIP[2] & 0xff) +
|
||||
".0/24&sybil\">us</a>";
|
||||
reason16 = "Same IPv4 /16 as <a href=\"/netdb?ip=" +
|
||||
reason16 = Points.REASON_SAME_IP4_16 + " as <a href=\"/netdb?ip=" +
|
||||
(ourIP[0] & 0xff) + '.' +
|
||||
(ourIP[1] & 0xff) +
|
||||
".0.0/16&sybil\">us</a>";
|
||||
@ -650,13 +679,13 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
reason16 = null;
|
||||
}
|
||||
if (ourIPv6 != null) {
|
||||
reason64 = "Same IPv6 /64 as <a href=\"/netdb?ip=" +
|
||||
reason64 = Points.REASON_SAME_IP6_64 + " as <a href=\"/netdb?ip=" +
|
||||
Integer.toString(((ourIPv6[0] << 8) & 0xff00) | (ourIPv6[1] & 0xff), 16) + ':' +
|
||||
Integer.toString(((ourIPv6[2] << 8) & 0xff00) | (ourIPv6[3] & 0xff), 16) + ':' +
|
||||
Integer.toString(((ourIPv6[4] << 8) & 0xff00) | (ourIPv6[5] & 0xff), 16) + ':' +
|
||||
Integer.toString(((ourIPv6[6] << 8) & 0xff00) | (ourIPv6[7] & 0xff), 16) +
|
||||
"::&sybil\">us</a>";
|
||||
reason48 = "Same IPv6 /48 as <a href=\"/netdb?ip=" +
|
||||
reason48 = Points.REASON_SAME_IP6_48 + " as <a href=\"/netdb?ip=" +
|
||||
Integer.toString(((ourIPv6[0] << 8) & 0xff00) | (ourIPv6[1] & 0xff), 16) + ':' +
|
||||
Integer.toString(((ourIPv6[2] << 8) & 0xff00) | (ourIPv6[3] & 0xff), 16) + ':' +
|
||||
Integer.toString(((ourIPv6[4] << 8) & 0xff00) | (ourIPv6[5] & 0xff), 16) +
|
||||
@ -729,7 +758,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int i1 = (i >> 16) & 0xff;
|
||||
int i2 = (i >> 8) & 0xff;
|
||||
int i3 = i & 0xff;
|
||||
String reason = "Same IP with <a href=\"/netdb?ip=" +
|
||||
String reason = Points.REASON_SAME_IP4 + " with <a href=\"/netdb?ip=" +
|
||||
i0 + '.' + i1 + '.' + i2 + '.' + i3 + "&sybil\">" +
|
||||
(count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
for (RouterInfo info : ris) {
|
||||
@ -778,7 +807,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int i0 = i >> 16;
|
||||
int i1 = (i >> 8) & 0xff;
|
||||
int i2 = i & 0xff;
|
||||
String reason = "Same IPv4 /24 with <a href=\"/netdb?ip=" +
|
||||
String reason = Points.REASON_SAME_IP4_24 + " with <a href=\"/netdb?ip=" +
|
||||
i0 + '.' + i1 + '.' + i2 + ".0/24&sybil\">" +
|
||||
(count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
for (RouterInfo info : ris) {
|
||||
@ -829,7 +858,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int i = ii.intValue();
|
||||
int i0 = i >> 8;
|
||||
int i1 = i & 0xff;
|
||||
String reason = "Same IPv4 /16 with <a href=\"/netdb?ip=" +
|
||||
String reason = Points.REASON_SAME_IP4_16 + " with <a href=\"/netdb?ip=" +
|
||||
i0 + '.' + i1 + ".0.0/16&sybil\">" +
|
||||
(count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
for (RouterInfo info : ris) {
|
||||
@ -878,7 +907,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int i5 = (int) ((i >> 16) & 0xff);
|
||||
int i6 = (int) ((i >> 8) & 0xff);
|
||||
int i7 = (int) (i & 0xff);
|
||||
String reason = "Same IPv6 /64 with <a href=\"/netdb?ip=" +
|
||||
String reason = Points.REASON_SAME_IP6_64 + " with <a href=\"/netdb?ip=" +
|
||||
Integer.toString((i0 << 8) | i1, 16) + ':' +
|
||||
Integer.toString((i2 << 8) | i3, 16) + ':' +
|
||||
Integer.toString((i4 << 8) | i5, 16) + ':' +
|
||||
@ -941,7 +970,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int i3 = (int) ((i >> 16) & 0xff);
|
||||
int i4 = (int) ((i >> 8) & 0xff);
|
||||
int i5 = (int) (i & 0xff);
|
||||
String reason = "Same IPv6 /48 with <a href=\"/netdb?ip=" +
|
||||
String reason = Points.REASON_SAME_IP6_48 + " with <a href=\"/netdb?ip=" +
|
||||
Integer.toString((i0 << 8) | i1, 16) + ':' +
|
||||
Integer.toString((i2 << 8) | i3, 16) + ':' +
|
||||
Integer.toString((i4 << 8) | i5, 16) +
|
||||
@ -1001,10 +1030,13 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
if (s.equals(ourFamily)) {
|
||||
if (fkc.verifyOurFamily(info)) {
|
||||
point = POINTS_OUR_FAMILY;
|
||||
reason = "Our family \"" + ss + "\" with <a href=\"/netdb?fam=" + ss + "&sybil\">" + (count - 1) + " other" + (( count > 2) ? "s" : "") + "</a>";
|
||||
reason = Points.REASON_MY_FAMILY + " \"" + ss + "\" with <a href=\"/netdb?fam=" + ss
|
||||
+ "&sybil\">"
|
||||
+ (count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
} else {
|
||||
point = POINTS_BAD_OUR_FAMILY;
|
||||
reason = "Spoofed our family \"" + ss + "\" with <a href=\"/netdb?fam=" + ss + "&sybil\">" + (count - 1) + " other" + (( count > 2) ? "s" : "") + "</a>";
|
||||
reason = Points.REASON_SPOOFED_MY_FAMILY + " \"" + ss + "\" with <a href=\"/netdb?fam=" + ss
|
||||
+ "&sybil\">" + (count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
}
|
||||
} else {
|
||||
FamilyKeyCrypto.Result r = fkc.verify(info);
|
||||
@ -1014,13 +1046,16 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
case INVALID_SIG:
|
||||
case NO_SIG:
|
||||
point = POINTS_BAD_FAMILY;
|
||||
reason = "Bad family config \"" + ss + '"';
|
||||
reason = Points.REASON_INVALID_FAMILY + " \"" + ss + '"';
|
||||
break;
|
||||
|
||||
case STORED_KEY:
|
||||
point = POINTS_FAMILY_VERIFIED;
|
||||
if (count > 1)
|
||||
reason = "In verified family \"" + ss + "\" with <a href=\"/netdb?fam=" + ss + "&sybil\">" + (count - 1) + " other" + (( count > 2) ? "s" : "") + "</a>";
|
||||
reason = Points.REASON_KNOWN_FAMILY + " \"" + ss + "\" with <a href=\"/netdb?fam="
|
||||
+ ss
|
||||
+ "&sybil\">" + (count - 1) + " other" + ((count > 2) ? "s" : "")
|
||||
+ "</a>";
|
||||
else
|
||||
reason = "In verified family \"" + ss + '"';
|
||||
break;
|
||||
@ -1034,18 +1069,23 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
default:
|
||||
point = POINTS_FAMILY;
|
||||
if (count > 1)
|
||||
reason = "In unverified family \"" + ss + "\" with <a href=\"/netdb?fam=" + ss + "&sybil\">" + (count - 1) + " other" + (( count > 2) ? "s" : "") + "</a>";
|
||||
reason = Points.REASON_VALID_FAMILY + " \"" + ss + "\" with <a href=\"/netdb?fam="
|
||||
+ ss
|
||||
+ "&sybil\">" + (count - 1) + " other" + ((count > 2) ? "s" : "")
|
||||
+ "</a>";
|
||||
else
|
||||
reason = "In unverified family \"" + ss + '"';
|
||||
reason = Points.REASON_VALID_FAMILY + " \"" + ss + '"';
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (count > 1) {
|
||||
point = POINTS_FAMILY;
|
||||
reason = "In unverified family \"" + ss + "\" with <a href=\"/netdb?fam=" + ss + "&sybil\">" + (count - 1) + " other" + (( count > 2) ? "s" : "") + "</a>";
|
||||
reason = Points.REASON_VALID_FAMILY + " \"" + ss + "\" with <a href=\"/netdb?fam=" + ss
|
||||
+ "&sybil\">"
|
||||
+ (count - 1) + " other" + ((count > 2) ? "s" : "") + "</a>";
|
||||
} else {
|
||||
point = POINTS_FAMILY;
|
||||
reason = "In unverified family \"" + ss + '"';
|
||||
reason = Points.REASON_VALID_FAMILY + " \"" + ss + '"';
|
||||
}
|
||||
addPoints(points, info.getHash(), point, reason);
|
||||
}
|
||||
@ -1062,7 +1102,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
for (RouterInfo info : ris) {
|
||||
Hash h = info.getHash();
|
||||
if (_context.banlist().isBanlisted(h)) {
|
||||
StringBuilder buf = new StringBuilder("Banlisted");
|
||||
StringBuilder buf = new StringBuilder(Points.REASON_BANLISTED);
|
||||
Banlist.Entry entry = banEntries.get(h);
|
||||
if (entry != null) {
|
||||
if (entry.cause != null) {
|
||||
@ -1087,7 +1127,7 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
// (POINTS_NEW / 48) for every hour under 48, max POINTS_NEW
|
||||
double point = Math.min(POINTS_NEW, (2 * DAY - age) / (2 * DAY / POINTS_NEW));
|
||||
addPoints(points, h, point,
|
||||
"First heard about: " + _t("{0} ago", DataHelper.formatDuration2(age)));
|
||||
Points.REASON_CONTACT + " " + _t("{0} ago", DataHelper.formatDuration2(age)));
|
||||
}
|
||||
}
|
||||
DBHistory dbh = prof.getDBHistory();
|
||||
@ -1100,7 +1140,8 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
if (ra.getTotalEventCount() > 0) {
|
||||
double avg = 100 * ra.getAverage();
|
||||
if (avg > 40)
|
||||
addPoints(points, h, (avg - 40) / 6.0, "Lookup fail rate " + ((int) avg) + '%');
|
||||
addPoints(points, h, (avg - 40) / 6.0,
|
||||
Points.REASON_ALWAYS_FAIL_LOOKUP + " " + ((int) avg) + '%');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1111,10 +1152,12 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
|
||||
public void addVersionPoints(List<RouterInfo> ris, Map<Hash, Points> points) {
|
||||
RouterInfo us = _context.router().getRouterInfo();
|
||||
if (us == null) return;
|
||||
if (us == null)
|
||||
return;
|
||||
String ourVer = us.getVersion();
|
||||
// TODO do the math once we hit version 1.0.0
|
||||
if (!ourVer.startsWith("0.9.")) return;
|
||||
if (!ourVer.startsWith("0.9."))
|
||||
return;
|
||||
ourVer = ourVer.substring(4);
|
||||
int dot = ourVer.indexOf('.');
|
||||
if (dot > 0)
|
||||
@ -1122,18 +1165,21 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int minor;
|
||||
try {
|
||||
minor = Integer.parseInt(ourVer);
|
||||
} catch (NumberFormatException nfe) { return; }
|
||||
} catch (NumberFormatException nfe) {
|
||||
return;
|
||||
}
|
||||
for (RouterInfo info : ris) {
|
||||
Hash h = info.getHash();
|
||||
String caps = info.getCapabilities();
|
||||
if (!caps.contains("R"))
|
||||
addPoints(points, h, POINTS_UNREACHABLE, "Unreachable: " + DataHelper.escapeHTML(caps));
|
||||
addPoints(points, h, POINTS_UNREACHABLE, Points.REASON_UNREACHABLE + DataHelper.escapeHTML(caps));
|
||||
if (!caps.contains("f"))
|
||||
addPoints(points, h, POINTS_NONFF, "Non-floodfill");
|
||||
addPoints(points, h, POINTS_NONFF, Points.REASON_NON_FLOODFILL);
|
||||
String hisFullVer = info.getVersion();
|
||||
if (!hisFullVer.startsWith("0.9.")) {
|
||||
if (!hisFullVer.startsWith("1."))
|
||||
addPoints(points, h, POINTS_BAD_VERSION, "Strange version " + DataHelper.escapeHTML(hisFullVer));
|
||||
addPoints(points, h, POINTS_BAD_VERSION,
|
||||
Points.REASON_BAD_VERSION + DataHelper.escapeHTML(hisFullVer));
|
||||
// TODO do the math once we hit version 1.0.0
|
||||
continue;
|
||||
}
|
||||
@ -1144,11 +1190,14 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
int hisMinor;
|
||||
try {
|
||||
hisMinor = Integer.parseInt(hisVer);
|
||||
} catch (NumberFormatException nfe) { continue; }
|
||||
} catch (NumberFormatException nfe) {
|
||||
continue;
|
||||
}
|
||||
int howOld = minor - hisMinor;
|
||||
if (howOld < 3)
|
||||
continue;
|
||||
addPoints(points, h, howOld * VERSION_FACTOR, howOld + " versions behind: " + DataHelper.escapeHTML(hisFullVer));
|
||||
addPoints(points, h, howOld * VERSION_FACTOR,
|
||||
Points.REASON_OLD_VERSION + howOld + " versions behind: " + DataHelper.escapeHTML(hisFullVer));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,13 +1221,15 @@ public class Analysis extends JobImpl implements RouterApp, Runnable {
|
||||
if (point <= 0)
|
||||
break;
|
||||
point *= OUR_KEY_FACTOR;
|
||||
addPoints(points, ri.getHash(), point, "Very close (" + fmt.format(dist) + ") to our key " + usName + ": " + us.toBase64());
|
||||
addPoints(points, ri.getHash(), point,
|
||||
Points.REASON_TOO_CLOSE + "(" + fmt.format(dist) + ") to our key " + usName + ": " + us.toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For debugging
|
||||
* http://forums.sun.com/thread.jspa?threadID=597652
|
||||
*
|
||||
* @since 0.7.14
|
||||
*/
|
||||
private static double biLog2(BigInteger a) {
|
||||
|
@ -3,6 +3,8 @@ package net.i2p.router.sybil;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
@ -12,18 +14,42 @@ import net.i2p.data.DataHelper;
|
||||
* @since 0.9.38 moved from SybilRenderer
|
||||
*/
|
||||
public class Points implements Comparable<Points> {
|
||||
private double points;
|
||||
private final List<String> reasons;
|
||||
private final Map<String, Double> reasons;
|
||||
|
||||
public static final String REASON_NON_FLOODFILL = "Non-floodfill: ";
|
||||
public static final String REASON_TOO_CLOSE = "Very close: ";
|
||||
public static final String REASON_ALWAYS_FAIL_LOOKUP = "Lookup fail rate: ";
|
||||
public static final String REASON_UNREACHABLE = "Unreachable: ";
|
||||
|
||||
public static final String REASON_BAD_VERSION = "Strange Version: ";
|
||||
public static final String REASON_OLD_VERSION = "Old Version: ";
|
||||
|
||||
public static final String REASON_MY_FAMILY = "Our family: ";
|
||||
public static final String REASON_SPOOFED_MY_FAMILY = "Spoofed my family: ";
|
||||
public static final String REASON_KNOWN_FAMILY = "Verified family: ";
|
||||
public static final String REASON_INVALID_FAMILY = "Invalid family: ";
|
||||
public static final String REASON_VALID_FAMILY = "Valid Unverified family: ";
|
||||
|
||||
public static final String REASON_SAME_IP4 = "Same IPv4: ";
|
||||
public static final String REASON_SAME_IP4_16 = "Same IPv4/16: ";
|
||||
public static final String REASON_SAME_IP4_24 = "Same IPv4/24: ";
|
||||
|
||||
public static final String REASON_SAME_IP6 = "Same IPv6: ";
|
||||
public static final String REASON_SAME_IP6_48 = "Same IPv6/48: ";
|
||||
public static final String REASON_SAME_IP6_64 = "Same IPv6/64: ";
|
||||
|
||||
public static final String REASON_BANLISTED = "Banlisted: ";
|
||||
public static final String REASON_CONTACT = "First Heard About: ";
|
||||
|
||||
/**
|
||||
* @since 0.9.38
|
||||
*/
|
||||
private Points() {
|
||||
reasons = new ArrayList<String>(4);
|
||||
reasons = new ConcurrentHashMap<String, Double>(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reason may not contain '%'
|
||||
* @param reason may not contain '%' or '\t'
|
||||
*/
|
||||
public Points(double d, String reason) {
|
||||
this();
|
||||
@ -31,32 +57,64 @@ public class Points implements Comparable<Points> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.38
|
||||
* Compare 2 reason strings by comparing them to the list of static constants above.
|
||||
* Ignores anything following the `:` when comparing the strings.
|
||||
*
|
||||
* @param comparator
|
||||
* @param base
|
||||
* @return
|
||||
*/
|
||||
public double getPoints() {
|
||||
return points;
|
||||
public static boolean compareReason(String comparator, String base) {
|
||||
String[] comparatorPrefix = DataHelper.split(comparator, ":");
|
||||
String[] basePrefix = DataHelper.split(base, ":");
|
||||
if (comparatorPrefix == null)
|
||||
return false;
|
||||
if (basePrefix == null)
|
||||
return false;
|
||||
return basePrefix[0].toLowerCase().equals(comparatorPrefix[0].toLowerCase());
|
||||
}
|
||||
|
||||
private double points() {
|
||||
double rv = 0;
|
||||
for (String reason : reasons.keySet()) {
|
||||
rv += reasons.get(reason);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public List<String> getReasons() {
|
||||
public double getPoints() {
|
||||
return points();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public Map<String, Double> getReasons() {
|
||||
return reasons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reason may not contain '%'
|
||||
* @param reason may not contain '%' or '\t'
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public void addPoints(double d, String reason) {
|
||||
points += d;
|
||||
DecimalFormat format = new DecimalFormat("#0.00");
|
||||
String rsn = format.format(d) + ": " + reason;
|
||||
reasons.add(rsn);
|
||||
Double rp = reasons.get(rsn);
|
||||
if (rp == null) {
|
||||
// reason was not yet present in the map, create a new entry for it.
|
||||
reasons.put(rsn, d);
|
||||
} else {
|
||||
// reason was present in the map, add the points to it.
|
||||
rp += d;
|
||||
}
|
||||
}
|
||||
|
||||
public int compareTo(Points r) {
|
||||
return Double.compare(points, r.points);
|
||||
return Double.compare(points(), r.points());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,28 +129,32 @@ public class Points implements Comparable<Points> {
|
||||
|
||||
/**
|
||||
* For persistence.
|
||||
* Total points and reasons, '%' separated, no newline.
|
||||
* points and reasons, '%' separated, new line between pairs.
|
||||
* The separation character is chosen to not conflict with
|
||||
* decimal point in various locales, or chars in reasons, including HTML links,
|
||||
* or special chars in Pattern.
|
||||
*
|
||||
* Format changed in 0.9.64
|
||||
*
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public void toString(StringBuilder buf) {
|
||||
buf.append(points);
|
||||
for (String r : reasons) {
|
||||
buf.append('%').append(r.replace("%", "%"));
|
||||
for (String r : reasons.keySet()) {
|
||||
buf.append(reasons.get(r)).append('%').append(r.replace("%", "%")).append("\t");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For persistence.
|
||||
*
|
||||
* @return null on failure
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public static Points fromString(String s) {
|
||||
String[] ss = DataHelper.split(s, "%");
|
||||
if (ss.length < 2)
|
||||
Points rv = new Points();
|
||||
for (String lineString : DataHelper.split(s, "\t")) {
|
||||
String[] ss = DataHelper.split(lineString, "%");
|
||||
if (ss.length != 2)
|
||||
return null;
|
||||
double d;
|
||||
try {
|
||||
@ -100,12 +162,8 @@ public class Points implements Comparable<Points> {
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
Points rv = new Points();
|
||||
for (int i = 1; i < ss.length; i++) {
|
||||
rv.reasons.add(ss[i]);
|
||||
rv.reasons.put(ss[1], d);
|
||||
}
|
||||
rv.points = d;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user