propagate from branch 'i2p.i2p.zzz.test' (head efc35e19029b7d92265f25eb024114737b6545e1)
to branch 'i2p.i2p' (head bbf149917e39bdd2f53246c238d440369498ae09)
This commit is contained in:
@ -673,6 +673,8 @@ class I2PSocketManagerImpl implements I2PSocketManager, I2PSessionListener {
|
|||||||
* Ping the specified peer, returning true if they replied to the ping within
|
* Ping the specified peer, returning true if they replied to the ping within
|
||||||
* the timeout specified, false otherwise. This call blocks.
|
* the timeout specified, false otherwise. This call blocks.
|
||||||
*
|
*
|
||||||
|
* @deprecated timeout is ignored - use I2PSocketManagerFull.ping()
|
||||||
|
* @param timeoutMs ignored
|
||||||
*/
|
*/
|
||||||
public boolean ping(Destination peer, long timeoutMs) {
|
public boolean ping(Destination peer, long timeoutMs) {
|
||||||
try {
|
try {
|
||||||
|
@ -73,11 +73,26 @@
|
|||||||
<delete dir="./tmpextract" />
|
<delete dir="./tmpextract" />
|
||||||
|
|
||||||
<ant target="war" />
|
<ant target="war" />
|
||||||
|
|
||||||
|
<!-- Update the messages_*.po files.
|
||||||
|
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||||
|
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
|
||||||
|
<arg value="./bundle-messages.sh" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
|
||||||
|
<arg value="./bundle-messages.sh" />
|
||||||
|
</exec>
|
||||||
|
<exec executable="cmd" osfamily="windows" failifexecutionfails="false" >
|
||||||
|
<arg value="/c" />
|
||||||
|
<arg value="bundle-messages.bat" />
|
||||||
|
</exec>
|
||||||
|
<!-- jar again to get the latest messages_*.class files -->
|
||||||
|
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class" update="true" />
|
||||||
</target>
|
</target>
|
||||||
<target name="war" depends="precompilejsp">
|
<target name="war" depends="precompilejsp">
|
||||||
<!-- Don't include the css in the war, the main build.xml will copy it to docs/themes/console/ -->
|
<!-- Don't include the css in the war, the main build.xml will copy it to docs/themes/console/ -->
|
||||||
<war destfile="build/routerconsole.war" webxml="../jsp/web-out.xml"
|
<war destfile="build/routerconsole.war" webxml="../jsp/web-out.xml"
|
||||||
basedir="../jsp/" excludes="web.xml, *.css, *.java, *.jsp, web-fragment.xml">
|
basedir="../jsp/" excludes="web.xml, *.css, **/*.java, *.jsp, web-fragment.xml">
|
||||||
</war>
|
</war>
|
||||||
</target>
|
</target>
|
||||||
<target name="precompilejsp" unless="precompilejsp.uptodate">
|
<target name="precompilejsp" unless="precompilejsp.uptodate">
|
||||||
@ -115,6 +130,7 @@
|
|||||||
</java>
|
</java>
|
||||||
|
|
||||||
<javac debug="true" deprecation="on" source="1.5" target="1.5"
|
<javac debug="true" deprecation="on" source="1.5" target="1.5"
|
||||||
|
encoding="UTF-8"
|
||||||
destdir="../jsp/WEB-INF/classes/"
|
destdir="../jsp/WEB-INF/classes/"
|
||||||
srcdir="../jsp/WEB-INF/classes" includes="**/*.java">
|
srcdir="../jsp/WEB-INF/classes" includes="**/*.java">
|
||||||
<compilerarg line="${javac.compilerargs}" />
|
<compilerarg line="${javac.compilerargs}" />
|
||||||
@ -133,10 +149,13 @@
|
|||||||
<pathelement location="../../../core/java/build/i2p.jar" />
|
<pathelement location="../../../core/java/build/i2p.jar" />
|
||||||
</classpath>
|
</classpath>
|
||||||
</javac>
|
</javac>
|
||||||
|
|
||||||
|
<!-- save these so we can run gettext on the generated java files later
|
||||||
<delete>
|
<delete>
|
||||||
<fileset dir="../jsp/WEB-INF/" includes="**/*.java" />
|
<fileset dir="../jsp/WEB-INF/" includes="**/*.java" />
|
||||||
<fileset dir="../jsp/WEB-INF/" includes="**/*.jsp" />
|
<fileset dir="../jsp/WEB-INF/" includes="**/*.jsp" />
|
||||||
</delete>
|
</delete>
|
||||||
|
-->
|
||||||
<copy file="../jsp/web.xml" tofile="../jsp/web-out.xml" />
|
<copy file="../jsp/web.xml" tofile="../jsp/web-out.xml" />
|
||||||
<loadfile property="jspc.web.fragment" srcfile="../jsp/web-fragment.xml" />
|
<loadfile property="jspc.web.fragment" srcfile="../jsp/web-fragment.xml" />
|
||||||
<replace file="../jsp/web-out.xml">
|
<replace file="../jsp/web-out.xml">
|
||||||
|
67
apps/routerconsole/java/bundle-messages.sh
Executable file
67
apps/routerconsole/java/bundle-messages.sh
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
#
|
||||||
|
# Update messages_xx.po and messages_xx.class files,
|
||||||
|
# from both java and jsp sources.
|
||||||
|
# Requires installed programs xgettext, msgfmt, msgmerge, and find.
|
||||||
|
# zzz - public domain
|
||||||
|
#
|
||||||
|
CLASS=net.i2p.router.web.messages
|
||||||
|
TMPFILE=build/javafiles.txt
|
||||||
|
export TZ=UTC
|
||||||
|
|
||||||
|
for i in ../locale/messages_*.po
|
||||||
|
do
|
||||||
|
# get language
|
||||||
|
LG=${i#../locale/messages_}
|
||||||
|
LG=${LG%.po}
|
||||||
|
|
||||||
|
# make list of java files newer than the .po file
|
||||||
|
find src ../jsp/WEB-INF -name *.java -newer $i > $TMPFILE
|
||||||
|
if [ -s build/obj/net/i2p/router/web/messages_$LG.class -a ! -s $TMPFILE ]
|
||||||
|
then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||||
|
|
||||||
|
# extract strings from java and jsp files, and update messages.po files
|
||||||
|
# translate calls must be one of the forms:
|
||||||
|
# _("foo")
|
||||||
|
# cssHelper._("foo")
|
||||||
|
# cssHelper.title("foo")
|
||||||
|
# handler._("foo")
|
||||||
|
# formhandler._("foo")
|
||||||
|
# In a jsp, you must use a helper or handler that has the context set.
|
||||||
|
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||||
|
# then ant distclean updater.
|
||||||
|
find src ../jsp/WEB-INF -name *.java > $TMPFILE
|
||||||
|
xgettext -f $TMPFILE -F -L java \
|
||||||
|
--keyword=_ --keyword=cssHelper._ --keyword=cssHelper.title --keyword=handler._ --keyword=formhandler._ \
|
||||||
|
-o ${i}t
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo 'Warning - xgettext failed, not updating translations'
|
||||||
|
rm -f ${i}t
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
msgmerge -U --backup=none $i ${i}t
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo 'Warning - msgmerge failed, not updating translations'
|
||||||
|
rm -f ${i}t
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
rm -f ${i}t
|
||||||
|
# so we don't do this again
|
||||||
|
touch $i
|
||||||
|
|
||||||
|
# convert to class files in build/obj
|
||||||
|
msgfmt --java -r $CLASS -l $LG -d build/obj $i
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo 'Warning - xgettext failed, not updating translations'
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rm -f $TMPFILE
|
||||||
|
# todo: return failure
|
||||||
|
exit 0
|
@ -22,4 +22,21 @@ public class CSSHelper extends HelperBase {
|
|||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** change default language for the router but don't save it */
|
||||||
|
public void setLang(String lang) {
|
||||||
|
if (lang != null && lang.length() > 0)
|
||||||
|
_context.router().setConfigSetting(Messages.PROP_LANG, lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** translate the title and display consistently */
|
||||||
|
public String title(String s) {
|
||||||
|
StringBuilder buf = new StringBuilder(128);
|
||||||
|
buf.append("<title>")
|
||||||
|
.append(_("I2P Router Console"))
|
||||||
|
.append(" - ")
|
||||||
|
.append(_(s))
|
||||||
|
.append("</title>");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public class ConfigUpdateHelper extends HelperBase {
|
|||||||
buf.append("<select name=\"updatePolicy\">");
|
buf.append("<select name=\"updatePolicy\">");
|
||||||
|
|
||||||
if ("notify".equals(policy))
|
if ("notify".equals(policy))
|
||||||
buf.append("<option value=\"notify\" selected=\"true\">Notify only</option>");
|
buf.append("<option value=\"notify\" selected=\"true\">").append(_("Notify only")).append("</option>");
|
||||||
else
|
else
|
||||||
buf.append("<option value=\"notify\">Notify only</option>");
|
buf.append("<option value=\"notify\">Notify only</option>");
|
||||||
|
|
||||||
|
@ -62,7 +62,8 @@ public class ContentHelper extends HelperBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert file.ext to file_lang.ext if it exists.
|
* Convert file.ext to file_lang.ext if it exists.
|
||||||
* Get lang from either the cgi lang param or from the default locale.
|
* Get lang from the cgi lang param, then properties, then from the default locale.
|
||||||
|
* _context must be set to check the property.
|
||||||
*/
|
*/
|
||||||
private String filename() {
|
private String filename() {
|
||||||
int lastdot = _page.lastIndexOf('.');
|
int lastdot = _page.lastIndexOf('.');
|
||||||
@ -70,9 +71,13 @@ public class ContentHelper extends HelperBase {
|
|||||||
return _page;
|
return _page;
|
||||||
String lang = _lang;
|
String lang = _lang;
|
||||||
if (lang == null || lang.length() <= 0) {
|
if (lang == null || lang.length() <= 0) {
|
||||||
lang = Locale.getDefault().getLanguage();
|
if (_context != null)
|
||||||
if (lang == null || lang.length() <= 0)
|
lang = _context.getProperty(Messages.PROP_LANG);
|
||||||
return _page;
|
if (lang == null || lang.length() <= 0) {
|
||||||
|
lang = Locale.getDefault().getLanguage();
|
||||||
|
if (lang == null || lang.length() <= 0)
|
||||||
|
return _page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lang.equals("en"))
|
if (lang.equals("en"))
|
||||||
return _page;
|
return _page;
|
||||||
|
@ -190,4 +190,8 @@ public class FormHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
public String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,4 +29,9 @@ public abstract class HelperBase {
|
|||||||
//public RouterContext getContext() { return _context; }
|
//public RouterContext getContext() { return _context; }
|
||||||
|
|
||||||
public void setWriter(Writer out) { _out = out; }
|
public void setWriter(Writer out) { _out = out; }
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
public String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
|
||||||
|
import org.mortbay.http.HttpRequest;
|
||||||
|
import org.mortbay.http.HttpResponse;
|
||||||
|
import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert foo.jsp to foo_xx.jsp for language xx.
|
||||||
|
* This is appropriate for jsps with large amounts of text.
|
||||||
|
* This does not work for included jsps (e.g. summary*)
|
||||||
|
*
|
||||||
|
* @author zzz
|
||||||
|
*/
|
||||||
|
public class LocaleWebAppHandler extends WebApplicationHandler
|
||||||
|
{
|
||||||
|
private I2PAppContext _context;
|
||||||
|
|
||||||
|
public LocaleWebAppHandler(I2PAppContext ctx) {
|
||||||
|
super();
|
||||||
|
_context = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle foo.jsp by converting to foo_xx.jsp
|
||||||
|
* for language xx, where xx is the language for the default locale,
|
||||||
|
* or as specified in the routerconsole.lang property.
|
||||||
|
* Unless language==="en".
|
||||||
|
*/
|
||||||
|
public void handle(String pathInContext,
|
||||||
|
String pathParams,
|
||||||
|
HttpRequest httpRequest,
|
||||||
|
HttpResponse httpResponse)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
//System.err.println("Path: " + pathInContext);
|
||||||
|
String newPath = pathInContext;
|
||||||
|
if (pathInContext.endsWith(".jsp")) {
|
||||||
|
int len = pathInContext.length();
|
||||||
|
// ...but leave foo_xx.jsp alone
|
||||||
|
if (len < 8 || pathInContext.charAt(len - 7) != '_') {
|
||||||
|
String lang = _context.getProperty(Messages.PROP_LANG);
|
||||||
|
if (lang == null || lang.length() <= 0)
|
||||||
|
lang = Locale.getDefault().getLanguage();
|
||||||
|
if (lang != null && lang.length() > 0 && !lang.equals("en")) {
|
||||||
|
String testPath = pathInContext.substring(0, len - 4) + '_' + lang + ".jsp";
|
||||||
|
// Do we have a servlet for the new path that isn't the catchall *.jsp?
|
||||||
|
Map.Entry servlet = getHolderEntry(testPath);
|
||||||
|
if (servlet != null) {
|
||||||
|
String servletPath = (String) servlet.getKey();
|
||||||
|
if (servletPath != null && !servletPath.startsWith("*")) {
|
||||||
|
// success!!
|
||||||
|
//System.err.println("Servlet is: " + servletPath);
|
||||||
|
newPath = testPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.err.println("New path: " + newPath);
|
||||||
|
super.handle(newPath, pathParams, httpRequest, httpResponse);
|
||||||
|
//System.err.println("Was handled? " + httpRequest.isHandled());
|
||||||
|
}
|
||||||
|
}
|
80
apps/routerconsole/java/src/net/i2p/router/web/Messages.java
Normal file
80
apps/routerconsole/java/src/net/i2p/router/web/Messages.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.util.ConcurrentHashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate strings efficiently.
|
||||||
|
* We don't include an English or default ResourceBundle, we simply check
|
||||||
|
* for "en" and return the original string.
|
||||||
|
* Support real-time language changing with the routerconsole.lang property.
|
||||||
|
*
|
||||||
|
* @author zzz, from a base generated by eclipse.
|
||||||
|
*/
|
||||||
|
public class Messages {
|
||||||
|
public static final String PROP_LANG = "routerconsole.lang";
|
||||||
|
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
||||||
|
private static final String _localeLang = Locale.getDefault().getLanguage();
|
||||||
|
private static final Map<String, ResourceBundle> _bundles = new ConcurrentHashMap(2);
|
||||||
|
private static final Set<String> _missing = new ConcurrentHashSet(2);
|
||||||
|
|
||||||
|
/** current locale **/
|
||||||
|
public static String getString(String key) {
|
||||||
|
if (_localeLang.equals("en"))
|
||||||
|
return key;
|
||||||
|
ResourceBundle bundle = findBundle(_localeLang);
|
||||||
|
if (bundle == null)
|
||||||
|
return key;
|
||||||
|
try {
|
||||||
|
return bundle.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** lang in routerconsole.lang property, else current locale */
|
||||||
|
public static String getString(String key, I2PAppContext ctx) {
|
||||||
|
String lang = getLanguage(ctx);
|
||||||
|
if (lang.equals("en"))
|
||||||
|
return key;
|
||||||
|
ResourceBundle bundle = findBundle(lang);
|
||||||
|
if (bundle == null)
|
||||||
|
return key;
|
||||||
|
try {
|
||||||
|
return bundle.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLanguage(I2PAppContext ctx) {
|
||||||
|
String lang = ctx.getProperty(PROP_LANG);
|
||||||
|
if (lang == null || lang.length() <= 0)
|
||||||
|
lang = _localeLang;
|
||||||
|
return lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** cache both found and not found for speed */
|
||||||
|
private static ResourceBundle findBundle(String lang) {
|
||||||
|
ResourceBundle rv = _bundles.get(lang);
|
||||||
|
if (rv == null && !_missing.contains(lang)) {
|
||||||
|
try {
|
||||||
|
// Would it be faster to specify a class loader?
|
||||||
|
// No matter we only do this once per lang.
|
||||||
|
rv = ResourceBundle.getBundle(BUNDLE_NAME, new Locale(lang));
|
||||||
|
if (rv != null)
|
||||||
|
_bundles.put(lang, rv);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
_missing.add(lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
@ -17,23 +17,24 @@ public class NetDbHelper extends HelperBase {
|
|||||||
public void setLease(String l) { _lease = "1".equals(l); }
|
public void setLease(String l) { _lease = "1".equals(l); }
|
||||||
|
|
||||||
public String getNetDbSummary() {
|
public String getNetDbSummary() {
|
||||||
|
NetDbRenderer renderer = new NetDbRenderer(_context);
|
||||||
try {
|
try {
|
||||||
if (_out != null) {
|
if (_out != null) {
|
||||||
if (_routerPrefix != null)
|
if (_routerPrefix != null)
|
||||||
_context.netDb().renderRouterInfoHTML(_out, _routerPrefix);
|
renderer.renderRouterInfoHTML(_out, _routerPrefix);
|
||||||
else if (_lease)
|
else if (_lease)
|
||||||
_context.netDb().renderLeaseSetHTML(_out);
|
renderer.renderLeaseSetHTML(_out);
|
||||||
else
|
else
|
||||||
_context.netDb().renderStatusHTML(_out, _full);
|
renderer.renderStatusHTML(_out, _full);
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||||
if (_routerPrefix != null)
|
if (_routerPrefix != null)
|
||||||
_context.netDb().renderRouterInfoHTML(new OutputStreamWriter(baos), _routerPrefix);
|
renderer.renderRouterInfoHTML(new OutputStreamWriter(baos), _routerPrefix);
|
||||||
else if (_lease)
|
else if (_lease)
|
||||||
_context.netDb().renderLeaseSetHTML(new OutputStreamWriter(baos));
|
renderer.renderLeaseSetHTML(new OutputStreamWriter(baos));
|
||||||
else
|
else
|
||||||
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos), _full);
|
renderer.renderStatusHTML(new OutputStreamWriter(baos), _full);
|
||||||
return new String(baos.toByteArray());
|
return new String(baos.toByteArray());
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -0,0 +1,275 @@
|
|||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
private String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
|
}
|
@ -319,4 +319,9 @@ class ProfileOrganizerRenderer {
|
|||||||
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
||||||
return "" + c;
|
return "" + c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
private String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ public class RouterConsoleRunner {
|
|||||||
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
|
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
|
||||||
tmpdir.mkdir();
|
tmpdir.mkdir();
|
||||||
wac.setTempDirectory(tmpdir);
|
wac.setTempDirectory(tmpdir);
|
||||||
|
wac.addHandler(0, new LocaleWebAppHandler(I2PAppContext.getGlobalContext()));
|
||||||
initialize(wac);
|
initialize(wac);
|
||||||
File dir = new File(_webAppsDir);
|
File dir = new File(_webAppsDir);
|
||||||
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
||||||
|
@ -235,4 +235,9 @@ public class StatsGenerator {
|
|||||||
|
|
||||||
private final static DecimalFormat _pct = new DecimalFormat("#0.00%");
|
private final static DecimalFormat _pct = new DecimalFormat("#0.00%");
|
||||||
private final static String pct(double num) { synchronized (_pct) { return _pct.format(num); } }
|
private final static String pct(double num) { synchronized (_pct) { return _pct.format(num); } }
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
private String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,417 @@
|
|||||||
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refactored from summarynoframe.jsp to save ~100KB
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SummaryBarRenderer {
|
||||||
|
private RouterContext _context;
|
||||||
|
private SummaryHelper _helper;
|
||||||
|
|
||||||
|
public SummaryBarRenderer(RouterContext context, SummaryHelper helper) {
|
||||||
|
_context = context;
|
||||||
|
_helper = helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderSummaryHTML(Writer out) throws IOException {
|
||||||
|
StringBuilder buf = new StringBuilder(8*1024);
|
||||||
|
|
||||||
|
buf.append("<a href=\"index.jsp\" target=\"_top\"><img src=\"/themes/console/images/i2plogo.png\" alt=\"")
|
||||||
|
.append(_("I2P Router Console"))
|
||||||
|
.append("\" title=\"")
|
||||||
|
.append(_("I2P Router Console"))
|
||||||
|
.append("\"></a><hr>");
|
||||||
|
|
||||||
|
File lpath = new File(_context.getBaseDir(), "docs/toolbar.html");
|
||||||
|
// you better have target="_top" for the links in there...
|
||||||
|
if (lpath.exists()) {
|
||||||
|
ContentHelper linkhelper = new ContentHelper();
|
||||||
|
linkhelper.setPage(lpath.getAbsolutePath());
|
||||||
|
linkhelper.setMaxLines("100");
|
||||||
|
buf.append(linkhelper.getContent());
|
||||||
|
} else {
|
||||||
|
buf.append("<h3><a href=\"/configclients.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append("Configure startup of clients and webapps (services); manually start dormant services")
|
||||||
|
.append("\">")
|
||||||
|
.append(_("I2P Services"))
|
||||||
|
.append("</a></h3>\n" +
|
||||||
|
|
||||||
|
"<hr><table>" +
|
||||||
|
|
||||||
|
"<tr><td><a href=\"susidns/index.jsp\" target=\"_blank\" title=\"")
|
||||||
|
.append(_("Manage your I2P hosts file here (I2P domain name resolution)"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Addressbook"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"i2psnark/\" target=\"_blank\" title=\"")
|
||||||
|
.append(_("Built-in anonymous BitTorrent Client"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Torrents"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"susimail/susimail\" target=\"blank\" title=\"")
|
||||||
|
.append(_("Anonymous webmail client"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Webmail"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"http://127.0.0.1:7658/\" target=\"_blank\" title=\"")
|
||||||
|
.append(_("Anonymous resident webserver"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Webserver"))
|
||||||
|
.append("</a></td></tr></table>\n" +
|
||||||
|
|
||||||
|
"<hr><h3><a href=\"config.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Configure I2P Router"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("I2P Internals"))
|
||||||
|
.append("</a></h3><hr>\n" +
|
||||||
|
|
||||||
|
"<table><tr><td>\n" +
|
||||||
|
|
||||||
|
"<a href=\"tunnels.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("View existing tunnels and tunnel build status"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Tunnels"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"peers.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Show all current peer connections"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Peers"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"profiles.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Show recent peer performance profiles"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Profiles"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"netdb.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Show list of all known I2P routers"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("NetDB"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"logs.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Health Report"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Logs"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"jobs.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Show the router's workload, and how it's performing"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Jobs"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"graphs.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Graph router performance"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Graphs"))
|
||||||
|
.append("</a>\n" +
|
||||||
|
|
||||||
|
"<a href=\"oldstats.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Textual router performance statistics"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Stats"))
|
||||||
|
.append("</a></td></tr></table>\n");
|
||||||
|
|
||||||
|
out.write(buf.toString());
|
||||||
|
buf.setLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
buf.append("<hr><h3><a href=\"help.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("I2P Router Help"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("General"))
|
||||||
|
.append("</a></h3><hr>" +
|
||||||
|
"<h4><a title=\"")
|
||||||
|
.append(_("Your unique I2P router identity is"))
|
||||||
|
.append(' ')
|
||||||
|
.append(_helper.getIdent())
|
||||||
|
.append(", ")
|
||||||
|
.append(_("never reveal it to anyone"))
|
||||||
|
.append("\" href=\"netdb.jsp?r=.\" target=\"_top\">")
|
||||||
|
.append(_("Local Identity"))
|
||||||
|
.append("<a></h4><hr>\n" +
|
||||||
|
|
||||||
|
"<table><tr><td align=\"left\">" +
|
||||||
|
"<b>")
|
||||||
|
.append(_("Version"))
|
||||||
|
.append(":</b></td>" +
|
||||||
|
"<td align=\"right\">")
|
||||||
|
.append(_helper.getVersion())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr title=\"")
|
||||||
|
.append(_("How long we've been running for this session"))
|
||||||
|
.append("\">" +
|
||||||
|
"<td align=\"left\"><b>")
|
||||||
|
.append(_("Uptime"))
|
||||||
|
.append(":</b></td>" +
|
||||||
|
"<td align=\"right\">")
|
||||||
|
.append(_helper.getUptime())
|
||||||
|
.append("</td></tr></table>\n" +
|
||||||
|
|
||||||
|
"<hr><h4><a href=\"config.jsp#help\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Help with configuring your firewall and router for optimal I2P performance"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_helper.getReachability())
|
||||||
|
.append("</a></h4><hr>\n");
|
||||||
|
|
||||||
|
|
||||||
|
if (_helper.updateAvailable() || _helper.unsignedUpdateAvailable()) {
|
||||||
|
// display all the time so we display the final failure message
|
||||||
|
buf.append("<br>").append(UpdateHandler.getStatus());
|
||||||
|
if ("true".equals(System.getProperty("net.i2p.router.web.UpdateHandler.updateInProgress"))) {
|
||||||
|
// nothing
|
||||||
|
} else if(
|
||||||
|
// isDone() is always false for now, see UpdateHandler
|
||||||
|
// ((!update.isDone()) &&
|
||||||
|
_helper.getAction() == null &&
|
||||||
|
_helper.getUpdateNonce() == null &&
|
||||||
|
ConfigRestartBean.getRestartTimeRemaining() > 12*60*1000) {
|
||||||
|
long nonce = _context.random().nextLong();
|
||||||
|
String prev = System.getProperty("net.i2p.router.web.UpdateHandler.nonce");
|
||||||
|
if (prev != null)
|
||||||
|
System.setProperty("net.i2p.router.web.UpdateHandler.noncePrev", prev);
|
||||||
|
System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+"");
|
||||||
|
String uri = _helper.getRequestURI();
|
||||||
|
buf.append("<form action=\"").append(uri).append("\" method=\"GET\">\n");
|
||||||
|
buf.append("<input type=\"hidden\" name=\"updateNonce\" value=\"").append(nonce).append("\" >\n");
|
||||||
|
if (_helper.updateAvailable()) {
|
||||||
|
buf.append("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >")
|
||||||
|
.append(_("Download"))
|
||||||
|
.append(' ')
|
||||||
|
.append(_helper.getUpdateVersion())
|
||||||
|
.append(' ')
|
||||||
|
.append(_("Update"))
|
||||||
|
.append("</button>\n");
|
||||||
|
}
|
||||||
|
if (_helper.unsignedUpdateAvailable()) {
|
||||||
|
buf.append("<button type=\"submit\" name=\"updateAction\" value=\"Unsigned\" >")
|
||||||
|
.append(_("Download Unsigned"))
|
||||||
|
.append("<br>")
|
||||||
|
.append(_helper.getUnsignedUpdateVersion())
|
||||||
|
.append(' ')
|
||||||
|
.append(_("Update"))
|
||||||
|
.append("</button>\n");
|
||||||
|
}
|
||||||
|
buf.append("</form>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
buf.append("<p>")
|
||||||
|
.append(ConfigRestartBean.renderStatus(_helper.getRequestURI(), _helper.getAction(), _helper.getConsoleNonce()))
|
||||||
|
|
||||||
|
.append("</p><hr><h3><a href=\"peers.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Show all current peer connections"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Peers"))
|
||||||
|
.append("</a></h3><hr>\n" +
|
||||||
|
|
||||||
|
"<table>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Active"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getActivePeers())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getActiveProfiles())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Fast"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getFastPeers())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("High capacity"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getHighCapacityPeers())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Integrated"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getWellIntegratedPeers())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Known"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getAllPeers())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"</table><hr>\n");
|
||||||
|
|
||||||
|
|
||||||
|
out.write(buf.toString());
|
||||||
|
buf.setLength(0);
|
||||||
|
|
||||||
|
|
||||||
|
boolean anotherLine = false;
|
||||||
|
if (_helper.showFirewallWarning()) {
|
||||||
|
buf.append("<h4><a href=\"config.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("Help with firewall configuration"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Check NAT/firewall"))
|
||||||
|
.append("</a></h4>");
|
||||||
|
anotherLine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
|
||||||
|
// If showing the reseed link is allowed
|
||||||
|
if (_helper.allowReseed()) {
|
||||||
|
if (reseedInProgress) {
|
||||||
|
// While reseed occurring, show status message instead
|
||||||
|
buf.append("<i>").append(System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","")).append("</i><br>");
|
||||||
|
} else {
|
||||||
|
// While no reseed occurring, show reseed link
|
||||||
|
long nonce = _context.random().nextLong();
|
||||||
|
String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
|
||||||
|
if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
|
||||||
|
System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
|
||||||
|
String uri = _helper.getRequestURI();
|
||||||
|
buf.append("<form action=\"").append(uri).append("\" method=\"GET\">\n");
|
||||||
|
buf.append("<input type=\"hidden\" name=\"reseedNonce\" value=\"").append(nonce).append("\" >\n");
|
||||||
|
buf.append("<button type=\"submit\" >Reseed</button></form>\n");
|
||||||
|
}
|
||||||
|
anotherLine = true;
|
||||||
|
}
|
||||||
|
// If a new reseed ain't running, and the last reseed had errors, show error message
|
||||||
|
if (!reseedInProgress) {
|
||||||
|
String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
|
||||||
|
if (reseedErrorMessage.length() > 0) {
|
||||||
|
buf.append("<i>").append(reseedErrorMessage).append("</i><br>");
|
||||||
|
anotherLine = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (anotherLine)
|
||||||
|
buf.append("<hr>");
|
||||||
|
|
||||||
|
|
||||||
|
buf.append("<h3><a href=\"config.jsp\" title=\"")
|
||||||
|
.append(_("Configure router bandwidth allocation"))
|
||||||
|
.append("\" target=\"_top\">")
|
||||||
|
.append(_("Bandwidth in/out"))
|
||||||
|
.append("</a></h3><hr>" +
|
||||||
|
"<table>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>1s:</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundSecondKBps())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundSecondKBps())
|
||||||
|
.append("K/s</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>5m:</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundFiveMinuteKBps())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundFiveMinuteKBps())
|
||||||
|
.append("K/s</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Total"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundLifetimeKBps())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundLifetimeKBps())
|
||||||
|
.append("K/s</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Used"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundTransferred())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundTransferred())
|
||||||
|
.append("</td></tr></table>\n" +
|
||||||
|
|
||||||
|
"<hr><h3><a href=\"tunnels.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("View existing tunnels and tunnel build status"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Tunnels in/out"))
|
||||||
|
.append("</a></h3><hr>" +
|
||||||
|
"<table>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Exploratory"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundTunnels())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundTunnels())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Client"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundClientTunnels())
|
||||||
|
.append('/')
|
||||||
|
.append(_helper.getOutboundClientTunnels())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Participating"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getParticipatingTunnels())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"</table><hr><h3><a href=\"/jobs.jsp\" target=\"_top\" title=\"")
|
||||||
|
.append(_("What's in the router's job queue?"))
|
||||||
|
.append("\">")
|
||||||
|
.append(_("Congestion"))
|
||||||
|
.append("</a></h3><hr>" +
|
||||||
|
"<table>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Job lag"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getJobLag())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Message delay"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getMessageDelay())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Tunnel lag"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getTunnelLag())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td align=\"left\"><b>")
|
||||||
|
.append(_("Backlog"))
|
||||||
|
.append(":</b></td><td align=\"right\">")
|
||||||
|
.append(_helper.getInboundBacklog())
|
||||||
|
.append("</td></tr>\n" +
|
||||||
|
|
||||||
|
"</table><hr><h4>")
|
||||||
|
.append(_helper.getTunnelStatus())
|
||||||
|
.append("</h4><hr>\n")
|
||||||
|
.append(_helper.getDestinations());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
out.write(buf.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
private String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package net.i2p.router.web;
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -563,4 +564,28 @@ public class SummaryHelper extends HelperBase {
|
|||||||
public String getUnsignedUpdateVersion() {
|
public String getUnsignedUpdateVersion() {
|
||||||
return NewsFetcher.getInstance(_context).unsignedUpdateVersion();
|
return NewsFetcher.getInstance(_context).unsignedUpdateVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** output the summary bar to _out */
|
||||||
|
public void renderSummaryBar() throws IOException {
|
||||||
|
SummaryBarRenderer renderer = new SummaryBarRenderer(_context, this);
|
||||||
|
renderer.renderSummaryHTML(_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* below here is stuff we need to get from summarynoframe.jsp to SummaryBarRenderer */
|
||||||
|
|
||||||
|
private String _action;
|
||||||
|
public void setAction(String s) { _action = s; }
|
||||||
|
public String getAction() { return _action; }
|
||||||
|
|
||||||
|
private String _consoleNonce;
|
||||||
|
public void setConsoleNonce(String s) { _consoleNonce = s; }
|
||||||
|
public String getConsoleNonce() { return _consoleNonce; }
|
||||||
|
|
||||||
|
private String _updateNonce;
|
||||||
|
public void setUpdateNonce(String s) { _updateNonce = s; }
|
||||||
|
public String getUpdateNonce() { return _updateNonce; }
|
||||||
|
|
||||||
|
private String _requestURI;
|
||||||
|
public void setRequestURI(String s) { _requestURI = s; }
|
||||||
|
public String getRequestURI() { return _requestURI; }
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,14 @@ public class TunnelHelper extends HelperBase {
|
|||||||
public TunnelHelper() {}
|
public TunnelHelper() {}
|
||||||
|
|
||||||
public String getTunnelSummary() {
|
public String getTunnelSummary() {
|
||||||
|
TunnelRenderer renderer = new TunnelRenderer(_context);
|
||||||
try {
|
try {
|
||||||
if (_out != null) {
|
if (_out != null) {
|
||||||
_context.tunnelManager().renderStatusHTML(_out);
|
renderer.renderStatusHTML(_out);
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||||
_context.tunnelManager().renderStatusHTML(new OutputStreamWriter(baos));
|
renderer.renderStatusHTML(new OutputStreamWriter(baos));
|
||||||
return new String(baos.toByteArray());
|
return new String(baos.toByteArray());
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -0,0 +1,318 @@
|
|||||||
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.data.Hash;
|
||||||
|
import net.i2p.data.RouterInfo;
|
||||||
|
import net.i2p.data.TunnelId;
|
||||||
|
import net.i2p.router.Router;
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.TunnelInfo;
|
||||||
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
|
import net.i2p.router.tunnel.HopConfig;
|
||||||
|
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||||
|
import net.i2p.stat.RateStat;
|
||||||
|
import net.i2p.util.ObjectCounter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TunnelRenderer {
|
||||||
|
private RouterContext _context;
|
||||||
|
|
||||||
|
public TunnelRenderer(RouterContext ctx) {
|
||||||
|
_context = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderStatusHTML(Writer out) throws IOException {
|
||||||
|
out.write("<div class=\"wideload\"><h2><a name=\"exploratory\" ></a>Exploratory tunnels (<a href=\"/configtunnels.jsp#exploratory\">config</a>):</h2>\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(clientInboundPools.keySet());
|
||||||
|
for (int i = 0; i < destinations.size(); i++) {
|
||||||
|
Hash client = destinations.get(i);
|
||||||
|
TunnelPool in = null;
|
||||||
|
TunnelPool outPool = null;
|
||||||
|
in = clientInboundPools.get(client);
|
||||||
|
outPool = clientOutboundPools.get(client);
|
||||||
|
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("<h2><a name=\"" + client.toBase64().substring(0,4)
|
||||||
|
+ "\" ></a>Client tunnels for " + name);
|
||||||
|
if (_context.clientManager().isLocal(client))
|
||||||
|
out.write(" (<a href=\"/configtunnels.jsp#" + client.toBase64().substring(0,4) +"\">config</a>):</h2>\n");
|
||||||
|
else
|
||||||
|
out.write(" (dead):</h2>\n");
|
||||||
|
renderPool(out, in, outPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
List participating = _context.tunnelDispatcher().listParticipatingTunnels();
|
||||||
|
Collections.sort(participating, new TunnelComparator());
|
||||||
|
out.write("<h2><a name=\"participating\"></a>Participating tunnels:</h2><table>\n");
|
||||||
|
out.write("<tr><th>Receive on</th><th>From</th><th>"
|
||||||
|
+ "Send on</th><th>To</th><th>Expiration</th>"
|
||||||
|
+ "<th>Usage</th><th>Rate</th><th>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;
|
||||||
|
for (int i = 0; i < participating.size(); i++) {
|
||||||
|
HopConfig cfg = (HopConfig)participating.get(i);
|
||||||
|
if (cfg.getProcessedMessagesCount() <= 0) {
|
||||||
|
inactive++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
out.write("<tr>");
|
||||||
|
if (cfg.getReceiveTunnel() != null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getReceiveTunnel().getTunnelId() +"</td>");
|
||||||
|
else
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">n/a</td>");
|
||||||
|
if (cfg.getReceiveFrom() != null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"right\">" + netDbLink(cfg.getReceiveFrom()) +"</td>");
|
||||||
|
else
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
||||||
|
if (cfg.getSendTunnel() != null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getSendTunnel().getTunnelId() +"</td>");
|
||||||
|
else
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
||||||
|
if (cfg.getSendTo() != null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + netDbLink(cfg.getSendTo()) +"</td>");
|
||||||
|
else
|
||||||
|
// out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
||||||
|
long timeLeft = cfg.getExpiration()-_context.clock().now();
|
||||||
|
if (timeLeft > 0)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>");
|
||||||
|
else
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">(grace period)</td>");
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getProcessedMessagesCount() + "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 * (int) cfg.getProcessedMessagesCount() / lifetime;
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + bps + "Bps</td>");
|
||||||
|
if (cfg.getSendTo() == null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">Outbound Endpoint</td>");
|
||||||
|
else if (cfg.getReceiveFrom() == null)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">Inbound Gateway</td>");
|
||||||
|
else
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">Participant</td>");
|
||||||
|
out.write("</tr>\n");
|
||||||
|
processed += cfg.getProcessedMessagesCount();
|
||||||
|
}
|
||||||
|
out.write("</table>\n");
|
||||||
|
out.write("<div class=\"statusnotes\"><b>Inactive participating tunnels: " + inactive + "</b></div>\n");
|
||||||
|
out.write("<div class=\"statusnotes\"><b>Lifetime bandwidth usage: " + DataHelper.formatSize(processed*1024) + "B</b></div>\n");
|
||||||
|
renderPeers(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TunnelComparator implements Comparator {
|
||||||
|
public int compare(Object l, Object r) {
|
||||||
|
return (int) (((HopConfig)r).getProcessedMessagesCount() - ((HopConfig)l).getProcessedMessagesCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPool(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
|
||||||
|
List<TunnelInfo> tunnels = null;
|
||||||
|
if (in == null)
|
||||||
|
tunnels = new ArrayList();
|
||||||
|
else
|
||||||
|
tunnels = in.listTunnels();
|
||||||
|
if (outPool != null)
|
||||||
|
tunnels.addAll(outPool.listTunnels());
|
||||||
|
|
||||||
|
long processedIn = (in != null ? in.getLifetimeProcessed() : 0);
|
||||||
|
long processedOut = (outPool != null ? outPool.getLifetimeProcessed() : 0);
|
||||||
|
|
||||||
|
int live = 0;
|
||||||
|
int maxLength = 1;
|
||||||
|
for (int i = 0; i < tunnels.size(); i++) {
|
||||||
|
TunnelInfo info = tunnels.get(i);
|
||||||
|
if (info.getLength() > maxLength)
|
||||||
|
maxLength = info.getLength();
|
||||||
|
}
|
||||||
|
out.write("<table><tr><th>In/Out</th><th>Expiry</th><th>Usage</th><th>Gateway</th>");
|
||||||
|
if (maxLength > 3) {
|
||||||
|
out.write("<th align=\"center\" colspan=\"" + (maxLength - 2));
|
||||||
|
out.write("\">Participants</th>");
|
||||||
|
}
|
||||||
|
else if (maxLength == 3) {
|
||||||
|
out.write("<th>Participant</th>");
|
||||||
|
}
|
||||||
|
if (maxLength > 1) {
|
||||||
|
out.write("<th>Endpoint</th>");
|
||||||
|
}
|
||||||
|
out.write("</tr>\n");
|
||||||
|
for (int i = 0; i < tunnels.size(); i++) {
|
||||||
|
TunnelInfo info = tunnels.get(i);
|
||||||
|
long timeLeft = info.getExpiration()-_context.clock().now();
|
||||||
|
if (timeLeft <= 0)
|
||||||
|
continue; // don't display tunnels in their grace period
|
||||||
|
live++;
|
||||||
|
if (info.isInbound())
|
||||||
|
out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"Inbound\"></td>");
|
||||||
|
else
|
||||||
|
out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"Outbound\"></td>");
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>\n");
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + info.getProcessedMessagesCount() + "KB</td>\n");
|
||||||
|
for (int j = 0; j < info.getLength(); j++) {
|
||||||
|
Hash peer = info.getPeer(j);
|
||||||
|
TunnelId id = (info.isInbound() ? info.getReceiveTunnelId(j) : info.getSendTunnelId(j));
|
||||||
|
if (_context.routerHash().equals(peer)) {
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + (id == null ? "" : "" + id) + "</td>");
|
||||||
|
} else {
|
||||||
|
String cap = getCapacity(peer);
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + netDbLink(peer) + (id == null ? "" : " " + id) + cap + "</td>");
|
||||||
|
}
|
||||||
|
if (info.getLength() < maxLength && (info.getLength() == 1 || j == info.getLength() - 2)) {
|
||||||
|
for (int k = info.getLength(); k < maxLength; k++)
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write("</tr>\n");
|
||||||
|
|
||||||
|
if (info.isInbound())
|
||||||
|
processedIn += info.getProcessedMessagesCount();
|
||||||
|
else
|
||||||
|
processedOut += info.getProcessedMessagesCount();
|
||||||
|
}
|
||||||
|
out.write("</table>\n");
|
||||||
|
if (in != null) {
|
||||||
|
List pending = in.listPending();
|
||||||
|
if (pending.size() > 0)
|
||||||
|
out.write("<div class=\"statusnotes\"><center><b>Build in progress: " + pending.size() + " inbound</b></center></div>\n");
|
||||||
|
live += pending.size();
|
||||||
|
}
|
||||||
|
if (outPool != null) {
|
||||||
|
List pending = outPool.listPending();
|
||||||
|
if (pending.size() > 0)
|
||||||
|
out.write("<div class=\"statusnotes\"><center><b>Build in progress: " + pending.size() + " outbound</b></center></div>\n");
|
||||||
|
live += pending.size();
|
||||||
|
}
|
||||||
|
if (live <= 0)
|
||||||
|
out.write("<div class=\"statusnotes\"><center><b>No tunnels; waiting for the grace period to end.</center></b></div>\n");
|
||||||
|
out.write("<div class=\"statusnotes\"><center><b>Lifetime bandwidth usage: " + DataHelper.formatSize(processedIn*1024) + "B in, " +
|
||||||
|
DataHelper.formatSize(processedOut*1024) + "B out</b></center></div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPeers(Writer out) throws IOException {
|
||||||
|
// count up the peers in the local pools
|
||||||
|
ObjectCounter<Hash> lc = new ObjectCounter();
|
||||||
|
int tunnelCount = countTunnelsPerPeer(lc);
|
||||||
|
|
||||||
|
// count up the peers in the participating tunnels
|
||||||
|
ObjectCounter<Hash> pc = new ObjectCounter();
|
||||||
|
int partCount = countParticipatingPerPeer(pc);
|
||||||
|
|
||||||
|
Set<Hash> peers = new HashSet(lc.objects());
|
||||||
|
peers.addAll(pc.objects());
|
||||||
|
List<Hash> peerList = new ArrayList(peers);
|
||||||
|
Collections.sort(peerList, new HashComparator());
|
||||||
|
|
||||||
|
out.write("<h2><a name=\"peers\"></a>Tunnel Counts By Peer:</h2>\n");
|
||||||
|
out.write("<table><tr><th>Peer</th><th>Expl. + Client</th><th>% of total</th><th>Part. from + to</th><th>% of total</th></tr>\n");
|
||||||
|
for (Hash h : peerList) {
|
||||||
|
out.write("<tr> <td class=\"cells\" align=\"center\">");
|
||||||
|
out.write(netDbLink(h));
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + lc.count(h));
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">");
|
||||||
|
if (tunnelCount > 0)
|
||||||
|
out.write("" + (lc.count(h) * 100 / tunnelCount));
|
||||||
|
else
|
||||||
|
out.write('0');
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">" + pc.count(h));
|
||||||
|
out.write(" <td class=\"cells\" align=\"center\">");
|
||||||
|
if (partCount > 0)
|
||||||
|
out.write("" + (pc.count(h) * 100 / partCount));
|
||||||
|
else
|
||||||
|
out.write('0');
|
||||||
|
out.write('\n');
|
||||||
|
}
|
||||||
|
out.write("<tr class=\"tablefooter\"> <td align=\"center\"><b>Tunnels</b> <td align=\"center\"><b>" + tunnelCount);
|
||||||
|
out.write("</b> <td> </td> <td align=\"center\"><b>" + partCount);
|
||||||
|
out.write("</b> <td> </td></tr></table></div>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* duplicate of that in tunnelPoolManager for now */
|
||||||
|
/** @return total number of non-fallback expl. + client tunnels */
|
||||||
|
private int countTunnelsPerPeer(ObjectCounter<Hash> lc) {
|
||||||
|
List<TunnelPool> pools = new ArrayList();
|
||||||
|
_context.tunnelManager().listPools(pools);
|
||||||
|
int tunnelCount = 0;
|
||||||
|
for (TunnelPool tp : pools) {
|
||||||
|
for (TunnelInfo info : tp.listTunnels()) {
|
||||||
|
if (info.getLength() > 1) {
|
||||||
|
tunnelCount++;
|
||||||
|
for (int j = 0; j < info.getLength(); j++) {
|
||||||
|
Hash peer = info.getPeer(j);
|
||||||
|
if (!_context.routerHash().equals(peer))
|
||||||
|
lc.increment(peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tunnelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return total number of part. tunnels */
|
||||||
|
private int countParticipatingPerPeer(ObjectCounter<Hash> pc) {
|
||||||
|
List<HopConfig> participating = _context.tunnelDispatcher().listParticipatingTunnels();
|
||||||
|
for (HopConfig cfg : participating) {
|
||||||
|
Hash from = cfg.getReceiveFrom();
|
||||||
|
if (from != null)
|
||||||
|
pc.increment(from);
|
||||||
|
Hash to = cfg.getSendTo();
|
||||||
|
if (to != null)
|
||||||
|
pc.increment(to);
|
||||||
|
}
|
||||||
|
return participating.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HashComparator implements Comparator {
|
||||||
|
public int compare(Object l, Object r) {
|
||||||
|
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCapacity(Hash peer) {
|
||||||
|
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||||
|
if (info != null) {
|
||||||
|
String caps = info.getCapabilities();
|
||||||
|
for (char c = Router.CAPABILITY_BW12; c <= Router.CAPABILITY_BW256; c++) {
|
||||||
|
if (caps.indexOf(c) >= 0)
|
||||||
|
return " " + c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String netDbLink(Hash peer) {
|
||||||
|
return _context.commSystem().renderPeerHTML(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** translate a string */
|
||||||
|
private String _(String s) {
|
||||||
|
return Messages.getString(s, _context);
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,9 @@
|
|||||||
<%@page pageEncoding="UTF-8"%>
|
<%@page pageEncoding="UTF-8"%>
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
<html><head><title>I2P Router Console - config update</title>
|
<html><head>
|
||||||
<%@include file="css.jsp" %>
|
<%@include file="css.jsp" %>
|
||||||
|
<%=cssHelper.title("config update")%>
|
||||||
</head><body>
|
</head><body>
|
||||||
|
|
||||||
<%@include file="summary.jsp" %>
|
<%@include file="summary.jsp" %>
|
||||||
@ -36,7 +37,7 @@
|
|||||||
<td><input type="text" size="60" name="newsURL" value="<jsp:getProperty name="updatehelper" property="newsURL" />"></td>
|
<td><input type="text" size="60" name="newsURL" value="<jsp:getProperty name="updatehelper" property="newsURL" />"></td>
|
||||||
</tr><tr><td class= "mediumtags" align="right"><b>Refresh frequency:</b>
|
</tr><tr><td class= "mediumtags" align="right"><b>Refresh frequency:</b>
|
||||||
<td><jsp:getProperty name="updatehelper" property="refreshFrequencySelectBox" /></td><tr>
|
<td><jsp:getProperty name="updatehelper" property="refreshFrequencySelectBox" /></td><tr>
|
||||||
<td class= "mediumtags" align="right"><b>Update policy:</b></td>
|
<td class= "mediumtags" align="right"><b><%=formhandler._("Update policy")%>:</b></td>
|
||||||
<td><jsp:getProperty name="updatehelper" property="updatePolicySelectBox" /></td>
|
<td><jsp:getProperty name="updatehelper" property="updatePolicySelectBox" /></td>
|
||||||
<tr><td class= "mediumtags" align="right"><b>Update through the eepProxy?</b></td>
|
<tr><td class= "mediumtags" align="right"><b>Update through the eepProxy?</b></td>
|
||||||
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td>
|
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td>
|
||||||
|
@ -25,5 +25,8 @@
|
|||||||
<link rel="shortcut icon" href="/themes/console/images/favicon.ico">
|
<link rel="shortcut icon" href="/themes/console/images/favicon.ico">
|
||||||
<jsp:useBean class="net.i2p.router.web.CSSHelper" id="cssHelper" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.CSSHelper" id="cssHelper" scope="request" />
|
||||||
<jsp:setProperty name="cssHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
<jsp:setProperty name="cssHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
|
<%
|
||||||
|
cssHelper.setLang(request.getParameter("lang"));
|
||||||
|
%>
|
||||||
<link href="<%=cssHelper.getTheme(request.getHeader("User-Agent"))%>console.css" rel="stylesheet" type="text/css">
|
<link href="<%=cssHelper.getTheme(request.getHeader("User-Agent"))%>console.css" rel="stylesheet" type="text/css">
|
||||||
<!--[if IE]><link href="/themes/console/classic/ieshim.css" rel="stylesheet" type="text/css" /><![endif]-->
|
<!--[if IE]><link href="/themes/console/classic/ieshim.css" rel="stylesheet" type="text/css" /><![endif]-->
|
||||||
|
@ -29,5 +29,6 @@ if (System.getProperty("router.consoleNonce") == null) {
|
|||||||
<jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
|
<jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
|
||||||
<jsp:setProperty name="contenthelper" property="maxLines" value="300" />
|
<jsp:setProperty name="contenthelper" property="maxLines" value="300" />
|
||||||
<jsp:setProperty name="contenthelper" property="lang" value="<%=request.getParameter("lang")%>" />
|
<jsp:setProperty name="contenthelper" property="lang" value="<%=request.getParameter("lang")%>" />
|
||||||
|
<jsp:setProperty name="contenthelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
<jsp:getProperty name="contenthelper" property="content" />
|
<jsp:getProperty name="contenthelper" property="content" />
|
||||||
</div></body></html>
|
</div></body></html>
|
||||||
|
@ -7,126 +7,29 @@
|
|||||||
%>
|
%>
|
||||||
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
|
||||||
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
|
<jsp:setProperty name="helper" property="action" value="<%=request.getParameter("action")%>" />
|
||||||
|
<jsp:setProperty name="helper" property="updateNonce" value="<%=request.getParameter("updateNonce")%>" />
|
||||||
|
<jsp:setProperty name="helper" property="consoleNonce" value="<%=request.getParameter("consoleNonce")%>" />
|
||||||
|
<jsp:setProperty name="helper" property="requestURI" value="<%=request.getRequestURI()%>" />
|
||||||
|
<jsp:setProperty name="helper" property="writer" value="<%=out%>" />
|
||||||
|
<%
|
||||||
|
/*
|
||||||
|
* The following is required for the reseed button to work, although we probably
|
||||||
|
* only need the reseedNonce property.
|
||||||
|
*/
|
||||||
|
%>
|
||||||
<jsp:useBean class="net.i2p.router.web.ReseedHandler" id="reseed" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.ReseedHandler" id="reseed" scope="request" />
|
||||||
<jsp:setProperty name="reseed" property="*" />
|
<jsp:setProperty name="reseed" property="*" />
|
||||||
|
<%
|
||||||
|
/*
|
||||||
|
* The following is required for the update buttons to work, although we probably
|
||||||
|
* only need the updateNonce property.
|
||||||
|
*/
|
||||||
|
%>
|
||||||
<jsp:useBean class="net.i2p.router.web.UpdateHandler" id="update" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.UpdateHandler" id="update" scope="request" />
|
||||||
<jsp:setProperty name="update" property="*" />
|
<jsp:setProperty name="update" property="*" />
|
||||||
<jsp:setProperty name="update" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
<jsp:setProperty name="update" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
<a href="index.jsp" target="_top"><img src="/themes/console/images/i2plogo.png" alt="I2P Router Console" title="I2P Router Console"></a><hr>
|
|
||||||
<% java.io.File lpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/toolbar.html");
|
|
||||||
// you better have target="_top" for the links in there...
|
|
||||||
if (lpath.exists()) { %>
|
|
||||||
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="linkhelper" scope="request" />
|
|
||||||
<jsp:setProperty name="linkhelper" property="page" value="<%=lpath.getAbsolutePath()%>" />
|
|
||||||
<jsp:setProperty name="linkhelper" property="maxLines" value="100" />
|
|
||||||
<jsp:getProperty name="linkhelper" property="content" />
|
|
||||||
<% } else { %>
|
|
||||||
<h3><a href="/configclients.jsp" target="_top" title="Configure startup of clients and webapps (services); manually start dormant services.">I2P Services</a></h3>
|
|
||||||
<hr><table>
|
|
||||||
<tr><td><a href="susidns/index.jsp" target="_blank" title="Manage your I2P hosts file here (I2P domain name resolution).">Addressbook</a>
|
|
||||||
<a href="i2psnark/" target="_blank" title="Built-in anonymous BitTorrent Client">Torrents</a>
|
|
||||||
<a href="susimail/susimail" target="blank" title="Anonymous webmail client.">Webmail</a>
|
|
||||||
<a href="http://127.0.0.1:7658/" target="_blank" title="Anonymous resident webserver.">Webserver</a></td></tr></table>
|
|
||||||
<hr><h3><a href="config.jsp" target="_top" title="Configure I2P Router.">I2P Internals</a></h3><hr>
|
|
||||||
<table><tr><td>
|
|
||||||
<a href="tunnels.jsp" target="_top" title="View existing tunnels and tunnel build status.">Tunnels</a>
|
|
||||||
<a href="peers.jsp" target="_top" title="Show all current peer connections.">Peers</a>
|
|
||||||
<a href="profiles.jsp" target="_top" title="Show recent peer performance profiles.">Profiles</a>
|
|
||||||
<a href="netdb.jsp" target="_top" title="Show list of all known I2P routers.">NetDB</a>
|
|
||||||
<a href="logs.jsp" target="_top" title="Health Report.">Logs</a>
|
|
||||||
<a href="jobs.jsp" target="_top" title="Show the router's workload, and how it's performing.">Jobs</a>
|
|
||||||
<a href="graphs.jsp" target="_top" title="Graph router performance.">Graphs</a>
|
|
||||||
<a href="oldstats.jsp" target="_top" title="Textual router performance statistics.">Stats</a></td></tr></table>
|
|
||||||
<% } %>
|
|
||||||
<hr><h3><a href="help.jsp" target="_top" title="I2P Router Help.">General</a></h3><hr>
|
|
||||||
<h4><a title="Your unique I2P router identity is <jsp:getProperty name="helper" property="ident" />, never reveal it to anyone" href="netdb.jsp?r=." target="_top">Local Identity</a></h4><hr>
|
|
||||||
<table><tr><td align="left">
|
|
||||||
<b>Version:</b></td>
|
|
||||||
<td align="right"><jsp:getProperty name="helper" property="version" /></td></tr>
|
|
||||||
<tr title="How long we've been running for this session.">
|
|
||||||
<td align="left"><b>Uptime:</b></td>
|
|
||||||
<td align="right"><jsp:getProperty name="helper" property="uptime" />
|
|
||||||
</td></tr></table>
|
|
||||||
<hr><h4><a href="config.jsp#help" target="_top" title="Help with configuring your firewall and router for optimal I2P performance."><jsp:getProperty name="helper" property="reachability" /></a></h4><hr>
|
|
||||||
<%
|
<%
|
||||||
if (helper.updateAvailable() || helper.unsignedUpdateAvailable()) {
|
// moved to java for ease of translation and to avoid 30 copies
|
||||||
// display all the time so we display the final failure message
|
helper.renderSummaryBar();
|
||||||
out.print("<br>" + net.i2p.router.web.UpdateHandler.getStatus());
|
|
||||||
if ("true".equals(System.getProperty("net.i2p.router.web.UpdateHandler.updateInProgress"))) {
|
|
||||||
} else if((!update.isDone()) &&
|
|
||||||
request.getParameter("action") == null &&
|
|
||||||
request.getParameter("updateNonce") == null &&
|
|
||||||
net.i2p.router.web.ConfigRestartBean.getRestartTimeRemaining() > 12*60*1000) {
|
|
||||||
long nonce = new java.util.Random().nextLong();
|
|
||||||
String prev = System.getProperty("net.i2p.router.web.UpdateHandler.nonce");
|
|
||||||
if (prev != null) System.setProperty("net.i2p.router.web.UpdateHandler.noncePrev", prev);
|
|
||||||
System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+"");
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
out.print("<form action=\"" + uri + "\" method=\"GET\">\n");
|
|
||||||
out.print("<input type=\"hidden\" name=\"updateNonce\" value=\"" + nonce + "\" />\n");
|
|
||||||
if (helper.updateAvailable())
|
|
||||||
out.print("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >Download " + helper.getUpdateVersion() + " Update</button>\n");
|
|
||||||
if (helper.unsignedUpdateAvailable())
|
|
||||||
out.print("<button type=\"submit\" name=\"updateAction\" value=\"Unsigned\" >Download Unsigned<br>Update " + helper.getUnsignedUpdateVersion() + "</button>\n");
|
|
||||||
out.print("</form>\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
%>
|
%>
|
||||||
<p>
|
|
||||||
<%=net.i2p.router.web.ConfigRestartBean.renderStatus(request.getRequestURI(), request.getParameter("action"), request.getParameter("consoleNonce"))%>
|
|
||||||
</p><hr><h3><a href="peers.jsp" target="_top" title="Show all current peer connections.">Peers</a></h3><hr>
|
|
||||||
<table>
|
|
||||||
<tr><td align="left"><b>Active:</b></td><td align="right"><jsp:getProperty name="helper" property="activePeers" />/<jsp:getProperty name="helper" property="activeProfiles" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Fast:</b></td><td align="right"><jsp:getProperty name="helper" property="fastPeers" /></td></tr>
|
|
||||||
<tr><td align="left"><b>High capacity:</b></td><td align="right"><jsp:getProperty name="helper" property="highCapacityPeers" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Integrated:</b></td><td align="right"><jsp:getProperty name="helper" property="wellIntegratedPeers" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Known:</b></td><td align="right"><jsp:getProperty name="helper" property="allPeers" /></td></tr>
|
|
||||||
</table><hr>
|
|
||||||
<%
|
|
||||||
if (helper.showFirewallWarning()) {
|
|
||||||
%><h4><a href="config.jsp" target="_top" title="Help with firewall configuration.">Check NAT/firewall</a></h4><%
|
|
||||||
}
|
|
||||||
boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
|
|
||||||
// If showing the reseed link is allowed
|
|
||||||
if (helper.allowReseed()) {
|
|
||||||
if (reseedInProgress) {
|
|
||||||
// While reseed occurring, show status message instead
|
|
||||||
out.print("<i>" + System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","") + "</i><br>");
|
|
||||||
} else {
|
|
||||||
// While no reseed occurring, show reseed link
|
|
||||||
long nonce = new java.util.Random().nextLong();
|
|
||||||
String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
|
|
||||||
if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
|
|
||||||
System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
out.print("<form action=\"" + uri + "\" method=\"GET\">\n");
|
|
||||||
out.print("<input type=\"hidden\" name=\"reseedNonce\" value=\"" + nonce + "\" />\n");
|
|
||||||
out.print("<button type=\"submit\" >Reseed</button></form>\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If a new reseed ain't running, and the last reseed had errors, show error message
|
|
||||||
if (!reseedInProgress) {
|
|
||||||
String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
|
|
||||||
if (reseedErrorMessage.length() > 0) {
|
|
||||||
out.print("<i>" + reseedErrorMessage + "</i><br>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
%>
|
|
||||||
<hr><h3><a href="config.jsp" title="Configure router bandwidth allocation." target="_top">Bandwidth in/out</a></h3><hr>
|
|
||||||
<table>
|
|
||||||
<tr><td align="left"><b>1s:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundSecondKBps" />/<jsp:getProperty name="helper" property="outboundSecondKBps" />K/s</td></tr>
|
|
||||||
<tr><td align="left"><b>5m:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundFiveMinuteKBps" />/<jsp:getProperty name="helper" property="outboundFiveMinuteKBps" />K/s</td></tr>
|
|
||||||
<tr><td align="left"><b>Total:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundLifetimeKBps" />/<jsp:getProperty name="helper" property="outboundLifetimeKBps" />K/s</td></tr>
|
|
||||||
<tr><td align="left"><b>Used:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundTransferred" />/<jsp:getProperty name="helper" property="outboundTransferred" /></td></tr></table>
|
|
||||||
<hr><h3><a href="tunnels.jsp" target="_top" title="View existing tunnels and tunnel build status.">Tunnels in/out</a></h3><hr>
|
|
||||||
<table>
|
|
||||||
<tr><td align="left"><b>Exploratory:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundTunnels" />/<jsp:getProperty name="helper" property="outboundTunnels" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Client:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundClientTunnels" />/<jsp:getProperty name="helper" property="outboundClientTunnels" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Participating:</b></td><td align="right"><jsp:getProperty name="helper" property="participatingTunnels" /></td></tr>
|
|
||||||
</table><hr><h3><a href="/jobs.jsp" target="_top" title="What's in the router's job queue?">Congestion</a></h3><hr>
|
|
||||||
<table>
|
|
||||||
<tr><td align="left"><b>Job lag:</b></td><td align="right"><jsp:getProperty name="helper" property="jobLag" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Message delay:</b></td><td align="right"><jsp:getProperty name="helper" property="messageDelay" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Tunnel lag:</b></td><td align="right"><jsp:getProperty name="helper" property="tunnelLag" /></td></tr>
|
|
||||||
<tr><td align="left"><b>Backlog:</b></td><td align="right"><jsp:getProperty name="helper" property="inboundBacklog" /></td></tr>
|
|
||||||
</table><hr><h4><jsp:getProperty name="helper" property="tunnelStatus" /></h4><hr><jsp:getProperty name="helper" property="destinations" />
|
|
||||||
|
281
apps/routerconsole/locale/messages_de.po
Normal file
281
apps/routerconsole/locale/messages_de.po
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
# I2P
|
||||||
|
# Copyright (C) 2009 The I2P Project
|
||||||
|
# This file is distributed under the same license as the routerconsole package.
|
||||||
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
|
# foo <foo@bar>, 2009.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P routerconsole\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2009-10-20 11:55+0000\n"
|
||||||
|
"PO-Revision-Date: 2009-10-19 12:50+0000\n"
|
||||||
|
"Last-Translator: foo <foo@bar>\n"
|
||||||
|
"Language-Team: foo <foo@bar>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Poedit-Language: German\n"
|
||||||
|
|
||||||
|
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:95
|
||||||
|
msgid "config update"
|
||||||
|
msgstr "config update in german test test test"
|
||||||
|
|
||||||
|
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:334
|
||||||
|
msgid "Update policy"
|
||||||
|
msgstr "Update policy in german foobarbaz"
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/CSSHelper.java:36
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:26
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:28
|
||||||
|
msgid "I2P Router Console"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/ConfigUpdateHelper.java:90
|
||||||
|
msgid "Notify only"
|
||||||
|
msgstr "Notify only in german"
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:42
|
||||||
|
msgid "I2P Services"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:48
|
||||||
|
msgid "Manage your I2P hosts file here (I2P domain name resolution)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:50
|
||||||
|
msgid "Addressbook"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:54
|
||||||
|
msgid "Built-in anonymous BitTorrent Client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:56
|
||||||
|
msgid "Torrents"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:60
|
||||||
|
msgid "Anonymous webmail client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:62
|
||||||
|
msgid "Webmail"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:66
|
||||||
|
msgid "Anonymous resident webserver"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:68
|
||||||
|
msgid "Webserver"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:72
|
||||||
|
msgid "Configure I2P Router"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:74
|
||||||
|
msgid "I2P Internals"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:80
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:344
|
||||||
|
msgid "View existing tunnels and tunnel build status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:82
|
||||||
|
msgid "Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:86
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:221
|
||||||
|
msgid "Show all current peer connections"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:88
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:223
|
||||||
|
msgid "Peers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:92
|
||||||
|
msgid "Show recent peer performance profiles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:94
|
||||||
|
msgid "Profiles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:98
|
||||||
|
msgid "Show list of all known I2P routers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:100
|
||||||
|
msgid "NetDB"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:104
|
||||||
|
msgid "Health Report"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:106
|
||||||
|
msgid "Logs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:110
|
||||||
|
msgid "Show the router's workload, and how it's performing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:112
|
||||||
|
msgid "Jobs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:116
|
||||||
|
msgid "Graph router performance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:118
|
||||||
|
msgid "Graphs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:122
|
||||||
|
msgid "Textual router performance statistics"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:124
|
||||||
|
msgid "Stats"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:134
|
||||||
|
msgid "I2P Router Help"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:136
|
||||||
|
msgid "General"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:139
|
||||||
|
msgid "Your unique I2P router identity is"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:143
|
||||||
|
msgid "never reveal it to anyone"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:145
|
||||||
|
msgid "Local Identity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:150
|
||||||
|
msgid "Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:157
|
||||||
|
msgid "How long we've been running for this session"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:160
|
||||||
|
msgid "Uptime"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:167
|
||||||
|
msgid ""
|
||||||
|
"Help with configuring your firewall and router for optimal I2P performance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:194
|
||||||
|
msgid "Download"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:198
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:207
|
||||||
|
msgid "Update"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:203
|
||||||
|
msgid "Download Unsigned"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:229
|
||||||
|
msgid "Active"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:237
|
||||||
|
msgid "Fast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:243
|
||||||
|
msgid "High capacity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:249
|
||||||
|
msgid "Integrated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:255
|
||||||
|
msgid "Known"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:270
|
||||||
|
msgid "Help with firewall configuration"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:272
|
||||||
|
msgid "Check NAT/firewall"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:309
|
||||||
|
msgid "Configure router bandwidth allocation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:311
|
||||||
|
msgid "Bandwidth in/out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:328
|
||||||
|
msgid "Total"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:336
|
||||||
|
msgid "Used"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:346
|
||||||
|
msgid "Tunnels in/out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:351
|
||||||
|
msgid "Exploratory"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:359
|
||||||
|
msgid "Client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:367
|
||||||
|
msgid "Participating"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:373
|
||||||
|
msgid "What's in the router's job queue?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:375
|
||||||
|
msgid "Congestion"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:380
|
||||||
|
msgid "Job lag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:386
|
||||||
|
msgid "Message delay"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:392
|
||||||
|
msgid "Tunnel lag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:398
|
||||||
|
msgid "Backlog"
|
||||||
|
msgstr ""
|
281
apps/routerconsole/locale/messages_zh.po
Normal file
281
apps/routerconsole/locale/messages_zh.po
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
# I2P
|
||||||
|
# Copyright (C) 2009 The I2P Project
|
||||||
|
# This file is distributed under the same license as the routerconsole package.
|
||||||
|
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||||
|
# foo <foo@bar>, 2009.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: I2P routerconsole\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2009-10-20 11:55+0000\n"
|
||||||
|
"PO-Revision-Date: 2009-10-19 12:59+0000\n"
|
||||||
|
"Last-Translator: foo <foo@bar>\n"
|
||||||
|
"Language-Team: foo <foo@par>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Poedit-Language: Chinese\n"
|
||||||
|
|
||||||
|
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:95
|
||||||
|
msgid "config update"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:334
|
||||||
|
msgid "Update policy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/CSSHelper.java:36
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:26
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:28
|
||||||
|
msgid "I2P Router Console"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/ConfigUpdateHelper.java:90
|
||||||
|
msgid "Notify only"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:42
|
||||||
|
msgid "I2P Services"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:48
|
||||||
|
msgid "Manage your I2P hosts file here (I2P domain name resolution)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:50
|
||||||
|
msgid "Addressbook"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:54
|
||||||
|
msgid "Built-in anonymous BitTorrent Client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:56
|
||||||
|
msgid "Torrents"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:60
|
||||||
|
msgid "Anonymous webmail client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:62
|
||||||
|
msgid "Webmail"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:66
|
||||||
|
msgid "Anonymous resident webserver"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:68
|
||||||
|
msgid "Webserver"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:72
|
||||||
|
msgid "Configure I2P Router"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:74
|
||||||
|
msgid "I2P Internals"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:80
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:344
|
||||||
|
msgid "View existing tunnels and tunnel build status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:82
|
||||||
|
msgid "Tunnels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:86
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:221
|
||||||
|
msgid "Show all current peer connections"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:88
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:223
|
||||||
|
msgid "Peers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:92
|
||||||
|
msgid "Show recent peer performance profiles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:94
|
||||||
|
msgid "Profiles"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:98
|
||||||
|
msgid "Show list of all known I2P routers"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:100
|
||||||
|
msgid "NetDB"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:104
|
||||||
|
msgid "Health Report"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:106
|
||||||
|
msgid "Logs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:110
|
||||||
|
msgid "Show the router's workload, and how it's performing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:112
|
||||||
|
msgid "Jobs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:116
|
||||||
|
msgid "Graph router performance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:118
|
||||||
|
msgid "Graphs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:122
|
||||||
|
msgid "Textual router performance statistics"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:124
|
||||||
|
msgid "Stats"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:134
|
||||||
|
msgid "I2P Router Help"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:136
|
||||||
|
msgid "General"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:139
|
||||||
|
msgid "Your unique I2P router identity is"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:143
|
||||||
|
msgid "never reveal it to anyone"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:145
|
||||||
|
msgid "Local Identity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:150
|
||||||
|
msgid "Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:157
|
||||||
|
msgid "How long we've been running for this session"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:160
|
||||||
|
msgid "Uptime"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:167
|
||||||
|
msgid ""
|
||||||
|
"Help with configuring your firewall and router for optimal I2P performance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:194
|
||||||
|
msgid "Download"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:198
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:207
|
||||||
|
msgid "Update"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:203
|
||||||
|
msgid "Download Unsigned"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:229
|
||||||
|
msgid "Active"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:237
|
||||||
|
msgid "Fast"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:243
|
||||||
|
msgid "High capacity"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:249
|
||||||
|
msgid "Integrated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:255
|
||||||
|
msgid "Known"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:270
|
||||||
|
msgid "Help with firewall configuration"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:272
|
||||||
|
msgid "Check NAT/firewall"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:309
|
||||||
|
msgid "Configure router bandwidth allocation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:311
|
||||||
|
msgid "Bandwidth in/out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:328
|
||||||
|
msgid "Total"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:336
|
||||||
|
msgid "Used"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:346
|
||||||
|
msgid "Tunnels in/out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:351
|
||||||
|
msgid "Exploratory"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:359
|
||||||
|
msgid "Client"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:367
|
||||||
|
msgid "Participating"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:373
|
||||||
|
msgid "What's in the router's job queue?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:375
|
||||||
|
msgid "Congestion"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:380
|
||||||
|
msgid "Job lag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:386
|
||||||
|
msgid "Message delay"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:392
|
||||||
|
msgid "Tunnel lag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/net/i2p/router/web/SummaryBarRenderer.java:398
|
||||||
|
msgid "Backlog"
|
||||||
|
msgstr ""
|
@ -153,13 +153,13 @@ class LogWriter implements Runnable {
|
|||||||
if (!parent.exists()) {
|
if (!parent.exists()) {
|
||||||
boolean ok = parent.mkdirs();
|
boolean ok = parent.mkdirs();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
System.err.println("Unable to create the parent directy: " + parent.getAbsolutePath());
|
System.err.println("Unable to create the parent directory: " + parent.getAbsolutePath());
|
||||||
System.exit(0);
|
//System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!parent.isDirectory()) {
|
if (!parent.isDirectory()) {
|
||||||
System.err.println("wtf, we cannot put the logs in a subdirectory of a plain file! we want to stre the log as " + f.getAbsolutePath());
|
System.err.println("wtf, we cannot put the logs in a subdirectory of a plain file! we want to stre the log as " + f.getAbsolutePath());
|
||||||
System.exit(0);
|
//System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -362,10 +362,10 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
|||||||
return new TunnelGatewayMessage(context);
|
return new TunnelGatewayMessage(context);
|
||||||
case DataMessage.MESSAGE_TYPE:
|
case DataMessage.MESSAGE_TYPE:
|
||||||
return new DataMessage(context);
|
return new DataMessage(context);
|
||||||
case TunnelCreateMessage.MESSAGE_TYPE:
|
//case TunnelCreateMessage.MESSAGE_TYPE:
|
||||||
return new TunnelCreateMessage(context);
|
// return new TunnelCreateMessage(context);
|
||||||
case TunnelCreateStatusMessage.MESSAGE_TYPE:
|
//case TunnelCreateStatusMessage.MESSAGE_TYPE:
|
||||||
return new TunnelCreateStatusMessage(context);
|
// return new TunnelCreateStatusMessage(context);
|
||||||
case TunnelBuildMessage.MESSAGE_TYPE:
|
case TunnelBuildMessage.MESSAGE_TYPE:
|
||||||
return new TunnelBuildMessage(context);
|
return new TunnelBuildMessage(context);
|
||||||
case TunnelBuildReplyMessage.MESSAGE_TYPE:
|
case TunnelBuildReplyMessage.MESSAGE_TYPE:
|
||||||
|
@ -60,6 +60,4 @@ class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
|||||||
|
|
||||||
public Set<Hash> getAllRouters() { return new HashSet(_routers.keySet()); }
|
public Set<Hash> getAllRouters() { return new HashSet(_routers.keySet()); }
|
||||||
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
|
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
|
||||||
|
|
||||||
public void renderStatusHTML(Writer out) throws IOException {}
|
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,14 @@ package net.i2p.router;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.TunnelId;
|
import net.i2p.data.TunnelId;
|
||||||
|
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build and maintain tunnels throughout the network.
|
* Build and maintain tunnels throughout the network.
|
||||||
@ -50,4 +53,10 @@ class DummyTunnelManagerFacade implements TunnelManagerFacade {
|
|||||||
public void restart() {}
|
public void restart() {}
|
||||||
public void shutdown() {}
|
public void shutdown() {}
|
||||||
public void startup() {}
|
public void startup() {}
|
||||||
|
|
||||||
|
public void listPools(List<TunnelPool> out) {}
|
||||||
|
public Map<Hash, TunnelPool> getInboundClientPools() { return null; }
|
||||||
|
public Map<Hash, TunnelPool> getOutboundClientPools() { return null; }
|
||||||
|
public TunnelPool getInboundExploratoryPool() { return null; }
|
||||||
|
public TunnelPool getOutboundExploratoryPool() { return null; }
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ import net.i2p.data.i2np.DatabaseLookupMessage;
|
|||||||
import net.i2p.data.i2np.DatabaseSearchReplyMessage;
|
import net.i2p.data.i2np.DatabaseSearchReplyMessage;
|
||||||
import net.i2p.data.i2np.DeliveryStatusMessage;
|
import net.i2p.data.i2np.DeliveryStatusMessage;
|
||||||
import net.i2p.data.i2np.I2NPMessage;
|
import net.i2p.data.i2np.I2NPMessage;
|
||||||
import net.i2p.data.i2np.TunnelCreateMessage;
|
//import net.i2p.data.i2np.TunnelCreateMessage;
|
||||||
import net.i2p.data.i2np.TunnelCreateStatusMessage;
|
//import net.i2p.data.i2np.TunnelCreateStatusMessage;
|
||||||
import net.i2p.data.i2np.TunnelDataMessage;
|
import net.i2p.data.i2np.TunnelDataMessage;
|
||||||
import net.i2p.data.i2np.TunnelGatewayMessage;
|
import net.i2p.data.i2np.TunnelGatewayMessage;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
@ -74,7 +74,7 @@ public class InNetMessagePool implements Service {
|
|||||||
_context.statManager().createRateStat("inNetPool.dropped", "How often do we drop a message", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("inNetPool.dropped", "How often do we drop a message", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("inNetPool.droppedDeliveryStatusDelay", "How long after a delivery status message is created do we receive it back again (for messages that are too slow to be handled)", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("inNetPool.droppedDeliveryStatusDelay", "How long after a delivery status message is created do we receive it back again (for messages that are too slow to be handled)", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("inNetPool.duplicate", "How often do we receive a duplicate message", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("inNetPool.duplicate", "How often do we receive a duplicate message", "InNetPool", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("inNetPool.droppedTunnelCreateStatusMessage", "How often we drop a slow-to-arrive tunnel request response", "InNetPool", new long[] { 60*60*1000l, 24*60*60*1000l });
|
//_context.statManager().createRateStat("inNetPool.droppedTunnelCreateStatusMessage", "How often we drop a slow-to-arrive tunnel request response", "InNetPool", new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("inNetPool.droppedDbLookupResponseMessage", "How often we drop a slow-to-arrive db search response", "InNetPool", new long[] { 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("inNetPool.droppedDbLookupResponseMessage", "How often we drop a slow-to-arrive db search response", "InNetPool", new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("pool.dispatchDataTime", "How long a tunnel dispatch takes", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("pool.dispatchDataTime", "How long a tunnel dispatch takes", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
_context.statManager().createRateStat("pool.dispatchGatewayTime", "How long a tunnel gateway dispatch takes", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRateStat("pool.dispatchGatewayTime", "How long a tunnel gateway dispatch takes", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
@ -125,8 +125,8 @@ public class InNetMessagePool implements Service {
|
|||||||
|
|
||||||
if (invalidReason != null) {
|
if (invalidReason != null) {
|
||||||
int level = Log.WARN;
|
int level = Log.WARN;
|
||||||
if (messageBody instanceof TunnelCreateMessage)
|
//if (messageBody instanceof TunnelCreateMessage)
|
||||||
level = Log.INFO;
|
// level = Log.INFO;
|
||||||
if (_log.shouldLog(level))
|
if (_log.shouldLog(level))
|
||||||
_log.log(level, "Duplicate message received [" + messageBody.getUniqueId()
|
_log.log(level, "Duplicate message received [" + messageBody.getUniqueId()
|
||||||
+ " expiring on " + exp + "]: " + messageBody.getClass().getName() + ": " + invalidReason
|
+ " expiring on " + exp + "]: " + messageBody.getClass().getName() + ": " + invalidReason
|
||||||
@ -195,10 +195,10 @@ public class InNetMessagePool implements Service {
|
|||||||
_log.warn("Dropping unhandled delivery status message created " + timeSinceSent + "ms ago: " + messageBody);
|
_log.warn("Dropping unhandled delivery status message created " + timeSinceSent + "ms ago: " + messageBody);
|
||||||
_context.statManager().addRateData("inNetPool.droppedDeliveryStatusDelay", timeSinceSent, timeSinceSent);
|
_context.statManager().addRateData("inNetPool.droppedDeliveryStatusDelay", timeSinceSent, timeSinceSent);
|
||||||
}
|
}
|
||||||
} else if (type == TunnelCreateStatusMessage.MESSAGE_TYPE) {
|
//} else if (type == TunnelCreateStatusMessage.MESSAGE_TYPE) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
// if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Dropping slow tunnel create request response: " + messageBody);
|
// _log.info("Dropping slow tunnel create request response: " + messageBody);
|
||||||
_context.statManager().addRateData("inNetPool.droppedTunnelCreateStatusMessage", 1, 0);
|
// _context.statManager().addRateData("inNetPool.droppedTunnelCreateStatusMessage", 1, 0);
|
||||||
} else if (type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
|
} else if (type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Dropping slow db lookup response: " + messageBody);
|
_log.info("Dropping slow db lookup response: " + messageBody);
|
||||||
|
@ -39,9 +39,8 @@ public class MessageHistory {
|
|||||||
private final static byte[] NL = System.getProperty("line.separator").getBytes();
|
private final static byte[] NL = System.getProperty("line.separator").getBytes();
|
||||||
private final static int FLUSH_SIZE = 1000; // write out at least once every 1000 entries
|
private final static int FLUSH_SIZE = 1000; // write out at least once every 1000 entries
|
||||||
|
|
||||||
/** config property determining whether we want to debug with the message history */
|
/** config property determining whether we want to debug with the message history - default false */
|
||||||
public final static String PROP_KEEP_MESSAGE_HISTORY = "router.keepHistory";
|
public final static String PROP_KEEP_MESSAGE_HISTORY = "router.keepHistory";
|
||||||
public final static boolean DEFAULT_KEEP_MESSAGE_HISTORY = false;
|
|
||||||
/** config property determining where we want to log the message history, if we're keeping one */
|
/** config property determining where we want to log the message history, if we're keeping one */
|
||||||
public final static String PROP_MESSAGE_HISTORY_FILENAME = "router.historyFilename";
|
public final static String PROP_MESSAGE_HISTORY_FILENAME = "router.historyFilename";
|
||||||
public final static String DEFAULT_MESSAGE_HISTORY_FILENAME = "messageHistory.txt";
|
public final static String DEFAULT_MESSAGE_HISTORY_FILENAME = "messageHistory.txt";
|
||||||
@ -67,19 +66,8 @@ public class MessageHistory {
|
|||||||
String getFilename() { return _historyFile; }
|
String getFilename() { return _historyFile; }
|
||||||
|
|
||||||
private void updateSettings() {
|
private void updateSettings() {
|
||||||
String keepHistory = _context.router().getConfigSetting(PROP_KEEP_MESSAGE_HISTORY);
|
_doLog = Boolean.valueOf(_context.getProperty(PROP_KEEP_MESSAGE_HISTORY)).booleanValue();
|
||||||
if (keepHistory != null) {
|
_historyFile = _context.getProperty(PROP_MESSAGE_HISTORY_FILENAME, DEFAULT_MESSAGE_HISTORY_FILENAME);
|
||||||
_doLog = Boolean.TRUE.toString().equalsIgnoreCase(keepHistory);
|
|
||||||
} else {
|
|
||||||
_doLog = DEFAULT_KEEP_MESSAGE_HISTORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
String filename = null;
|
|
||||||
if (_doLog) {
|
|
||||||
filename = _context.router().getConfigSetting(PROP_MESSAGE_HISTORY_FILENAME);
|
|
||||||
if ( (filename == null) || (filename.trim().length() <= 0) )
|
|
||||||
filename = DEFAULT_MESSAGE_HISTORY_FILENAME;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,13 +84,6 @@ public class MessageHistory {
|
|||||||
_reinitializeJob.getTiming().setStartAfter(_context.clock().now()+5000);
|
_reinitializeJob.getTiming().setStartAfter(_context.clock().now()+5000);
|
||||||
_context.jobQueue().addJob(_reinitializeJob);
|
_context.jobQueue().addJob(_reinitializeJob);
|
||||||
} else {
|
} else {
|
||||||
String filename = null;
|
|
||||||
filename = _context.router().getConfigSetting(PROP_MESSAGE_HISTORY_FILENAME);
|
|
||||||
if ( (filename == null) || (filename.trim().length() <= 0) )
|
|
||||||
filename = DEFAULT_MESSAGE_HISTORY_FILENAME;
|
|
||||||
|
|
||||||
_doLog = DEFAULT_KEEP_MESSAGE_HISTORY;
|
|
||||||
_historyFile = filename;
|
|
||||||
_localIdent = getName(_context.routerHash());
|
_localIdent = getName(_context.routerHash());
|
||||||
// _unwrittenEntries = new ArrayList(64);
|
// _unwrittenEntries = new ArrayList(64);
|
||||||
updateSettings();
|
updateSettings();
|
||||||
@ -142,6 +123,7 @@ public class MessageHistory {
|
|||||||
* @param replyTunnel the tunnel sourceRoutePeer should forward the source routed message to
|
* @param replyTunnel the tunnel sourceRoutePeer should forward the source routed message to
|
||||||
* @param replyThrough the gateway of the tunnel that the sourceRoutePeer will be sending to
|
* @param replyThrough the gateway of the tunnel that the sourceRoutePeer will be sending to
|
||||||
*/
|
*/
|
||||||
|
/********
|
||||||
public void requestTunnelCreate(TunnelId createTunnel, TunnelId outTunnel, Hash peerRequested, Hash nextPeer, TunnelId replyTunnel, Hash replyThrough) {
|
public void requestTunnelCreate(TunnelId createTunnel, TunnelId outTunnel, Hash peerRequested, Hash nextPeer, TunnelId replyTunnel, Hash replyThrough) {
|
||||||
if (!_doLog) return;
|
if (!_doLog) return;
|
||||||
StringBuilder buf = new StringBuilder(128);
|
StringBuilder buf = new StringBuilder(128);
|
||||||
@ -156,6 +138,7 @@ public class MessageHistory {
|
|||||||
buf.append("who forwards it through [").append(replyTunnel.getTunnelId()).append("] on [").append(getName(replyThrough)).append("]");
|
buf.append("who forwards it through [").append(replyTunnel.getTunnelId()).append("] on [").append(getName(replyThrough)).append("]");
|
||||||
addEntry(buf.toString());
|
addEntry(buf.toString());
|
||||||
}
|
}
|
||||||
|
*********/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The local router has received a request to join the createTunnel with the next hop being nextPeer,
|
* The local router has received a request to join the createTunnel with the next hop being nextPeer,
|
||||||
@ -167,6 +150,7 @@ public class MessageHistory {
|
|||||||
* @param ok whether we will join the tunnel
|
* @param ok whether we will join the tunnel
|
||||||
* @param sourceRoutePeer peer through whom we should send our garlic routed ok through
|
* @param sourceRoutePeer peer through whom we should send our garlic routed ok through
|
||||||
*/
|
*/
|
||||||
|
/*********
|
||||||
public void receiveTunnelCreate(TunnelId createTunnel, Hash nextPeer, Date expire, boolean ok, Hash sourceRoutePeer) {
|
public void receiveTunnelCreate(TunnelId createTunnel, Hash nextPeer, Date expire, boolean ok, Hash sourceRoutePeer) {
|
||||||
if (!_doLog) return;
|
if (!_doLog) return;
|
||||||
StringBuilder buf = new StringBuilder(128);
|
StringBuilder buf = new StringBuilder(128);
|
||||||
@ -177,6 +161,7 @@ public class MessageHistory {
|
|||||||
buf.append("ok? ").append(ok).append(" expiring on [").append(getTime(expire.getTime())).append("]");
|
buf.append("ok? ").append(ok).append(" expiring on [").append(getTime(expire.getTime())).append("]");
|
||||||
addEntry(buf.toString());
|
addEntry(buf.toString());
|
||||||
}
|
}
|
||||||
|
*********/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The local router has joined the given tunnel operating in the given state.
|
* The local router has joined the given tunnel operating in the given state.
|
||||||
|
@ -10,6 +10,7 @@ package net.i2p.router;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
@ -60,7 +61,10 @@ public abstract class NetworkDatabaseFacade implements Service {
|
|||||||
public int getKnownLeaseSets() { return 0; }
|
public int getKnownLeaseSets() { return 0; }
|
||||||
public boolean isInitialized() { return true; }
|
public boolean isInitialized() { return true; }
|
||||||
public void rescan() {}
|
public void rescan() {}
|
||||||
public void renderRouterInfoHTML(Writer out, String s) throws IOException {}
|
/** @deprecated moved to router console */
|
||||||
public void renderLeaseSetHTML(Writer out) throws IOException {}
|
public void renderStatusHTML(Writer out) throws IOException {}
|
||||||
public void renderStatusHTML(Writer out, boolean b) 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; }
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,14 @@ package net.i2p.router;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.TunnelId;
|
import net.i2p.data.TunnelId;
|
||||||
|
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build and maintain tunnels throughout the network.
|
* Build and maintain tunnels throughout the network.
|
||||||
@ -74,4 +77,14 @@ public interface TunnelManagerFacade extends Service {
|
|||||||
public void setOutboundSettings(TunnelPoolSettings settings);
|
public void setOutboundSettings(TunnelPoolSettings settings);
|
||||||
public void setInboundSettings(Hash client, TunnelPoolSettings settings);
|
public void setInboundSettings(Hash client, TunnelPoolSettings settings);
|
||||||
public void setOutboundSettings(Hash client, TunnelPoolSettings settings);
|
public void setOutboundSettings(Hash client, TunnelPoolSettings settings);
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public void listPools(List<TunnelPool> out);
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public Map<Hash, TunnelPool> getInboundClientPools();
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public Map<Hash, TunnelPool> getOutboundClientPools();
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public TunnelPool getInboundExploratoryPool();
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public TunnelPool getOutboundExploratoryPool();
|
||||||
}
|
}
|
||||||
|
@ -848,7 +848,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
|||||||
return searchJob;
|
return searchJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set getLeases() {
|
/** public for NetDbRenderer in routerconsole */
|
||||||
|
@Override
|
||||||
|
public Set<LeaseSet> getLeases() {
|
||||||
if (!_initialized) return null;
|
if (!_initialized) return null;
|
||||||
Set leases = new HashSet();
|
Set leases = new HashSet();
|
||||||
Set keys = getDataStore().getKeys();
|
Set keys = getDataStore().getKeys();
|
||||||
@ -860,7 +862,9 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
|||||||
}
|
}
|
||||||
return leases;
|
return leases;
|
||||||
}
|
}
|
||||||
private Set<RouterInfo> getRouters() {
|
/** public for NetDbRenderer in routerconsole */
|
||||||
|
@Override
|
||||||
|
public Set<RouterInfo> getRouters() {
|
||||||
if (!_initialized) return null;
|
if (!_initialized) return null;
|
||||||
Set routers = new HashSet();
|
Set routers = new HashSet();
|
||||||
Set keys = getDataStore().getKeys();
|
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));
|
_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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ public class PeerManagerFacadeImpl implements PeerManagerFacade {
|
|||||||
return _manager.getPeersByCapability(capability);
|
return _manager.getPeersByCapability(capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated, moved to routerconsole */
|
/** @deprecated moved to routerconsole */
|
||||||
public void renderStatusHTML(Writer out) throws IOException {
|
public void renderStatusHTML(Writer out) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +374,9 @@ public class TunnelDispatcher implements Service {
|
|||||||
_context.statManager().addRateData("tunnel.dispatchDataTime", dispatchTime, dispatchTime);
|
_context.statManager().addRateData("tunnel.dispatchDataTime", dispatchTime, dispatchTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** High for now, just to prevent long-lived-message attacks */
|
||||||
|
private static final long MAX_FUTURE_EXPIRATION = 3*60*1000 + Router.CLOCK_FUDGE_FACTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are the inbound tunnel gateway, so encrypt it as necessary and forward
|
* We are the inbound tunnel gateway, so encrypt it as necessary and forward
|
||||||
* it on.
|
* it on.
|
||||||
@ -385,7 +388,10 @@ public class TunnelDispatcher implements Service {
|
|||||||
if (gw != null) {
|
if (gw != null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("dispatch where we are the inbound gateway: " + gw + ": " + msg);
|
_log.debug("dispatch where we are the inbound gateway: " + gw + ": " + msg);
|
||||||
if ( (msg.getMessageExpiration() < before - Router.CLOCK_FUDGE_FACTOR) || (msg.getMessage().getMessageExpiration() < before - Router.CLOCK_FUDGE_FACTOR) ) {
|
long minTime = before - Router.CLOCK_FUDGE_FACTOR;
|
||||||
|
long maxTime = before + MAX_FUTURE_EXPIRATION;
|
||||||
|
if ( (msg.getMessageExpiration() < minTime) || (msg.getMessage().getMessageExpiration() < minTime) ||
|
||||||
|
(msg.getMessageExpiration() > maxTime) || (msg.getMessage().getMessageExpiration() > maxTime) ) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Not dispatching a gateway message for tunnel " + msg.getTunnelId().getTunnelId()
|
_log.error("Not dispatching a gateway message for tunnel " + msg.getTunnelId().getTunnelId()
|
||||||
+ " as the wrapper's expiration is in " + DataHelper.formatDuration(msg.getMessageExpiration()-before)
|
+ " as the wrapper's expiration is in " + DataHelper.formatDuration(msg.getMessageExpiration()-before)
|
||||||
@ -463,6 +469,12 @@ public class TunnelDispatcher implements Service {
|
|||||||
_log.warn("why are you sending a tunnel message that expired "
|
_log.warn("why are you sending a tunnel message that expired "
|
||||||
+ (before-msg.getMessageExpiration()) + "ms ago? "
|
+ (before-msg.getMessageExpiration()) + "ms ago? "
|
||||||
+ msg, new Exception("cause"));
|
+ msg, new Exception("cause"));
|
||||||
|
} else if (msg.getMessageExpiration() > before + MAX_FUTURE_EXPIRATION) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("why are you sending a tunnel message that expires "
|
||||||
|
+ (msg.getMessageExpiration() - before) + "ms from now? "
|
||||||
|
+ msg, new Exception("cause"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
long tid1 = outboundTunnel.getTunnelId();
|
long tid1 = outboundTunnel.getTunnelId();
|
||||||
long tid2 = (targetTunnel != null ? targetTunnel.getTunnelId() : -1);
|
long tid2 = (targetTunnel != null ? targetTunnel.getTunnelId() : -1);
|
||||||
|
@ -391,7 +391,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** list of TunnelPool instances currently in play */
|
/** list of TunnelPool instances currently in play */
|
||||||
void listPools(List<TunnelPool> out) {
|
public void listPools(List<TunnelPool> out) {
|
||||||
synchronized (_clientInboundPools) {
|
synchronized (_clientInboundPools) {
|
||||||
out.addAll(_clientInboundPools.values());
|
out.addAll(_clientInboundPools.values());
|
||||||
}
|
}
|
||||||
@ -409,227 +409,8 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
|||||||
|
|
||||||
public int getInboundBuildQueueSize() { return _executor.getInboundBuildQueueSize(); }
|
public int getInboundBuildQueueSize() { return _executor.getInboundBuildQueueSize(); }
|
||||||
|
|
||||||
|
/** @deprecated moved to routerconsole */
|
||||||
public void renderStatusHTML(Writer out) throws IOException {
|
public void renderStatusHTML(Writer out) throws IOException {
|
||||||
out.write("<div class=\"wideload\"><h2><a name=\"exploratory\" ></a>Exploratory tunnels (<a href=\"/configtunnels.jsp#exploratory\">config</a>):</h2>\n");
|
|
||||||
renderPool(out, _inboundExploratory, _outboundExploratory);
|
|
||||||
|
|
||||||
List<Hash> destinations = null;
|
|
||||||
synchronized (_clientInboundPools) {
|
|
||||||
destinations = new ArrayList(_clientInboundPools.keySet());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < destinations.size(); i++) {
|
|
||||||
Hash client = destinations.get(i);
|
|
||||||
TunnelPool in = null;
|
|
||||||
TunnelPool outPool = null;
|
|
||||||
synchronized (_clientInboundPools) {
|
|
||||||
in = _clientInboundPools.get(client);
|
|
||||||
}
|
|
||||||
synchronized (_clientOutboundPools) {
|
|
||||||
outPool = _clientOutboundPools.get(client);
|
|
||||||
}
|
|
||||||
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("<h2><a name=\"" + client.toBase64().substring(0,4)
|
|
||||||
+ "\" ></a>Client tunnels for " + name);
|
|
||||||
if (_context.clientManager().isLocal(client))
|
|
||||||
out.write(" (<a href=\"/configtunnels.jsp#" + client.toBase64().substring(0,4) +"\">config</a>):</h2>\n");
|
|
||||||
else
|
|
||||||
out.write(" (dead):</h2>\n");
|
|
||||||
renderPool(out, in, outPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
List participating = _context.tunnelDispatcher().listParticipatingTunnels();
|
|
||||||
Collections.sort(participating, new TunnelComparator());
|
|
||||||
out.write("<h2><a name=\"participating\"></a>Participating tunnels:</h2><table>\n");
|
|
||||||
out.write("<tr><th>Receive on</th><th>From</th><th>"
|
|
||||||
+ "Send on</th><th>To</th><th>Expiration</th>"
|
|
||||||
+ "<th>Usage</th><th>Rate</th><th>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;
|
|
||||||
for (int i = 0; i < participating.size(); i++) {
|
|
||||||
HopConfig cfg = (HopConfig)participating.get(i);
|
|
||||||
if (cfg.getProcessedMessagesCount() <= 0) {
|
|
||||||
inactive++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out.write("<tr>");
|
|
||||||
if (cfg.getReceiveTunnel() != null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getReceiveTunnel().getTunnelId() +"</td>");
|
|
||||||
else
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">n/a</td>");
|
|
||||||
if (cfg.getReceiveFrom() != null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"right\">" + netDbLink(cfg.getReceiveFrom()) +"</td>");
|
|
||||||
else
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
|
||||||
if (cfg.getSendTunnel() != null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getSendTunnel().getTunnelId() +"</td>");
|
|
||||||
else
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
|
||||||
if (cfg.getSendTo() != null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + netDbLink(cfg.getSendTo()) +"</td>");
|
|
||||||
else
|
|
||||||
// out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
|
||||||
long timeLeft = cfg.getExpiration()-_context.clock().now();
|
|
||||||
if (timeLeft > 0)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>");
|
|
||||||
else
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">(grace period)</td>");
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + cfg.getProcessedMessagesCount() + "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 * (int) cfg.getProcessedMessagesCount() / lifetime;
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + bps + "Bps</td>");
|
|
||||||
if (cfg.getSendTo() == null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">Outbound Endpoint</td>");
|
|
||||||
else if (cfg.getReceiveFrom() == null)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">Inbound Gateway</td>");
|
|
||||||
else
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">Participant</td>");
|
|
||||||
out.write("</tr>\n");
|
|
||||||
processed += cfg.getProcessedMessagesCount();
|
|
||||||
}
|
|
||||||
out.write("</table>\n");
|
|
||||||
out.write("<div class=\"statusnotes\"><b>Inactive participating tunnels: " + inactive + "</b></div>\n");
|
|
||||||
out.write("<div class=\"statusnotes\"><b>Lifetime bandwidth usage: " + DataHelper.formatSize(processed*1024) + "B</b></div>\n");
|
|
||||||
renderPeers(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TunnelComparator implements Comparator {
|
|
||||||
public int compare(Object l, Object r) {
|
|
||||||
return (int) (((HopConfig)r).getProcessedMessagesCount() - ((HopConfig)l).getProcessedMessagesCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderPool(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
|
|
||||||
List<TunnelInfo> tunnels = null;
|
|
||||||
if (in == null)
|
|
||||||
tunnels = new ArrayList();
|
|
||||||
else
|
|
||||||
tunnels = in.listTunnels();
|
|
||||||
if (outPool != null)
|
|
||||||
tunnels.addAll(outPool.listTunnels());
|
|
||||||
|
|
||||||
long processedIn = (in != null ? in.getLifetimeProcessed() : 0);
|
|
||||||
long processedOut = (outPool != null ? outPool.getLifetimeProcessed() : 0);
|
|
||||||
|
|
||||||
int live = 0;
|
|
||||||
int maxLength = 1;
|
|
||||||
for (int i = 0; i < tunnels.size(); i++) {
|
|
||||||
TunnelInfo info = tunnels.get(i);
|
|
||||||
if (info.getLength() > maxLength)
|
|
||||||
maxLength = info.getLength();
|
|
||||||
}
|
|
||||||
out.write("<table><tr><th>In/Out</th><th>Expiry</th><th>Usage</th><th>Gateway</th>");
|
|
||||||
if (maxLength > 3) {
|
|
||||||
out.write("<th align=\"center\" colspan=\"" + (maxLength - 2));
|
|
||||||
out.write("\">Participants</th>");
|
|
||||||
}
|
|
||||||
else if (maxLength == 3) {
|
|
||||||
out.write("<th>Participant</th>");
|
|
||||||
}
|
|
||||||
if (maxLength > 1) {
|
|
||||||
out.write("<th>Endpoint</th>");
|
|
||||||
}
|
|
||||||
out.write("</tr>\n");
|
|
||||||
for (int i = 0; i < tunnels.size(); i++) {
|
|
||||||
TunnelInfo info = tunnels.get(i);
|
|
||||||
long timeLeft = info.getExpiration()-_context.clock().now();
|
|
||||||
if (timeLeft <= 0)
|
|
||||||
continue; // don't display tunnels in their grace period
|
|
||||||
live++;
|
|
||||||
if (info.isInbound())
|
|
||||||
out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"Inbound\"></td>");
|
|
||||||
else
|
|
||||||
out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"Outbound\"></td>");
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>\n");
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + info.getProcessedMessagesCount() + "KB</td>\n");
|
|
||||||
for (int j = 0; j < info.getLength(); j++) {
|
|
||||||
Hash peer = info.getPeer(j);
|
|
||||||
TunnelId id = (info.isInbound() ? info.getReceiveTunnelId(j) : info.getSendTunnelId(j));
|
|
||||||
if (_context.routerHash().equals(peer)) {
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + (id == null ? "" : "" + id) + "</td>");
|
|
||||||
} else {
|
|
||||||
String cap = getCapacity(peer);
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + netDbLink(peer) + (id == null ? "" : " " + id) + cap + "</td>");
|
|
||||||
}
|
|
||||||
if (info.getLength() < maxLength && (info.getLength() == 1 || j == info.getLength() - 2)) {
|
|
||||||
for (int k = info.getLength(); k < maxLength; k++)
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\"> </td>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.write("</tr>\n");
|
|
||||||
|
|
||||||
if (info.isInbound())
|
|
||||||
processedIn += info.getProcessedMessagesCount();
|
|
||||||
else
|
|
||||||
processedOut += info.getProcessedMessagesCount();
|
|
||||||
}
|
|
||||||
out.write("</table>\n");
|
|
||||||
if (in != null) {
|
|
||||||
List pending = in.listPending();
|
|
||||||
if (pending.size() > 0)
|
|
||||||
out.write("<div class=\"statusnotes\"><center><b>Build in progress: " + pending.size() + " inbound</b></center></div>\n");
|
|
||||||
live += pending.size();
|
|
||||||
}
|
|
||||||
if (outPool != null) {
|
|
||||||
List pending = outPool.listPending();
|
|
||||||
if (pending.size() > 0)
|
|
||||||
out.write("<div class=\"statusnotes\"><center><b>Build in progress: " + pending.size() + " outbound</b></center></div>\n");
|
|
||||||
live += pending.size();
|
|
||||||
}
|
|
||||||
if (live <= 0)
|
|
||||||
out.write("<div class=\"statusnotes\"><center><b>No tunnels; waiting for the grace period to end.</center></b></div>\n");
|
|
||||||
out.write("<div class=\"statusnotes\"><center><b>Lifetime bandwidth usage: " + DataHelper.formatSize(processedIn*1024) + "B in, " +
|
|
||||||
DataHelper.formatSize(processedOut*1024) + "B out</b></center></div>");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderPeers(Writer out) throws IOException {
|
|
||||||
// count up the peers in the local pools
|
|
||||||
ObjectCounter<Hash> lc = new ObjectCounter();
|
|
||||||
int tunnelCount = countTunnelsPerPeer(lc);
|
|
||||||
|
|
||||||
// count up the peers in the participating tunnels
|
|
||||||
ObjectCounter<Hash> pc = new ObjectCounter();
|
|
||||||
int partCount = countParticipatingPerPeer(pc);
|
|
||||||
|
|
||||||
Set<Hash> peers = new HashSet(lc.objects());
|
|
||||||
peers.addAll(pc.objects());
|
|
||||||
List<Hash> peerList = new ArrayList(peers);
|
|
||||||
Collections.sort(peerList, new HashComparator());
|
|
||||||
|
|
||||||
out.write("<h2><a name=\"peers\"></a>Tunnel Counts By Peer:</h2>\n");
|
|
||||||
out.write("<table><tr><th>Peer</th><th>Expl. + Client</th><th>% of total</th><th>Part. from + to</th><th>% of total</th></tr>\n");
|
|
||||||
for (Hash h : peerList) {
|
|
||||||
out.write("<tr> <td class=\"cells\" align=\"center\">");
|
|
||||||
out.write(netDbLink(h));
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + lc.count(h));
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">");
|
|
||||||
if (tunnelCount > 0)
|
|
||||||
out.write("" + (lc.count(h) * 100 / tunnelCount));
|
|
||||||
else
|
|
||||||
out.write('0');
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">" + pc.count(h));
|
|
||||||
out.write(" <td class=\"cells\" align=\"center\">");
|
|
||||||
if (partCount > 0)
|
|
||||||
out.write("" + (pc.count(h) * 100 / partCount));
|
|
||||||
else
|
|
||||||
out.write('0');
|
|
||||||
out.write('\n');
|
|
||||||
}
|
|
||||||
out.write("<tr class=\"tablefooter\"> <td align=\"center\"><b>Tunnels</b> <td align=\"center\"><b>" + tunnelCount);
|
|
||||||
out.write("</b> <td> </td> <td align=\"center\"><b>" + partCount);
|
|
||||||
out.write("</b> <td> </td></tr></table></div>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return total number of non-fallback expl. + client tunnels */
|
/** @return total number of non-fallback expl. + client tunnels */
|
||||||
@ -682,39 +463,27 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return total number of part. tunnels */
|
/** for TunnelRenderer in router console */
|
||||||
private int countParticipatingPerPeer(ObjectCounter<Hash> pc) {
|
public Map<Hash, TunnelPool> getInboundClientPools() {
|
||||||
List<HopConfig> participating = _context.tunnelDispatcher().listParticipatingTunnels();
|
synchronized (_clientInboundPools) {
|
||||||
for (HopConfig cfg : participating) {
|
return new HashMap(_clientInboundPools);
|
||||||
Hash from = cfg.getReceiveFrom();
|
|
||||||
if (from != null)
|
|
||||||
pc.increment(from);
|
|
||||||
Hash to = cfg.getSendTo();
|
|
||||||
if (to != null)
|
|
||||||
pc.increment(to);
|
|
||||||
}
|
|
||||||
return participating.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
class HashComparator implements Comparator {
|
|
||||||
public int compare(Object l, Object r) {
|
|
||||||
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCapacity(Hash peer) {
|
/** for TunnelRenderer in router console */
|
||||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
public Map<Hash, TunnelPool> getOutboundClientPools() {
|
||||||
if (info != null) {
|
synchronized (_clientOutboundPools) {
|
||||||
String caps = info.getCapabilities();
|
return new HashMap(_clientOutboundPools);
|
||||||
for (char c = Router.CAPABILITY_BW12; c <= Router.CAPABILITY_BW256; c++) {
|
|
||||||
if (caps.indexOf(c) >= 0)
|
|
||||||
return " " + c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String netDbLink(Hash peer) {
|
/** for TunnelRenderer in router console */
|
||||||
return _context.commSystem().renderPeerHTML(peer);
|
public TunnelPool getInboundExploratoryPool() {
|
||||||
|
return _inboundExploratory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** for TunnelRenderer in router console */
|
||||||
|
public TunnelPool getOutboundExploratoryPool() {
|
||||||
|
return _outboundExploratory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user