Search in sources :

Example 1 with TunnelPool

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&amp;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&amp;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&amp;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&amp;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);
}
Also used : TunnelPool(net.i2p.router.tunnel.pool.TunnelPool) HashMap(java.util.HashMap) RouterInfo(net.i2p.data.router.RouterInfo) RouterKeyGenerator(net.i2p.data.router.RouterKeyGenerator) ArrayList(java.util.ArrayList) Hash(net.i2p.data.Hash) ConvertToHash(net.i2p.util.ConvertToHash) Date(java.util.Date) LeaseSet(net.i2p.data.LeaseSet)

Example 2 with TunnelPool

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\">&nbsp;</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\">&nbsp;</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\">&nbsp;</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") + ":&nbsp;&nbsp;" + 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") + ":&nbsp;&nbsp;" + 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>&nbsp;</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>&nbsp;</td></tr>");
    out.write("<tr><td>&nbsp;</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>&nbsp;</td></tr>");
    out.write("<tr><td>&nbsp;</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>&nbsp;</td></tr>");
    out.write("</tbody></table>");
}
Also used : TunnelPool(net.i2p.router.tunnel.pool.TunnelPool) HopConfig(net.i2p.router.tunnel.HopConfig) Hash(net.i2p.data.Hash) RateStat(net.i2p.stat.RateStat)

Aggregations

Hash (net.i2p.data.Hash)2 TunnelPool (net.i2p.router.tunnel.pool.TunnelPool)2 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 LeaseSet (net.i2p.data.LeaseSet)1 RouterInfo (net.i2p.data.router.RouterInfo)1 RouterKeyGenerator (net.i2p.data.router.RouterKeyGenerator)1 HopConfig (net.i2p.router.tunnel.HopConfig)1 RateStat (net.i2p.stat.RateStat)1 ConvertToHash (net.i2p.util.ConvertToHash)1