move NetDb renderStatusHTML() to routerconsole

This commit is contained in:
zzz
2009-10-17 23:16:53 +00:00
parent 219095404a
commit 011a32f741
5 changed files with 291 additions and 250 deletions

View File

@ -17,23 +17,24 @@ public class NetDbHelper extends HelperBase {
public void setLease(String l) { _lease = "1".equals(l); }
public String getNetDbSummary() {
NetDbRenderer renderer = new NetDbRenderer(_context);
try {
if (_out != null) {
if (_routerPrefix != null)
_context.netDb().renderRouterInfoHTML(_out, _routerPrefix);
renderer.renderRouterInfoHTML(_out, _routerPrefix);
else if (_lease)
_context.netDb().renderLeaseSetHTML(_out);
renderer.renderLeaseSetHTML(_out);
else
_context.netDb().renderStatusHTML(_out, _full);
renderer.renderStatusHTML(_out, _full);
return "";
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
if (_routerPrefix != null)
_context.netDb().renderRouterInfoHTML(new OutputStreamWriter(baos), _routerPrefix);
renderer.renderRouterInfoHTML(new OutputStreamWriter(baos), _routerPrefix);
else if (_lease)
_context.netDb().renderLeaseSetHTML(new OutputStreamWriter(baos));
renderer.renderLeaseSetHTML(new OutputStreamWriter(baos));
else
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos), _full);
renderer.renderStatusHTML(new OutputStreamWriter(baos), _full);
return new String(baos.toByteArray());
}
} catch (IOException ioe) {

View File

@ -0,0 +1,271 @@
package net.i2p.router.web;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.RouterAddress;
import net.i2p.data.RouterInfo;
import net.i2p.router.RouterContext;
import net.i2p.router.TunnelPoolSettings;
import net.i2p.util.ObjectCounter;
public class NetDbRenderer {
private RouterContext _context;
public NetDbRenderer (RouterContext ctx) {
_context = ctx;
}
private class LeaseSetComparator implements Comparator {
public int compare(Object l, Object r) {
Destination dl = ((LeaseSet)l).getDestination();
Destination dr = ((LeaseSet)r).getDestination();
boolean locall = _context.clientManager().isLocal(dl);
boolean localr = _context.clientManager().isLocal(dr);
if (locall && !localr) return -1;
if (localr && !locall) return 1;
return dl.calculateHash().toBase64().compareTo(dr.calculateHash().toBase64());
}
}
private static class RouterInfoComparator implements Comparator {
public int compare(Object l, Object r) {
return ((RouterInfo)l).getIdentity().getHash().toBase64().compareTo(((RouterInfo)r).getIdentity().getHash().toBase64());
}
}
public void renderRouterInfoHTML(Writer out, String routerPrefix) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h2>Network Database RouterInfo Lookup</h2>\n");
if (".".equals(routerPrefix)) {
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
} else {
boolean notFound = true;
Set routers = _context.netDb().getRouters();
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
if (key.toBase64().startsWith(routerPrefix)) {
renderRouterInfo(buf, ri, false, true);
notFound = false;
}
}
if (notFound)
buf.append("Router ").append(routerPrefix).append(" not found in network database");
}
out.write(buf.toString());
out.flush();
}
public void renderStatusHTML(Writer out) throws IOException {
renderStatusHTML(out, true);
}
public void renderLeaseSetHTML(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h2>Network Database Contents</h2>\n");
buf.append("<a href=\"netdb.jsp\">View RouterInfo</a>");
buf.append("<h3>LeaseSets</h3>\n");
Set leases = new TreeSet(new LeaseSetComparator());
leases.addAll(_context.netDb().getLeases());
long now = _context.clock().now();
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
LeaseSet ls = (LeaseSet)iter.next();
Destination dest = ls.getDestination();
Hash key = dest.calculateHash();
buf.append("<b>LeaseSet: ").append(key.toBase64());
if (_context.clientManager().isLocal(dest)) {
buf.append(" (<a href=\"tunnels.jsp#" + key.toBase64().substring(0,4) + "\">Local</a> ");
if (! _context.clientManager().shouldPublishLeaseSet(key))
buf.append("Unpublished ");
buf.append("Destination ");
TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(key);
if (in != null && in.getDestinationNickname() != null)
buf.append(in.getDestinationNickname());
else
buf.append(dest.toBase64().substring(0, 6));
} else {
buf.append(" (Destination ");
String host = _context.namingService().reverseLookup(dest);
if (host != null)
buf.append(host);
else
buf.append(dest.toBase64().substring(0, 6));
}
buf.append(")</b><br>\n");
long exp = ls.getEarliestLeaseDate()-now;
if (exp > 0)
buf.append("Expires in ").append(DataHelper.formatDuration(exp)).append("<br>\n");
else
buf.append("Expired ").append(DataHelper.formatDuration(0-exp)).append(" ago<br>\n");
for (int i = 0; i < ls.getLeaseCount(); i++) {
buf.append("Lease ").append(i + 1).append(": Gateway ");
buf.append(_context.commSystem().renderPeerHTML(ls.getLease(i).getGateway()));
buf.append(" Tunnel ").append(ls.getLease(i).getTunnelId().getTunnelId()).append("<br>\n");
}
buf.append("<hr>\n");
out.write(buf.toString());
buf.setLength(0);
}
out.write(buf.toString());
out.flush();
}
public void renderStatusHTML(Writer out, boolean full) throws IOException {
int size = _context.netDb().getKnownRouters() * 512;
if (full)
size *= 4;
StringBuilder buf = new StringBuilder(size);
out.write("<h2>Network Database Contents (<a href=\"netdb.jsp?l=1\">View LeaseSets</a>)</h2>\n");
if (!_context.netDb().isInitialized()) {
buf.append("Not initialized\n");
out.write(buf.toString());
out.flush();
return;
}
Hash us = _context.routerHash();
out.write("<a name=\"routers\" ></a><h3>Routers (<a href=\"netdb.jsp");
if (full)
out.write("#routers\" >view without");
else
out.write("?f=1#routers\" >view with");
out.write(" stats</a>)</h3>\n");
RouterInfo ourInfo = _context.router().getRouterInfo();
renderRouterInfo(buf, ourInfo, true, true);
out.write(buf.toString());
buf.setLength(0);
ObjectCounter<String> versions = new ObjectCounter();
ObjectCounter<String> countries = new ObjectCounter();
Set routers = new TreeSet(new RouterInfoComparator());
routers.addAll(_context.netDb().getRouters());
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
boolean isUs = key.equals(us);
if (!isUs) {
renderRouterInfo(buf, ri, false, full);
out.write(buf.toString());
buf.setLength(0);
String routerVersion = ri.getOption("router.version");
if (routerVersion != null)
versions.increment(routerVersion);
String country = _context.commSystem().getCountry(key);
if(country != null)
countries.increment(country);
}
}
buf.append("<table border=\"0\" cellspacing=\"30\"><tr><td>");
List<String> versionList = new ArrayList(versions.objects());
if (versionList.size() > 0) {
Collections.sort(versionList, Collections.reverseOrder());
buf.append("<table>\n");
buf.append("<tr><th>Version</th><th>Count</th></tr>\n");
for (String routerVersion : versionList) {
int num = versions.count(routerVersion);
buf.append("<tr><td align=\"center\">").append(DataHelper.stripHTML(routerVersion));
buf.append("</td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td><td>");
out.write(buf.toString());
buf.setLength(0);
List<String> countryList = new ArrayList(countries.objects());
if (countryList.size() > 0) {
Collections.sort(countryList);
buf.append("<table>\n");
buf.append("<tr><th align=\"left\">Country</th><th>Count</th></tr>\n");
for (String country : countryList) {
int num = countries.count(country);
buf.append("<tr><td><img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase()).append("\"");
buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ");
buf.append(_context.commSystem().getCountryName(country));
buf.append("</td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td></tr></table>");
out.write(buf.toString());
out.flush();
}
/**
* Be careful to use stripHTML for any displayed routerInfo data
* to prevent vulnerabilities
*/
private void renderRouterInfo(StringBuilder buf, RouterInfo info, boolean isUs, boolean full) {
String hash = info.getIdentity().getHash().toBase64();
buf.append("<table><tr><th><a name=\"").append(hash.substring(0, 6)).append("\" ></a>");
if (isUs) {
buf.append("<a name=\"our-info\" ></a><b>Our info: ").append(hash).append("</b></th></tr><tr><td>\n");
} else {
buf.append("<b>Peer info for:</b> ").append(hash).append("\n");
if (full) {
buf.append("[<a href=\"netdb.jsp\" >Back</a>]</th></tr><td>\n");
} else {
buf.append("[<a href=\"netdb.jsp?r=").append(hash.substring(0, 6)).append("\" >Full entry</a>]</th></tr><td>\n");
}
}
long age = _context.clock().now() - info.getPublished();
if (isUs && _context.router().isHidden())
buf.append("<b>Hidden, Updated:</b> ").append(DataHelper.formatDuration(age)).append(" ago<br>\n");
else if (age > 0)
buf.append("<b>Published:</b> ").append(DataHelper.formatDuration(age)).append(" ago<br>\n");
else
buf.append("<b>Published:</b> in ").append(DataHelper.formatDuration(0-age)).append("???<br>\n");
buf.append("<b>Address(es):</b> ");
String country = _context.commSystem().getCountry(info.getIdentity().getHash());
if(country != null) {
buf.append("<img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase()).append("\"");
buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ");
}
for (Iterator iter = info.getAddresses().iterator(); iter.hasNext(); ) {
RouterAddress addr = (RouterAddress)iter.next();
buf.append(DataHelper.stripHTML(addr.getTransportStyle())).append(": ");
for (Iterator optIter = addr.getOptions().keySet().iterator(); optIter.hasNext(); ) {
String name = (String)optIter.next();
String val = addr.getOptions().getProperty(name);
buf.append('[').append(DataHelper.stripHTML(name)).append('=').append(DataHelper.stripHTML(val)).append("] ");
}
}
buf.append("</td></tr>\n");
if (full) {
buf.append("<tr><td>Stats: <br><code>\n");
for (Iterator iter = info.getOptions().keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
String val = info.getOption(key);
buf.append(DataHelper.stripHTML(key)).append(" = ").append(DataHelper.stripHTML(val)).append("<br>\n");
}
buf.append("</code></td></tr>\n");
} else {
}
buf.append("</td></tr>\n");
}
}

View File

@ -60,6 +60,4 @@ class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
public Set<Hash> getAllRouters() { return new HashSet(_routers.keySet()); }
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
public void renderStatusHTML(Writer out) throws IOException {}
}

View File

@ -10,6 +10,7 @@ package net.i2p.router;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Set;
import net.i2p.data.Hash;
@ -60,7 +61,10 @@ public abstract class NetworkDatabaseFacade implements Service {
public int getKnownLeaseSets() { return 0; }
public boolean isInitialized() { return true; }
public void rescan() {}
public void renderRouterInfoHTML(Writer out, String s) throws IOException {}
public void renderLeaseSetHTML(Writer out) throws IOException {}
public void renderStatusHTML(Writer out, boolean b) throws IOException {}
/** @deprecated moved to router console */
public void renderStatusHTML(Writer out) throws IOException {}
/** public for NetDbRenderer in routerconsole */
public Set<LeaseSet> getLeases() { return Collections.EMPTY_SET; }
/** public for NetDbRenderer in routerconsole */
public Set<RouterInfo> getRouters() { return Collections.EMPTY_SET; }
}

View File

@ -848,7 +848,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
return searchJob;
}
private Set getLeases() {
/** public for NetDbRenderer in routerconsole */
@Override
public Set<LeaseSet> getLeases() {
if (!_initialized) return null;
Set leases = new HashSet();
Set keys = getDataStore().getKeys();
@ -860,7 +862,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
}
return leases;
}
private Set<RouterInfo> getRouters() {
/** public for NetDbRenderer in routerconsole */
@Override
public Set<RouterInfo> getRouters() {
if (!_initialized) return null;
Set routers = new HashSet();
Set keys = getDataStore().getKeys();
@ -897,241 +901,4 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
}
_context.jobQueue().addJob(new StoreJob(_context, this, key, ds, onSuccess, onFailure, sendTimeout, toIgnore));
}
class LeaseSetComparator implements Comparator {
public int compare(Object l, Object r) {
Destination dl = ((LeaseSet)l).getDestination();
Destination dr = ((LeaseSet)r).getDestination();
boolean locall = _context.clientManager().isLocal(dl);
boolean localr = _context.clientManager().isLocal(dr);
if (locall && !localr) return -1;
if (localr && !locall) return 1;
return dl.calculateHash().toBase64().compareTo(dr.calculateHash().toBase64());
}
}
class RouterInfoComparator implements Comparator {
public int compare(Object l, Object r) {
return ((RouterInfo)l).getIdentity().getHash().toBase64().compareTo(((RouterInfo)r).getIdentity().getHash().toBase64());
}
}
@Override
public void renderRouterInfoHTML(Writer out, String routerPrefix) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h2>Network Database RouterInfo Lookup</h2>\n");
if (".".equals(routerPrefix)) {
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
} else {
boolean notFound = true;
Set routers = getRouters();
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
if (key.toBase64().startsWith(routerPrefix)) {
renderRouterInfo(buf, ri, false, true);
notFound = false;
}
}
if (notFound)
buf.append("Router ").append(routerPrefix).append(" not found in network database");
}
out.write(buf.toString());
out.flush();
}
public void renderStatusHTML(Writer out) throws IOException {
renderStatusHTML(out, true);
}
@Override
public void renderLeaseSetHTML(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h2>Network Database Contents</h2>\n");
buf.append("<a href=\"netdb.jsp\">View RouterInfo</a>");
buf.append("<h3>LeaseSets</h3>\n");
Set leases = new TreeSet(new LeaseSetComparator());
leases.addAll(getLeases());
long now = _context.clock().now();
for (Iterator iter = leases.iterator(); iter.hasNext(); ) {
LeaseSet ls = (LeaseSet)iter.next();
Destination dest = ls.getDestination();
Hash key = dest.calculateHash();
buf.append("<b>LeaseSet: ").append(key.toBase64());
if (_context.clientManager().isLocal(dest)) {
buf.append(" (<a href=\"tunnels.jsp#" + key.toBase64().substring(0,4) + "\">Local</a> ");
if (! _context.clientManager().shouldPublishLeaseSet(key))
buf.append("Unpublished ");
buf.append("Destination ");
TunnelPoolSettings in = _context.tunnelManager().getInboundSettings(key);
if (in != null && in.getDestinationNickname() != null)
buf.append(in.getDestinationNickname());
else
buf.append(dest.toBase64().substring(0, 6));
} else {
buf.append(" (Destination ");
String host = _context.namingService().reverseLookup(dest);
if (host != null)
buf.append(host);
else
buf.append(dest.toBase64().substring(0, 6));
}
buf.append(")</b><br>\n");
long exp = ls.getEarliestLeaseDate()-now;
if (exp > 0)
buf.append("Expires in ").append(DataHelper.formatDuration(exp)).append("<br>\n");
else
buf.append("Expired ").append(DataHelper.formatDuration(0-exp)).append(" ago<br>\n");
for (int i = 0; i < ls.getLeaseCount(); i++) {
buf.append("Lease ").append(i + 1).append(": Gateway ");
buf.append(_context.commSystem().renderPeerHTML(ls.getLease(i).getGateway()));
buf.append(" Tunnel ").append(ls.getLease(i).getTunnelId().getTunnelId()).append("<br>\n");
}
buf.append("<hr>\n");
out.write(buf.toString());
buf.setLength(0);
}
out.write(buf.toString());
out.flush();
}
@Override
public void renderStatusHTML(Writer out, boolean full) throws IOException {
int size = getKnownRouters() * 512;
if (full)
size *= 4;
StringBuilder buf = new StringBuilder(size);
out.write("<h2>Network Database Contents (<a href=\"netdb.jsp?l=1\">View LeaseSets</a>)</h2>\n");
if (!_initialized) {
buf.append("Not initialized\n");
out.write(buf.toString());
out.flush();
return;
}
Hash us = _context.routerHash();
out.write("<a name=\"routers\" ></a><h3>Routers (<a href=\"netdb.jsp");
if (full)
out.write("#routers\" >view without");
else
out.write("?f=1#routers\" >view with");
out.write(" stats</a>)</h3>\n");
RouterInfo ourInfo = _context.router().getRouterInfo();
renderRouterInfo(buf, ourInfo, true, true);
out.write(buf.toString());
buf.setLength(0);
ObjectCounter<String> versions = new ObjectCounter();
ObjectCounter<String> countries = new ObjectCounter();
Set routers = new TreeSet(new RouterInfoComparator());
routers.addAll(getRouters());
for (Iterator iter = routers.iterator(); iter.hasNext(); ) {
RouterInfo ri = (RouterInfo)iter.next();
Hash key = ri.getIdentity().getHash();
boolean isUs = key.equals(us);
if (!isUs) {
renderRouterInfo(buf, ri, false, full);
out.write(buf.toString());
buf.setLength(0);
String routerVersion = ri.getOption("router.version");
if (routerVersion != null)
versions.increment(routerVersion);
String country = _context.commSystem().getCountry(key);
if(country != null)
countries.increment(country);
}
}
buf.append("<table border=\"0\" cellspacing=\"30\"><tr><td>");
List<String> versionList = new ArrayList(versions.objects());
if (versionList.size() > 0) {
Collections.sort(versionList, Collections.reverseOrder());
buf.append("<table>\n");
buf.append("<tr><th>Version</th><th>Count</th></tr>\n");
for (String routerVersion : versionList) {
int num = versions.count(routerVersion);
buf.append("<tr><td align=\"center\">").append(DataHelper.stripHTML(routerVersion));
buf.append("</td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td><td>");
out.write(buf.toString());
buf.setLength(0);
List<String> countryList = new ArrayList(countries.objects());
if (countryList.size() > 0) {
Collections.sort(countryList);
buf.append("<table>\n");
buf.append("<tr><th align=\"left\">Country</th><th>Count</th></tr>\n");
for (String country : countryList) {
int num = countries.count(country);
buf.append("<tr><td><img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase()).append("\"");
buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ");
buf.append(_context.commSystem().getCountryName(country));
buf.append("</td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td></tr></table>");
out.write(buf.toString());
out.flush();
}
/**
* Be careful to use stripHTML for any displayed routerInfo data
* to prevent vulnerabilities
*/
private void renderRouterInfo(StringBuilder buf, RouterInfo info, boolean isUs, boolean full) {
String hash = info.getIdentity().getHash().toBase64();
buf.append("<table><tr><th><a name=\"").append(hash.substring(0, 6)).append("\" ></a>");
if (isUs) {
buf.append("<a name=\"our-info\" ></a><b>Our info: ").append(hash).append("</b></th></tr><tr><td>\n");
} else {
buf.append("<b>Peer info for:</b> ").append(hash).append("\n");
if (full) {
buf.append("[<a href=\"netdb.jsp\" >Back</a>]</th></tr><td>\n");
} else {
buf.append("[<a href=\"netdb.jsp?r=").append(hash.substring(0, 6)).append("\" >Full entry</a>]</th></tr><td>\n");
}
}
long age = _context.clock().now() - info.getPublished();
if (isUs && _context.router().isHidden())
buf.append("<b>Hidden, Updated:</b> ").append(DataHelper.formatDuration(age)).append(" ago<br>\n");
else if (age > 0)
buf.append("<b>Published:</b> ").append(DataHelper.formatDuration(age)).append(" ago<br>\n");
else
buf.append("<b>Published:</b> in ").append(DataHelper.formatDuration(0-age)).append("???<br>\n");
buf.append("<b>Address(es):</b> ");
String country = _context.commSystem().getCountry(info.getIdentity().getHash());
if(country != null) {
buf.append("<img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase()).append("\"");
buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ");
}
for (Iterator iter = info.getAddresses().iterator(); iter.hasNext(); ) {
RouterAddress addr = (RouterAddress)iter.next();
buf.append(DataHelper.stripHTML(addr.getTransportStyle())).append(": ");
for (Iterator optIter = addr.getOptions().keySet().iterator(); optIter.hasNext(); ) {
String name = (String)optIter.next();
String val = addr.getOptions().getProperty(name);
buf.append('[').append(DataHelper.stripHTML(name)).append('=').append(DataHelper.stripHTML(val)).append("] ");
}
}
buf.append("</td></tr>\n");
if (full) {
buf.append("<tr><td>Stats: <br><code>\n");
for (Iterator iter = info.getOptions().keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
String val = info.getOption(key);
buf.append(DataHelper.stripHTML(key)).append(" = ").append(DataHelper.stripHTML(val)).append("<br>\n");
}
buf.append("</code></td></tr>\n");
} else {
}
buf.append("</td></tr>\n");
}
}