diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbHelper.java index a9a300a0a..0d026bae8 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbHelper.java @@ -25,7 +25,7 @@ public class NetDbHelper extends FormHandler { private String _routerPrefix; private String _version; private String _country; - private String _family, _caps, _ip, _sybil, _mtu, _ssucaps, _ipv6, _transport; + private String _family, _caps, _ip, _sybil, _mtu, _ssucaps, _ipv6, _transport, _hostname; private int _full, _port, _cost, _page, _mode; private long _date; private int _limit = DEFAULT_LIMIT; @@ -50,7 +50,8 @@ public class NetDbHelper extends FormHandler { _x("LeaseSets"), // 5 "LeaseSet Debug", // 6 "Sybil", // 7 - "Advanced Lookup" }; // 8 + "Advanced Lookup", // 8 + "LeaseSet Lookup" }; // 9 private static final String links[] = {"", // 0 @@ -61,7 +62,8 @@ public class NetDbHelper extends FormHandler { "?l=1", // 5 "?l=2", // 6 "?f=3", // 7 - "?f=4" }; // 8 + "?f=4", // 8 + "" }; // 9 public void setRouter(String r) { if (r != null && r.length() > 0) @@ -190,6 +192,12 @@ public class NetDbHelper extends FormHandler { _lease = _debug || "1".equals(l); } + /** @since 0.9.57 */ + public void setLeaseset(String f) { + if (f != null && f.length() > 0) + _hostname = DataHelper.stripHTML(f); + } + /** @since 0.9.36 */ public void setLimit(String f) { try { @@ -290,6 +298,8 @@ public class NetDbHelper extends FormHandler { _mtu, _ipv6, _ssucaps, _transport, _cost); } else if (_lease) { renderer.renderLeaseSetHTML(_out, _debug); + } else if (_hostname != null) { + renderer.renderLeaseSet(_out, _hostname, true); } else if (_full == 3) { if (_mode == 12 && !_postOK) _mode = 0; @@ -330,6 +340,8 @@ public class NetDbHelper extends FormHandler { return 7; if (_full == 4) return 8; + if (_hostname != null) + return 9; return 0; } @@ -346,6 +358,8 @@ public class NetDbHelper extends FormHandler { for (int i = 0; i < titles.length; i++) { if (i == 2 && tab != 2) continue; // can't nav to lookup + if (i == 9 && tab != 9) + continue; // can't nav to lookup if (i > 2 && i != tab && !isAdvanced()) continue; if (i == tab) { @@ -397,6 +411,7 @@ public class NetDbHelper extends FormHandler { _out.write("\n" + "Router Family:\n" + "Hash Prefix:\n" + + "Hostname or b32:\n" + "IP:IPv4 or IPv6, /24,/16,/8 suffixes optional for IPv4, prefix ok for IPv6\n" + "IPv6 Prefix:\n" + "MTU:\n" + diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java index a2454a41d..fb1e4f87c 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java @@ -49,6 +49,7 @@ import net.i2p.router.transport.GeoIP; import net.i2p.router.web.HelperBase; import net.i2p.router.web.Messages; import net.i2p.router.web.WebAppStarter; +import net.i2p.util.ConvertToHash; import net.i2p.util.Log; import net.i2p.util.ObjectCounter; import net.i2p.util.Translate; @@ -512,6 +513,8 @@ class NetDbRenderer { } /** + * All the leasesets + * * @param debug @since 0.7.14 sort by distance from us, display * median distance, and other stuff, useful when floodfill */ @@ -579,6 +582,90 @@ class NetDbRenderer { long now = _context.clock().now(); buf.append("
"); for (LeaseSet ls : leases) { + String distance; + if (debug) { + BigInteger dist = HashDistance.getDistance(ourRKey, ls.getRoutingKey()); + if (ls.getReceivedAsPublished()) { + if (c++ == medianCount) + median = dist; + } + distance = fmt.format(biLog2(dist)); + } else { + distance = null; + } + renderLeaseSet(buf, ls, debug, now, linkSusi, distance); + out.write(buf.toString()); + buf.setLength(0); + } // for each + if (debug) { + buf.append("") + .append("\n"); + // 2 for 4 floodfills... -1 for median + // this can be way off for unknown reasons + int total = (int) Math.round(Math.pow(2, 2 + 256 - 1 - log2)); + buf.append("\n"); + buf.append("
Network data (only valid if floodfill):"); + //buf.append("

Center of Key Space (router hash): " + ourRKey.toBase64()); + if (median != null) { + double log2 = biLog2(median); + buf.append("

Median distance (bits):").append(fmt.format(log2)).append("
Estimated total floodfills:").append(total).append("
Estimated total leasesets:").append(total * rapCount / 4); + } else { + buf.append("Not floodfill or no data."); + } + buf.append("
\n"); + } // median table + buf.append("
"); + } // !empty + out.write(buf.toString()); + out.flush(); + } + + /** + * Single LeaseSet + * @since 0.9.57 + */ + public void renderLeaseSet(Writer out, String hostname, boolean debug) throws IOException { + StringBuilder buf = new StringBuilder(1024); + Hash hash = ConvertToHash.getHash(hostname); + if (hash == null) { + buf.append("
"); + buf.append("Hostname not found").append(' '); + buf.append(hostname); + buf.append("
"); + } else { + LeaseSet ls = _context.netDb().lookupLeaseSetLocally(hash); + if (ls == null) { + // remote lookup + LookupWaiter lw = new LookupWaiter(); + _context.netDb().lookupLeaseSetRemotely(hash, lw, lw, 8*1000, null); + // just wait right here in the middle of the rendering, sure + synchronized(lw) { + try { lw.wait(9*1000); } catch (InterruptedException ie) {} + } + ls = _context.netDb().lookupLeaseSetLocally(hash); + } + if (ls != null) { + BigInteger dist = HashDistance.getDistance(_context.routerHash(), ls.getRoutingKey()); + DecimalFormat fmt = new DecimalFormat("#0.00"); + String distance = fmt.format(biLog2(dist)); + buf.append("
"); + renderLeaseSet(buf, ls, true, _context.clock().now(), false, distance); + buf.append("
"); + } else { + buf.append("
"); + buf.append(_t("LeaseSet")).append(" for "); + buf.append(hostname); + buf.append(' ').append(_t("not found in network database")); + buf.append("
"); + } + } + out.write(buf.toString()); + out.flush(); + } + + /** @since 0.9.57 split out from above */ + private void renderLeaseSet(StringBuilder buf, LeaseSet ls, boolean debug, long now, + boolean linkSusi, String distance) { // warning - will be null for non-local encrypted Destination dest = ls.getDestination(); Hash key = ls.getHash(); @@ -667,12 +754,7 @@ class NetDbRenderer { buf.append(""); buf.append("RAP? ").append(ls.getReceivedAsPublished()); buf.append("  RAR? ").append(ls.getReceivedAsReply()); - BigInteger dist = HashDistance.getDistance(ourRKey, ls.getRoutingKey()); - if (ls.getReceivedAsPublished()) { - if (c++ == medianCount) - median = dist; - } - buf.append("  Distance: ").append(fmt.format(biLog2(dist))); + buf.append("  Distance: ").append(distance); buf.append("  Type: ").append(type); if (type != DatabaseEntry.KEY_TYPE_LEASESET) { LeaseSet2 ls2 = (LeaseSet2) ls; @@ -741,30 +823,6 @@ class NetDbRenderer { } buf.append("\n"); buf.append("\n"); - out.write(buf.toString()); - buf.setLength(0); - } // for each - if (debug) { - buf.append("") - .append("\n"); - // 2 for 4 floodfills... -1 for median - // this can be way off for unknown reasons - int total = (int) Math.round(Math.pow(2, 2 + 256 - 1 - log2)); - buf.append("\n"); - buf.append("
Network data (only valid if floodfill):"); - //buf.append("

Center of Key Space (router hash): " + ourRKey.toBase64()); - if (median != null) { - double log2 = biLog2(median); - buf.append("

Median distance (bits):").append(fmt.format(log2)).append("
Estimated total floodfills:").append(total).append("
Estimated total leasesets:").append(total * rapCount / 4); - } else { - buf.append("Not floodfill or no data."); - } - buf.append("
\n"); - } // median table - buf.append(""); - } // !empty - out.write(buf.toString()); - out.flush(); } /** diff --git a/apps/routerconsole/jsp/netdb.jsp b/apps/routerconsole/jsp/netdb.jsp index cb61276af..38045056e 100644 --- a/apps/routerconsole/jsp/netdb.jsp +++ b/apps/routerconsole/jsp/netdb.jsp @@ -37,6 +37,7 @@ " /> " /> " /> + " /> <%@include file="formhandler.jsi" %>