merge of '18a7dd067a56c2552cf30f4a045628f91c360c80'

and 'd6b8e99c4aee82652446fe759f45f27e0da9fbc0'
This commit is contained in:
dev
2009-11-16 19:45:10 +00:00
60 changed files with 1069 additions and 352 deletions

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.io.File;
import java.io.IOException;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.io.BufferedReader;
import java.io.BufferedWriter;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.io.File;
import java.util.HashMap;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
/**
* A thread that waits five minutes, then runs the addressbook daemon.

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.io.BufferedWriter;
import java.io.File;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
/**
* A subscription to a remote address book.

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.util.Iterator;
import java.util.List;

View File

@@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package addressbook;
package net.i2p.addressbook;
import java.io.File;
import java.io.IOException;

View File

@@ -6,11 +6,11 @@
<web-app>
<servlet>
<servlet-name>addressbook</servlet-name>
<servlet-class>addressbook.Servlet</servlet-class>
<servlet-class>net.i2p.addressbook.Servlet</servlet-class>
<init-param>
<param-name>home</param-name>
<param-value>./addressbook</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
</web-app>

View File

@@ -714,7 +714,6 @@ public class SnarkManager implements Snark.CompleteListener {
"POSTMAN", "http://tracker2.postman.i2p/announce.php=http://tracker2.postman.i2p/"
,"WELTERDE", "http://tracker.welterde.i2p/a=http://tracker.welterde.i2p/stats?mode=top5"
, "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
, "ThePirateBay", "http://tracker.thepiratebay.i2p/announce=http://thepiratebay.i2p/"
};
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */

View File

