diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java index 8c59725dabe35488a3e997945550ab39ba675cba..e69d33c30f7dd30a268afd6a6276307e5bb7c96d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java @@ -26,6 +26,7 @@ import net.i2p.router.web.HelperBase; import net.i2p.router.web.Messages; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; +import net.i2p.util.ObjectCounterUnsafe; /** * For /tunnels.jsp, used by TunnelHelper. @@ -138,8 +139,9 @@ class TunnelRenderer { recv + "</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>"); + Hash from = cfg.getReceiveFrom(); + if (from != null) + out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(from) +"</span></td>"); else out.write("<td class=\"cells\"> </td>"); long send = cfg.getSendTunnelId(); @@ -147,8 +149,9 @@ class TunnelRenderer { out.write("<td class=\"cells\" align=\"center\" title=\"" + _t("Tunnel identity") + "\"><span class=\"tunnel_id\">" + send +"</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>"); + Hash to = cfg.getSendTo(); + if (to != null) + out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(to) +"</span></td>"); else out.write("<td class=\"cells\"> </td>"); long timeLeft = cfg.getExpiration() - now; @@ -164,9 +167,9 @@ class TunnelRenderer { lifetime = 10*60; long bps = 1024L * count / lifetime; out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatSize2Decimal(bps) + "Bps</td>"); - if (cfg.getSendTo() == null) + if (to == null) out.write("<td class=\"cells\" align=\"center\">" + _t("Outbound Endpoint") + "</td>"); - else if (cfg.getReceiveFrom() == null) + else if (from == null) out.write("<td class=\"cells\" align=\"center\">" + _t("Inbound Gateway") + "</td>"); else out.write("<td class=\"cells\" align=\"center\">" + _t("Participant") + "</td>"); @@ -181,6 +184,49 @@ class TunnelRenderer { 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.formatSize2(processed*1024) + "B</b></div>\n"); + + if (debug && participating.size() > 1) { + // peer table sorted by number of tunnels + ObjectCounterUnsafe<Hash> counts = new ObjectCounterUnsafe<Hash>(); + ObjectCounterUnsafe<Hash> bws = new ObjectCounterUnsafe<Hash>(); + for (int i = 0; i < participating.size(); i++) { + HopConfig cfg = participating.get(i); + Hash from = cfg.getReceiveFrom(); + Hash to = cfg.getSendTo(); + int msgs = cfg.getProcessedMessagesCount(); + if (from != null) { + counts.increment(from); + if (msgs > 0) + bws.add(from, msgs); + } + if (to != null) { + counts.increment(to); + if (msgs > 0) + bws.add(to, msgs); + } + } + // sort and output + out.write("<h3 class=\"tabletitle\">Peers in multiple participating tunnels (including inactive)</h3>\n"); + out.write("<table class=\"tunneldisplay tunnels_participating\"><tr><th>" + _t("Router") + "</th><th>" + _t("Tunnels") + "</th><th>" + + _t("Usage") + "</th></tr>\n"); + displayed = 0; + List<Hash> sort = counts.sortedObjects(); + for (Hash h : sort) { + int count = counts.count(h); + if (count <= 1) + break; + if (++displayed > DISPLAY_LIMIT) + break; + out.write("<tr><td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(h) + "</span></td>\n"); + out.write("<td class=\"cells\" align=\"center\">" + count + "</td>\n"); + out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatSize2(bws.count(h) * 1024) + "B</td></tr>\n"); + } + out.write("</table>\n"); + if (displayed <= 0) + out.write("<div class=\"statusnotes\"><b>" + _t("none") + "</b></div>\n"); + } + + } else { // bwShare > 12 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");