use of net.i2p.data.router.RouterKeyGenerator in project i2p.i2p by i2p.
the class SybilRenderer method renderRouterInfoHTML.
/**
* The whole thing
*
* @param routerPrefix ignored
*/
private void renderRouterInfoHTML(Writer out, String routerPrefix) throws IOException {
Set<Hash> ffs = _context.peerManager().getPeersByCapability('f');
List<RouterInfo> ris = new ArrayList<RouterInfo>(ffs.size());
Hash us = _context.routerHash();
Hash ourRKey = _context.router().getRouterInfo().getRoutingKey();
for (Hash ff : ffs) {
if (ff.equals(us))
continue;
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(ff);
if (ri != null)
ris.add(ri);
}
if (ris.isEmpty()) {
out.write("<h3 class=\"sybils\">No known floodfills</h3>");
return;
}
StringBuilder buf = new StringBuilder(4 * 1024);
buf.append("<p id=\"sybilinfo\"><b>This is an experimental network database tool for debugging and analysis. Do not panic even if you see warnings below. " + "Possible \"threats\" are summarized at the bottom, however these are unlikely to be real threats. " + "If you see anything you would like to discuss with the devs, contact us on IRC #i2p-dev.</b></p>" + "<div id=\"sybilnav\"><ul><li><a href=\"#known\">FF Summary</a>" + "</li><li><a href=\"#family\">Same Family</a>" + "</li><li><a href=\"#ourIP\">IP close to us</a>" + "</li><li><a href=\"#sameIP\">Same IP</a>" + "</li><li><a href=\"#same24\">Same /24</a>" + "</li><li><a href=\"#same16\">Same /16</a>" + "</li><li><a href=\"#pairs\">Pair distance</a>" + "</li><li><a href=\"#ritoday\">Close to us</a>" + "</li><li><a href=\"#ritmrw\">Close to us tomorrow</a>" + "</li><li><a href=\"#dht\">DHT neighbors</a>" + "</li><li><a href=\"#dest\">Close to our destinations</a>" + "</li><li><a href=\"#threats\">Highest threats</a>" + "</li></ul></div>");
renderRouterInfo(buf, _context.router().getRouterInfo(), null, true, false);
buf.append("<h3 id=\"known\" class=\"sybils\">Known Floodfills: ").append(ris.size()).append("</h3>");
double tot = 0;
int count = 200;
byte[] b = new byte[32];
for (int i = 0; i < count; i++) {
_context.random().nextBytes(b);
Hash h = new Hash(b);
double d = closestDistance(h, ris);
tot += d;
}
double avgMinDist = tot / count;
buf.append("<div id=\"sybils_summary\">\n");
buf.append("<b>Average closest floodfill distance:</b> ").append(fmt.format(avgMinDist)).append("<br>\n");
buf.append("<b>Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getModData())).append("\" <b>Last Changed:</b> ").append(new Date(_context.routerKeyGenerator().getLastChanged())).append("<br>\n");
buf.append("<b>Next Routing Data:</b> \"").append(DataHelper.getUTF8(_context.routerKeyGenerator().getNextModData())).append("\" <b>Rotates in:</b> ").append(DataHelper.formatDuration(_context.routerKeyGenerator().getTimeTillMidnight())).append("\n");
buf.append("</div>\n");
Map<Hash, Points> points = new HashMap<Hash, Points>(64);
// IP analysis
renderIPGroupsFamily(out, buf, ris, points);
renderIPGroupsUs(out, buf, ris, points);
renderIPGroups32(out, buf, ris, points);
renderIPGroups24(out, buf, ris, points);
renderIPGroups16(out, buf, ris, points);
// Pairwise distance analysis
renderPairDistance(out, buf, ris, points);
// Distance to our router analysis
buf.append("<h3 id=\"ritoday\" class=\"sybils\">Closest Floodfills to Our Routing Key (Where we Store our RI)</h3>");
buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil\">See all</a></p>");
renderRouterInfoHTML(out, buf, ourRKey, avgMinDist, ris, points);
RouterKeyGenerator rkgen = _context.routerKeyGenerator();
Hash nkey = rkgen.getNextRoutingKey(us);
buf.append("<h3 id=\"ritmrw\" class=\"sybils\">Closest Floodfills to Tomorrow's Routing Key (Where we will Store our RI)</h3>");
buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil\">See all</a></p>");
renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
buf.append("<h3 id=\"dht\" class=\"sybils\">Closest Floodfills to Our Router Hash (DHT Neighbors if we are Floodfill)</h3>");
renderRouterInfoHTML(out, buf, us, avgMinDist, ris, points);
// Distance to our published destinations analysis
buf.append("<h3 id=\"dest\" class=\"sybils\">Floodfills Close to Our Destinations</h3>");
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
List<Hash> destinations = new ArrayList<Hash>(clientInboundPools.keySet());
// boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
for (Hash client : destinations) {
boolean isLocal = _context.clientManager().isLocal(client);
if (!isLocal)
continue;
if (!_context.clientManager().shouldPublishLeaseSet(client))
continue;
LeaseSet ls = _context.netDb().lookupLeaseSetLocally(client);
if (ls == null)
continue;
Hash rkey = ls.getRoutingKey();
TunnelPool in = clientInboundPools.get(client);
String name = (in != null) ? in.getSettings().getDestinationNickname() : client.toBase64().substring(0, 4);
buf.append("<h3 class=\"sybils\">Closest floodfills to the Routing Key for " + DataHelper.escapeHTML(name) + " (where we store our LS)</h3>");
buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
renderRouterInfoHTML(out, buf, rkey, avgMinDist, ris, points);
nkey = rkgen.getNextRoutingKey(ls.getHash());
buf.append("<h3 class=\"sybils\">Closest floodfills to Tomorrow's Routing Key for " + DataHelper.escapeHTML(name) + " (where we will store our LS)</h3>");
buf.append("<p class=\"sybil_info\"><a href=\"/netdb?caps=f&sybil=" + ls.getHash().toBase64() + "\">See all</a></p>");
renderRouterInfoHTML(out, buf, nkey, avgMinDist, ris, points);
}
// Profile analysis
addProfilePoints(ris, points);
addVersionPoints(ris, points);
if (!points.isEmpty()) {
List<Hash> warns = new ArrayList<Hash>(points.keySet());
Collections.sort(warns, new PointsComparator(points));
buf.append("<h3 id=\"threats\" class=\"sybils\">Routers with Most Threat Points</h3>");
for (Hash h : warns) {
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(h);
if (ri == null)
continue;
Points pp = points.get(h);
double p = pp.points;
if (p < MIN_DISPLAY_POINTS)
// sorted
break;
buf.append("<p class=\"threatpoints\"><b>Threat Points: " + fmt.format(p) + "</b></p><ul>");
for (String s : pp.reasons) {
buf.append("<li>").append(s).append("</li>");
}
buf.append("</ul>");
renderRouterInfo(buf, ri, null, false, false);
}
}
out.write(buf.toString());
out.flush();
buf.setLength(0);
}
use of net.i2p.data.router.RouterKeyGenerator in project i2p.i2p by i2p.
the class FloodfillNetworkDatabaseFacade method flood.
/**
* Send to a subset of all floodfill peers.
* We do this to implement Kademlia within the floodfills, i.e.
* we flood to those closest to the key.
*/
public void flood(DatabaseEntry ds) {
Hash key = ds.getHash();
RouterKeyGenerator gen = _context.routerKeyGenerator();
Hash rkey = gen.getRoutingKey(key);
FloodfillPeerSelector sel = (FloodfillPeerSelector) getPeerSelector();
List<Hash> peers = sel.selectFloodfillParticipants(rkey, MAX_TO_FLOOD, getKBuckets());
// todo key cert skip?
long until = gen.getTimeTillMidnight();
if (until < NEXT_RKEY_LS_ADVANCE_TIME || (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && until < NEXT_RKEY_RI_ADVANCE_TIME)) {
// to avoid lookup faulures after midnight, also flood to some closest to the
// next routing key for a period of time before midnight.
Hash nkey = gen.getNextRoutingKey(key);
List<Hash> nextPeers = sel.selectFloodfillParticipants(nkey, NEXT_FLOOD_QTY, getKBuckets());
int i = 0;
for (Hash h : nextPeers) {
// But other implementations may not...
if (h.equals(key))
continue;
// todo key cert skip?
if (!peers.contains(h)) {
peers.add(h);
i++;
}
}
if (i > 0 && _log.shouldLog(Log.INFO))
_log.info("Flooding the entry for " + key + " to " + i + " more, just before midnight");
}
int flooded = 0;
for (int i = 0; i < peers.size(); i++) {
Hash peer = peers.get(i);
RouterInfo target = lookupRouterInfoLocally(peer);
if ((target == null) || (_context.banlist().isBanlisted(peer)))
continue;
// But other implementations may not...
if (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && peer.equals(key))
continue;
if (peer.equals(_context.routerHash()))
continue;
DatabaseStoreMessage msg = new DatabaseStoreMessage(_context);
msg.setEntry(ds);
OutNetMessage m = new OutNetMessage(_context, msg, _context.clock().now() + FLOOD_TIMEOUT, FLOOD_PRIORITY, target);
Job floodFail = new FloodFailedJob(_context, peer);
m.setOnFailedSendJob(floodFail);
// we want to give credit on success, even if we aren't sure,
// because otherwise no use noting failure
Job floodGood = new FloodSuccessJob(_context, peer);
m.setOnSendJob(floodGood);
_context.commSystem().processMessage(m);
flooded++;
if (_log.shouldLog(Log.INFO))
_log.info("Flooding the entry for " + key.toBase64() + " to " + peer.toBase64());
}
if (_log.shouldLog(Log.INFO))
_log.info("Flooded the data to " + flooded + " of " + peers.size() + " peers");
}
use of net.i2p.data.router.RouterKeyGenerator in project i2p.i2p by i2p.
the class UpdateRoutingKeyModifierJob method runJob.
public void runJob() {
RouterKeyGenerator gen = getContext().routerKeyGenerator();
// make sure we requeue quickly if just before midnight
long delay = Math.max(5, Math.min(MAX_DELAY_FAILSAFE, gen.getTimeTillMidnight()));
// TODO tell netdb if mod data changed?
gen.generateDateBasedModData();
requeue(delay);
}
use of net.i2p.data.router.RouterKeyGenerator in project i2p.i2p by i2p.
the class SybilRenderer method renderSybilHTML.
/**
* 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 class=\"tabletitle\">Group Distances</h3><table class=\"sybil_distance\"><tr><th>Hash<th>Distance from previous</tr>\n");
Collections.sort(sybils, xor);
Hash prev = null;
for (Hash h : sybils) {
String hh = h.toBase64();
out.write("<tr><td><a href=\"#" + hh.substring(0, 6) + "\"><tt>" + hh + "</tt></a><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 start = -3;
now += start * 24 * 60 * 60 * 1000L;
final int days = 10;
Hash from = ctx.routerHash();
if (victim != null) {
Hash v = ConvertToHash.getHash(victim);
if (v != null)
from = v;
}
out.write("<h3>Distance to " + from.toBase64() + "</h3>");
prev = null;
final int limit = Math.min(10, sybils.size());
for (int i = start; i <= days; i++) {
out.write("<h3 class=\"tabletitle\">Distance for " + new Date(now) + "</h3><table class=\"sybil_distance\"><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 (int j = 0; j < limit; j++) {
Hash h = sybils.get(j);
String hh = h.toBase64();
out.write("<tr><td><a href=\"#" + hh.substring(0, 6) + "\"><tt>" + hh + "</tt></a><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;
}
}
use of net.i2p.data.router.RouterKeyGenerator in project i2p.i2p by i2p.
the class RouterContext method initAll.
/**
* The following properties may be used to replace various parts
* of the context with dummy implementations for testing, by setting
* the property to "true":
*<pre>
* i2p.dummyClientFacade
* i2p.dummyNetDb
* i2p.dummyPeerManager
* i2p.dummyTunnelManager
* i2p.vmCommSystem (transport)
*</pre>
*/
public synchronized void initAll() {
if (_initialized)
throw new IllegalStateException();
if (!getBooleanProperty("i2p.dummyClientFacade")) {
ClientManagerFacadeImpl cmfi = new ClientManagerFacadeImpl(this);
_clientManagerFacade = cmfi;
_internalClientManager = cmfi;
} else {
_clientManagerFacade = new DummyClientManagerFacade(this);
// internal client manager is null
}
_garlicMessageParser = new GarlicMessageParser(this);
_clientMessagePool = new ClientMessagePool(this);
_jobQueue = new JobQueue(this);
_jobQueue.startup();
_inNetMessagePool = new InNetMessagePool(this);
_outNetMessagePool = new OutNetMessagePool(this);
_messageHistory = new MessageHistory(this);
_messageRegistry = new OutboundMessageRegistry(this);
// _messageStateMonitor = new MessageStateMonitor(this);
_routingKeyGenerator = new RouterKeyGenerator(this);
if (!getBooleanProperty("i2p.dummyNetDb"))
// new KademliaNetworkDatabaseFacade(this);
_netDb = new FloodfillNetworkDatabaseFacade(this);
else
_netDb = new DummyNetworkDatabaseFacade(this);
_keyManager = new KeyManager(this);
if (!getBooleanProperty("i2p.vmCommSystem"))
_commSystem = new CommSystemFacadeImpl(this);
else
_commSystem = new VMCommSystem(this);
_profileOrganizer = new ProfileOrganizer(this);
if (!getBooleanProperty("i2p.dummyPeerManager"))
_peerManagerFacade = new PeerManagerFacadeImpl(this);
else
_peerManagerFacade = new DummyPeerManagerFacade();
_profileManager = new ProfileManagerImpl(this);
_bandwidthLimiter = new FIFOBandwidthLimiter(this);
if (!getBooleanProperty("i2p.dummyTunnelManager"))
_tunnelManager = new TunnelPoolManager(this);
else
_tunnelManager = new DummyTunnelManagerFacade();
_tunnelDispatcher = new TunnelDispatcher(this);
_statPublisher = new StatisticsManager(this);
_banlist = new Banlist(this);
_blocklist = new Blocklist(this);
_messageValidator = new MessageValidator(this);
_throttle = new RouterThrottleImpl(this);
// _throttle = new RouterDoSThrottle(this);
_appManager = new RouterAppManager(this);
_initialized = true;
}
Aggregations