forked from I2P_Developers/i2p.i2p
Sybil: Option to run on non-floodfills too
This commit is contained in:
@@ -65,6 +65,7 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
public static final String PROP_FREQUENCY = "router.sybilFrequency";
|
||||
public static final String PROP_THRESHOLD = "router.sybilThreshold";
|
||||
public static final String PROP_BLOCK = "router.sybilBlock.enable";
|
||||
public static final String PROP_NONFF = "router.sybilIncludeAll";
|
||||
public static final String PROP_BLOCKTIME = "router.sybilBlock.period";
|
||||
private static final long MIN_FREQUENCY = 60*60*1000L;
|
||||
private static final long MIN_UPTIME = 75*60*1000L;
|
||||
@@ -81,6 +82,7 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
private static final double POINTS_US24 = 20.0;
|
||||
private static final double POINTS_US16 = 10.0;
|
||||
private static final double POINTS_FAMILY = -10.0;
|
||||
private static final double POINTS_NONFF = -5.0;
|
||||
private static final double POINTS_BAD_OUR_FAMILY = 100.0;
|
||||
private static final double POINTS_OUR_FAMILY = -100.0;
|
||||
public static final double MIN_CLOSE = 242.0;
|
||||
@@ -126,7 +128,7 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
public void runJob() {
|
||||
long now = _context.clock().now();
|
||||
_log.info("Running analysis");
|
||||
Map<Hash, Points> points = backgroundAnalysis();
|
||||
Map<Hash, Points> points = backgroundAnalysis(_context.getBooleanProperty(PROP_NONFF));
|
||||
if (!points.isEmpty()) {
|
||||
try {
|
||||
_log.info("Storing analysis");
|
||||
@@ -282,17 +284,30 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
/**
|
||||
* Analyze threats. No output.
|
||||
* Return separate maps for each cause instead?
|
||||
* @param includeAll false for floodfills only
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public synchronized Map<Hash, Points> backgroundAnalysis() {
|
||||
public synchronized Map<Hash, Points> backgroundAnalysis(boolean includeAll) {
|
||||
_wasRun = true;
|
||||
Map<Hash, Points> points = new HashMap<Hash, Points>(64);
|
||||
Hash us = _context.routerHash();
|
||||
if (us == null)
|
||||
return points;
|
||||
List<RouterInfo> ris = getFloodfills(us);
|
||||
List<RouterInfo> ris;
|
||||
if (includeAll) {
|
||||
Set<RouterInfo> set = _context.netDb().getRouters();
|
||||
ris = new ArrayList<RouterInfo>(set.size());
|
||||
for (RouterInfo ri : set) {
|
||||
if (!ri.getIdentity().getHash().equals(us))
|
||||
ris.add(ri);
|
||||
}
|
||||
} else {
|
||||
ris = getFloodfills(us);
|
||||
}
|
||||
if (ris.isEmpty())
|
||||
return points;
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Analyzing " + ris.size() + " routers, including non-floodfills? " + includeAll);
|
||||
|
||||
double avgMinDist = getAvgMinDist(ris);
|
||||
|
||||
@@ -396,8 +411,14 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
double total = 0;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
RouterInfo info1 = ris.get(i);
|
||||
// don't do distance calculation for non-floodfills
|
||||
if (!info1.getCapabilities().contains("f"))
|
||||
continue;
|
||||
for (int j = i + 1; j < sz; j++) {
|
||||
RouterInfo info2 = ris.get(j);
|
||||
// don't do distance calculation for non-floodfills
|
||||
if (!info2.getCapabilities().contains("f"))
|
||||
continue;
|
||||
BigInteger dist = HashDistance.getDistance(info1.getHash(), info2.getHash());
|
||||
if (pairs.isEmpty()) {
|
||||
pairs.add(new Pair(info1, info2, dist));
|
||||
@@ -699,6 +720,9 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
}
|
||||
addPoints(points, h, POINTS_BANLIST, buf.toString());
|
||||
}
|
||||
// don't do profile calcluations for non-floodfills
|
||||
if (!info.getCapabilities().contains("f"))
|
||||
continue;
|
||||
PeerProfile prof = _context.profileOrganizer().getProfileNonblocking(h);
|
||||
if (prof != null) {
|
||||
long heard = prof.getFirstHeardAbout();
|
||||
@@ -748,6 +772,8 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
String caps = info.getCapabilities();
|
||||
if (!caps.contains("R"))
|
||||
addPoints(points, h, POINTS_UNREACHABLE, "Unreachable: " + DataHelper.escapeHTML(caps));
|
||||
if (!caps.contains("f"))
|
||||
addPoints(points, h, POINTS_NONFF, "Non-floodfill");
|
||||
String hisFullVer = info.getVersion();
|
||||
if (!hisFullVer.startsWith("0.9.")) {
|
||||
addPoints(points, h, POINTS_BAD_VERSION, "Strange version " + DataHelper.escapeHTML(hisFullVer));
|
||||
@@ -779,6 +805,9 @@ public class Analysis extends JobImpl implements RouterApp {
|
||||
int count = Math.min(MAX, ris.size());
|
||||
for (int i = 0; i < count; i++) {
|
||||
RouterInfo ri = ris.get(i);
|
||||
// don't do distance calculation for non-floodfills
|
||||
if (!ri.getCapabilities().contains("f"))
|
||||
continue;
|
||||
BigInteger bidist = HashDistance.getDistance(us, ri.getHash());
|
||||
double dist = biLog2(bidist);
|
||||
double point = MIN_CLOSE - dist;
|
||||
|
@@ -242,6 +242,8 @@ public class NetDbHelper extends FormHandler {
|
||||
}
|
||||
String enable = getJettyString("block");
|
||||
toSave.put(Analysis.PROP_BLOCK, Boolean.toString(enable != null));
|
||||
String nonff = getJettyString("nonff");
|
||||
toSave.put(Analysis.PROP_NONFF, Boolean.toString(nonff != null));
|
||||
if (_context.router().saveConfig(toSave, null))
|
||||
addFormNotice(_t("Configuration saved successfully."));
|
||||
else
|
||||
@@ -273,7 +275,7 @@ public class NetDbHelper extends FormHandler {
|
||||
} else if (_full == 3) {
|
||||
if (_mode == 12 && !_postOK)
|
||||
_mode = 0;
|
||||
else if (_mode == 13 && !_postOK)
|
||||
else if ((_mode == 13 || _mode == 16) && !_postOK)
|
||||
_mode = 14;
|
||||
(new SybilRenderer(_context)).getNetDbSummary(_out, _newNonce, _mode, _date);
|
||||
} else if (_full == 4) {
|
||||
|
@@ -134,7 +134,7 @@ public class SybilRenderer {
|
||||
Hash us = _context.routerHash();
|
||||
Analysis analysis = Analysis.getInstance(_context);
|
||||
List<RouterInfo> ris = null;
|
||||
if (mode != 0 && mode != 12 && mode != 13 && mode != 14) {
|
||||
if (mode != 0 && mode != 12 && mode != 13 && mode != 14 && mode != 16) {
|
||||
ris = analysis.getFloodfills(us);
|
||||
if (ris.isEmpty()) {
|
||||
out.write("<h3 class=\"sybils\">No known floodfills</h3>");
|
||||
@@ -208,10 +208,10 @@ public class SybilRenderer {
|
||||
} else {
|
||||
renderThreatsHTML(out, buf, date, points);
|
||||
}
|
||||
} else if (mode == 13) {
|
||||
} else if (mode == 13 || mode == 16) {
|
||||
// run analysis and store it
|
||||
long now = _context.clock().now();
|
||||
points = analysis.backgroundAnalysis();
|
||||
points = analysis.backgroundAnalysis(mode == 16);
|
||||
if (!points.isEmpty()) {
|
||||
PersistSybil ps = analysis.getPersister();
|
||||
try {
|
||||
@@ -273,6 +273,14 @@ public class SybilRenderer {
|
||||
"<input type=\"hidden\" name=\"m\" value=\"13\">\n" +
|
||||
"<input type=\"hidden\" name=\"nonce\" value=\"").append(nonce).append("\" >\n" +
|
||||
"<input type=\"submit\" name=\"action\" class=\"go\" value=\"Run new analysis\" />" +
|
||||
"(floodfills only)" +
|
||||
"</form><br>\n");
|
||||
buf.append("<form action=\"netdb\" method=\"POST\">\n" +
|
||||
"<input type=\"hidden\" name=\"f\" value=\"3\">\n" +
|
||||
"<input type=\"hidden\" name=\"m\" value=\"16\">\n" +
|
||||
"<input type=\"hidden\" name=\"nonce\" value=\"").append(nonce).append("\" >\n" +
|
||||
"<input type=\"submit\" name=\"action\" class=\"go\" value=\"Run new analysis\" />" +
|
||||
"(all routers)" +
|
||||
"</form>\n");
|
||||
writeBuf(out, buf);
|
||||
}
|
||||
@@ -302,12 +310,17 @@ public class SybilRenderer {
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
boolean auto = _context.getBooleanProperty(Analysis.PROP_BLOCK);
|
||||
boolean nonff = _context.getBooleanProperty(Analysis.PROP_NONFF);
|
||||
String thresh = _context.getProperty(Analysis.PROP_THRESHOLD, "50");
|
||||
long days = _context.getProperty(Analysis.PROP_BLOCKTIME, 7*24*60*60*1000L) / (24*60*60*1000L);
|
||||
buf.append("</select></td></tr>\n<tr><td>" +
|
||||
"Auto-block routers?</td><td><input type=\"checkbox\" class=\"optbox\" value=\"1\" name=\"block\" ");
|
||||
if (auto)
|
||||
buf.append(HelperBase.CHECKED);
|
||||
buf.append("></td></tr>\n<tr><td>" +
|
||||
"Include non-floodfills?</td><td><input type=\"checkbox\" class=\"optbox\" value=\"1\" name=\"nonff\" ");
|
||||
if (nonff)
|
||||
buf.append(HelperBase.CHECKED);
|
||||
buf.append("></td></tr>\n<tr><td>" +
|
||||
"Minimum threat points to block:</td><td><input type=\"text\" name=\"threshold\" value=\"").append(thresh).append("\"></td></tr>\n<tr><td>" +
|
||||
"Days to block:</td><td><input type=\"text\" name=\"days\" value=\"").append(days).append("\"></td></tr>\n<tr><td></td><td>" +
|
||||
|
Reference in New Issue
Block a user