use of net.i2p.router.tunnel.pool.TunnelPool 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.router.tunnel.pool.TunnelPool in project i2p.i2p by i2p.
the class TunnelRenderer method renderStatusHTML.
public void renderStatusHTML(Writer out) throws IOException {
out.write("<h3 class=\"tabletitle\" id=\"exploratorytunnels\"><a name=\"exploratory\" ></a>" + _t("Exploratory tunnels") + " <a href=\"/configtunnels#exploratory\" title=\"" + _t("Configure tunnels") + "\">[" + _t("configure") + "]</a></h3>\n");
renderPool(out, _context.tunnelManager().getInboundExploratoryPool(), _context.tunnelManager().getOutboundExploratoryPool());
List<Hash> destinations = null;
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
Map<Hash, TunnelPool> clientOutboundPools = _context.tunnelManager().getOutboundClientPools();
destinations = new ArrayList<Hash>(clientInboundPools.keySet());
boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
for (int i = 0; i < destinations.size(); i++) {
Hash client = destinations.get(i);
boolean isLocal = _context.clientManager().isLocal(client);
if ((!isLocal) && (!debug))
continue;
TunnelPool in = clientInboundPools.get(client);
TunnelPool outPool = clientOutboundPools.get(client);
if ((in != null && in.getSettings().getAliasOf() != null) || (outPool != null && outPool.getSettings().getAliasOf() != null)) {
// skip aliases, we will print a header under the main tunnel pool below
continue;
}
// TODO the following code is duplicated in SummaryHelper
String name = (in != null) ? in.getSettings().getDestinationNickname() : null;
if ((name == null) && (outPool != null))
name = outPool.getSettings().getDestinationNickname();
if (name == null)
name = client.toBase64().substring(0, 4);
out.write("<h3 class=\"tabletitle\" id=\"" + client.toBase64().substring(0, 4) + "\" >" + _t("Client tunnels for") + ' ' + DataHelper.escapeHTML(_t(name)));
if (isLocal)
out.write(" <a href=\"/configtunnels#" + client.toBase64().substring(0, 4) + "\" title=\"" + _t("Configure tunnels for session") + "\">[" + _t("configure") + "]</a></h3>\n");
else
out.write(" (" + _t("dead") + ")</h3>\n");
if (in != null) {
// list aliases
Set<Hash> aliases = in.getSettings().getAliases();
if (aliases != null) {
for (Hash a : aliases) {
TunnelPool ain = clientInboundPools.get(a);
if (ain != null) {
String aname = ain.getSettings().getDestinationNickname();
if (aname == null)
aname = a.toBase64().substring(0, 4);
out.write("<h3 class=\"tabletitle\" id=\"" + a.toBase64().substring(0, 4) + "\" >" + _t("Client tunnels for") + ' ' + DataHelper.escapeHTML(_t(aname)));
if (isLocal)
out.write(" <a href=\"/configtunnels#" + client.toBase64().substring(0, 4) + "\" title=\"" + _t("Configure tunnels for session") + "\">[" + _t("configure") + "]</a></h3>\n");
else
out.write(" (" + _t("dead") + ")</h3>\n");
}
}
}
}
renderPool(out, in, outPool);
}
List<HopConfig> participating = _context.tunnelDispatcher().listParticipatingTunnels();
out.write("<h3 class=\"tabletitle\" id=\"participating\">" + _t("Participating tunnels") + "</h3>\n");
int bwShare = getShareBandwidth();
if (bwShare > 12) {
// Don't bother re-indenting
if (!participating.isEmpty()) {
Collections.sort(participating, new TunnelComparator());
out.write("<table class=\"tunneldisplay tunnels_participating\"><tr><th>" + _t("Receive on") + "</th><th>" + _t("From") + "</th><th>" + _t("Send on") + "</th><th>" + _t("To") + "</th><th>" + _t("Expiration") + "</th>" + "<th>" + _t("Usage") + "</th><th>" + _t("Rate") + "</th><th>" + _t("Role") + "</th></tr>\n");
}
long processed = 0;
RateStat rs = _context.statManager().getRate("tunnel.participatingMessageCount");
if (rs != null)
processed = (long) rs.getRate(10 * 60 * 1000).getLifetimeTotalValue();
int inactive = 0;
int displayed = 0;
for (int i = 0; i < participating.size(); i++) {
HopConfig cfg = participating.get(i);
int count = cfg.getProcessedMessagesCount();
if (count <= 0) {
inactive++;
continue;
}
// everything that isn't 'recent' is already in the tunnel.participatingMessageCount stat
processed += cfg.getRecentMessagesCount();
if (++displayed > DISPLAY_LIMIT)
continue;
out.write("<tr>");
if (cfg.getReceiveTunnel() != null)
out.write("<td class=\"cells\" align=\"center\" title=\"" + _t("Tunnel identity") + "\"><span class=\"tunnel_id\">" + cfg.getReceiveTunnel().getTunnelId() + "</span></td>");
else
out.write("<td class=\"cells\" align=\"center\">n/a</td>");
if (cfg.getReceiveFrom() != null)
out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(cfg.getReceiveFrom()) + "</span></td>");
else
out.write("<td class=\"cells\"> </td>");
if (cfg.getSendTunnel() != null)
out.write("<td class=\"cells\" align=\"center\" title=\"" + _t("Tunnel identity") + "\"><span class=\"tunnel_id\">" + cfg.getSendTunnel().getTunnelId() + "</span></td>");
else
out.write("<td class=\"cells\"> </td>");
if (cfg.getSendTo() != null)
out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(cfg.getSendTo()) + "</span></td>");
else
out.write("<td class=\"cells\"> </td>");
long timeLeft = cfg.getExpiration() - _context.clock().now();
if (timeLeft > 0)
out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatDuration2(timeLeft) + "</td>");
else
out.write("<td class=\"cells\" align=\"center\">(" + _t("grace period") + ")</td>");
out.write("<td class=\"cells\" align=\"center\">" + (count * 1024 / 1000) + " KB</td>");
int lifetime = (int) ((_context.clock().now() - cfg.getCreation()) / 1000);
if (lifetime <= 0)
lifetime = 1;
if (lifetime > 10 * 60)
lifetime = 10 * 60;
int bps = 1024 * count / lifetime;
out.write("<td class=\"cells\" align=\"center\">" + bps + " Bps</td>");
if (cfg.getSendTo() == null)
out.write("<td class=\"cells\" align=\"center\">" + _t("Outbound Endpoint") + "</td>");
else if (cfg.getReceiveFrom() == null)
out.write("<td class=\"cells\" align=\"center\">" + _t("Inbound Gateway") + "</td>");
else
out.write("<td class=\"cells\" align=\"center\">" + _t("Participant") + "</td>");
out.write("</tr>\n");
}
if (!participating.isEmpty())
out.write("</table>\n");
if (displayed > DISPLAY_LIMIT)
out.write("<div class=\"statusnotes\"><b>" + _t("Limited display to the {0} tunnels with the highest usage", DISPLAY_LIMIT) + "</b></div>\n");
if (inactive > 0)
out.write("<div class=\"statusnotes\"><b>" + _t("Inactive participating tunnels") + ": " + inactive + "</b></div>\n");
else if (displayed <= 0)
out.write("<div class=\"statusnotes\"><b>" + _t("none") + "</b></div>\n");
out.write("<div class=\"statusnotes\"><b>" + _t("Lifetime bandwidth usage") + ": " + DataHelper.formatSize2Decimal(processed * 1024) + "B</b></div>\n");
} else {
out.write("<div class=\"statusnotes noparticipate\"><b>" + _t("Not enough shared bandwidth to build participating tunnels.") + "</b> <a href=\"config\">[" + _t("Configure") + "]</a></div>\n");
}
// renderPeers(out);
out.write("<h3 class=\"tabletitle\">" + _t("Bandwidth Tiers") + "</h3>\n");
out.write("<table id=\"tunnel_defs\"><tbody>");
out.write("<tr><td> </td>" + "<td><span class=\"tunnel_cap\"><b>L</b></span></td><td>" + _t("{0} shared bandwidth", range(Router.MIN_BW_L, Router.MIN_BW_M)) + "</td>" + "<td><span class=\"tunnel_cap\"><b>M</b></span></td><td>" + _t("{0} shared bandwidth", range(Router.MIN_BW_M, Router.MIN_BW_N)) + "</td>" + "<td> </td></tr>");
out.write("<tr><td> </td>" + "<td><span class=\"tunnel_cap\"><b>N</b></span></td><td>" + _t("{0} shared bandwidth", range(Router.MIN_BW_N, Router.MIN_BW_O)) + "</td>" + "<td><span class=\"tunnel_cap\"><b>O</b></span></td><td>" + _t("{0} shared bandwidth", range(Router.MIN_BW_O, Router.MIN_BW_P)) + "</td>" + "<td> </td></tr>");
out.write("<tr><td> </td>" + "<td><span class=\"tunnel_cap\"><b>P</b></span></td><td>" + _t("{0} shared bandwidth", range(Router.MIN_BW_P, Router.MIN_BW_X)) + "</td>" + "<td><span class=\"tunnel_cap\"><b>X</b></span></td><td>" + _t("Over {0} shared bandwidth", Math.round(Router.MIN_BW_X * 1.024f) + " KBps") + "</td>" + "<td> </td></tr>");
out.write("</tbody></table>");
}
Aggregations