@@ -505,7 +505,6 @@ public class I2PSnarkServlet extends HttpServlet {
// temporarily hardcoded for postman* and anonymity, requires bytemonsoon patch for lookup by info_hash
String announce = snark.meta.getAnnounce();
if (announce.startsWith("http://YRgrgTLG") || announce.startsWith("http://8EoJZIKr") ||
announce.startsWith("http://4svjpPox") || announce.startsWith("http://tracker.thepiratebay.i2p/") ||
announce.startsWith("http://lnQ6yoBT") || announce.startsWith("http://tracker2.postman.i2p/")) {
Map trackers = _manager.getTrackers();
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
@@ -513,8 +512,7 @@ public class I2PSnarkServlet extends HttpServlet {
String name = (String)entry.getKey();
String baseURL = (String)entry.getValue();
if (!(baseURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
(announce.startsWith("http://lnQ6yoBT") && baseURL.startsWith("http://tracker2.postman.i2p/")) ||
(announce.startsWith("http://4svjpPox") && baseURL.startsWith("http://thepiratebay.i2p/"))))
(announce.startsWith("http://lnQ6yoBT") && baseURL.startsWith("http://tracker2.postman.i2p/"))))
continue;
int e = baseURL.indexOf('=');
if (e < 0)

View File

@@ -3,8 +3,10 @@
*/
package net.i2p.i2ptunnel;
import java.io.ByteArrayOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -15,6 +17,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.StringTokenizer;
@@ -55,6 +58,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private HashMap addressHelpers = new HashMap();
/**
* These are backups if the xxx.ht error page is missing.
*/
private final static byte[] ERR_REQUEST_DENIED =
("HTTP/1.1 403 Access Denied\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -77,6 +84,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"Could not find the following Destination:<BR><BR><div>")
.getBytes();
/*****
private final static byte[] ERR_TIMEOUT =
("HTTP/1.1 504 Gateway Timeout\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -88,6 +96,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"destination may have issues. Could not get a response from "+
"the following Destination:<BR><BR>")
.getBytes();
*****/
private final static byte[] ERR_NO_OUTPROXY =
("HTTP/1.1 503 Service Unavailable\r\n"+
@@ -108,11 +117,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"The addresshelper link you followed specifies a different destination key "+
"than a host entry in your host database. "+
"Someone could be trying to impersonate another eepsite, "+
"or people have given two eepsites identical names.<P/>"+
"or people have given two eepsites identical names.<p>"+
"You can resolve the conflict by considering which key you trust, "+
"and either discarding the addresshelper link, "+
"discarding the host entry from your host database, "+
"or naming one of them differently.<P/>")
"or naming one of them differently.<p>")
.getBytes();
private final static byte[] ERR_BAD_PROTOCOL =
@@ -376,22 +385,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
// Did addresshelper key conflict?
if (ahelperConflict)
{
String str;
byte[] header;
str = FileUtil.readTextFile((new File(_errorDir, "ahelper-conflict-header.ht")).getAbsolutePath(), 100, true);
if (str != null) header = str.getBytes();
else header = ERR_AHELPER_CONFLICT;
if (out != null) {
// Fixme untranslated
long alias = I2PAppContext.getGlobalContext().random().nextLong();
String trustedURL = protocol + uriPath + urlEncoding;
String conflictURL = protocol + alias + ".i2p/?" + initialFragments;
byte[] header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
out.write(header);
out.write(("To visit the destination in your host database, click <a href=\"" + trustedURL + "\">here</a>. To visit the conflicting addresshelper link by temporarily giving it a random alias, click <a href=\"" + conflictURL + "\">here</a>.<P/>").getBytes());
out.write("</div><div class=\"proxyfooter\"><p><i>I2P HTTP Proxy Server<br />Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></div></body></html>\n".getBytes());
out.flush();
out.write(("To visit the destination in your host database, click <a href=\"" + trustedURL + "\">here</a>. To visit the conflicting addresshelper link by temporarily giving it a random alias, click <a href=\"" + conflictURL + "\">here</a>.<p></div>").getBytes());
writeFooter(out);
}
s.close();
return;
@@ -408,11 +411,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
line = method + " " + request.substring(pos);
} else if (host.toLowerCase().equals("localhost") || host.equals("127.0.0.1")) {
if (out != null) {
out.write(ERR_LOCALHOST);
out.write("<p /><i>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></body></html>\n".getBytes());
out.flush();
out.write(getErrorPage("localhost", ERR_LOCALHOST));
writeFooter(out);
}
s.close();
return;
@@ -430,11 +430,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
_log.warn(getPrefix(requestId) + "Host wants to be outproxied, but we dont have any!");
l.log("No HTTP outproxy found for the request.");
if (out != null) {
out.write(ERR_NO_OUTPROXY);
out.write("<p /><i>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></body></html>\n".getBytes());
out.flush();
out.write(getErrorPage("noproxy", ERR_NO_OUTPROXY));
writeFooter(out);
}
s.close();
return;
@@ -449,11 +446,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (pos < 0) {
l.log("Invalid request url [" + request + "]");
if (out != null) {
out.write(ERR_REQUEST_DENIED);
out.write("<p /><i>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></body></html>\n".getBytes());
out.flush();
out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
writeFooter(out);
}
s.close();
return;
@@ -540,13 +534,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
l.log("No HTTP method found in the request.");
if (out != null) {
if ("http://".equalsIgnoreCase(protocol))
out.write(ERR_REQUEST_DENIED);
out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
else
out.write(ERR_BAD_PROTOCOL);
out.write("<p /><i>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></body></html>\n".getBytes());
out.flush();
out.write(getErrorPage("protocol", ERR_BAD_PROTOCOL));
writeFooter(out);
}
s.close();
return;
@@ -568,23 +559,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
//l.log("Could not resolve " + destination + ".");
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
String str;
byte[] header;
boolean showAddrHelper = false;
if (usingWWWProxy)
str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true);
header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
else if(ahelper != 0)
str = FileUtil.readTextFile((new File(_errorDir, "dnfb-header.ht")).getAbsolutePath(), 100, true);
header = getErrorPage("dnfb", ERR_DESTINATION_UNKNOWN);
else if (destination.length() == 60 && destination.endsWith(".b32.i2p"))
str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true);
header = getErrorPage("dnf", ERR_DESTINATION_UNKNOWN);
else {
str = FileUtil.readTextFile((new File(_errorDir, "dnfh-header.ht")).getAbsolutePath(), 100, true);
header = getErrorPage("dnfh", ERR_DESTINATION_UNKNOWN);
showAddrHelper = true;
}
if (str != null)
header = str.getBytes();
else
header = ERR_DESTINATION_UNKNOWN;
writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination, showAddrHelper);
s.close();
return;
@@ -658,6 +644,64 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
}
/**
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
* or the backup byte array on fail.
*
* .ht files must be UTF-8 encoded and use \r\n terminators so the
* HTTP headers are conformant.
* We can't use FileUtil.readFile() because it strips \r
*
* @return non-null
*/
private byte[] getErrorPage(String base, byte[] backup) {
return getErrorPage(getTunnel().getContext(), base, backup);
}
private static byte[] getErrorPage(I2PAppContext ctx, String base, byte[] backup) {
File errorDir = new File(ctx.getBaseDir(), "docs");
String lang = ctx.getProperty("routerconsole.lang", Locale.getDefault().getLanguage());
if (lang != null && lang.length() > 0 && !lang.equals("en")) {
File file = new File(errorDir, base + "-header_" + lang + ".ht");
try {
return readFile(file);
} catch (IOException ioe) {
// try the english version now
}
}
File file = new File(errorDir, base + "-header.ht");
try {
return readFile(file);
} catch (IOException ioe) {
return backup;
}
}
private static byte[] readFile(File file) throws IOException {
FileInputStream fis = null;
byte[] buf = new byte[512];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
try {
int len = 0;
fis = new FileInputStream(file);
while ((len = fis.read(buf)) > 0) {
baos.write(buf, 0, len);
}
return baos.toByteArray();
} finally {
try { if (fis != null) fis.close(); } catch (IOException foo) {}
}
// we won't ever get here
}
private static void writeFooter(OutputStream out) throws IOException {
// the css is hiding this div for now, but we'll keep it here anyway
out.write("<div class=\"proxyfooter\"><p><i>I2P HTTP Proxy Server<br>Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></div></body></html>\n".getBytes());
out.flush();
}
private static class OnTimeout implements Runnable {
private Socket _socket;
private OutputStream _out;
@@ -705,9 +749,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
out.write("\">http://".getBytes());
out.write(uri.getBytes());
out.write("</a>".getBytes());
if (usingWWWProxy) out.write(("<br />WWW proxy: " + wwwProxy).getBytes());
if (usingWWWProxy) out.write(("<br>WWW proxy: " + wwwProxy).getBytes());
if (showAddrHelper) {
out.write("<br /><br />Click a link below to look for an address helper by using a \"jump\" service:<br />".getBytes());
// Fixme untranslated
out.write("<br><br>Click a link below to look for an address helper by using a \"jump\" service:<br>".getBytes());
for (int i = 0; i < jumpServers.length; i++) {
// Skip jump servers we don't know
String jumphost = jumpServers[i].substring(7); // "http://"
@@ -719,7 +764,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
continue;
}
out.write("<br /><a href=\"".getBytes());
out.write("<br><a href=\"".getBytes());
out.write(jumpServers[i].getBytes());
out.write(uri.getBytes());
out.write("\">".getBytes());
@@ -729,10 +774,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
}
}
out.write("</div><div class=\"proxyfooter\"><p><i>I2P HTTP Proxy Server<br />Generated on: ".getBytes());
out.write(new Date().toString().getBytes());
out.write("</i></div></body></html>\n".getBytes());
out.flush();
out.write("</div>".getBytes());
writeFooter(out);
}
}
@@ -744,16 +787,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
// _log.warn(getPrefix(requestId) + "Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
if (out != null) {
try {
String str;
byte[] header;
if (usingWWWProxy)
str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true);
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
else
str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true);
if (str != null)
header = str.getBytes();
else
header = ERR_DESTINATION_UNKNOWN;
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf", ERR_DESTINATION_UNKNOWN);
writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy, false);
} catch (IOException ioe) {
// static

View File

@@ -14,89 +14,4 @@ echo $PWD
## except this everything is the same with bundle-message.sh
## walking - public domain :-D
CLASS=net.i2p.router.web.messages
TMPFILE=build/javafiles.txt
export TZ=UTC
#
# generate strings/Countries.java from ../../../installer/resources/countries.txt
#
CFILE=../../../installer/resources/countries.txt
JFILE=build/Countries.java
if [ $CFILE -nt $JFILE -o ! -s $JFILE ]
then
mkdir -p build
echo '// Automatically generated pseudo-java for xgettext - do not edit' > $JFILE
echo '// Translators may wish to translate a few of these, do not bother to translate all of them!!' >> $JFILE
sed 's/..,\(..*\)/_("\1");/' $CFILE >> $JFILE
fi
# list specific files in router/ here, so we don't scan the whole tree
ROUTERFILES="\
../../../router/java/src/net/i2p/router/RouterThrottleImpl.java \
../../../router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java"
JPATHS="src ../jsp/WEB-INF strings $JFILE $ROUTERFILES"
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 $JPATHS -name *.java -newer $i > $TMPFILE
if [ -s build/obj/net/i2p/router/web/messages_$LG.class -a \
build/obj/net/i2p/router/web/messages_$LG.class -nt $i -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")
# _x("foo")
# intl._("foo")
# intl.title("foo")
# handler._("foo")
# formhandler._("foo")
# net.i2p.router.web.Messages.getString("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 $JPATHS -name *.java > $TMPFILE
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
--keyword=handler._ --keyword=formhandler._ \
--keyword=net.i2p.router.web.Messages.getString \
-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 - msgfmt failed, not updating translations'
break
fi
done
rm -f $TMPFILE
# todo: return failure
exit 0
source bundle-messages.sh

View File

@@ -24,7 +24,12 @@ fi
# list specific files in router/ here, so we don't scan the whole tree
ROUTERFILES="\
../../../router/java/src/net/i2p/router/RouterThrottleImpl.java \
../../../router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java"
../../../router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java \
../../../router/java/src/net/i2p/router/transport/TransportManager.java \
../../../router/java/src/net/i2p/router/transport/GetBidsJob.java \
../../../router/java/src/net/i2p/router/Blocklist.java \
../../../router/java/src/net/i2p/router/transport/ntcp/EstablishState.java"
JPATHS="src ../jsp/WEB-INF strings $JFILE $ROUTERFILES"
for i in ../locale/messages_*.po
do

View File

@@ -20,7 +20,7 @@ public class ConfigPeerHandler extends FormHandler {
} else if (_action.equals(_("Ban peer until restart"))) {
Hash h = getHash();
if (h != null) {
_context.shitlist().shitlistRouterForever(h, "Manually banned via <a href=\"configpeer.jsp\">configpeer.jsp</a>");
_context.shitlist().shitlistRouterForever(h, _("Manually banned via {0}"), "<a href=\"configpeer.jsp\">configpeer.jsp</a>");
addFormNotice(_("Peer") + " " + _peer + " " + _("banned until restart") );
return;
}

View File

@@ -43,7 +43,7 @@ public class ConfigTunnelsHelper extends HelperBase {
String prefix = dest.calculateHash().toBase64().substring(0,4);
buf.append("<input type=\"hidden\" name=\"pool.").append(cur).append("\" value=\"");
buf.append(dest.calculateHash().toBase64()).append("\" >");
renderForm(buf, cur, prefix, _("Client tunnels for") + " " + name, in, out);
renderForm(buf, cur, prefix, _("Client tunnels for") + " " + _(name), in, out);
cur++;
}

View File

@@ -201,7 +201,7 @@ public class NetDbRenderer {
// transports table
buf.append("<table>\n");
buf.append("<tr><th align=\"left\">" + _("Addresses") + "</th><th>" + _("Count") + "</th></tr>\n");
buf.append("<tr><th align=\"left\">" + _("Transports") + "</th><th>" + _("Count") + "</th></tr>\n");
for (int i = 0; i < 8; i++) {
int num = transportCount[i];
if (num > 0) {
@@ -276,7 +276,7 @@ public class NetDbRenderer {
}
for (Iterator iter = info.getAddresses().iterator(); iter.hasNext(); ) {
RouterAddress addr = (RouterAddress)iter.next();
buf.append("<b>").append(DataHelper.stripHTML(addr.getTransportStyle())).append("</b>: ");
buf.append("<b>").append(DataHelper.stripHTML(addr.getTransportStyle())).append(":</b> ");
for (Iterator optIter = addr.getOptions().keySet().iterator(); optIter.hasNext(); ) {
String name = (String)optIter.next();
String val = addr.getOptions().getProperty(name);

View File

@@ -234,14 +234,14 @@ class ProfileOrganizerRenderer {
}
buf.append("</table>");
buf.append("<h3>").append(_("Thresholds:")).append("</h3>");
buf.append("<h3>").append(_("Thresholds")).append("</h3>");
buf.append("<p><b>").append(_("Speed")).append(":</b> ").append(num(_organizer.getSpeedThreshold()))
.append(" (").append(fast).append(' ').append(_("fast peers")).append(")<br>");
buf.append("<b>").append(_("Capacity")).append(":</b> ").append(num(_organizer.getCapacityThreshold()))
.append(" (").append(reliable).append(' ').append(_("high capacity peers")).append(")<br>");
buf.append("<b>").append(_("Integration")).append(":</b> ").append(num(_organizer.getIntegrationThreshold()))
.append(" (").append(integrated).append(' ').append(_(" well integrated peers")).append(")</p>");
buf.append("<h3>").append(_("Definitions")).append(":</h3><ul>");
buf.append("<h3>").append(_("Definitions")).append("</h3><ul>");
buf.append("<li><b>").append(_("groups")).append("</b>: ").append(_("as determined by the profile organizer")).append("</li>");
buf.append("<li><b>").append(_("caps")).append("</b>: ").append(_("capabilities in the netDb, not used to determine profiles")).append("</li>");
buf.append("<li><b>").append(_("speed")).append("</b>: ").append(_("peak throughput (bytes per second) over a 1 minute period that the peer has sustained in a single tunnel")).append("</li>");

View File

@@ -20,7 +20,8 @@ public class ProfilesHelper extends HelperBase {
/** @return empty string, writes directly to _out */
public String getShitlistSummary() {
try {
_context.shitlist().renderStatusHTML(_out);
ShitlistRenderer rend = new ShitlistRenderer(_context);
rend.renderStatusHTML(_out);
} catch (IOException ioe) {
ioe.printStackTrace();
}

View File

@@ -0,0 +1,99 @@
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.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.router.RouterContext;
import net.i2p.router.Shitlist;
/**
* Moved from Shitlist.java
*/
public class ShitlistRenderer {
private RouterContext _context;
public ShitlistRenderer(RouterContext context) {
_context = context;
}
private static class HashComparator implements Comparator {
public int compare(Object l, Object r) {
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
}
}
public void renderStatusHTML(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(1024);
// move to the jsp
//buf.append("<h2>Banned Peers</h2>");
Map<Hash, Shitlist.Entry> entries = new TreeMap(new HashComparator());
entries.putAll(_context.shitlist().getEntries());
buf.append("<ul>");
for (Map.Entry<Hash, Shitlist.Entry> e : entries.entrySet()) {
Hash key = e.getKey();
Shitlist.Entry entry = e.getValue();
buf.append("<li>").append(_context.commSystem().renderPeerHTML(key));
buf.append(' ');
long expires = entry.expireOn-_context.clock().now();
String expireString = DataHelper.formatDuration(expires);
if (expires < 5l*24*60*60*1000)
buf.append(_("Temporary ban expiring in {0}", expireString));
else
buf.append(_("Banned until restart or in {0}", expireString));
Set transports = entry.transports;
if ( (transports != null) && (transports.size() > 0) )
buf.append(" on the following transport: ").append(transports);
if (entry.cause != null) {
buf.append("<br>\n");
if (entry.causeCode != null)
buf.append(_(entry.cause, entry.causeCode));
else
buf.append(_(entry.cause));
}
buf.append(" (<a href=\"configpeer.jsp?peer=").append(key.toBase64())
.append("#unsh\">").append(_("unban now")).append("</a>)");
buf.append("</li>\n");
}
buf.append("</ul>\n");
out.write(buf.toString());
out.flush();
}
/** translate a string */
private String _(String s) {
return Messages.getString(s, _context);
}
/**
* translate a string with a parameter
* This is a lot more expensive than _(s), so use sparingly.
*
* @param s string to be translated containing {0}
* The {0} will be replaced by the parameter.
* Single quotes must be doubled, i.e. ' -> '' in the string.
* @param o parameter, not translated.
* To tranlslate parameter also, use _("foo {0} bar", _("baz"))
* Do not double the single quotes in the parameter.
* Use autoboxing to call with ints, longs, floats, etc.
*/
private String _(String s, Object o) {
return Messages.getString(s, o, _context);
}
}

View File

@@ -37,7 +37,7 @@ public class TunnelRenderer {
}
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");
out.write("<div class=\"wideload\"><h2><a name=\"exploratory\" ></a>" + _("Exploratory tunnels") + " (<a href=\"/configtunnels.jsp#exploratory\">" + _("configure") + "</a>)</h2>\n");
renderPool(out, _context.tunnelManager().getInboundExploratoryPool(), _context.tunnelManager().getOutboundExploratoryPool());
List<Hash> destinations = null;
@@ -59,15 +59,15 @@ public class TunnelRenderer {
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");
out.write(" (<a href=\"/configtunnels.jsp#" + client.toBase64().substring(0,4) +"\">" + _("configure") + "</a>)</h2>\n");
else
out.write(" (dead):</h2>\n");
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("<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");
@@ -104,7 +104,7 @@ public class TunnelRenderer {
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\">(" + _("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)
@@ -231,7 +231,7 @@ public class TunnelRenderer {
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("<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\">");

View File

@@ -19,7 +19,7 @@ help with other aspects of the project, please see the documentation for
<ul class="links">
<li class="tidylist"><a href="http://www.i2p2.i2p/faq.html">FAQ on www.i2p2.i2p</a>
<li class="tidylist"><a href="http://www.i2p2.i2p/faq_de.html">Deutsch FAQ</a>.</ul>
</p><p>You may also try the <a href="http://forum.i2p/">I2P forum</a>
<br>You may also try the <a href="http://forum.i2p/">I2P forum</a>
or IRC.</p>
<h2>Summary Bar Information</h2><p>

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P routerconsole\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-11-11 11:09+0000\n"
"POT-Creation-Date: 2009-11-12 06:00+0000\n"
"PO-Revision-Date: \n"
"Last-Translator: walking <walking@mail.i2p>\n"
"Language-Team: \n"
@@ -18,6 +18,24 @@ msgstr ""
"X-Poedit-Language: Chinese\n"
"X-Poedit-Country: CHINA\n"
#: ../../../router/java/src/net/i2p/router/Blocklist.java:117
#, java-format
msgid "Banned by router hash: {0}"
msgstr "按路由器指纹封杀:{0}"
#: ../../../router/java/src/net/i2p/router/Blocklist.java:119
msgid "Banned by router hash"
msgstr "路由指纹封锁"
#: ../../../router/java/src/net/i2p/router/Blocklist.java:664
msgid "IP banned"
msgstr "IP封锁"
#: ../../../router/java/src/net/i2p/router/Blocklist.java:734
#, java-format
msgid "IP banned by blocklist.txt entry {0}"
msgstr "按IP黑名单blocklist.txt封杀的节点{0}"
#: ../../../router/java/src/net/i2p/router/RouterThrottleImpl.java:91
msgid "Rejecting tunnels: Shutting down"
msgstr "拒绝共享:准备退出"
@@ -54,6 +72,20 @@ msgstr "接收共享隧道"
msgid "Rejecting tunnels"
msgstr "拒绝参与共享隧道"
#: ../../../router/java/src/net/i2p/router/transport/GetBidsJob.java:70
msgid "No transports (hidden or starting up?)"
msgstr "无数据传输(隐身或正在启动)"
#: ../../../router/java/src/net/i2p/router/transport/TransportManager.java:450
msgid "Unreachable on any transport"
msgstr "各协议均不可达"
#: ../../../router/java/src/net/i2p/router/transport/ntcp/EstablishState.java:373
#: ../../../router/java/src/net/i2p/router/transport/ntcp/EstablishState.java:578
#, java-format
msgid "Excessive clock skew: {0}"
msgstr "严重时滞:{0}"
#: ../../../router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java:128
msgid "Dropping tunnel requests: Too slow"
msgstr "忽略共享请求:速度太慢"
@@ -836,7 +868,7 @@ msgstr "(建议不要使用 DEBUG 或 INFO 作为默认等级,他们会明显降
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:329
msgid "Log level overrides"
msgstr "等级外日志项目"
msgstr "等级外<br>日志项目"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:106
msgid "config peers"
@@ -856,7 +888,7 @@ msgstr "路由器Key(见NetDB)"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:310
msgid "Manually Ban / Unban a Peer"
msgstr "手动封/解封某个节点"
msgstr "手动封/解封某个节点"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:312
msgid "Banning will prevent the participation of this peer in tunnels you create."
@@ -865,7 +897,7 @@ msgstr "封锁将阻止节点参与您的隧道创建"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:314
#: src/net/i2p/router/web/ConfigPeerHandler.java:20
msgid "Ban peer until restart"
msgstr "封节点直到重启"
msgstr "封节点直到重启"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:316
#: src/net/i2p/router/web/ConfigPeerHandler.java:28
@@ -1219,15 +1251,15 @@ msgstr "升级策略"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:326
msgid "Update through the eepProxy?"
msgstr "通过eepProxy更新?"
msgstr "通过I2P代理更新?"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:330
msgid "eepProxy host"
msgstr "eepProxy主机"
msgstr "I2P代理主机"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:334
msgid "eepProxy port"
msgstr "eepProxy端口"
msgstr "I2P代理端口"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:338
msgid "Update URLs"
@@ -1334,7 +1366,7 @@ msgstr "I2P 网络节点信息"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/stats_jsp.java:105
msgid "statistics"
msgstr "统计数据"
msgstr "统计"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/stats_jsp.java:242
msgid "I2P Router Statistics"
@@ -2453,7 +2485,7 @@ msgstr "节点"
#: src/net/i2p/router/web/NetDbRenderer.java:288
#: src/net/i2p/router/web/SummaryBarRenderer.java:124
msgid "Stats"
msgstr "统计数据"
msgstr "统计"
#: src/net/i2p/router/web/ConfigNavHelper.java:20
msgid "Advanced"
@@ -2543,6 +2575,11 @@ msgstr "未知"
msgid "bits per second"
msgstr "比特/秒"
#: src/net/i2p/router/web/ConfigPeerHandler.java:23
#, java-format
msgid "Manually banned via {0}"
msgstr "通过{0}手动封锁"
#: src/net/i2p/router/web/ConfigPeerHandler.java:24
#: src/net/i2p/router/web/ConfigPeerHandler.java:33
#: src/net/i2p/router/web/ConfigPeerHandler.java:35
@@ -3249,8 +3286,8 @@ msgid "1d Fail Rate"
msgstr "1d失败率"
#: src/net/i2p/router/web/ProfileOrganizerRenderer.java:237
msgid "Thresholds:"
msgstr "临界值:"
msgid "Thresholds"
msgstr "临界值"
#: src/net/i2p/router/web/ProfileOrganizerRenderer.java:239
msgid "fast peers"
@@ -3320,6 +3357,20 @@ msgstr "状态"
msgid "n/a"
msgstr ""
#: src/net/i2p/router/web/ShitlistRenderer.java:57
#, java-format
msgid "Temporary ban expiring in {0}"
msgstr "临时封锁{0}后解除"
#: src/net/i2p/router/web/ShitlistRenderer.java:59
#, java-format
msgid "Banned until restart or in {0}"
msgstr "封锁直到重启或{0}后"
#: src/net/i2p/router/web/ShitlistRenderer.java:71
msgid "unban now"
msgstr "立即解封"
#: src/net/i2p/router/web/StatsGenerator.java:58
msgid "Statistics gathered during this router's uptime"
msgstr "路由运行时收集的统计数据"
@@ -3366,7 +3417,7 @@ msgstr "内置的匿名Web服务器"
#: src/net/i2p/router/web/SummaryBarRenderer.java:68
msgid "Webserver"
msgstr "匿名网站服务器"
msgstr "匿名主页服务器"
#: src/net/i2p/router/web/SummaryBarRenderer.java:72
msgid "Configure I2P Router"
@@ -3638,9 +3689,13 @@ msgstr "共享客户端"
#: src/net/i2p/router/web/TunnelRenderer.java:40
#: src/net/i2p/router/web/TunnelRenderer.java:62
msgid "config"
msgid "configure"
msgstr "设置"
#: src/net/i2p/router/web/TunnelRenderer.java:64
msgid "dead"
msgstr "失效"
#: src/net/i2p/router/web/TunnelRenderer.java:70
msgid "Participating tunnels"
msgstr "共享隧道"
@@ -3678,6 +3733,10 @@ msgstr "职能"
msgid "Usage"
msgstr "使用情况"
#: src/net/i2p/router/web/TunnelRenderer.java:107
msgid "grace period"
msgstr "过渡期"
#: src/net/i2p/router/web/TunnelRenderer.java:117
msgid "Outbound Endpoint"
msgstr "出站终端"
@@ -3795,7 +3854,7 @@ msgstr "程序隧道"
#: strings/Strings.java:25
msgid "My eepsite web server"
msgstr "我的匿名Web服务器"
msgstr "匿名主页服务器"
#: strings/Strings.java:26
msgid "Browser launch at startup"
@@ -3807,7 +3866,7 @@ msgstr "BOB 协议桥"
#: strings/Strings.java:34
msgid "IRC proxy"
msgstr "IRC 代理"
msgstr "I2P聊天室"
#: strings/Strings.java:35
msgid "eepsite"
@@ -3819,7 +3878,7 @@ msgstr "I2P代理"
#: strings/Strings.java:38
msgid "ircProxy"
msgstr "IRC代理"
msgstr "I2P聊天室"
#: strings/Strings.java:40
msgid "I2PSnark"

View File

@@ -286,8 +286,10 @@
<copy file="history.txt" todir="pkg-temp/" />
<mkdir dir="pkg-temp/scripts" />
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
<!-- test classes aren't in the jars anymore
<copy file="core/perl/i2pbench.sh" todir="pkg-temp/scripts/" />
<copy file="core/perl/i2ptest.sh" todir="pkg-temp/scripts/" />
-->
<!-- polecat: please put your modified toolbar.html in installer/resources/toolbar.html
and uncomment the following -->
<!-- <copy file="installer/resources/toolbar.html" todir="pkg-temp/docs/" /> -->
@@ -333,7 +335,7 @@
-->
<!-- Since the logo moved, we have to update the error pages -->
<copy todir="pkg-temp/docs/" >
<fileset dir="installer/resources/" includes="*-header.ht" />
<fileset dir="installer/resources/proxy" />
</copy>
<!-- make a "classic" theme -->
<copy todir="pkg-temp/docs/themes/console/classic/" >
@@ -372,7 +374,7 @@
<target name="prepconsoleDocs" depends="prepgeoupdate">
<copy todir="pkg-temp/docs/" >
<fileset dir="." includes="readme*.html" />
<fileset dir="installer/resources/" includes="*-header.ht" />
<fileset dir="installer/resources/proxy" />
</copy>
</target>
<target name="consoleDocs" depends="deletepkg-temp, prepconsoleDocs">

View File

@@ -196,9 +196,14 @@ public class FileUtil {
* Read in the last few lines of a (newline delimited) textfile, or null if
* the file doesn't exist.
*
* Warning - this inefficiently allocates a StringBuilder of size maxNumLines*80,
* so don't make it too big.
* Warning - converts \r\n to \n
*
* @param startAtBeginning if true, read the first maxNumLines, otherwise read
* the last maxNumLines
* @param maxNumLines max number of lines (or -1 for unlimited)
* @return string or null; does not throw IOException.
*
*/
public static String readTextFile(String filename, int maxNumLines, boolean startAtBeginning) {

View File

@@ -1,3 +1,26 @@
2009-11-16 zzz
* addressbook: Move class to net.i2p.addressbook
* build: Take two test scripts out of the installer
* i2psnark: Bye TPB
* Shitlist: Fix bug from two checkins ago, all were forever
2009-11-14 zzz
* HTTP Proxy:
- Add support for error page translations
- Add support for external pages for all errors
- Fix lack of \r in error page headers
- HTML transitional fixes
- Cleanups
* UDP PeerTestManager: Throw in some synchronization to
try to fix stuck tests
2009-11-11 zzz
* Console: Some colon cleansing
* FloodfillPeerSelector: Adjustments
* Shitlist: Move HTML renderer to router console,
add cause parameter for ease of translation,
tag all causes
2009-11-11 zzz
* Addressbook, NamingService: Allow 516 byte dests
that end with AA but not AAAA, so we can permit

View File

@@ -319,5 +319,3 @@ bob.i2p=5uAI6ENnNP8acDkAtYqBjLa-gFqM~uERNZdJBKtRwUvDkuXvIM66pYfYL3-ugTmoR-SIveDl
sponge.i2p=VG4Bd~q1RA3BdoF3z5fSR7p0xe1CTVgDMWVGyFchA9Wm2iXUkIR35G45XE31Uc9~IOt-ktNLL2~TYQZ13Vl8udosngDn8RJG1NtVASH4khsbgkkoFLWd6UuvuOjQKBFKjaEPJgxOzh0kxolRPPNHhFuuAGzNLKvz~LI2MTf0P6nwmRg1lBoRIUpSVocEHY4X306nT2VtY07FixbJcPCU~EeRin24yNoiZop-C3Wi1SGwJJK-NS7mnkNzd8ngDJXDJtR-wLP1vNyyBY6NySgqPiIhENHoVeXd5krlR42HORCxEDb4jhoqlbyJq-PrhTJ5HdH4-~gEq09B~~NIHzy7X02XgmBXhTYRtl6HbLMXs6SI5fq9OFgVp5YZWYUklJjMDI7jOrGrEZGSHhnJK9kT6D3CqVIM0cYEhe4ttmTegbZvC~J6DrRTIAX422qRQJBPsTUnv4iFyuJE-8SodP6ikTjRH21Qx73SxqOvmrOiu7Bsp0lvVDa84aoaYLdiGv87AAAA
docs.i2p2.i2p=BhSHFwXW7zGTLRVTRuTfgxWC1PxKGDyY2OYpS0IrDnYhQklWVFxHz4xVpw8UXo8LTFXAnAjknrcYdLt6DfHcO-ZkFPo5UbOIfywSsHoet4J6BQ1MOt1MLTAejks4Rkj3~sfK2fJHHvHYTjm1v5~f8c13ZH5fPfQ3A71RRCyiYaeO5-VxC6rqvW~z0dNO~-jakjwD7tHtzQL2vQTqarYT859yUiHmLJ~yw5jXfxNBhlxIxaXg0Nat9S5N2W4Eqemy-UYtSGOM4IUGKoM902JxhVpz~O1~iB5H211E3x-o8dKTt9Yz2G5Qcp1kRB0NCO2Noivsxjnfv~64zoUVbPepyJFQKenRtX844HgOESNcUp~FoVzI~QJne5irJDMLK1dNsua3L1kz0MA-2Aev8byWe4TIXeZCuDpYi4bRK6OPKDETwJG8edw7CFtsQaFI-2wGMFu8GDH7pUL8~1qyDjjFv5c~q1MFhty9q8LRUGHHgWP47u9n8OX4zcS4P1~5z2M3AAAA
paste.i2p2.i2p=PbHXL5PXan7siJiFcUAV~VC0JCLxgnoOnZFjyvJ0dbYlQ3fi1K6SD961pjQ51OSeTnbe5iGRzbY2X0~pG4k~hexau4NizxprAdgdiC-4J3-xpVRjZ4IxuMoDXp-V8Nhv8pLCQcxiEXbWft2v7zLvkp2y6uqH7kab8FXL~z568rMMH0DDs8imwAawasyGtLLo77X8n-C0K~7orcWDVZicWABJ-zky1Zlllx~Y~S8RHWyN4dueP6wkH484b81xNbbt3P-HzE3TcKAvUcSV1Bq4J5UNafQYU7DhV7roUtw4HuJYoxiXnlXVeC-uTCGF~bPrjrB-~Yn0KyObmXs5yvAcKHIS2tgmlsP9nahyn1ZOrlZc0L3DEsv4rkfQyzHVBxcCzMUOchWehE09GLy3bviWZ43lB7kU8kRaja7G4xLrD-CXNXq6q7WNYXrqX7EmtsvCo8VDcFn2ODyLb3eyDe~CkO7ES7mv3u8jJxJRQEcjj71pvu7bMzSMh-xN08X6vx9AAAAA
thepiratebay.i2p=9Sng0F-cAyGgPyr1xenqY87Uf2AG~PlTXzUJRQnr7gpYFPUfRlH3OfWOVFat67jUl37ZzWBOSYC7-6YqFzPQV5u~DrTGaoImfa7BsRbnBlPXbSNIaP59C6Vp1RCbhtTpxQ4PvLLn9xzUKWoPkrQ222TCSxPR6-j2ChSuuCIA7bP7EP75BobL6n9hMmekzB4FbmBhC64Kri72Uhv~rMDdMZaDD9cD9-BgnZkyrI5jRtSuOUVnTexKMQ0UiYHanSDlBvNwLRMGdb0AsckOdXHrleKrwPnW4YTp0q89dPGP6fad4sVxgvxLHF6NuoWXGbnD0sYuv5qkegjBzioHOjxI~n52ObdeELVhs~peeiXpRavZcwlu1HzwNKfU8lJrpnLSoQsCuqd4OBFMmjvo3HhovLsTeUAo1W2O1F8gcPeOj3tD0ihInncMIbEUTI7kdbkBTsoMY8~73jKgQYC0c~hiEUb1tG4NLcfdxgAlWF5q9cJPDHFh9jtzDvq63OntBQ5OAAAA
tracker.thepiratebay.i2p=4svjpPox0vc527neBdWyfLiVulEeHtzQrC6IDDB2~rPwnZYWm3xsyrDYTa9gu5~1QrFitr5RMCcj34tzZZCKIg~INFNhi7Zk7UwsOCHtedS0RpRjDi2O3q~T~k8D4P39Rz0So91D624lofDV48itdkX8B3dNUHE0Qq5hCGjb2UVxLUhKh8DYOUAqYPoLaF1RpQx5DT~r-Hf57vA9bW3Q31xYH~Ys6AxCZ8~EmMqdgm0ZMQ57oWldHgkSbtQsoiBn2igJ24GDUDUvBsRVLt7He1nKg1ei2JvqQajKN31cQeS5fjqiGdUTkXjc1FftKB8HC9CbnsMJjPEFT6gvvtSpxULvSQGSJyD6OIzebXvQIYANAapEk1VP1OSIJlteOIwGDXkGj9ZyLpT7~RpUpk92v9L53Zjof~WjJmGqqWWsL~yypl0~nMUw5MLaKv5AJywDnFIJDR-GlkQQj5fECeefge30Y92CHwxgImwj3v7~DwXuU9d5u6KyzJSuByOGRvwVAAAA

View File

@@ -8,32 +8,32 @@
# fire up the web console
clientApp.0.args=7657 ::1,127.0.0.1 ./webapps/
clientApp.0.main=net.i2p.router.web.RouterConsoleRunner
clientApp.0.name=Web console
clientApp.0.name=I2P Router Console
clientApp.0.onBoot=true
clientApp.0.startOnLoad=true
# SAM bridge
clientApp.1.main=net.i2p.sam.SAMBridge
clientApp.1.name=SAM application bridge
clientApp.1.name=SAM Application Bridge
clientApp.1.args=sam.keys 127.0.0.1 7656 i2cp.tcp.host=127.0.0.1 i2cp.tcp.port=7654
clientApp.1.startOnLoad=false
# poke the i2ptunnels defined in i2ptunnel.config
clientApp.2.main=net.i2p.i2ptunnel.TunnelControllerGroup
clientApp.2.name=Application tunnels
clientApp.2.name=Application Tunnels
clientApp.2.args=i2ptunnel.config
clientApp.2.startOnLoad=true
# run our own eepsite with a seperate jetty instance
clientApp.3.main=org.mortbay.jetty.Server
clientApp.3.name=My eepsite web server
clientApp.3.name=Local Anonymous I2P Webserver
clientApp.3.args="eepsite/jetty.xml"
clientApp.3.delay=30
clientApp.3.startOnLoad=true
# load a browser pointing at the web console whenever we start up
clientApp.4.main=net.i2p.apps.systray.UrlLauncher
clientApp.4.name=Browser launch at startup
clientApp.4.name=Launch web browser and load I2P Router Console at startup
clientApp.4.args=http://127.0.0.1:7657/index.jsp
clientApp.4.delay=15
clientApp.4.startOnLoad=true

View File

@@ -0,0 +1,2 @@
@echo off
java -cp lib/i2p.jar net.i2p.util.EepGet %1 %2 %3 %4 %5

View File

@@ -0,0 +1,118 @@
<html>
<head>
<title>I2P serveur web anonyme | Bienvenue à votre eepsite</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="shortcut icon" href="favicon.ico" />
<link rel="stylesheet" type="text/css" href="lib/eepsite.css" />
</head>
<body>
<div class="fairylights">
<div class="main">
<h1>Serveur web anonyme I2P</h1>
<div class="langbar">
<!-- Most of these languages listed here are yet to be translated -->
<a href="index.html"><img src="lib/us.png" title="English" alt="English"></a>
<a href="index_na.html"><img src="lib/cn.png" title="Chinese" alt="Chinese"></a>
<a href="index_de.html"><img src="lib/de.png" title="Deutsch" alt="Deutsch"></a>
<a href="index_fr.html"><img src="lib/fr.png" title="Français" alt="Français"></a>
<a href="index_na.html"><img src="lib/nl.png" title="Nederlands" alt="Nederlands"></a>
<a href="index_na.html"><img src="lib/se.png" title="Svenska" alt="Svenska"></a>
</div>
<h2>Un mini guide pour faire un serveur web anonyme utilisant I2P</h2>
<p>C'est votre eepsite qui fonctionne sur votre propre serveur web anonyme I2P. Afin de le mettre en route, simplement éditer les fichiers sous ./eepsite/docroot/
et ils seront accessibles aux autres internautes dès que vous avez suivi les instructions suivantes.
Avec I2P, on accède aux eepsites en utilisant une 'clé', qui est réprésentée par une chaîne de caractères de base64.
(Cette 'clé' est un analogue d'une adresse IP et elle est montrée sur l'eepsite's I2PTunnel
<a href="http://127.0.0.1:7657/i2ptunnel/edit.jsp?tunnel=3">Page de configuration</a>).
Les instructions ci dessous expliquent comment associer un nom de site tel que "monsite.i2p" à votre clé et ensuite comment lancer votre eepsite.</p>
<p>Vous pouvez accéder votre eepsite localement via
<a href="http://127.0.0.1:7658/">http://127.0.0.1:7658/</a>.
</p>
<h2>Comment configurer et annoncer votre eepsite</h2>
Votre eepsite ne fonctionne pas par défaut.
Après que vous l'ayez lancé, il sera difficile à trouver pour les internautes, car ils n'ont pas le nom de votre site et votre longue clé base64.
Vous pourriez simplement distribuer cette très longue clé manuellement. Mais, heureusement il y un carnet d'adresse I2P
et plusieurs manières faciles de faire connaitre votre eepsite. Voici les instructions détaillées :
<ul>
<li>Choissisez un nom pour votre eepsite (<i>quelquechose</i>.i2p). Tout en minuscule.
D'abord, vérifiez dans le carnet d'adresse de votre router
<a href="http://127.0.0.1:7657/susidns/addressbook.jsp?book=router&filter=none">ici</a>,
ou dans le fichier i2p/hosts.txt pour voir si le nom a déjà été pris.
Entrez le nouveau nom de votre eepsite sur le
<a href="http://127.0.0.1:7657/i2ptunnel/edit.jsp?tunnel=3">eepsite i2ptunnel page de configuration</a>
où c'est marqué "Website name". Cela remplacera le nom défaut "mysite.i2p".
En outre, cochez "Auto Start". Votre eepsite démarrera automatiquement chaque fois que vous lancez votre router I2P.
Soyez certain de cliquer sur "Save".
<li>Cliquez sur le bouton marqué "start"
<a href="http://127.0.0.1:7657/i2ptunnel/index.jsp">main i2ptunnel page de configuration</a> pour lancer votre eepsite.
Maintenant vous devriez voir "eepsite" indiqué sous "Local Destinations" sur le côté gauche de votre
<a href="http://127.0.0.1:7657/index.jsp">I2P Router Console</a>.
Votre eepsite fonctionne.
<li>Surlignez la clé de "Local destination" en entier sur le
<a href="http://127.0.0.1:7657/i2ptunnel/edit.jsp?tunnel=3">eepsite i2ptunnel page de configuration</a>
et copiez-la pour la coller plus tard.
Soyez certain de copier la clé entière - elle a plus de 500 octets et elle se termine avec "AAAA".
<li>Entrez le nom et coller la clé de destination dans votre
<a href="http://127.0.0.1:7657/susidns/addressbook.jsp?book=master">master address book</a>.
Cliquez sur "Add" pour ajouter la destination à votre carnet d'adresse.
<li>Dans votre explorateur internet, entrez le nom de votre eepsite (<i>quelquechose</i>.i2p) et vous devriez vous retrouver sur cette page.
Avec un peu de chance - si vous êtes arrivé ici, c'est que ça a marché !
<li>Avant de parler à tout le monde de votre nouvel eepsite, vous devriez ajouter du contenu.
Allez à i2p/eepsite/docroot et remplacez la page index.html avec votre propre page. Les dossiers virtuels fonctionnent, donc vous pouvez héberger un sous-dossier sans explicitement ajouter des liens vers des fichiers. Si vous avez besoin d'un gabarit pour un site de base, n'hésitez pas à utiliser et à changer <a href="pagetemplate.html">cette page</a> et <a href="lib/">contenu</a>!
</ul>
<h2>Enregistrer votre propre .I2P domaine</h2><ul>
<li>Maintenant il faut ajouter votre eepsite au carnet d'adresse hébergé par un site
tel que <a href="http://stats.i2p/">stats.i2p</a>.
C'est-à-dire, vous devez entrer
votre nom d'eepsite et sa clé dans l'interface web d'un ou plus de ces sites.
Voici <a href="http://stats.i2p/i2p/addkey.html">le formulaire pour l'entrée d'une clé à stats.i2p.</a>
Encore, votre clé est la "Local destination", disponible en entier ici
<a href="http://127.0.0.1:7657/i2ptunnel/edit.jsp?tunnel=3">eepsite i2ptunnel page de configuration.</a>
Prenez toute la clé, souvenez qu'elle se termine en "AAAA".
N'oubliez pas de cliquer sur "add a key".
Vérifiez que le site montre que la clé a été correctement ajoutée.
Comme beaucoup de routers se mettent à jour regulièrement à partir de ces sites, en quelques heures d'autres internautes seront capables de trouver et d'accéder à votre eepsite simplement en tapant <i>quelquechose</i>.i2p dans leurs explorateurs internet.
</ul><h2>Comment ajouter des abonnements au carnet d'adresse.</h2><ul>
<li>En parlant de mises à jour de carnet d'adresse, il serait prudent d'ajouter quelques carnets d'adresses de plus
à votre <a href="http://127.0.0.1:7657/susidns/subscriptions.jsp">subscription list.</a> Allez sur votre page d'abonnements et ajoutez quelques listes directement ci dessous afin que votre liste d'hôtes soit mise à jour automatiquement :<ul>
<li><a href="http://tino.i2p/hosts.txt">http://tino.i2p/hosts.txt</a>
<li><a href="http://stats.i2p/cgi-bin/newhosts.txt">http://stats.i2p/cgi-bin/newhosts.txt</a>
<li><a href="http://i2host.i2p/cgi-bin/i2hostetag">http://i2host.i2p/cgi-bin/i2hostetag</a></ul>
<li>Si vous êtes pressé et que vous ne pouvez pas attendre quelques heures, vous pouvez demander aux autres d'utiliser un "jump" (service d'aide de ré-direction d'adresse).
Cela marchera en quelques minutes après que vous ayez entré votre clé dans le carnet d'adresse sur le même site.
Testez-le vous-même en entrant :
http://stats.i2p/cgi-bin/jump.cgi?a=<i>quelquechose</i>.i2p
ou http://i2host.i2p/cgi-bin/i2hostjump?<i>quelquechose</i>.i2p
dans votre explorateur internet.
Dès que cela fonctionne, vous pouvez en parler aux autres.
<li>Certains personnes vérifient les nouveaux eepsites sur les listes tels que
<a href="http://inproxy.tino.i2p/status.php">inproxy.tino.i2p/status.php</a>. Vous pouvez commencer à avoir
quelques visiteurs. Il y a beaucoup des manières d'informers les autres. Voici quelques idées :
<ul>
<li>Poster un message sur le <a href="http://forum.i2p/viewforum.php?f=16">Eepsite announce forum</a>
sur <a href="http://forum.i2p/">forum.i2p</a>.
<li>Parlez aux autres sur les canaux #i2p ou #i2p-chat sur IRC.
<li>Mettez-le dans un post <a href="http://syndie.i2p2.de/">le nouveau Syndie</a>.
<li>Placez-le sur <a href="http://ugha.i2p/EepsiteIndex">Ugha's Eepsite Index Wiki</a>
</ul>
A noter que certains sites recommandent de coller la clé de destination directement. Vous pouvez si vous voulez,
mais si vous avez déjà réussi à poster la clé sur un service de "add key" (type stats.i2p), et attendu 24 heures pour que le carnet d'adresse
se propage aux autres, cela ne doit pas être nécessaire. </ul>
<h2>Plus d'assistance</h2><ul>
<li>Si vous avez plus de questions, trouvez du soutien à ces endroits :
<ul>
<li>Notre canal IRC de soutien : <ul><li><a href="irc://irc.freenode.net/i2p">#i2p sur Freenode</a>
<li>En anonymat via votre <a href="irc://127.0.0.1:6668/i2p">I2P IRC tunnel</a>.</ul>
<li><a href="http://forum.i2p/viewforum.php?f=10">The technical problems section</a> sur
<a href="http://forum.i2p/">forum.i2p</a>.</ul>
</ul><div class="notify">
<b>Note:</b> This page, the website and the console all need translating into YOUR language if it's not already been done or in progress. Please consider helping the project grow by <a href="http://www.i2p2.i2p/getinvolved.html">volunteering your time</a> to translate. Contact the project via the IRC channel listed above. Thanks in advance!</div>
<hr><div class="footnote">
Document last edited: November 2009.</div>
</div></div>
</body>
</html>

View File

@@ -1,17 +1,17 @@
HTTP/1.1 409 Conflict
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Destination key conflict</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" />
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"/></a><hr>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>
@@ -20,9 +20,9 @@ The addresshelper link you followed specifies a different destination key
than a host entry in your host database.
Someone could be trying to impersonate another eepsite,
or people have given two eepsites identical names.
<P/>
<p>
You can resolve the conflict by considering which key you trust,
and either discarding the addresshelper link,
discarding the host entry from your host database,
or naming one of them differently.
<P/>
<p>

View File

@@ -0,0 +1,26 @@
HTTP/1.1 409 Conflict
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 目标密钥冲突</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 目标密钥冲突</h3>
您所打开的地址跳转链接中所指定的目标密钥
与您I2P路由地址簿中对应匿名站点的密钥地址不同。
可能有人在伪造匿名地址或有人为自己的匿名网站设定了相同的域名。
<p>
您需要选择并信任一个目标密钥,才能解决这一冲突,
您可以通过直接输入这个.i2p网址利用地址簿中的目标密钥访问
或在地址簿删除对应的域名或为其改名来信任当前的跳转链接。
<p>

View File

@@ -0,0 +1,20 @@
HTTP/1.1 403 Request Denied
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Request Denied</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>
<h3>Warning: Request Denied</h3>
You attempted to connect to a non-I2P website or location.
</div>

View File

@@ -0,0 +1,20 @@
HTTP/1.1 403 Request Denied
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 请求被拒绝</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 请求被拒绝</h3>
您正试图连接非I2P内的网站或地址。
</div>

View File

@@ -1,17 +1,17 @@
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Eepsite not reachable</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" />
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"/></a><hr>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/index.jsp">Addressbook</a>
</div>
<div class=warning id=warning>

View File

@@ -0,0 +1,24 @@
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 匿名站点不可达</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/index.jsp">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 匿名站点不可达</h3>
无法打开此匿名站点。
此匿名站点可能不在线(时区差异、对方路由器繁忙等),
或您的路由器在网络中的整合度不佳。
你可以尝试
<a href="javascript: window.location.reload()">重试</a>。
<hr><b>找不到一下目标:</b><BR><BR>

View File

@@ -1,17 +1,17 @@
HTTP/1.1 400 Destination Not Found
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Invalid eepsite destination</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" />
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"/></a><hr>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>

View File

@@ -0,0 +1,23 @@
HTTP/1.1 400 Destination Not Found
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 站点目标无效</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">配置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 目标无效</h3>
匿名站点所对应的目标密钥无效因而无法访问。
或许您复制的Base64字符串有误或者您所点击的跳转链接有问题。
也许对方的 I2P 主机目前不在线。您可以选择
<a href="javascript: window.location.reload()">重试</a>.
<hr><b>找不到以下目标:</b><BR><BR>

View File

@@ -1,17 +1,17 @@
HTTP/1.1 404 Domain Not Found
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Eepsite unknown</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" />
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"/></a><hr>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/index.jsp">Addressbook</a>
</div>
<div class=warning id=warning>

View File

@@ -0,0 +1,26 @@
HTTP/1.1 404 Domain Not Found
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 未知站点</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/index.jsp">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 地址簿中的找不到此站点</h3>
您所访问的匿名站点(的目标密钥)不存在于您路由器的地址簿中。
检查链接或寻找对应的BASE64地址.
如果您知道对应的BASE64地址请通过
<a href="http://127.0.0.1:7657/susidns/addressbook.jsp?book=master">SusiDNS</a>
将其复制入您的 userhosts.txt 中,直接使用 BASE64 地址访问,或使用下面的跳转链接。<br><br>
经常见到此页面? 请参见 <a href="http://www.i2p2.i2p/faq.html#subscriptions"> FAQ 常见问答</a>
中的 <a href="http://127.0.0.1:7657/susidns/config.jsp">添加更多订阅到地址簿中</a>。<hr>
<b>找不到以下目标:</b><BR><BR>

View File

@@ -1,17 +1,17 @@
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=iso-8859-1
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Outproxy Not Found</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" />
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"/></a><hr>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>

View File

@@ -0,0 +1,28 @@
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 未找到出口代理</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: I2P 未找到代理</h3>
未找到 WWW 出口代理.
它可能以下线, 或网络拥堵,或你的路由器与网络
尚未良好整合。您可以
<a href="javascript: parent.window.location.reload()">重试</a>
这将从所设置的所有出口代理中随机选择一个代理做出口。
<a href="http://127.0.0.1:7657/i2ptunnel/index.jsp">点此</a>
(如果您设置了超过1个的出口代理地址)。
如果您总是遇到此错误,你也许需要修改出口代理列表了
<a href="http://127.0.0.1:7657/i2ptunnel/edit.jsp?tunnel=0">点此</a>.
<hr><b>找不到以下目标:</b><BR><BR>

View File

@@ -0,0 +1,23 @@
HTTP/1.1 403 Access Denied
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Request Denied</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<!-----------------------------
Let's not infinite loop here....
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
------------------------------>
<div class=warning id=warning>
<h3>Warning: Localhost Access</h3>
Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.
</div>

View File

@@ -0,0 +1,23 @@
HTTP/1.1 403 Access Denied
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 请求被拒绝</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<!-----------------------------
Let's not infinite loop here....
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
------------------------------>
<div class=warning id=warning>
<h3>警告: 企图访问 Localhost </h3>
您的浏览器配置有误请不要使I2P代理访问路由器控制台或其他本地(Localhost)地址。
</div>

View File

@@ -0,0 +1,21 @@
HTTP/1.1 503 Service Unavailable
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: No outproxy configured</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>
<h3>Warning: No Outproxy Configured</h3>
Your request was for a site outside of I2P, but you have no
HTTP outproxy configured. Please configure an outproxy in I2PTunnel.
</div>

View File

@@ -0,0 +1,21 @@
HTTP/1.1 503 Service Unavailable
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 没有设置出口代理</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 没有设置出口代理</h3>
你请求的网站在I2P网络外但您的I2P没有设置HTTP出口代理
请在 I2P Tunnel(本地目标) 中设置HTTP代理隧道.
</div>

View File

@@ -0,0 +1,21 @@
HTTP/1.1 403 Bad Protocol
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P Warning: Non-HTTP Protocol</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">Configuration</a> <a href="http://127.0.0.1:7657/help.jsp">Help</a> <a href="http://127.0.0.1:7657/susidns/">Addressbook</a>
</div>
<div class=warning id=warning>
<h3>Warning: Non-HTTP Protocol</h3>
The request uses a bad protocol.
The I2P HTTP Proxy supports http:// requests ONLY. Other protocols such as https:// and ftp:// are not allowed.
</div>

View File

@@ -0,0 +1,21 @@
HTTP/1.1 403 Bad Protocol
Content-Type: text/html; charset=UTF-8
Cache-control: no-cache
Connection: close
Proxy-Connection: close
<html><head>
<title>I2P 警告: 非HTTP请求</title>
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico" >
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css" >
</head>
<body>
<div class=logo>
<a href="http://127.0.0.1:7657/index.jsp" title="Router Console"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="I2P Router Console" border="0"></a><hr>
<a href="http://127.0.0.1:7657/config.jsp">设置</a> <a href="http://127.0.0.1:7657/help.jsp">帮助</a> <a href="http://127.0.0.1:7657/susidns/">地址簿</a>
</div>
<div class=warning id=warning>
<h3>警告: 非HTTP请求</h3>
请求使用了错误的协议
I2P HTTP 代理【只】支持 http:// 请求,不支持其他协议例如 https:// and ftp:// 。
</div>

View File

@@ -1,5 +1,5 @@
/* I2P Theme: Midnight */
/* I2P Description: Minimalist Midnight Blue, based on Classic theme.*/
/* Description: Minimalist Midnight Blue, based on Classic theme.*/
/* Author: Dr|Z3d */
@@ -107,29 +107,38 @@ div.warning hr {
}
div.warning h3 {
border: 0;
border-bottom: 1px solid #fb7;
padding-bottom: 10px;
padding-left: 0;
font-variant: small-caps;
text-transform: capitalize;
font-size: 12.5pt;
}
/* console error messages */
div.sorry {
padding: 20px;
padding: 20px 20px 20px 70px;
background: #003;
margin: -2px 1px 0 200px;
margin: 0 5px 0 200px;
border: 1px solid #99f;
border-top: 0;
text-align: justify;
-moz-box-shadow: inset 0px 0px 0px 1px #d00;
word-wrap: break-word;
font-weight: bold;
color: #eef;
background-image: url("../images/errortriangle.png");
background-position: 15px center;
background-repeat: no-repeat;
}
div.sorry hr {
color: #eef;
background: #eef;
color: #99f;
background: #99f;
height: 1px;
border: 1px solid #99f;
border: 0;
margin: 10px 0;
}
@@ -153,7 +162,7 @@ div.routersummary {
width: 190px;
color: inherit;
margin: 0;
padding: 10px 1px 7px 1px;
padding: 10px 1px 5px 1px;
text-align: center !important;
border: 1px solid #99f;
font-size: 9pt;
@@ -174,6 +183,10 @@ div.routersummary hr {
margin: 8px -1px 7px -1px;
}
div.routersummary hr:last-child {
display: none;
}
div.routersummary h3 {
border: 0px solid #f00;
font-size: 9.5pt;
@@ -251,6 +264,11 @@ div.routersummary form {
margin-bottom: -8px !important;
}
div.routersummary form:last-child {
padding-top: 3px !important;
margin-bottom: -10px !important;
}
div.refresh {
margin-top: 10px !important;
margin-bottom: 10px !important;
@@ -288,7 +306,6 @@ div.main {
text-align: left;
color: #eef;
min-width: 570px;
-moz-box-shadow: inset 0px 0px 2px 0px #005;
}
div.main ul {
@@ -321,6 +338,11 @@ div.main textarea {
div.main h2 {
margin-top: 20px;
margin-bottom: -5px;
padding-bottom: 10px !important;
}
table h2 {
padding-bottom: 15px;
}
div.welcome {
@@ -495,33 +517,38 @@ h1 {
text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.4);
text-align: center;
border: 1px solid #99f;
padding: 13px 10px 12px 10px;
padding: 15px 10px 15px 10px;
margin: 5px 5px 0 200px;
line-height: 93%;
text-transform: uppercase;
letter-spacing: 0.3em;
background: #000008;
min-width: 600px;
-moz-box-shadow: inset 0px 0px 4px 2px #00000A;
line-height: 100%;
color: #fff;
}
h2 {
font-size: 14pt;
font-size: 13pt;
padding: 10px 10px 10px 10px;
border: 1px solid #77f;
border-top: 1px solid #99f;
border-left: 1px solid #99f;
letter-spacing: 0.04em;
background: #00000A;
background: #000008;
background-image: url("images/h2bg.png");
background-repeat: no-repeat;
background-position: right center;
font-variant: small-caps;
text-transform: capitalize;
letter-spacing: 0.07em;
}
h3 {
font-size: 12pt;
padding: 0 0px 5px 0px;
border-bottom: 1px solid #99f;
border-top: 0px solid #99f;
font-size: 11pt;
padding: 5px 10px;
border: 1px solid #99f;
border-right: 1px solid #77f;
border-bottom: 1px solid #77f;
letter-spacing: 0.04em;
margin-bottom: 10px;
font-weight: bold !important;
@@ -600,11 +627,11 @@ hr {
font-size: 8pt;
color: #eef;
text-align: center;
margin: -7px 0 7px 0;
margin: -5px 0 5px 0;
background: #000;
border: 1px solid #99f;
border-top: 0;
padding: 4px 0 2px 0;
padding: 3px 0;
}
div.joblog {
@@ -722,7 +749,7 @@ p {
padding-bottom: -2px;
text-align: justify;
margin-top: 5px !important;
margin-left:5px !important;
margin-left: 5px !important;
}
.links li {
@@ -786,33 +813,30 @@ tt {
}
div.graphspanel {
padding: 5px 0px 20px 0px;
padding: 10px 0px 20px 0px;
margin: -16px -16px -11px -16px;
background: #000012;
-moz-border-radius: 4px;
-khtml-border-radius: 4px;
border-radius: 4px;
border: 1px solid #99f;
-moz-box-shadow: inset 0px 0px 1px 0px #002;
text-align: center !important;
}
div.graphspanel img {
border: 1px solid #77f;
border: 1px solid #99f;
padding: 2px;
margin: 6px;
background: #ccf;
-moz-box-shadow: inset 0px 0px 0px 0px #002;
background: #00000A;
opacity: 0.9;
}
div.graphspanel img:hover {
border: 1px solid #003;
border: 1px solid #f60;
padding: 2px;
margin: 6px;
text-align: center !important;
background: #eef;
-moz-box-shadow: inset 0px 0px 2px 1px #f60;
background: #002;
opacity: 1;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -111,11 +111,13 @@ public class Blocklist {
}
for (Iterator iter = _peerBlocklist.keySet().iterator(); iter.hasNext(); ) {
Hash peer = (Hash) iter.next();
String reason = "Banned by router hash";
String reason;
String comment = (String) _peerBlocklist.get(peer);
if (comment != null)
reason = reason + ": " + comment;
_context.shitlist().shitlistRouterForever(peer, reason);
reason = _x("Banned by router hash: {0}");
else
reason = _x("Banned by router hash");
_context.shitlist().shitlistRouterForever(peer, reason, comment);
}
_peerBlocklist = null;
@@ -659,7 +661,7 @@ public class Blocklist {
*/
public void shitlist(Hash peer) {
// Temporary reason, until the job finishes
_context.shitlist().shitlistRouterForever(peer, "IP Banned");
_context.shitlist().shitlistRouterForever(peer, _x("IP banned"));
if (! "true".equals( _context.getProperty(PROP_BLOCKLIST_DETAIL, "true")))
return;
boolean shouldRunJob;
@@ -729,16 +731,17 @@ public class Blocklist {
}
if (match(ipint, toEntry(e.ip1, e.ip2))) {
try { in.close(); } catch (IOException ioe) {}
String reason = "IP ";
for (int i = 0; i < 4; i++) {
reason = reason + (ip[i] & 0xff);
if (i != 3)
reason = reason + '.';
}
reason = reason + " banned by " + BLOCKLIST_FILE_DEFAULT + " entry \"" + buf + "\"";
String reason = _x("IP banned by blocklist.txt entry {0}");
// only one translate parameter for now
//for (int i = 0; i < 4; i++) {
// reason = reason + (ip[i] & 0xff);
// if (i != 3)
// reason = reason + '.';
//}
//reason = reason + " banned by " + BLOCKLIST_FILE_DEFAULT + " entry \"" + buf + "\"";
if (_log.shouldLog(Log.WARN))
_log.warn("Shitlisting " + peer + " " + reason);
_context.shitlist().shitlistRouterForever(peer, reason);
_context.shitlist().shitlistRouterForever(peer, reason, buf.toString());
return;
}
buf.setLength(0);
@@ -791,6 +794,16 @@ public class Blocklist {
out.flush();
}
/**
* Mark a string for extraction by xgettext and translation.
* Use this only in static initializers.
* It does not translate!
* @return s
*/
private static final String _x(String s) {
return s;
}
public static void main(String args[]) {
Blocklist b = new Blocklist();
if ( (args != null) && (args.length == 1) )

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 15;
public final static long BUILD = 18;
/** for example "-test" */
public final static String EXTRA = "";
public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;

View File

@@ -12,12 +12,11 @@ import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
@@ -36,13 +35,15 @@ public class Shitlist {
private RouterContext _context;
private Map<Hash, Entry> _entries;
private static class Entry {
public static class Entry {
/** when it should expire, per the i2p clock */
long expireOn;
public long expireOn;
/** why they were shitlisted */
String cause;
public String cause;
/** separate code so cause can contain {0} for translation */
public String causeCode;
/** what transports they were shitlisted for (String), or null for all transports */
Set<String> transports;
public Set<String> transports;
}
public final static long SHITLIST_DURATION_MS = 20*60*1000;
@@ -95,17 +96,32 @@ public class Shitlist {
return _entries.size();
}
/** for ShitlistRenderer in router console */
public Map<Hash, Entry> getEntries() {
return new HashMap<Hash, Entry>(_entries);
}
public boolean shitlistRouter(Hash peer) {
return shitlistRouter(peer, null);
}
public boolean shitlistRouter(Hash peer, String reason) { return shitlistRouter(peer, reason, null); }
/** ick have to put the reasonCode in the front to avoid ambiguity */
public boolean shitlistRouter(String reasonCode, Hash peer, String reason) {
return shitlistRouter(peer, reason, reasonCode, null, false);
}
public boolean shitlistRouter(Hash peer, String reason, String transport) {
return shitlistRouter(peer, reason, transport, false);
}
public boolean shitlistRouterForever(Hash peer, String reason) {
return shitlistRouter(peer, reason, null, true);
}
public boolean shitlistRouterForever(Hash peer, String reason, String reasonCode) {
return shitlistRouter(peer, reason, reasonCode, null, true);
}
public boolean shitlistRouter(Hash peer, String reason, String transport, boolean forever) {
return shitlistRouter(peer, reason, null, transport, forever);
}
private boolean shitlistRouter(Hash peer, String reason, String reasonCode, String transport, boolean forever) {
if (peer == null) {
_log.error("wtf, why did we try to shitlist null?", new Exception("shitfaced"));
return false;
@@ -137,6 +153,7 @@ public class Shitlist {
e.expireOn = _context.clock().now() + period;
}
e.cause = reason;
e.causeCode = reasonCode;
e.transports = null;
if (transport != null) {
e.transports = new ConcurrentHashSet(1);
@@ -150,6 +167,7 @@ public class Shitlist {
if (old.expireOn > e.expireOn) {
e.expireOn = old.expireOn;
e.cause = old.cause;
e.causeCode = old.causeCode;
}
if (e.transports != null) {
if (old.transports != null)
@@ -157,6 +175,7 @@ public class Shitlist {
else {
e.transports = null;
e.cause = reason;
e.causeCode = reasonCode;
}
}
}
@@ -245,44 +264,7 @@ public class Shitlist {
return entry != null && entry.expireOn > _context.clock().now() + SHITLIST_DURATION_MAX;
}
class HashComparator implements Comparator {
public int compare(Object l, Object r) {
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
}
}
/** @deprecated moved to router console */
public void renderStatusHTML(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(1024);
// move to the jsp
//buf.append("<h2>Banned Peers</h2>");
Map<Hash, Entry> entries = new TreeMap(new HashComparator());
entries.putAll(_entries);
buf.append("<ul>");
for (Map.Entry<Hash, Entry> e : entries.entrySet()) {
Hash key = e.getKey();
Entry entry = e.getValue();
buf.append("<li>").append(_context.commSystem().renderPeerHTML(key));
long expires = entry.expireOn-_context.clock().now();
if (expires < 5l*24*60*60*1000)
buf.append(" Temporary ban expiring in ");
else
buf.append(" Banned until restart or in ");
buf.append(DataHelper.formatDuration(expires));
Set transports = entry.transports;
if ( (transports != null) && (transports.size() > 0) )
buf.append(" on the following transport: ").append(transports);
if (entry.cause != null) {
buf.append("<br>\n");
buf.append(entry.cause);
}
buf.append(" (<a href=\"configpeer.jsp?peer=").append(key.toBase64()).append("#unsh\">unban now</a>)");
buf.append("</li>\n");
}
buf.append("</ul>\n");
out.write(buf.toString());
out.flush();
}
}

View File

@@ -85,24 +85,31 @@ class FloodfillPeerSelector extends PeerSelector {
}
/**
* Sort the floodfills. The challenge here is to keep the good ones
* at the front and the bad ones at the back. If they are all good or bad,
* searches and stores won't work well.
*
* @return all floodfills not shitlisted foreverx
* @param key the routing key
* @param maxNumRouters max to return
* Sorted by closest to the key if > maxNumRouters, otherwise not
* The list is in 3 groups - sorted by routing key within each group.
* Group 1: No store or lookup failure in last 15 minutes
* Group 2: No store or lookup failure in last 3 minutes
* Group 1: No store or lookup failure in a long time
* Group 2: No store or lookup failure in a little while or
* success newer than failure
* Group 3: All others
*/
public List<Hash> selectFloodfillParticipants(Hash key, int maxNumRouters, KBucketSet kbuckets) {
return selectFloodfillParticipants(key, maxNumRouters, null, kbuckets);
}
/** 1.5 * PublishLocalRouterInfoJob.PUBLISH_DELAY */
private static final int NO_FAIL_STORE_OK = 30*60*1000;
/** .75 * PublishLocalRouterInfoJob.PUBLISH_DELAY */
private static final int NO_FAIL_STORE_OK = 15*60*1000;
private static final int NO_FAIL_STORE_GOOD = NO_FAIL_STORE_OK * 2;
/** this must be longer than the max streaming timeout (60s) */
private static final int NO_FAIL_LOOKUP_OK = 5*60*1000;
private static final int NO_FAIL_LOOKUP_GOOD = NO_FAIL_LOOKUP_OK * 3;
private static final int MAX_GOOD_RESP_TIME = 5*1000;
public List<Hash> selectFloodfillParticipants(Hash key, int howMany, Set<Hash> toIgnore, KBucketSet kbuckets) {
List<Hash> ffs = selectFloodfillParticipants(toIgnore, kbuckets);
@@ -110,8 +117,8 @@ class FloodfillPeerSelector extends PeerSelector {
sorted.addAll(ffs);
List<Hash> rv = new ArrayList(howMany);
List<Hash> okff = new ArrayList(howMany);
List<Hash> badff = new ArrayList(howMany);
List<Hash> okff = new ArrayList(ffs.size());
List<Hash> badff = new ArrayList(ffs.size());
int found = 0;
long now = _context.clock().now();
@@ -125,10 +132,11 @@ class FloodfillPeerSelector extends PeerSelector {
if (info != null && now - info.getPublished() > 3*60*60*1000) {
badff.add(entry);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Skipping, published a while ago: " + entry);
_log.debug("Old: " + entry);
} else {
PeerProfile prof = _context.profileOrganizer().getProfile(entry);
if (prof != null && prof.getDBHistory() != null
&& ((int) prof.getDbResponseTime().getRate(10*60*1000).getAverageValue()) < MAX_GOOD_RESP_TIME
&& prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_GOOD
&& prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_GOOD) {
// good
@@ -137,8 +145,10 @@ class FloodfillPeerSelector extends PeerSelector {
rv.add(entry);
found++;
} else if (prof != null && prof.getDBHistory() != null
&& prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_OK
&& prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_OK) {
&& (prof.getDBHistory().getLastStoreFailed() <= prof.getDBHistory().getLastStoreSuccessful()
|| prof.getDBHistory().getLastLookupFailed() <= prof.getDBHistory().getLastLookupSuccessful()
|| (prof.getDBHistory().getLastStoreFailed() < now - NO_FAIL_STORE_OK
&& prof.getDBHistory().getLastLookupFailed() < now - NO_FAIL_LOOKUP_OK))) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("OK: " + entry);
okff.add(entry);
@@ -149,8 +159,8 @@ class FloodfillPeerSelector extends PeerSelector {
}
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Good: " + rv + " OK: " + okff + " Bad: " + badff);
if (_log.shouldLog(Log.INFO))
_log.info("Good: " + rv + " OK: " + okff + " Bad: " + badff);
// Put the ok floodfills after the good floodfills
for (int i = 0; found < howMany && i < okff.size(); i++) {

View File

@@ -67,7 +67,7 @@ public class GetBidsJob extends JobImpl {
if (failedCount == 0) {
context.statManager().addRateData("transport.bidFailNoTransports", msg.getLifetime(), 0);
// This used to be "no common transports" but it is almost always no transports at all
context.shitlist().shitlistRouter(to, "No transports (hidden or starting up?)");
context.shitlist().shitlistRouter(to, _x("No transports (hidden or starting up?)"));
} else if (failedCount >= facade.getTransportCount()) {
context.statManager().addRateData("transport.bidFailAllTransports", msg.getLifetime(), 0);
// fail after all transports were unsuccessful
@@ -98,4 +98,14 @@ public class GetBidsJob extends JobImpl {
msg.discardData();
}
/**
* Mark a string for extraction by xgettext and translation.
* Use this only in static initializers.
* It does not translate!
* @return s
*/
private static final String _x(String s) {
return s;
}
}

View File

@@ -447,7 +447,7 @@ public class TransportManager implements TransportEventListener {
// Don't shitlist if we aren't talking to anybody, as we may have a network connection issue
if (unreachableTransports >= _transports.size() && countActivePeers() > 0) {
_context.statManager().addRateData("transport.shitlistOnUnreachable", msg.getLifetime(), msg.getLifetime());
_context.shitlist().shitlistRouter(peer, "Unreachable on any transport");
_context.shitlist().shitlistRouter(peer, _x("Unreachable on any transport"));
}
} else if (rv == null) {
_context.statManager().addRateData("transport.noBidsYetNotAllUnreachable", unreachableTransports, msg.getLifetime());
@@ -493,7 +493,7 @@ public class TransportManager implements TransportEventListener {
t.renderStatusHTML(out, urlBase, sortFlags);
}
StringBuilder buf = new StringBuilder(4*1024);
buf.append("<h3>Router Transport Addresses:</h3><pre>\n");
buf.append("<h3>Router Transport Addresses</h3><pre>\n");
for (int i = 0; i < _transports.size(); i++) {
Transport t = (Transport)_transports.get(i);
if (t.getCurrentAddress() != null)
@@ -508,4 +508,15 @@ public class TransportManager implements TransportEventListener {
buf.append("</p>\n");
out.flush();
}
/**
* Mark a string for extraction by xgettext and translation.
* Use this only in static initializers.
* It does not translate!
* @return s
*/
private static final String _x(String s) {
return s;
}
}

View File

@@ -368,8 +368,9 @@ public class EstablishState {
if (diff >= Router.CLOCK_FUDGE_FACTOR) {
_context.statManager().addRateData("ntcp.invalidOutboundSkew", diff, 0);
_transport.markReachable(_con.getRemotePeer().calculateHash(), false);
_context.shitlist().shitlistRouter(_con.getRemotePeer().calculateHash(),
"Excessive clock skew: " + DataHelper.formatDuration(diff));
_context.shitlist().shitlistRouter(DataHelper.formatDuration(diff),
_con.getRemotePeer().calculateHash(),
_x("Excessive clock skew: {0}"));
fail("Clocks too skewed (" + diff + " ms)", null, true);
return;
} else if (_log.shouldLog(Log.DEBUG)) {
@@ -572,7 +573,9 @@ public class EstablishState {
if (diff >= Router.CLOCK_FUDGE_FACTOR) {
_context.statManager().addRateData("ntcp.invalidInboundSkew", diff, 0);
_transport.markReachable(alice.calculateHash(), true);
_context.shitlist().shitlistRouter(alice.calculateHash(), "Clock skew of " + diff + " ms");
_context.shitlist().shitlistRouter(DataHelper.formatDuration(diff),
alice.calculateHash(),
_x("Excessive clock skew: {0}"));
fail("Clocks too skewed (" + diff + " ms)", null, true);
return;
} else if (_log.shouldLog(Log.DEBUG)) {
@@ -923,4 +926,15 @@ public class EstablishState {
e.printStackTrace();
}
}
/**
* Mark a string for extraction by xgettext and translation.
* Use this only in static initializers.
* It does not translate!
* @return s
*/
private static final String _x(String s) {
return s;
}
}

View File

@@ -19,23 +19,99 @@ import net.i2p.util.SimpleScheduler;
import net.i2p.util.SimpleTimer;
/**
*
* From udp.html on the website:
<p>The automation of collaborative reachability testing for peers is
enabled by a sequence of PeerTest messages. With its proper
execution, a peer will be able to determine their own reachability
and may update its behavior accordingly. The testing process is
quite simple:</p>
<pre>
Alice Bob Charlie
PeerTest -------------------&gt;
PeerTest--------------------&gt;
&lt;-------------------PeerTest
&lt;-------------------PeerTest
&lt;------------------------------------------PeerTest
PeerTest------------------------------------------&gt;
&lt;------------------------------------------PeerTest
</pre>
<p>Each of the PeerTest messages carry a nonce identifying the
test series itself, as initialized by Alice. If Alice doesn't
get a particular message that she expects, she will retransmit
accordingly, and based upon the data received or the messages
missing, she will know her reachability. The various end states
that may be reached are as follows:</p>
<ul>
<li>If she doesn't receive a response from Bob, she will retransmit
up to a certain number of times, but if no response ever arrives,
she will know that her firewall or NAT is somehow misconfigured,
rejecting all inbound UDP packets even in direct response to an
outbound packet. Alternately, Bob may be down or unable to get
Charlie to reply.</li>
<li>If Alice doesn't receive a PeerTest message with the
expected nonce from a third party (Charlie), she will retransmit
her initial request to Bob up to a certain number of times, even
if she has received Bob's reply already. If Charlie's first message
still doesn't get through but Bob's does, she knows that she is
behind a NAT or firewall that is rejecting unsolicited connection
attempts and that port forwarding is not operating properly (the
IP and port that Bob offered up should be forwarded).</li>
<li>If Alice receives Bob's PeerTest message and both of Charlie's
PeerTest messages but the enclosed IP and port numbers in Bob's
and Charlie's second messages don't match, she knows that she is
behind a symmetric NAT, rewriting all of her outbound packets with
different 'from' ports for each peer contacted. She will need to
explicitly forward a port and always have that port exposed for
remote connectivity, ignoring further port discovery.</li>
<li>If Alice receives Charlie's first message but not his second,
she will retransmit her PeerTest message to Charlie up to a
certain number of times, but if no response is received she knows
that Charlie is either confused or no longer online.</li>
</ul>
<p>Alice should choose Bob arbitrarily from known peers who seem
to be capable of participating in peer tests. Bob in turn should
choose Charlie arbitrarily from peers that he knows who seem to be
capable of participating in peer tests and who are on a different
IP from both Bob and Alice. If the first error condition occurs
(Alice doesn't get PeerTest messages from Bob), Alice may decide
to designate a new peer as Bob and try again with a different nonce.</p>
<p>Alice's introduction key is included in all of the PeerTest
messages so that she doesn't need to already have an established
session with Bob and so that Charlie can contact her without knowing
any additional information. Alice may go on to establish a session
with either Bob or Charlie, but it is not required.</p>
*/
class PeerTestManager {
private RouterContext _context;
private Log _log;
private UDPTransport _transport;
private PacketBuilder _packetBuilder;
/** map of Long(nonce) to PeerTestState for tests currently in progress */
private final Map _activeTests;
/** current test we are running, or null */
/** map of Long(nonce) to PeerTestState for tests currently in progress (as Bob/Charlie) */
private final Map<Long, PeerTestState> _activeTests;
/** current test we are running (as Alice), or null */
private PeerTestState _currentTest;
private boolean _currentTestComplete;
private List _recentTests;
/** as Alice */
private List<Long> _recentTests;
/** longest we will keep track of a Charlie nonce for */
private static final int MAX_CHARLIE_LIFETIME = 10*1000;
/**
* Have seen peer tests (as Alice) get stuck (_currentTest != null)
* so I've thrown some synchronizization on the methods;
* don't know the root cause or whether this fixes it
*/
public PeerTestManager(RouterContext context, UDPTransport transport) {
_context = context;
_transport = transport;
@@ -54,7 +130,11 @@ class PeerTestManager {
private static final int MAX_TEST_TIME = 30*1000;
private static final long MAX_NONCE = (1l << 32) - 1l;
//public void runTest(InetAddress bobIP, int bobPort, SessionKey bobIntroKey) {
public void runTest(InetAddress bobIP, int bobPort, SessionKey bobCipherKey, SessionKey bobMACKey) {
/**
* The next few methods are for when we are Alice
*/
public synchronized void runTest(InetAddress bobIP, int bobPort, SessionKey bobCipherKey, SessionKey bobMACKey) {
if (_currentTest != null) {
if (_log.shouldLog(Log.WARN))
_log.warn("We are already running a test with bob = " + _currentTest.getBobIP() + ", aborting test with bob = " + bobIP);
@@ -85,30 +165,33 @@ class PeerTestManager {
private class ContinueTest implements SimpleTimer.TimedEvent {
public void timeReached() {
PeerTestState state = _currentTest;
if (state == null) {
// already completed
return;
} else if (expired()) {
testComplete(true);
} else if (_context.clock().now() - state.getLastSendTime() >= RESEND_TIMEOUT) {
if (state.getReceiveBobTime() <= 0) {
// no message from Bob yet, send it again
sendTestToBob();
} else if (state.getReceiveCharlieTime() <= 0) {
// received from Bob, but no reply from Charlie. send it to
// Bob again so he pokes Charlie
sendTestToBob();
} else {
// received from both Bob and Charlie, but we haven't received a
// second message from Charlie yet
sendTestToCharlie();
synchronized (PeerTestManager.this) {
PeerTestState state = _currentTest;
if (state == null) {
// already completed
return;
} else if (expired()) {
testComplete(true);
} else if (_context.clock().now() - state.getLastSendTime() >= RESEND_TIMEOUT) {
if (state.getReceiveBobTime() <= 0) {
// no message from Bob yet, send it again
sendTestToBob();
} else if (state.getReceiveCharlieTime() <= 0) {
// received from Bob, but no reply from Charlie. send it to
// Bob again so he pokes Charlie
sendTestToBob();
} else {
// received from both Bob and Charlie, but we haven't received a
// second message from Charlie yet
sendTestToCharlie();
}
SimpleScheduler.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT);
}
SimpleScheduler.getInstance().addEvent(ContinueTest.this, RESEND_TIMEOUT);
}
}
}
/** call from a synchronized method */
private boolean expired() {
PeerTestState state = _currentTest;
if (state != null)
@@ -117,6 +200,7 @@ class PeerTestManager {
return true;
}
/** call from a synchronized method */
private void sendTestToBob() {
PeerTestState test = _currentTest;
if (!expired()) {
@@ -128,6 +212,7 @@ class PeerTestManager {
_currentTest = null;
}
}
/** call from a synchronized method */
private void sendTestToCharlie() {
PeerTestState test = _currentTest;
if (!expired()) {
@@ -153,9 +238,9 @@ class PeerTestManager {
/**
* Receive a PeerTest message which contains the correct nonce for our current
* test
* test. We are Alice.
*/
private void receiveTestReply(RemoteHostId from, UDPPacketReader.PeerTestReader testInfo) {
private synchronized void receiveTestReply(RemoteHostId from, UDPPacketReader.PeerTestReader testInfo) {
_context.statManager().addRateData("udp.receiveTestReply", 1, 0);
PeerTestState test = _currentTest;
if (expired())
@@ -208,6 +293,7 @@ class PeerTestManager {
if (_log.shouldLog(Log.WARN))
_log.warn("Bob chose a charlie we already have a session to, cancelling the test and rerunning (bob: "
+ _currentTest + ", charlie: " + from + ")");
// why are we doing this instead of calling testComplete() ?
_currentTestComplete = true;
_context.statManager().addRateData("udp.statusKnownCharlie", 1, 0);
honorStatus(CommSystemFacade.STATUS_UNKNOWN);
@@ -267,6 +353,9 @@ class PeerTestManager {
* Evaluate the info we have and act accordingly, since the test has either timed out or
* we have successfully received the second PeerTest from a Charlie.
*
* @param forgetTest must be true to clear out this test and allow another
*
* call from a synchronized method
*/
private void testComplete(boolean forgetTest) {
_currentTestComplete = true;
@@ -324,7 +413,7 @@ class PeerTestManager {
* Receive a test message of some sort from the given peer, queueing up any packet
* that should be sent in response, or if its a reply to our own current testing,
* adjusting our test state.
*
* We could be Alice, Bob, or Charlie.
*/
public void receiveTest(RemoteHostId from, UDPPacketReader reader) {
_context.statManager().addRateData("udp.receiveTest", 1, 0);
@@ -334,10 +423,13 @@ class PeerTestManager {
long nonce = testInfo.readNonce();
PeerTestState test = _currentTest;
if ( (test != null) && (test.getNonce() == nonce) ) {
// we are Alice
receiveTestReply(from, testInfo);
return;
}
// we are Bob or Charlie
if ( (testInfo.readIPSize() > 0) && (testPort > 0) ) {
testIP = new byte[testInfo.readIPSize()];
testInfo.readIP(testIP, 0);
@@ -360,7 +452,7 @@ class PeerTestManager {
// initiated test
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("We are charlie, as te testIP/port is " + RemoteHostId.toString(testIP) + ":" + testPort + " and the state is unknown for " + nonce);
_log.debug("We are charlie, as the testIP/port is " + RemoteHostId.toString(testIP) + ":" + testPort + " and the state is unknown for " + nonce);
// we are charlie, since alice never sends us her IP and port, only bob does (and,
// erm, we're not alice, since it isn't our nonce)
receiveFromBobAsCharlie(from, testInfo, nonce, null);
@@ -388,6 +480,8 @@ class PeerTestManager {
}
}
// Below here are methods for when we are Bob or Charlie
private static final int MAX_RELAYED_PER_TEST = 5;
/**

View File

@@ -2059,7 +2059,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
}
private static final String KEY = "<h3>Definitions:</h3><div class=\"configure\">" +
private static final String KEY = "<h3>Definitions</h3><div class=\"configure\">" +
"<p><b id=\"def.peer\">Peer</b>: the remote peer.<br>\n" +
"<b id=\"def.dir\">Dir</b>: v means they offer to introduce us, ^ means we offer to introduce them.<br>\n" +
"<b id=\"def.idle\">Idle</b>: the idle time is how long since a packet has been received or sent.<br>\n" +