forked from I2P_Developers/i2p.i2p
Sybil tool enhancements
This commit is contained in:
@ -7,7 +7,7 @@ public class NetDbHelper extends HelperBase {
|
|||||||
private String _routerPrefix;
|
private String _routerPrefix;
|
||||||
private String _version;
|
private String _version;
|
||||||
private String _country;
|
private String _country;
|
||||||
private String _family, _caps, _ip;
|
private String _family, _caps, _ip, _sybil;
|
||||||
private int _full;
|
private int _full;
|
||||||
private boolean _lease;
|
private boolean _lease;
|
||||||
private boolean _debug;
|
private boolean _debug;
|
||||||
@ -68,6 +68,12 @@ public class NetDbHelper extends HelperBase {
|
|||||||
_ip = DataHelper.stripHTML(c); // XSS
|
_ip = DataHelper.stripHTML(c); // XSS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.28 */
|
||||||
|
public void setSybil(String c) {
|
||||||
|
if (c != null)
|
||||||
|
_sybil = DataHelper.stripHTML(c); // XSS
|
||||||
|
}
|
||||||
|
|
||||||
public void setFull(String f) {
|
public void setFull(String f) {
|
||||||
try {
|
try {
|
||||||
_full = Integer.parseInt(f);
|
_full = Integer.parseInt(f);
|
||||||
@ -95,8 +101,9 @@ public class NetDbHelper extends HelperBase {
|
|||||||
try {
|
try {
|
||||||
renderNavBar();
|
renderNavBar();
|
||||||
if (_routerPrefix != null || _version != null || _country != null ||
|
if (_routerPrefix != null || _version != null || _country != null ||
|
||||||
_family != null || _caps != null || _ip != null)
|
_family != null || _caps != null || _ip != null || _sybil != null)
|
||||||
renderer.renderRouterInfoHTML(_out, _routerPrefix, _version, _country, _family, _caps, _ip);
|
renderer.renderRouterInfoHTML(_out, _routerPrefix, _version, _country,
|
||||||
|
_family, _caps, _ip, _sybil);
|
||||||
else if (_lease)
|
else if (_lease)
|
||||||
renderer.renderLeaseSetHTML(_out, _debug);
|
renderer.renderLeaseSetHTML(_out, _debug);
|
||||||
else if (_full == 3)
|
else if (_full == 3)
|
||||||
|
@ -88,8 +88,10 @@ class NetDbRenderer {
|
|||||||
* @param family may be null
|
* @param family may be null
|
||||||
*/
|
*/
|
||||||
public void renderRouterInfoHTML(Writer out, String routerPrefix, String version,
|
public void renderRouterInfoHTML(Writer out, String routerPrefix, String version,
|
||||||
String country, String family, String caps, String ip) throws IOException {
|
String country, String family, String caps,
|
||||||
|
String ip, String sybil) throws IOException {
|
||||||
StringBuilder buf = new StringBuilder(4*1024);
|
StringBuilder buf = new StringBuilder(4*1024);
|
||||||
|
List<Hash> sybils = sybil != null ? new ArrayList<Hash>(128) : null;
|
||||||
if (".".equals(routerPrefix)) {
|
if (".".equals(routerPrefix)) {
|
||||||
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
|
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
|
||||||
} else {
|
} else {
|
||||||
@ -116,14 +118,18 @@ class NetDbRenderer {
|
|||||||
(version != null && version.equals(ri.getVersion())) ||
|
(version != null && version.equals(ri.getVersion())) ||
|
||||||
(country != null && country.equals(_context.commSystem().getCountry(key))) ||
|
(country != null && country.equals(_context.commSystem().getCountry(key))) ||
|
||||||
(family != null && family.equals(ri.getOption("family"))) ||
|
(family != null && family.equals(ri.getOption("family"))) ||
|
||||||
(caps != null && caps.equals(ri.getCapabilities()))) {
|
(caps != null && ri.getCapabilities().contains(caps))) {
|
||||||
renderRouterInfo(buf, ri, false, true);
|
renderRouterInfo(buf, ri, false, true);
|
||||||
|
if (sybil != null)
|
||||||
|
sybils.add(key);
|
||||||
notFound = false;
|
notFound = false;
|
||||||
} else if (ip != null) {
|
} else if (ip != null) {
|
||||||
for (RouterAddress ra : ri.getAddresses()) {
|
for (RouterAddress ra : ri.getAddresses()) {
|
||||||
if (ipMode == 0) {
|
if (ipMode == 0) {
|
||||||
if (ip.equals(ra.getHost())) {
|
if (ip.equals(ra.getHost())) {
|
||||||
renderRouterInfo(buf, ri, false, true);
|
renderRouterInfo(buf, ri, false, true);
|
||||||
|
if (sybil != null)
|
||||||
|
sybils.add(key);
|
||||||
notFound = false;
|
notFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -131,6 +137,8 @@ class NetDbRenderer {
|
|||||||
String host = ra.getHost();
|
String host = ra.getHost();
|
||||||
if (host != null && host.startsWith(ip)) {
|
if (host != null && host.startsWith(ip)) {
|
||||||
renderRouterInfo(buf, ri, false, true);
|
renderRouterInfo(buf, ri, false, true);
|
||||||
|
if (sybil != null)
|
||||||
|
sybils.add(key);
|
||||||
notFound = false;
|
notFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -153,6 +161,8 @@ class NetDbRenderer {
|
|||||||
}
|
}
|
||||||
out.write(buf.toString());
|
out.write(buf.toString());
|
||||||
out.flush();
|
out.flush();
|
||||||
|
if (sybil != null)
|
||||||
|
SybilRenderer.renderSybilHTML(out, _context, sybils, sybil);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.data.Base64;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
@ -23,6 +24,7 @@ import net.i2p.data.LeaseSet;
|
|||||||
import net.i2p.data.router.RouterAddress;
|
import net.i2p.data.router.RouterAddress;
|
||||||
import net.i2p.data.router.RouterInfo;
|
import net.i2p.data.router.RouterInfo;
|
||||||
import net.i2p.data.router.RouterKeyGenerator;
|
import net.i2p.data.router.RouterKeyGenerator;
|
||||||
|
import net.i2p.kademlia.XORComparator;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import net.i2p.router.crypto.FamilyKeyCrypto;
|
import net.i2p.router.crypto.FamilyKeyCrypto;
|
||||||
@ -450,7 +452,7 @@ class SybilRenderer {
|
|||||||
int i3 = i & 0xff;
|
int i3 = i & 0xff;
|
||||||
String sip = i0 + "." + i1 + '.' + i2 + '.' + i3;
|
String sip = i0 + "." + i1 + '.' + i2 + '.' + i3;
|
||||||
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
||||||
.append(sip).append("\">").append(sip)
|
.append(sip).append("&sybil\">").append(sip)
|
||||||
.append("</a>:</b></p>");
|
.append("</a>:</b></p>");
|
||||||
for (RouterInfo info : ris) {
|
for (RouterInfo info : ris) {
|
||||||
byte[] ip = getIP(info);
|
byte[] ip = getIP(info);
|
||||||
@ -503,7 +505,7 @@ class SybilRenderer {
|
|||||||
int i2 = i & 0xff;
|
int i2 = i & 0xff;
|
||||||
String sip = i0 + "." + i1 + '.' + i2 + ".0/24";
|
String sip = i0 + "." + i1 + '.' + i2 + ".0/24";
|
||||||
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
||||||
.append(sip).append("\">").append(sip)
|
.append(sip).append("&sybil\">").append(sip)
|
||||||
.append("</a>:</b></p>");
|
.append("</a>:</b></p>");
|
||||||
for (RouterInfo info : ris) {
|
for (RouterInfo info : ris) {
|
||||||
byte[] ip = getIP(info);
|
byte[] ip = getIP(info);
|
||||||
@ -553,7 +555,7 @@ class SybilRenderer {
|
|||||||
int i1 = i & 0xff;
|
int i1 = i & 0xff;
|
||||||
String sip = i0 + "." + i1 + ".0/16";
|
String sip = i0 + "." + i1 + ".0/16";
|
||||||
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
buf.append("<p><b>").append(count).append(" floodfills with IP <a href=\"/netdb?ip=")
|
||||||
.append(sip).append("\">").append(sip)
|
.append(sip).append("&sybil\">").append(sip)
|
||||||
.append("</a></b></p>");
|
.append("</a></b></p>");
|
||||||
for (RouterInfo info : ris) {
|
for (RouterInfo info : ris) {
|
||||||
byte[] ip = getIP(info);
|
byte[] ip = getIP(info);
|
||||||
@ -595,7 +597,7 @@ class SybilRenderer {
|
|||||||
int count = oc.count(s);
|
int count = oc.count(s);
|
||||||
String ss = DataHelper.escapeHTML(s);
|
String ss = DataHelper.escapeHTML(s);
|
||||||
buf.append("<p><b>").append(count).append(" floodfills in declared family \"<a href=\"/netdb?fam=")
|
buf.append("<p><b>").append(count).append(" floodfills in declared family \"<a href=\"/netdb?fam=")
|
||||||
.append(ss).append("\">").append(ss).append("</a>\"</b></p>");
|
.append(ss).append("&sybil\">").append(ss).append("</a>\"</b></p>");
|
||||||
for (RouterInfo info : ris) {
|
for (RouterInfo info : ris) {
|
||||||
String fam = info.getOption("family");
|
String fam = info.getOption("family");
|
||||||
if (fam == null)
|
if (fam == null)
|
||||||
@ -901,6 +903,77 @@ class SybilRenderer {
|
|||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from NetDbRenderer
|
||||||
|
*
|
||||||
|
* @since 0.9.28
|
||||||
|
*/
|
||||||
|
public static void renderSybilHTML(Writer out, RouterContext ctx, List<Hash> sybils, String victim) throws IOException {
|
||||||
|
if (sybils.isEmpty())
|
||||||
|
return;
|
||||||
|
final DecimalFormat fmt = new DecimalFormat("#0.00");
|
||||||
|
XORComparator<Hash> xor = new XORComparator<Hash>(Hash.FAKE_HASH);
|
||||||
|
out.write("<h3>Group Distances</h3><table><tr><th>Hash<th>Distance from previous</tr>\n");
|
||||||
|
Collections.sort(sybils, xor);
|
||||||
|
Hash prev = null;
|
||||||
|
for (Hash h : sybils) {
|
||||||
|
out.write("<tr><td><tt>" + h.toBase64() + "</tt><td>");
|
||||||
|
if (prev != null) {
|
||||||
|
BigInteger dist = HashDistance.getDistance(prev, h);
|
||||||
|
writeDistance(out, fmt, dist);
|
||||||
|
}
|
||||||
|
prev = h;
|
||||||
|
out.write("</tr>\n");
|
||||||
|
}
|
||||||
|
out.write("</table>\n");
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
RouterKeyGenerator rkgen = ctx.routerKeyGenerator();
|
||||||
|
long now = ctx.clock().now();
|
||||||
|
final int days = 7;
|
||||||
|
Hash from = ctx.routerHash();
|
||||||
|
if (victim != null) {
|
||||||
|
byte[] b = Base64.decode(victim);
|
||||||
|
if (b != null && b.length == Hash.HASH_LENGTH)
|
||||||
|
from = Hash.create(b);
|
||||||
|
}
|
||||||
|
out.write("<h3>Distance to " + from.toBase64() + "</h3>");
|
||||||
|
prev = null;
|
||||||
|
for (int i = 0; i < days; i++) {
|
||||||
|
out.write("<h3>Distance for " + new Date(now) +
|
||||||
|
"</h3><table><tr><th>Hash<th>Distance<th>Distance from previous</tr>\n");
|
||||||
|
Hash rkey = rkgen.getRoutingKey(from, now);
|
||||||
|
xor = new XORComparator<Hash>(rkey);
|
||||||
|
Collections.sort(sybils, xor);
|
||||||
|
for (Hash h : sybils) {
|
||||||
|
out.write("<tr><td><tt>" + h.toBase64() + "</tt><td>");
|
||||||
|
BigInteger dist = HashDistance.getDistance(rkey, h);
|
||||||
|
writeDistance(out, fmt, dist);
|
||||||
|
out.write("<td>");
|
||||||
|
if (prev != null) {
|
||||||
|
dist = HashDistance.getDistance(prev, h);
|
||||||
|
writeDistance(out, fmt, dist);
|
||||||
|
}
|
||||||
|
prev = h;
|
||||||
|
out.write("</tr>\n");
|
||||||
|
}
|
||||||
|
out.write("</table>\n");
|
||||||
|
out.flush();
|
||||||
|
now += 24*60*60*1000;
|
||||||
|
prev = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.28 */
|
||||||
|
private static void writeDistance(Writer out, DecimalFormat fmt, BigInteger dist) throws IOException {
|
||||||
|
double distance = biLog2(dist);
|
||||||
|
if (distance < MIN_CLOSE)
|
||||||
|
out.write("<font color=\"red\">");
|
||||||
|
out.write(fmt.format(distance));
|
||||||
|
if (distance < MIN_CLOSE)
|
||||||
|
out.write("</font>");
|
||||||
|
}
|
||||||
|
|
||||||
/** translate a string */
|
/** translate a string */
|
||||||
private String _t(String s) {
|
private String _t(String s) {
|
||||||
return Messages.getString(s, _context);
|
return Messages.getString(s, _context);
|
||||||
|
@ -28,5 +28,6 @@
|
|||||||
<jsp:setProperty name="netdbHelper" property="family" value="<%=request.getParameter(\"fam\")%>" />
|
<jsp:setProperty name="netdbHelper" property="family" value="<%=request.getParameter(\"fam\")%>" />
|
||||||
<jsp:setProperty name="netdbHelper" property="caps" value="<%=request.getParameter(\"caps\")%>" />
|
<jsp:setProperty name="netdbHelper" property="caps" value="<%=request.getParameter(\"caps\")%>" />
|
||||||
<jsp:setProperty name="netdbHelper" property="ip" value="<%=request.getParameter(\"ip\")%>" />
|
<jsp:setProperty name="netdbHelper" property="ip" value="<%=request.getParameter(\"ip\")%>" />
|
||||||
|
<jsp:setProperty name="netdbHelper" property="sybil" value="<%=request.getParameter(\"sybil\")%>" />
|
||||||
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
||||||
</div></div></body></html>
|
</div></div></body></html>
|
||||||
|
@ -186,6 +186,26 @@ public class RouterKeyGenerator extends RoutingKeyGenerator {
|
|||||||
return getKey(origKey, _nextModData);
|
return getKey(origKey, _nextModData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the routing key for the specified date, not today's
|
||||||
|
*
|
||||||
|
* @param time Java time
|
||||||
|
* @since 0.9.28
|
||||||
|
*/
|
||||||
|
public Hash getRoutingKey(Hash origKey, long time) {
|
||||||
|
String modVal;
|
||||||
|
synchronized(this) {
|
||||||
|
modVal = _fmt.format(time);
|
||||||
|
}
|
||||||
|
if (modVal.length() != LENGTH)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
byte[] mod = new byte[LENGTH];
|
||||||
|
for (int i = 0; i < LENGTH; i++) {
|
||||||
|
mod[i] = (byte)(modVal.charAt(i) & 0xFF);
|
||||||
|
}
|
||||||
|
return getKey(origKey, mod);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a modified (yet consistent) hash from the origKey by generating the
|
* Generate a modified (yet consistent) hash from the origKey by generating the
|
||||||
* SHA256 of the targetKey with the specified modData appended to it
|
* SHA256 of the targetKey with the specified modData appended to it
|
||||||
|
Reference in New Issue
Block a user