forked from I2P_Developers/i2p.i2p
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
178b229d66 | ||
|
|
276493da65 | ||
|
|
e85dadfef2 | ||
|
|
1c70efb350 | ||
|
|
6804a0c564 | ||
|
|
6eb7ecc2d4 | ||
|
|
f4956b06b6 | ||
|
|
9a2f7c2660 | ||
|
|
b6017c558a | ||
|
|
62ed6c6a58 | ||
|
|
24966c812f | ||
|
|
ea8dc2e0af | ||
|
|
010b285e67 | ||
|
|
774231f347 | ||
|
|
ff1dfd8f25 | ||
|
|
2741ac195d | ||
|
|
cf780e296e | ||
|
|
0361246db0 | ||
|
|
63355ecd5b | ||
|
|
0f54ba59fb | ||
|
|
b67b243ebd | ||
|
|
4c29c20613 | ||
|
|
4c2619d948 | ||
|
|
ea5662a4a2 | ||
|
|
7c1ce777a1 | ||
|
|
3bb85f2d61 | ||
|
|
93e36b3113 | ||
|
|
932fb670e3 | ||
|
|
54dce61a95 | ||
|
|
e686c0e0a2 | ||
|
|
05acf32f39 | ||
|
|
67064012c9 | ||
|
|
10e93c3b1b | ||
|
|
5b2ec1cbb5 | ||
|
|
972f701c5c | ||
|
|
51285efbc3 | ||
|
|
e2635705f9 | ||
|
|
7762107543 | ||
|
|
9123ad89c8 | ||
|
|
39f3d6cc80 | ||
|
|
af5665f67c | ||
|
|
c2175cc692 | ||
|
|
1ef371a467 | ||
|
|
58461ff5bb | ||
|
|
665959da90 | ||
|
|
8e63974f94 | ||
|
|
eae86f54ba | ||
|
|
30128a122d | ||
|
|
56e22a39ac | ||
|
|
6ceb330baa | ||
|
|
f30509c7ba | ||
|
|
9489136bd6 | ||
|
|
05cd3d736b | ||
|
|
29b17772e5 | ||
|
|
6151d63eac | ||
|
|
e57aa68854 | ||
|
|
73fa6d9bd0 | ||
|
|
da3c4b87c1 | ||
|
|
0eedc1b128 | ||
|
|
db339d40de | ||
|
|
f72aa7884d | ||
|
|
1434f1bb40 | ||
|
|
6bc92b26a7 |
@@ -17,6 +17,8 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
@@ -118,7 +120,16 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
return getSocketManager(getTunnel());
|
||||
}
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
|
||||
if (socketManager == null) {
|
||||
if (socketManager != null) {
|
||||
I2PSession s = socketManager.getSession();
|
||||
if ( (s == null) || (s.isClosed()) ) {
|
||||
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
|
||||
socketManager = buildSocketManager(tunnel);
|
||||
} else {
|
||||
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
|
||||
}
|
||||
} else {
|
||||
_log.info("Building a new socket manager since there is no other one");
|
||||
socketManager = buildSocketManager(tunnel);
|
||||
}
|
||||
return socketManager;
|
||||
@@ -277,7 +288,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getTunnel().removeSession(sockMgr.getSession());
|
||||
I2PSession session = sockMgr.getSession();
|
||||
if (session != null) {
|
||||
getTunnel().removeSession(session);
|
||||
}
|
||||
l.log("Closing client " + toString());
|
||||
try {
|
||||
if (ss != null) ss.close();
|
||||
|
||||
@@ -190,8 +190,8 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
|
||||
} catch (IOException ex) {
|
||||
if (!finished)
|
||||
_log.error("Error forwarding", ex);
|
||||
else
|
||||
_log.warn("You may ignore this", ex);
|
||||
//else
|
||||
// _log.warn("You may ignore this", ex);
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
@@ -28,6 +29,7 @@ public class TunnelController implements Logging {
|
||||
private Properties _config;
|
||||
private I2PTunnel _tunnel;
|
||||
private List _messages;
|
||||
private List _sessions;
|
||||
private boolean _running;
|
||||
|
||||
/**
|
||||
@@ -144,9 +146,42 @@ public class TunnelController implements Logging {
|
||||
_tunnel.runHttpClient(new String[] { listenPort }, this);
|
||||
else
|
||||
_tunnel.runHttpClient(new String[] { listenPort, proxyList }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that we are using some sessions, so that they dont get
|
||||
* closed by some other tunnels
|
||||
*/
|
||||
private void acquire() {
|
||||
List sessions = _tunnel.getSessions();
|
||||
if (sessions != null) {
|
||||
for (int i = 0; i < sessions.size(); i++) {
|
||||
I2PSession session = (I2PSession)sessions.get(i);
|
||||
TunnelControllerGroup.getInstance().acquire(this, session);
|
||||
}
|
||||
_sessions = sessions;
|
||||
} else {
|
||||
_log.error("No sessions to acquire?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that we are no longer using some sessions, and if
|
||||
* no other tunnels are using them, close them.
|
||||
*/
|
||||
private void release() {
|
||||
if (_sessions != null) {
|
||||
for (int i = 0; i < _sessions.size(); i++) {
|
||||
I2PSession s = (I2PSession)_sessions.get(i);
|
||||
TunnelControllerGroup.getInstance().release(this, s);
|
||||
}
|
||||
} else {
|
||||
_log.error("No sessions to release?");
|
||||
}
|
||||
}
|
||||
|
||||
private void startClient() {
|
||||
setI2CPOptions();
|
||||
setSessionOptions();
|
||||
@@ -154,6 +189,7 @@ public class TunnelController implements Logging {
|
||||
String listenPort = getListenPort();
|
||||
String dest = getTargetDestination();
|
||||
_tunnel.runClient(new String[] { listenPort, dest }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
@@ -164,6 +200,7 @@ public class TunnelController implements Logging {
|
||||
String targetPort = getTargetPort();
|
||||
String privKeyFile = getPrivKeyFile();
|
||||
_tunnel.runServer(new String[] { targetHost, targetPort, privKeyFile }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
@@ -201,6 +238,7 @@ public class TunnelController implements Logging {
|
||||
|
||||
public void stopTunnel() {
|
||||
_tunnel.runClose(new String[] { "forced", "all" }, this);
|
||||
release();
|
||||
_running = false;
|
||||
}
|
||||
|
||||
@@ -334,14 +372,21 @@ public class TunnelController implements Logging {
|
||||
Destination dest = session.getMyDestination();
|
||||
if (dest != null) {
|
||||
buf.append("Destination hash: ").append(dest.calculateHash().toBase64()).append("<br />\n");
|
||||
buf.append("Full destination: ");
|
||||
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
|
||||
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
|
||||
if ("server".equals(getType())) {
|
||||
buf.append(" Give that out to people so they can view your service.");
|
||||
buf.append(" If you are going to share it on irc, be sure to split it on two lines");
|
||||
buf.append("Full destination: ");
|
||||
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
|
||||
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
|
||||
long val = new Random().nextLong();
|
||||
if (val < 0) val = 0 - val;
|
||||
buf.append("<br />You can <a href=\"http://temp").append(val);
|
||||
buf.append(".i2p/?i2paddresshelper=").append(dest.toBase64()).append("\">view</a>");
|
||||
buf.append(" it in a browser (only when you're using the eepProxy)\n");
|
||||
buf.append("<br />If you are going to share this on IRC, you need to split it up:<br />\n");
|
||||
String str = dest.toBase64();
|
||||
buf.append(str.substring(0, str.length()/2)).append("<br />\n");
|
||||
buf.append(str.substring(str.length()/2)).append("<br />\n");
|
||||
buf.append("You can also post it to <a href=\"http://forum.i2p/viewforum.php?f=16\">Eepsite announcement forum</a><br />");
|
||||
}
|
||||
buf.append("<br />\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,18 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@@ -30,23 +35,33 @@ public class TunnelControllerGroup {
|
||||
private List _controllers;
|
||||
private String _configFile = DEFAULT_CONFIG_FILE;
|
||||
|
||||
/**
|
||||
* Map of I2PSession to a Set of TunnelController objects
|
||||
* using the session (to prevent closing the session until
|
||||
* no more tunnels are using it)
|
||||
*
|
||||
*/
|
||||
private Map _sessions;
|
||||
|
||||
public static TunnelControllerGroup getInstance() { return _instance; }
|
||||
|
||||
private TunnelControllerGroup(String configFile) {
|
||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(TunnelControllerGroup.class);
|
||||
_instance = this;
|
||||
_controllers = new ArrayList();
|
||||
_configFile = configFile;
|
||||
_sessions = new HashMap(4);
|
||||
loadControllers(_configFile);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
if ( (args == null) || (args.length <= 0) ) {
|
||||
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
} else if (args.length == 1) {
|
||||
if (DEFAULT_CONFIG_FILE.equals(args[0]))
|
||||
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
else
|
||||
_instance = new TunnelControllerGroup(args[0]);
|
||||
new TunnelControllerGroup(args[0]);
|
||||
} else {
|
||||
System.err.println("Usage: TunnelControllerGroup [filename]");
|
||||
return;
|
||||
@@ -281,4 +296,61 @@ public class TunnelControllerGroup {
|
||||
*/
|
||||
public List getControllers() { return _controllers; }
|
||||
|
||||
|
||||
/**
|
||||
* Note the fact that the controller is using the session so that
|
||||
* it isn't destroyed prematurely.
|
||||
*
|
||||
*/
|
||||
void acquire(TunnelController controller, I2PSession session) {
|
||||
synchronized (_sessions) {
|
||||
Set owners = (Set)_sessions.get(session);
|
||||
if (owners == null) {
|
||||
owners = new HashSet(1);
|
||||
_sessions.put(session, owners);
|
||||
}
|
||||
owners.add(controller);
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Acquiring session " + session + " for " + controller);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that the controller is no longer using the session, and if
|
||||
* no other controllers are using it, destroy the session.
|
||||
*
|
||||
*/
|
||||
void release(TunnelController controller, I2PSession session) {
|
||||
boolean shouldClose = false;
|
||||
synchronized (_sessions) {
|
||||
Set owners = (Set)_sessions.get(session);
|
||||
if (owners != null) {
|
||||
owners.remove(controller);
|
||||
if (owners.size() <= 0) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("After releasing session " + session + " by " + controller + ", no more owners remain");
|
||||
shouldClose = true;
|
||||
_sessions.remove(session);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("After releasing session " + session + " by " + controller + ", " + owners.size() + " owners remain");
|
||||
shouldClose = false;
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("After releasing session " + session + " by " + controller + ", no owners were even known?!");
|
||||
shouldClose = true;
|
||||
}
|
||||
}
|
||||
if (shouldClose) {
|
||||
try {
|
||||
session.destroySession();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Session destroyed: " + session);
|
||||
} catch (I2PSessionException ise) {
|
||||
_log.error("Error closing the client session", ise);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.Random;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Uuuugly... generate the edit/add forms for the various
|
||||
* Uuuugly code to generate the edit/add forms for the various
|
||||
* I2PTunnel types (httpclient/client/server)
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.WebStatusPageHelper" id="helper" scope="request" />
|
||||
<jsp:setProperty name="helper" property="*" />
|
||||
<h2>Messages since last page load:</h2>
|
||||
<b><jsp:getProperty name="helper" property="actionResults" /></b>
|
||||
|
||||
<jsp:getProperty name="helper" property="summaryList" />
|
||||
|
||||
@@ -234,7 +234,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the socket from the I2P side, e. g. by a close packet.
|
||||
* Close the socket from the I2P side (by a close packet)
|
||||
*/
|
||||
protected void internalClose() {
|
||||
synchronized (flagLock) {
|
||||
|
||||
@@ -5,12 +5,19 @@
|
||||
** License: Public Domain
|
||||
** Date: 11 May 2004
|
||||
**
|
||||
** Revised: 07 Sep 2004
|
||||
** Changes:
|
||||
** Proxy recursion disabled by default (strict)
|
||||
** Password Authentication for session commands
|
||||
** Support for http://path?i2paddresshelper=BASE64
|
||||
** Support for http://i2p/BASE64/path syntax
|
||||
** Revised: 17 May 2004
|
||||
** Added:
|
||||
** Changes:
|
||||
** Ability for the user to control the proxy
|
||||
** status on a per browser-session basis.
|
||||
********************************************************/
|
||||
|
||||
|
||||
/* C O N F I G U R A T I O N
|
||||
*/
|
||||
|
||||
@@ -53,12 +60,13 @@ var proxyStatus = "auto";
|
||||
** could change your status mode by linking to command keywords...
|
||||
** eg. <img src="i2p.off" ...
|
||||
** This is why the default setting for statusKeyword is "limited", which only
|
||||
** allows you to set the proxy status to "on".
|
||||
** allows you to set the proxy status to "on". See also keywordAuthPassword.
|
||||
**
|
||||
** [1] "all" => All proxy status urls are available.
|
||||
** '-> i2p.on, i2p.off, i2p.auto (respective to proxyStatus settings)
|
||||
** '-> WARNING: Setting "all" is a big risk to your anonymity!
|
||||
**
|
||||
** '-> In this mode it is highly recommended you set an AuthPassword too!
|
||||
**
|
||||
** [2] "limited" => Only i2p.on is available..
|
||||
** '-> This setting lasts for the duration of the browser setting.
|
||||
** '-> You have to close your browser in order to revert to
|
||||
@@ -70,7 +78,7 @@ var proxyStatus = "auto";
|
||||
**
|
||||
*/
|
||||
|
||||
var statusKeyword = "limited";
|
||||
var statusKeyword = "all";
|
||||
|
||||
/*
|
||||
** By default if proxyStatus is set to "auto" the config script
|
||||
@@ -84,7 +92,24 @@ var statusKeyword = "limited";
|
||||
** sites will be rejected if the i2p proxy is offline. (safest)
|
||||
*/
|
||||
|
||||
var strict = false;
|
||||
var strict = true;
|
||||
|
||||
/*
|
||||
** By setting an authentication password, all activated session keywords
|
||||
** will require the addition of a password to prevent malicious sites from
|
||||
** hijacking your proxy settings. ie. <img src="i2p.off" ...
|
||||
** Users should append whatever they set here to any command keywords
|
||||
** they use.
|
||||
** eg. i2p.on.passw0rd
|
||||
** If left blank, authentication is ignored - it is recommended that
|
||||
** you use "limited" statusKeyword mode if you choose not to require a password.
|
||||
** If you do require this feature then you should replace the default "passw0rd" with
|
||||
** one of your own (recommend at least 8 letters with a case-sensitive alpha-numeric
|
||||
** mix of characters).
|
||||
**
|
||||
*/
|
||||
|
||||
var keywordAuthPassword = "passw0rd";
|
||||
|
||||
|
||||
/* E N D C O N F I G U R A T I O N
|
||||
@@ -96,7 +121,13 @@ var strict = false;
|
||||
*/
|
||||
|
||||
if (strict == false) {
|
||||
i2pProxy = i2pProxy + "; " + normal;
|
||||
i2pProxy = i2pProxy + "; " + normal;
|
||||
}
|
||||
|
||||
/*Check for User Authentication Password.
|
||||
*/
|
||||
if (keywordAuthPassword != "") {
|
||||
keywordAuthPassword = "." + keywordAuthPassword;
|
||||
}
|
||||
|
||||
/* This function gets called every time a url is submitted
|
||||
@@ -108,16 +139,17 @@ function FindProxyForURL(url, host) {
|
||||
*/
|
||||
|
||||
if (statusKeyword != "off") {
|
||||
if (host == "i2p.off" && statusKeyword == "all") {
|
||||
if (host == "i2p.off" + keywordAuthPassword && statusKeyword == "all") {
|
||||
/*Proxy is bypassed - outweb available only
|
||||
*/
|
||||
proxyStatus = "off";
|
||||
} else if (host == "i2p.auto" && statusKeyword == "all") {
|
||||
} else if (host == "i2p.auto" + keywordAuthPassword && statusKeyword == "all") {
|
||||
/* Proxy is used only for .i2p hosts otherwise
|
||||
** '-> browse as normal.
|
||||
*/
|
||||
proxyStatus = "auto";
|
||||
} else if (host == "i2p.on" && statusKeyword == "limited") {
|
||||
} else if (host == "i2p.on" + keywordAuthPassword && (statusKeyword == "limited" ||
|
||||
statusKeyword == "all" )) {
|
||||
/* Only I2P traffic is accepted.
|
||||
*/
|
||||
proxyStatus = "on";
|
||||
@@ -135,13 +167,14 @@ function FindProxyForURL(url, host) {
|
||||
}
|
||||
|
||||
host = host.toLowerCase();
|
||||
/* check tld for "i2p" - if found then redirect
|
||||
/* check tld for "i2p" or oOo's new "i2paddresshelper" syntax - if found then redirect
|
||||
** '-> request to the i2p proxy
|
||||
*/
|
||||
|
||||
if (shExpMatch(host, "*.i2p")) { // seems more reliable than:
|
||||
return i2pProxy; // dnsDomainIs(host, ".i2p") ||
|
||||
} else { // i2pRegex.test(host)
|
||||
if (url.match(/^http:\/\/i2p\/[a-zA-Z0-9\-\~]{516}|i2paddresshelper=/i) ||
|
||||
shExpMatch(host, "*.i2p")) { // seems more reliable than:
|
||||
return i2pProxy; // dnsDomainIs(host, ".i2p") ||
|
||||
} else { // i2pRegex.test(host)
|
||||
return normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,29 +15,40 @@ import org.tanukisoftware.wrapper.WrapperManager;
|
||||
public class ConfigServiceHandler extends FormHandler {
|
||||
public void ConfigNetHandler() {}
|
||||
|
||||
private class UpdateWrapperManagerTask implements Runnable {
|
||||
private int _exitCode;
|
||||
public UpdateWrapperManagerTask(int exitCode) {
|
||||
_exitCode = exitCode;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
WrapperManager.signalStopped(_exitCode);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void processForm() {
|
||||
if (_action == null) return;
|
||||
|
||||
if ("Shutdown gracefully".equals(_action)) {
|
||||
try {
|
||||
WrapperManager.signalStopped(Router.EXIT_GRACEFUL);
|
||||
} catch (Throwable t) {
|
||||
addFormError("Warning: unable to contact the service manager - " + t.getMessage());
|
||||
}
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL));
|
||||
_context.router().shutdownGracefully();
|
||||
addFormNotice("Graceful shutdown initiated");
|
||||
} else if ("Shutdown immediately".equals(_action)) {
|
||||
try {
|
||||
WrapperManager.signalStopped(Router.EXIT_HARD);
|
||||
} catch (Throwable t) {
|
||||
addFormError("Warning: unable to contact the service manager - " + t.getMessage());
|
||||
}
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD));
|
||||
_context.router().shutdown(Router.EXIT_HARD);
|
||||
addFormNotice("Shutdown immediately! boom bye bye bad bwoy");
|
||||
} else if ("Cancel graceful shutdown".equals(_action)) {
|
||||
_context.router().cancelGracefulShutdown();
|
||||
addFormNotice("Graceful shutdown cancelled");
|
||||
} else if ("Graceful restart".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
addFormNotice("Graceful restart requested");
|
||||
} else if ("Hard restart".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD_RESTART));
|
||||
_context.router().shutdown(Router.EXIT_HARD_RESTART);
|
||||
addFormNotice("Hard restart requested");
|
||||
} else if ("Run I2P on startup".equals(_action)) {
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
public class ContentHelper {
|
||||
private String _page;
|
||||
@@ -40,14 +40,14 @@ public class ContentHelper {
|
||||
}
|
||||
}
|
||||
public String getContent() {
|
||||
String str = DataHelper.readTextFile(_page, _maxLines);
|
||||
String str = FileUtil.readTextFile(_page, _maxLines);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
return str;
|
||||
}
|
||||
public String getTextContent() {
|
||||
String str = DataHelper.readTextFile(_page, _maxLines);
|
||||
String str = FileUtil.readTextFile(_page, _maxLines);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
|
||||
@@ -4,8 +4,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
public class LogsHelper {
|
||||
private RouterContext _context;
|
||||
@@ -28,7 +28,7 @@ public class LogsHelper {
|
||||
public String getLogs() {
|
||||
List msgs = _context.logManager().getBuffer().getMostRecentMessages();
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h2>Most recent console messages:</h2><ul>");
|
||||
buf.append("<ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = msgs.size(); i > 0; i--) {
|
||||
String msg = (String)msgs.get(i - 1);
|
||||
@@ -42,10 +42,26 @@ public class LogsHelper {
|
||||
}
|
||||
|
||||
public String getServiceLogs() {
|
||||
String str = DataHelper.readTextFile("wrapper.log", 500);
|
||||
String str = FileUtil.readTextFile("wrapper.log", 500);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
return "<pre>" + str + "</pre>";
|
||||
}
|
||||
|
||||
public String getConnectionLogs() {
|
||||
List msgs = _context.commSystem().getMostRecentErrorMessages();
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = msgs.size(); i > 0; i--) {
|
||||
String msg = (String)msgs.get(i - 1);
|
||||
buf.append("<li>");
|
||||
buf.append(msg);
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</code></ul>\n");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class NetDbHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@@ -23,13 +26,21 @@ public class NetDbHelper {
|
||||
|
||||
public NetDbHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) { _out = writer; }
|
||||
|
||||
public String getNetDbSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
try {
|
||||
_context.netDb().renderStatusHTML(baos);
|
||||
if (_out != null) {
|
||||
_context.netDb().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
@@ -9,6 +11,7 @@ import net.i2p.router.admin.StatsGenerator;
|
||||
|
||||
public class OldConsoleHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@@ -25,11 +28,20 @@ public class OldConsoleHelper {
|
||||
|
||||
public OldConsoleHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) {
|
||||
_out = writer;
|
||||
}
|
||||
|
||||
public String getConsole() {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
_context.router().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
@@ -38,9 +50,14 @@ public class OldConsoleHelper {
|
||||
public String getStats() {
|
||||
StatsGenerator gen = new StatsGenerator(_context);
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
gen.generateStatsPage(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
@@ -26,7 +27,7 @@ public class ProfilesHelper {
|
||||
public String getProfileSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(16*1024);
|
||||
try {
|
||||
_context.profileOrganizer().renderStatusHTML(baos);
|
||||
_context.profileOrganizer().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
@@ -36,7 +37,7 @@ public class ProfilesHelper {
|
||||
public String getShitlistSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
|
||||
try {
|
||||
_context.shitlist().renderStatusHTML(baos);
|
||||
_context.shitlist().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.apps.systray.SysTray;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
@@ -21,6 +23,10 @@ public class RouterConsoleRunner {
|
||||
private String _listenHost = "127.0.0.1";
|
||||
private String _webAppsDir = "./webapps/";
|
||||
|
||||
static {
|
||||
System.setProperty("org.mortbay.http.Version.paranoid", "true");
|
||||
}
|
||||
|
||||
public RouterConsoleRunner(String args[]) {
|
||||
if (args.length == 3) {
|
||||
_listenPort = args[0].trim();
|
||||
@@ -35,6 +41,14 @@ public class RouterConsoleRunner {
|
||||
}
|
||||
|
||||
public void startConsole() {
|
||||
File workDir = new File("work");
|
||||
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
|
||||
if (!workDirRemoved)
|
||||
System.err.println("ERROR: Unable to remove Jetty temporary work directory");
|
||||
boolean workDirCreated = workDir.mkdirs();
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
_server = new Server();
|
||||
WebApplicationContext contexts[] = null;
|
||||
try {
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
@@ -78,10 +79,20 @@ public class SummaryHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* How many active peers the router has.
|
||||
* How many peers we are talking to now
|
||||
*
|
||||
*/
|
||||
public int getActivePeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.commSystem().countActivePeers();
|
||||
}
|
||||
/**
|
||||
* How many active identities have we spoken with recently
|
||||
*
|
||||
*/
|
||||
public int getActiveProfiles() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
@@ -287,26 +298,27 @@ public class SummaryHelper {
|
||||
}
|
||||
|
||||
private static String getTransferred(long bytes) {
|
||||
double val = bytes;
|
||||
int scale = 0;
|
||||
if (bytes > 1024*1024*1024) {
|
||||
// gigs transferred
|
||||
scale = 3;
|
||||
bytes /= (1024*1024*1024);
|
||||
val /= (double)(1024*1024*1024);
|
||||
} else if (bytes > 1024*1024) {
|
||||
// megs transferred
|
||||
scale = 2;
|
||||
bytes /= (1024*1024);
|
||||
val /= (double)(1024*1024);
|
||||
} else if (bytes > 1024) {
|
||||
// kbytes transferred
|
||||
scale = 1;
|
||||
bytes /= 1024;
|
||||
val /= (double)1024;
|
||||
} else {
|
||||
scale = 0;
|
||||
}
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
String str = fmt.format(bytes);
|
||||
String str = fmt.format(val);
|
||||
switch (scale) {
|
||||
case 1: return str + "KB";
|
||||
case 2: return str + "MB";
|
||||
@@ -323,7 +335,9 @@ public class SummaryHelper {
|
||||
public String getDestinations() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
_context.clientManager().renderStatusHTML(baos);
|
||||
OutputStreamWriter osw = new OutputStreamWriter(baos);
|
||||
_context.clientManager().renderStatusHTML(osw);
|
||||
osw.flush();
|
||||
return new String(baos.toByteArray());
|
||||
} catch (IOException ioe) {
|
||||
_context.logManager().getLog(SummaryHelper.class).error("Error rendering client info", ioe);
|
||||
@@ -386,8 +400,7 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return ((int)delayRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getMessageDelay() + "ms";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,7 +412,6 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return ((int)lagRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getTunnelLag() + "ms";
|
||||
}
|
||||
}
|
||||
@@ -35,8 +35,11 @@
|
||||
<input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br />
|
||||
<i>The hostname/IP address and TCP port must be reachable from the outside world. If
|
||||
you are behind a firewall or NAT, this means you must poke a hole for this port. If
|
||||
you are using DHCP and do not have a static IP address, you must use a service like
|
||||
<a href="http://dyndns.org/">dyndns</a>. The "guess" functionality makes an HTTP request
|
||||
you are using DHCP and do not have a static IP address, you should either use a service like
|
||||
<a href="http://dyndns.org/">dyndns</a> or leave the hostname blank. If you leave it blank,
|
||||
your router will autodetect the 'correct' IP address by asking a peer (and unconditionally
|
||||
believing them if the address is routable and you don't have any established connections yet).
|
||||
The "guess" functionality makes an HTTP request
|
||||
to <a href="http://www.whatismyip.com/">www.whatismyip.com</a>.</i>
|
||||
<hr />
|
||||
<b>Enable internal time synchronization?</b> <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<input type="hidden" name="action" value="blah" />
|
||||
<b>Logging filename:</b>
|
||||
<input type="text" name="logfilename" size="40" value="<jsp:getProperty name="logginghelper" property="logFilePattern" />" /><br />
|
||||
<i>(the symbol '#' will be replaced during log rotation)</i><br />
|
||||
<i>(the symbol '@' will be replaced during log rotation)</i><br />
|
||||
<b>Log record format:</b>
|
||||
<input type="text" name="logformat" size="20" value="<jsp:getProperty name="logginghelper" property="recordPattern" />" /><br />
|
||||
<i>(use 'd' = date, 'c' = class, 't' = thread, 'p' = priority, 'm' = message)</i><br />
|
||||
|
||||
@@ -25,36 +25,47 @@
|
||||
System.setProperty("net.i2p.router.web.ConfigServiceHandler.nonce", new java.util.Random().nextLong()+""); %>
|
||||
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigServiceHandler.nonce")%>" />
|
||||
<h4>Shutdown the router</h4>
|
||||
Graceful shutdown lets the router satisfy the agreements it has already made
|
||||
<p>Graceful shutdown lets the router satisfy the agreements it has already made
|
||||
before shutting down, but may take a few minutes. If you need to kill the
|
||||
router immediately, that option is available as well.<br />
|
||||
router immediately, that option is available as well.</p>
|
||||
|
||||
<input type="submit" name="action" value="Shutdown gracefully" />
|
||||
<input type="submit" name="action" value="Shutdown immediately" />
|
||||
<input type="submit" name="action" value="Cancel graceful shutdown" />
|
||||
|
||||
<p>If you want the router to restart itself after shutting down, you can choose one of
|
||||
the following. This is useful in some situations - for example, if you changed
|
||||
some settings that client applications only read at startup, such as the routerconsole password
|
||||
or the interface it listens on. A graceful restart will take a few minutes (but your peers
|
||||
will appreciate your patience), while a hard restart does so immediately. After tearing down
|
||||
the router, it will wait 1 minute before starting back up again.</p>
|
||||
|
||||
<input type="submit" name="action" value="Graceful restart" />
|
||||
<input type="submit" name="action" value="Hard restart" />
|
||||
|
||||
<% if ( (System.getProperty("os.name") != null) && (System.getProperty("os.name").startsWith("Win")) ) { %>
|
||||
<h4>Systray integration</h4>
|
||||
On the windows platform, there is a small application to sit in the system
|
||||
<p>On the windows platform, there is a small application to sit in the system
|
||||
tray, allowing you to view the router's status (later on, I2P client applications
|
||||
will be able to integrate their own functionality into the system tray as well).
|
||||
If you are on windows, you can either enable or disable that icon here. <br />
|
||||
If you are on windows, you can either enable or disable that icon here.</p>
|
||||
<input type="submit" name="action" value="Show systray icon" />
|
||||
<input type="submit" name="action" value="Hide systray icon" />
|
||||
<h4>Run on startup</h4>
|
||||
You can control whether I2P is run on startup or not by selecting one of the
|
||||
<p>You can control whether I2P is run on startup or not by selecting one of the
|
||||
following options - I2P will install (or remove) a service accordingly. You can
|
||||
also run the <code>install_i2p_service_winnt.bat</code> (or
|
||||
<code>uninstall_i2p_service_winnt.bat</code>) from the command line, if you prefer.<br />
|
||||
<code>uninstall_i2p_service_winnt.bat</code>) from the command line, if you prefer.</p>
|
||||
<input type="submit" name="action" value="Run I2P on startup" />
|
||||
<input type="submit" name="action" value="Don't run I2P on startup" /><br />
|
||||
<b>Note:</b> If you are running I2P as service right now, removing it will shut
|
||||
<p><b>Note:</b> If you are running I2P as service right now, removing it will shut
|
||||
down your router immediately. You may want to consider shutting down gracefully, as
|
||||
above, then running uninstall_i2p_service_winnt.bat.
|
||||
above, then running uninstall_i2p_service_winnt.bat.</p>
|
||||
<% } %>
|
||||
<h4>Debugging</h4>
|
||||
At times, it may be helpful to debug I2P by getting a thread dump. To do so,
|
||||
<p>At times, it may be helpful to debug I2P by getting a thread dump. To do so,
|
||||
please select the following option and review the thread dumped to
|
||||
<a href="logs.jsp#servicelogs">wrapper.log</a>.<br />
|
||||
<a href="logs.jsp#servicelogs">wrapper.log</a>.</p>
|
||||
<input type="submit" name="action" value="Dump threads" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<h4>Router logs:</h4>
|
||||
<jsp:getProperty name="logsHelper" property="logs" />
|
||||
<hr />
|
||||
<h4>Connection logs:</h4><a name="connectionlogs"> </a>
|
||||
<jsp:getProperty name="logsHelper" property="connectionLogs" />
|
||||
<hr />
|
||||
<h4>Service logs:</h4><a name="servicelogs"> </a>
|
||||
<jsp:getProperty name="logsHelper" property="serviceLogs" />
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
<%
|
||||
<% response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Cache-Control","no-cache");
|
||||
response.setDateHeader("Expires", 0);
|
||||
// the above will b0rk if the servlet engine has already flushed
|
||||
// the response prior to including nav.jsp, so nav should be
|
||||
// near the top
|
||||
|
||||
if (request.getParameter("i2p.contextId") != null) {
|
||||
session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
|
||||
}%>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.NetDbHelper" id="netdbHelper" scope="request" />
|
||||
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="netdbHelper" property="writer" value="<%=out%>" />
|
||||
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="conhelper" scope="request" />
|
||||
<jsp:setProperty name="conhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="conhelper" property="writer" value="<%=out%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:getProperty name="conhelper" property="console" />
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.OldConsoleHelper" id="oldhelper" scope="request" />
|
||||
<jsp:setProperty name="oldhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="oldhelper" property="writer" value="<%=out%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:getProperty name="oldhelper" property="stats" />
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<hr />
|
||||
|
||||
<u><b>Peers</b></u><br />
|
||||
<b>Active:</b> <jsp:getProperty name="helper" property="activePeers" /><br />
|
||||
<b>Active:</b> <jsp:getProperty name="helper" property="activePeers" />/<jsp:getProperty name="helper" property="activeProfiles" /><br />
|
||||
<b>Fast:</b> <jsp:getProperty name="helper" property="fastPeers" /><br />
|
||||
<b>High capacity:</b> <jsp:getProperty name="helper" property="highCapacityPeers" /><br />
|
||||
<b>Well integrated:</b> <jsp:getProperty name="helper" property="wellIntegratedPeers" /><br />
|
||||
|
||||
@@ -28,6 +28,20 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* I2P-Ping won't compile on Windows because Windows lacks getopt()
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exit values:
|
||||
* 0: Received at least one response from one dest, or help
|
||||
* message was successfully displayed
|
||||
* 1: Received no responses from any dest
|
||||
* 2: Naming lookup failed, or dest unspecified
|
||||
* 3: SAM error
|
||||
*/
|
||||
|
||||
#include <getopt.h> /* needed on Gentoo Linux */
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -58,10 +72,11 @@ sam_sid_t laststream = 0;
|
||||
bool mihi = false;
|
||||
bool bell = false;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
int count = INT_MAX; /* number of times to ping */
|
||||
int pongcount = -1;
|
||||
char *samhost = "localhost";
|
||||
uint16_t samport = 7656;
|
||||
|
||||
@@ -88,7 +103,7 @@ int main(int argc, char* argv[])
|
||||
quiet = true;
|
||||
break;
|
||||
case 'v': /* version */
|
||||
puts("$Id: i2p-ping.c,v 1.2 2004/07/31 22:20:22 mpc Exp $");
|
||||
puts("$Id: i2p-ping.c,v 1.4 2004/09/22 20:05:40 jrandom Exp $");
|
||||
puts("Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>");
|
||||
break;
|
||||
case '?':
|
||||
@@ -101,7 +116,7 @@ int main(int argc, char* argv[])
|
||||
argv += optind;
|
||||
if (argc == 0) { /* they forgot to specify a ping target */
|
||||
fprintf(stderr, "Ping who?\n");
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Hook up the callback functions - required by LibSAM */
|
||||
@@ -120,9 +135,10 @@ int main(int argc, char* argv[])
|
||||
if (rc != SAM_OK) {
|
||||
fprintf(stderr, "SAM connection failed: %s\n", sam_strerror(rc));
|
||||
sam_session_free(&session);
|
||||
return 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
pongcount = 0;
|
||||
for (int j = 0; j < argc; j++) {
|
||||
if (strlen(argv[j]) == 516) {
|
||||
memcpy(dest, argv[j], SAM_PUBKEY_LEN);
|
||||
@@ -144,6 +160,8 @@ int main(int argc, char* argv[])
|
||||
time_t finish = time(0);
|
||||
laststream = 0;
|
||||
if (laststatus == SAM_OK) {
|
||||
pongcount++;
|
||||
|
||||
if (bell)
|
||||
printf("\a"); /* putchar() doesn't work for some reason */
|
||||
if (!mihi)
|
||||
@@ -164,7 +182,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
sam_close(session);
|
||||
sam_session_free(&session);
|
||||
return 0;
|
||||
return pongcount == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
void usage()
|
||||
@@ -178,7 +196,7 @@ void usage()
|
||||
*/
|
||||
static void closeback(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason)
|
||||
{
|
||||
fprintf(stderr, "Connection closed to stream %d: %s\n", stream_id,
|
||||
fprintf(stderr, "Connection closed to stream %d: %s\n", (int)stream_id,
|
||||
sam_strerror(reason));
|
||||
}
|
||||
|
||||
@@ -207,7 +225,7 @@ static void databack(sam_sess_t *session, sam_sid_t stream_id, void *data,
|
||||
static void diedback(sam_sess_t *session)
|
||||
{
|
||||
fprintf(stderr, "Lost SAM connection!\n");
|
||||
exit(1);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -228,7 +246,7 @@ static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result)
|
||||
{
|
||||
if (result != SAM_OK) {
|
||||
fprintf(stderr, "Naming lookup failed: %s\n", sam_strerror(result));
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
memcpy(dest, pubkey, SAM_PUBKEY_LEN);
|
||||
gotdest = true;
|
||||
@@ -238,7 +256,7 @@ static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result)
|
||||
* Our connection attempt returned a result
|
||||
*/
|
||||
static void statusback(sam_sess_t *session, sam_sid_t stream_id,
|
||||
samerr_t result)
|
||||
samerr_t result)
|
||||
{
|
||||
laststatus = result;
|
||||
laststream = stream_id;
|
||||
|
||||
@@ -55,7 +55,7 @@ static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result);
|
||||
bool gotdest = false;
|
||||
sam_pubkey_t dest;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/*
|
||||
* The target of our attack is specified on the command line
|
||||
@@ -142,7 +142,7 @@ int main(int argc, char* argv[])
|
||||
* service programs don't need input ;)
|
||||
*/
|
||||
static void dgramback(sam_sess_t *session, sam_pubkey_t dest, void *data,
|
||||
size_t size)
|
||||
size_t size)
|
||||
{
|
||||
puts("Received a datagram (ignored)");
|
||||
free(data);
|
||||
|
||||
29
build.xml
29
build.xml
@@ -6,7 +6,7 @@
|
||||
<echo message=" dist: distclean then package everything up (installer, clean tarball, update tarball)" />
|
||||
<echo message=" installer: build the GUI installer" />
|
||||
<echo message=" tarball: tar the full install into i2p.tar.bz2 (extracts to build a new clean install)" />
|
||||
<echo message=" updater: tar the built i2p specific files into an i2pupdate.tar.bz2 (extracts safely over existing installs)" />
|
||||
<echo message=" updater: tar the built i2p specific files into an i2pupdate.zip (extracts safely over existing installs)" />
|
||||
<echo message=" distclean: clean up all derived files" />
|
||||
<echo message=" javadoc: generate javadoc for the entire project into ./build/javadoc" />
|
||||
</target>
|
||||
@@ -57,7 +57,7 @@
|
||||
<target name="javadoc">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/javadoc" />
|
||||
<javadoc
|
||||
<javadoc access="package"
|
||||
destdir="./build/javadoc"
|
||||
packagenames="*"
|
||||
use="true"
|
||||
@@ -143,7 +143,7 @@
|
||||
<target name="pkgclean">
|
||||
<delete dir="pkg-temp" />
|
||||
<delete>
|
||||
<fileset dir="." includes="i2p.tar.bz2 install.jar i2pupdate.tar.bz2" />
|
||||
<fileset dir="." includes="i2p.tar.bz2 install.jar i2pupdate.zip" />
|
||||
</delete>
|
||||
</target>
|
||||
<target name="preppkg" depends="build">
|
||||
@@ -176,6 +176,7 @@
|
||||
<copy file="installer/resources/clients.config" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/i2prouter" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/i2prouter.bat" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/i2prouter_win9x.bat" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/i2ptunnel.config" todir="pkg-temp/" />
|
||||
<!-- <copy file="installer/resources/install_i2p_service_unix" todir="pkg-temp/" /> -->
|
||||
<copy file="installer/resources/install_i2p_service_winnt.bat" todir="pkg-temp/" />
|
||||
@@ -185,7 +186,7 @@
|
||||
<copy file="installer/resources/systray.config" todir="pkg-temp/" />
|
||||
<!-- <copy file="installer/resources/uninstall_i2p_service_unix" todir="pkg-temp/" /> -->
|
||||
<copy file="installer/resources/uninstall_i2p_service_winnt.bat" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/wrapper.conf" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/wrapper.config" todir="pkg-temp/" />
|
||||
<copy todir="pkg-temp/lib/wrapper/freebsd/">
|
||||
<fileset dir="installer/lib/wrapper/freebsd/" />
|
||||
</copy>
|
||||
@@ -206,6 +207,12 @@
|
||||
<copy file="history.txt" todir="pkg-temp/" />
|
||||
<mkdir dir="pkg-temp/docs" />
|
||||
<copy file="readme.html" todir="pkg-temp/docs/" />
|
||||
<mkdir dir="pkg-temp/eepsite" />
|
||||
<mkdir dir="pkg-temp/eepsite/webapps" />
|
||||
<mkdir dir="pkg-temp/eepsite/logs" />
|
||||
<mkdir dir="pkg-temp/eepsite/docroot" />
|
||||
<copy file="installer/resources/eepsite_index.html" tofile="pkg-temp/eepsite/docroot/index.html" />
|
||||
<copy file="installer/resources/jetty.xml" tofile="pkg-temp/eepsite/jetty.xml" />
|
||||
</target>
|
||||
<target name="tarball" depends="preppkg">
|
||||
<tar compression="bzip2" destfile="i2p.tar.bz2">
|
||||
@@ -214,20 +221,22 @@
|
||||
</target>
|
||||
<target name="updater" depends="build">
|
||||
<delete dir="pkg-temp" />
|
||||
<copy file="build/heartbeat.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/i2p.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/i2ptunnel.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/mstreaming.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/router.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/routerconsole.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/sam.jar" todir="pkg-temp/lib/" />
|
||||
<copy file="build/systray.jar" todir="pkg-temp/lib" />
|
||||
<copy file="build/i2ptunnel.war" todir="pkg-temp/webapps/" />
|
||||
<copy file="build/routerconsole.war" todir="pkg-temp/webapps/" />
|
||||
<copy file="history.txt" todir="pkg-temp/" />
|
||||
<tar compression="bzip2" destfile="i2pupdate.tar.bz2">
|
||||
<tarfileset dir="pkg-temp" includes="**/*" prefix="i2p" />
|
||||
</tar>
|
||||
<copy file="hosts.txt" todir="pkg-temp/" />
|
||||
<mkdir dir="pkg-temp/eepsite" />
|
||||
<mkdir dir="pkg-temp/eepsite/webapps" />
|
||||
<mkdir dir="pkg-temp/eepsite/logs" />
|
||||
<mkdir dir="pkg-temp/eepsite/docroot" />
|
||||
<copy file="installer/resources/eepsite_index.html" tofile="pkg-temp/eepsite/docroot/index.html" />
|
||||
<copy file="installer/resources/jetty.xml" tofile="pkg-temp/eepsite/jetty.xml" />
|
||||
<zip destfile="i2pupdate.zip" basedir="pkg-temp" />
|
||||
</target>
|
||||
<taskdef name="izpack" classpath="${basedir}/installer/lib/izpack/standalone-compiler.jar" classname="com.izforge.izpack.ant.IzPackTask" />
|
||||
<target name="installer" depends="preppkg">
|
||||
|
||||
@@ -417,17 +417,17 @@ public class CPUID {
|
||||
String wantedProp = System.getProperty("jcpuid.enable", "true");
|
||||
boolean wantNative = "true".equalsIgnoreCase(wantedProp);
|
||||
if (wantNative) {
|
||||
boolean loaded = loadFromResource();
|
||||
boolean loaded = loadGeneric();
|
||||
if (loaded) {
|
||||
_nativeOk = true;
|
||||
if (_doLog)
|
||||
System.err.println("INFO: Native CPUID library '"+getResourceName()+"' loaded from resource");
|
||||
System.err.println("INFO: Native CPUID library '"+getLibraryMiddlePart()+"' loaded from somewhere in the path");
|
||||
} else {
|
||||
loaded = loadGeneric();
|
||||
loaded = loadFromResource();
|
||||
if (loaded) {
|
||||
_nativeOk = true;
|
||||
if (_doLog)
|
||||
System.err.println("INFO: Native CPUID library '"+getLibraryMiddlePart()+"' loaded from somewhere in the path");
|
||||
System.err.println("INFO: Native CPUID library '"+getResourceName()+"' loaded from resource");
|
||||
} else {
|
||||
_nativeOk = false;
|
||||
if (_doLog)
|
||||
@@ -451,6 +451,12 @@ public class CPUID {
|
||||
*
|
||||
*/
|
||||
private static final boolean loadGeneric() {
|
||||
try {
|
||||
System.loadLibrary("jcpuid");
|
||||
return true;
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
// fallthrough, try the OS-specific filename
|
||||
}
|
||||
try {
|
||||
System.loadLibrary(getLibraryMiddlePart());
|
||||
return true;
|
||||
@@ -486,7 +492,7 @@ public class CPUID {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
InputStream libStream = resource.openStream();
|
||||
outFile = File.createTempFile(libPrefix + "jcpuid", "lib.tmp" + libSuffix);
|
||||
outFile = new File(libPrefix + "jcpuid" + libSuffix);
|
||||
fos = new FileOutputStream(outFile);
|
||||
byte buf[] = new byte[4096*1024];
|
||||
while (true) {
|
||||
@@ -515,10 +521,6 @@ public class CPUID {
|
||||
if (fos != null) {
|
||||
try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
if (outFile != null) {
|
||||
if (!outFile.delete())
|
||||
outFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ package net.i2p;
|
||||
*
|
||||
*/
|
||||
public class CoreVersion {
|
||||
public final static String ID = "$Revision: 1.18 $ $Date: 2004/08/20 14:56:35 $";
|
||||
public final static String VERSION = "0.4";
|
||||
public final static String ID = "$Revision: 1.20 $ $Date: 2004/09/08 21:26:42 $";
|
||||
public final static String VERSION = "0.4.1";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Core version: " + VERSION);
|
||||
|
||||
@@ -284,7 +284,7 @@ public class I2PAppContext {
|
||||
* matter. Though for the crazy people out there, we do expose a way to
|
||||
* disable it.
|
||||
*/
|
||||
public AESEngine AESEngine() {
|
||||
public AESEngine aes() {
|
||||
if (!_AESEngineInitialized) initializeAESEngine();
|
||||
return _AESEngine;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,13 @@ public interface I2PSession {
|
||||
*/
|
||||
public void connect() throws I2PSessionException;
|
||||
|
||||
/**
|
||||
* Have we closed the session?
|
||||
*
|
||||
* @return true if the session is closed
|
||||
*/
|
||||
public boolean isClosed();
|
||||
|
||||
/**
|
||||
* Retrieve the Destination this session serves as the endpoint for.
|
||||
* Returns null if no destination is available.
|
||||
|
||||
@@ -85,8 +85,6 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
/** used to seperate things out so we can get rid of singletons */
|
||||
protected I2PAppContext _context;
|
||||
|
||||
private int _totalReconnectAttempts;
|
||||
|
||||
/** monitor for waiting until a lease set has been granted */
|
||||
private Object _leaseSetWait = new Object();
|
||||
|
||||
@@ -137,7 +135,6 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
loadConfig(options);
|
||||
_sessionId = null;
|
||||
_leaseSet = null;
|
||||
_totalReconnectAttempts = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,7 +354,12 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
_pendingSizes = new ArrayList(2);
|
||||
}
|
||||
|
||||
public void stopNotifying() { _alive = false; }
|
||||
public void stopNotifying() {
|
||||
_alive = false;
|
||||
synchronized (AvailabilityNotifier.this) {
|
||||
AvailabilityNotifier.this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void available(int msgId, int size) {
|
||||
synchronized (AvailabilityNotifier.this) {
|
||||
@@ -502,7 +504,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
public void destroySession(boolean sendDisconnect) {
|
||||
if (_closed) return;
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Destroy the session", new Exception("DestroySession()"));
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Destroy the session", new Exception("DestroySession()"));
|
||||
if (sendDisconnect) {
|
||||
try {
|
||||
_producer.disconnect(this);
|
||||
@@ -521,7 +523,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
*
|
||||
*/
|
||||
private void closeSocket() {
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Closing the socket", new Exception("closeSocket"));
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Closing the socket", new Exception("closeSocket"));
|
||||
_closed = true;
|
||||
if (_reader != null) _reader.stopReading();
|
||||
_reader = null;
|
||||
@@ -564,8 +566,8 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
private final static int MAX_RECONNECT_ATTEMPTS = 1;
|
||||
private final static int MAX_TOTAL_RECONNECT_ATTEMPTS = 3;
|
||||
private final static int MAX_RECONNECT_DELAY = 320*1000;
|
||||
private final static int BASE_RECONNECT_DELAY = 10*1000;
|
||||
|
||||
protected boolean shouldReconnect() {
|
||||
return true;
|
||||
@@ -573,24 +575,25 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
||||
|
||||
protected boolean reconnect() {
|
||||
closeSocket();
|
||||
if (_totalReconnectAttempts < MAX_TOTAL_RECONNECT_ATTEMPTS) {
|
||||
_totalReconnectAttempts++;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.CRIT))
|
||||
_log.log(Log.CRIT, getPrefix() + "Max number of reconnects exceeded ["
|
||||
+ _totalReconnectAttempts + "], we give up!");
|
||||
return false;
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Reconnecting...");
|
||||
for (int i = 0; i < MAX_RECONNECT_ATTEMPTS; i++) {
|
||||
int i = 0;
|
||||
while (true) {
|
||||
long delay = BASE_RECONNECT_DELAY << i;
|
||||
i++;
|
||||
if ( (delay > MAX_RECONNECT_DELAY) || (delay <= 0) )
|
||||
delay = MAX_RECONNECT_DELAY;
|
||||
try { Thread.sleep(delay); } catch (InterruptedException ie) {}
|
||||
|
||||
try {
|
||||
connect();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix() + "Reconnected on attempt " + i);
|
||||
return true;
|
||||
} catch (I2PSessionException ise) {
|
||||
if (_log.shouldLog(Log.ERROR)) _log.error(getPrefix() + "Error reconnecting on attempt " + i, ise);
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error(getPrefix() + "Error reconnecting on attempt " + i, ise);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String getPrefix() { return "[" + (_sessionId == null ? -1 : _sessionId.getSessionId()) + "]: "; }
|
||||
|
||||
@@ -33,7 +33,6 @@ import net.i2p.util.Log;
|
||||
* @author jrandom
|
||||
*/
|
||||
class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
private final static Log _log = new Log(RequestLeaseSetMessageHandler.class);
|
||||
private Map _existingLeaseSets;
|
||||
|
||||
public RequestLeaseSetMessageHandler(I2PAppContext context) {
|
||||
@@ -67,9 +66,13 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
|
||||
synchronized (_existingLeaseSets) {
|
||||
_existingLeaseSets.put(session.getMyDestination(), li);
|
||||
}
|
||||
_log.debug("Creating new leaseInfo keys", new Exception("new leaseInfo keys"));
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Creating new leaseInfo keys for "
|
||||
+ session.getMyDestination().calculateHash().toBase64());
|
||||
} else {
|
||||
_log.debug("Caching the old leaseInfo keys", new Exception("cached! w00t"));
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Caching the old leaseInfo keys for "
|
||||
+ session.getMyDestination().calculateHash().toBase64());
|
||||
}
|
||||
|
||||
leaseSet.setEncryptionKey(li.getPublicKey());
|
||||
|
||||
@@ -10,7 +10,10 @@ package net.i2p.client.naming;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Destination;
|
||||
@@ -34,42 +37,58 @@ public class HostsTxtNamingService extends NamingService {
|
||||
* If this system property is specified, the tunnel will read the
|
||||
* given file for hostname=destKey values when resolving names
|
||||
*/
|
||||
public final static String PROP_HOSTS_FILE = "i2p.hostsfile";
|
||||
public final static String PROP_HOSTS_FILE = "i2p.hostsfilelist";
|
||||
|
||||
/** default hosts.txt filename */
|
||||
public final static String DEFAULT_HOSTS_FILE = "hosts.txt";
|
||||
public final static String DEFAULT_HOSTS_FILE = "userhosts.txt,hosts.txt";
|
||||
|
||||
private final static Log _log = new Log(HostsTxtNamingService.class);
|
||||
|
||||
private List getFilenames() {
|
||||
String list = _context.getProperty(PROP_HOSTS_FILE, DEFAULT_HOSTS_FILE);
|
||||
StringTokenizer tok = new StringTokenizer(list, ",");
|
||||
List rv = new ArrayList(tok.countTokens());
|
||||
while (tok.hasMoreTokens())
|
||||
rv.add(tok.nextToken());
|
||||
return rv;
|
||||
}
|
||||
|
||||
public Destination lookup(String hostname) {
|
||||
// Try to look it up in hosts.txt
|
||||
// Reload file each time to catch changes.
|
||||
// (and it's easier :P
|
||||
String hostsfile = _context.getProperty(PROP_HOSTS_FILE, DEFAULT_HOSTS_FILE);
|
||||
Properties hosts = new Properties();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
File f = new File(hostsfile);
|
||||
if (f.canRead()) {
|
||||
fis = new FileInputStream(f);
|
||||
hosts.load(fis);
|
||||
} else {
|
||||
_log.error("Hosts file " + hostsfile + " does not exist.");
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
_log.error("Error loading hosts file " + hostsfile, ioe);
|
||||
} finally {
|
||||
if (fis != null) try {
|
||||
fis.close();
|
||||
} catch (IOException ioe) { // nop
|
||||
// check the list each time, reloading the file on each
|
||||
// lookup
|
||||
|
||||
List filenames = getFilenames();
|
||||
for (int i = 0; i < filenames.size(); i++) {
|
||||
String hostsfile = (String)filenames.get(i);
|
||||
Properties hosts = new Properties();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
File f = new File(hostsfile);
|
||||
if ( (f.exists()) && (f.canRead()) ) {
|
||||
fis = new FileInputStream(f);
|
||||
hosts.load(fis);
|
||||
|
||||
String key = hosts.getProperty(hostname);
|
||||
if ( (key != null) && (key.trim().length() > 0) ) {
|
||||
return lookupBase64(key);
|
||||
}
|
||||
|
||||
} else {
|
||||
_log.warn("Hosts file " + hostsfile + " does not exist.");
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
_log.error("Error loading hosts file " + hostsfile, ioe);
|
||||
} finally {
|
||||
if (fis != null) try {
|
||||
fis.close();
|
||||
} catch (IOException ioe) { // nop
|
||||
}
|
||||
}
|
||||
// not found, continue to the next file
|
||||
}
|
||||
String res = hosts.getProperty(hostname);
|
||||
// If we can't find name in hosts, assume it's a key.
|
||||
if ((res == null) || (res.trim().length() == 0)) {
|
||||
res = hostname;
|
||||
}
|
||||
return lookupBase64(res);
|
||||
// If we can't find name in any of the hosts files,
|
||||
// assume it's a key.
|
||||
return lookupBase64(hostname);
|
||||
}
|
||||
|
||||
public String reverseLookup(Destination dest) {
|
||||
|
||||
@@ -37,28 +37,23 @@ public class AESEngine {
|
||||
|
||||
/** Encrypt the payload with the session key
|
||||
* @param payload data to be encrypted
|
||||
* @param payloadIndex index into the payload to start encrypting
|
||||
* @param out where to store the result
|
||||
* @param outIndex where in out to start writing
|
||||
* @param sessionKey private esession key to encrypt to
|
||||
* @param initializationVector IV for CBC
|
||||
* @return encrypted data
|
||||
* @param iv IV for CBC
|
||||
* @param length how much data to encrypt
|
||||
*/
|
||||
public byte[] encrypt(byte payload[], SessionKey sessionKey, byte initializationVector[]) {
|
||||
if ((initializationVector == null) || (payload == null) || (sessionKey == null)
|
||||
|| (initializationVector.length != 16)) return null;
|
||||
|
||||
byte cyphertext[] = null;
|
||||
if ((payload.length % 16) == 0)
|
||||
cyphertext = new byte[payload.length];
|
||||
else
|
||||
cyphertext = new byte[payload.length + (16 - (payload.length % 16))];
|
||||
System.arraycopy(payload, 0, cyphertext, 0, payload.length);
|
||||
return cyphertext;
|
||||
public void encrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int length) {
|
||||
System.arraycopy(payload, payloadIndex, out, outIndex, length);
|
||||
_log.warn("Warning: AES is disabled");
|
||||
}
|
||||
|
||||
public byte[] safeEncrypt(byte payload[], SessionKey sessionKey, byte iv[], int paddedSize) {
|
||||
if ((iv == null) || (payload == null) || (sessionKey == null) || (iv.length != 16)) return null;
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(paddedSize + 64);
|
||||
Hash h = _context.sha().calculateHash(sessionKey.getData());
|
||||
Hash h = _context.sha().calculateHash(iv);
|
||||
try {
|
||||
h.writeBytes(baos);
|
||||
DataHelper.writeLong(baos, 4, payload.length);
|
||||
@@ -72,19 +67,23 @@ public class AESEngine {
|
||||
_log.error("Error writing data", dfe);
|
||||
return null;
|
||||
}
|
||||
return encrypt(baos.toByteArray(), sessionKey, iv);
|
||||
byte orig[] = baos.toByteArray();
|
||||
byte rv[] = new byte[orig.length];
|
||||
encrypt(orig, 0, rv, 0, sessionKey, iv, rv.length);
|
||||
return rv;
|
||||
}
|
||||
|
||||
public byte[] safeDecrypt(byte payload[], SessionKey sessionKey, byte iv[]) {
|
||||
if ((iv == null) || (payload == null) || (sessionKey == null) || (iv.length != 16)) return null;
|
||||
|
||||
byte decr[] = decrypt(payload, sessionKey, iv);
|
||||
byte decr[] = new byte[payload.length];
|
||||
decrypt(payload, 0, decr, 0, sessionKey, iv, payload.length);
|
||||
if (decr == null) {
|
||||
_log.error("Error decrypting the data - payload " + payload.length + " decrypted to null");
|
||||
return null;
|
||||
}
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(decr);
|
||||
Hash h = _context.sha().calculateHash(sessionKey.getData());
|
||||
Hash h = _context.sha().calculateHash(iv);
|
||||
try {
|
||||
Hash rh = new Hash();
|
||||
rh.readBytes(bais);
|
||||
@@ -110,19 +109,19 @@ public class AESEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/** decrypt the data with the session key provided
|
||||
* @param cyphertext encrypted data
|
||||
* @param sessionKey private session key
|
||||
* @param initializationVector IV for CBC
|
||||
* @return unencrypted data
|
||||
*/
|
||||
public byte[] decrypt(byte cyphertext[], SessionKey sessionKey, byte initializationVector[]) {
|
||||
if ((initializationVector == null) || (cyphertext == null) || (sessionKey == null)
|
||||
|| (initializationVector.length != 16)) return null;
|
||||
|
||||
byte payload[] = new byte[cyphertext.length];
|
||||
/** Decrypt the data with the session key
|
||||
* @param payload data to be decrypted
|
||||
* @param payloadIndex index into the payload to start decrypting
|
||||
* @param out where to store the cleartext
|
||||
* @param outIndex where in out to start writing
|
||||
* @param sessionKey private session key to decrypt to
|
||||
* @param iv IV for CBC
|
||||
* @param length how much data to decrypt
|
||||
*/
|
||||
public void decrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int length) {
|
||||
System.arraycopy(payload, payloadIndex, out, outIndex, length);
|
||||
_log.warn("Warning: AES is disabled");
|
||||
return cyphertext;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
@@ -133,14 +132,16 @@ public class AESEngine {
|
||||
|
||||
byte sbuf[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(sbuf);
|
||||
byte se[] = ctx.AESEngine().encrypt(sbuf, key, iv);
|
||||
byte sd[] = ctx.AESEngine().decrypt(se, key, iv);
|
||||
byte se[] = new byte[16];
|
||||
ctx.aes().encrypt(sbuf, 0, se, 0, key, iv, sbuf.length);
|
||||
byte sd[] = new byte[16];
|
||||
ctx.aes().decrypt(se, 0, sd, 0, key, iv, se.length);
|
||||
ctx.logManager().getLog(AESEngine.class).debug("Short test: " + DataHelper.eq(sd, sbuf));
|
||||
|
||||
byte lbuf[] = new byte[1024];
|
||||
RandomSource.getInstance().nextBytes(sbuf);
|
||||
byte le[] = ctx.AESEngine().safeEncrypt(lbuf, key, iv, 2048);
|
||||
byte ld[] = ctx.AESEngine().safeDecrypt(le, key, iv);
|
||||
byte le[] = ctx.aes().safeEncrypt(lbuf, key, iv, 2048);
|
||||
byte ld[] = ctx.aes().safeDecrypt(le, key, iv);
|
||||
ctx.logManager().getLog(AESEngine.class).debug("Long test: " + DataHelper.eq(ld, lbuf));
|
||||
}
|
||||
}
|
||||
@@ -230,22 +230,21 @@ public class AESInputStream extends FilterInputStream {
|
||||
_log.info(encrypted.length + " bytes makes up " + numBlocks + " blocks to decrypt normally");
|
||||
}
|
||||
|
||||
byte block[] = new byte[BLOCK_SIZE];
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
System.arraycopy(encrypted, i * BLOCK_SIZE, block, 0, BLOCK_SIZE);
|
||||
byte decrypted[] = _context.AESEngine().decrypt(block, _key, _lastBlock);
|
||||
byte data[] = DataHelper.xor(decrypted, _lastBlock);
|
||||
int cleaned[] = stripPadding(data);
|
||||
for (int j = 0; j < cleaned.length; j++) {
|
||||
if (cleaned[j] <= 0) {
|
||||
cleaned[j] += 256;
|
||||
//_log.error("(modified: " + cleaned[j] + ")");
|
||||
}
|
||||
_readyBuf.add(new Integer(cleaned[j]));
|
||||
_context.aes().decrypt(encrypted, i * BLOCK_SIZE, encrypted, i * BLOCK_SIZE, _key, _lastBlock, BLOCK_SIZE);
|
||||
DataHelper.xor(encrypted, i * BLOCK_SIZE, _lastBlock, 0, encrypted, i * BLOCK_SIZE, BLOCK_SIZE);
|
||||
int payloadBytes = countBlockPayload(encrypted, i * BLOCK_SIZE);
|
||||
|
||||
for (int j = 0; j < payloadBytes; j++) {
|
||||
int c = encrypted[j + i * BLOCK_SIZE];
|
||||
if (c <= 0)
|
||||
c += 256;
|
||||
_readyBuf.add(new Integer(c));
|
||||
}
|
||||
_cumulativePrepared += cleaned.length;
|
||||
//_log.debug("Updating last block for inputStream");
|
||||
System.arraycopy(decrypted, 0, _lastBlock, 0, BLOCK_SIZE);
|
||||
_cumulativePaddingStripped += BLOCK_SIZE - payloadBytes;
|
||||
_cumulativePrepared += payloadBytes;
|
||||
|
||||
System.arraycopy(encrypted, i * BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
int remaining = encrypted.length % BLOCK_SIZE;
|
||||
@@ -263,6 +262,9 @@ public class AESInputStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
/**
|
||||
* How many non-padded bytes are there in the block starting at the given
|
||||
* location.
|
||||
*
|
||||
* PKCS#5 specifies the padding for the block has the # of padding bytes
|
||||
* located in the last byte of the block, and each of the padding bytes are
|
||||
* equal to that value.
|
||||
@@ -275,31 +277,29 @@ public class AESInputStream extends FilterInputStream {
|
||||
*
|
||||
* We use 16 byte blocks in this AES implementation
|
||||
*
|
||||
* @throws IOException if the padding is invalid
|
||||
*/
|
||||
private int[] stripPadding(byte data[]) throws IOException {
|
||||
int numPadBytes = data[data.length - 1];
|
||||
if ((numPadBytes >= data.length) || (numPadBytes <= 0)) {
|
||||
private int countBlockPayload(byte data[], int startIndex) throws IOException {
|
||||
int numPadBytes = data[startIndex + BLOCK_SIZE - 1];
|
||||
if ((numPadBytes >= BLOCK_SIZE) || (numPadBytes <= 0)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("stripPadding from block " + DataHelper.toHexString(data) + " (" + data.length + "bytes): "
|
||||
_log.debug("countBlockPayload on block index " + startIndex
|
||||
+ numPadBytes + " is an invalid # of pad bytes");
|
||||
throw new IOException("Invalid number of pad bytes (" + numPadBytes
|
||||
+ ") for " + data.length + " bytes");
|
||||
+ ") for " + startIndex + " index");
|
||||
}
|
||||
|
||||
int rv[] = new int[data.length - numPadBytes];
|
||||
// optional, but a really good idea: verify the padding
|
||||
if (true) {
|
||||
for (int i = data.length - numPadBytes; i < data.length; i++) {
|
||||
if (data[i] != (byte) numPadBytes) {
|
||||
for (int i = BLOCK_SIZE - numPadBytes; i < BLOCK_SIZE; i++) {
|
||||
if (data[startIndex + i] != (byte) numPadBytes) {
|
||||
throw new IOException("Incorrect padding on decryption: data[" + i
|
||||
+ "] = " + data[i] + " not " + numPadBytes);
|
||||
+ "] = " + data[startIndex + i] + " not " + numPadBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = data[i];
|
||||
_cumulativePaddingStripped += numPadBytes;
|
||||
return rv;
|
||||
|
||||
return BLOCK_SIZE - numPadBytes;
|
||||
}
|
||||
|
||||
int remainingBytes() {
|
||||
@@ -377,12 +377,12 @@ public class AESInputStream extends FilterInputStream {
|
||||
long endE = Clock.getInstance().now();
|
||||
|
||||
ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encrypted);
|
||||
AESInputStream in = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
AESInputStream sin = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||
byte buf[] = new byte[1024 * 32];
|
||||
int read = DataHelper.read(in, buf);
|
||||
int read = DataHelper.read(sin, buf);
|
||||
if (read > 0) baos.write(buf, 0, read);
|
||||
in.close();
|
||||
sin.close();
|
||||
byte fin[] = baos.toByteArray();
|
||||
long end = Clock.getInstance().now();
|
||||
Hash origHash = SHA256Generator.getInstance().calculateHash(orig);
|
||||
@@ -422,15 +422,15 @@ public class AESInputStream extends FilterInputStream {
|
||||
System.arraycopy(encrypted, 0, encryptedSegment, 0, 40);
|
||||
|
||||
ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encryptedSegment);
|
||||
AESInputStream in = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
AESInputStream sin = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||
byte buf[] = new byte[1024 * 32];
|
||||
int read = DataHelper.read(in, buf);
|
||||
int remaining = in.remainingBytes();
|
||||
int readyBytes = in.readyBytes();
|
||||
int read = DataHelper.read(sin, buf);
|
||||
int remaining = sin.remainingBytes();
|
||||
int readyBytes = sin.readyBytes();
|
||||
log.info("Read: " + read);
|
||||
if (read > 0) baos.write(buf, 0, read);
|
||||
in.close();
|
||||
sin.close();
|
||||
byte fin[] = baos.toByteArray();
|
||||
log.info("fin.length: " + fin.length + " remaining: " + remaining + " ready: " + readyBytes);
|
||||
long end = Clock.getInstance().now();
|
||||
|
||||
@@ -106,18 +106,16 @@ public class AESOutputStream extends FilterOutputStream {
|
||||
int numBlocks = src.length / (BLOCK_SIZE - 1);
|
||||
|
||||
byte block[] = new byte[BLOCK_SIZE];
|
||||
block[BLOCK_SIZE - 1] = 0x01; // the padding byte for "full" blocks
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
System.arraycopy(src, i * 15, block, 0, 15);
|
||||
byte data[] = DataHelper.xor(block, _lastBlock);
|
||||
byte encrypted[] = _context.AESEngine().encrypt(data, _key, _lastBlock);
|
||||
_cumulativeWritten += encrypted.length;
|
||||
DataHelper.xor(src, i * 15, _lastBlock, 0, block, 0, 15);
|
||||
// the padding byte for "full" blocks
|
||||
block[BLOCK_SIZE - 1] = (byte)(_lastBlock[BLOCK_SIZE - 1] ^ 0x01);
|
||||
_context.aes().encrypt(block, 0, block, 0, _key, _lastBlock, BLOCK_SIZE);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Padding block " + i + " of " + numBlocks + " with 1 byte. orig= "
|
||||
+ DataHelper.toHexString(data) + " (size=" + data.length + ") encrypted= "
|
||||
+ DataHelper.toHexString(encrypted) + " (size=" + encrypted.length + ")");
|
||||
out.write(encrypted);
|
||||
System.arraycopy(encrypted, encrypted.length - BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE);
|
||||
_log.debug("Padding block " + i + " of " + numBlocks + " with 1 byte");
|
||||
out.write(block);
|
||||
System.arraycopy(block, 0, _lastBlock, 0, BLOCK_SIZE);
|
||||
_cumulativeWritten += BLOCK_SIZE;
|
||||
_cumulativePadding++;
|
||||
}
|
||||
|
||||
@@ -129,12 +127,12 @@ public class AESOutputStream extends FilterOutputStream {
|
||||
_log.debug("Padding " + src.length + " with " + paddingBytes + " bytes in " + numBlocks + " blocks");
|
||||
System.arraycopy(src, numBlocks * 15, block, 0, remainingBytes);
|
||||
Arrays.fill(block, remainingBytes, BLOCK_SIZE, (byte) paddingBytes);
|
||||
byte data[] = DataHelper.xor(block, _lastBlock);
|
||||
byte encrypted[] = _context.AESEngine().encrypt(data, _key, _lastBlock);
|
||||
out.write(encrypted);
|
||||
System.arraycopy(encrypted, encrypted.length - BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE);
|
||||
DataHelper.xor(block, 0, _lastBlock, 0, block, 0, BLOCK_SIZE);
|
||||
_context.aes().encrypt(block, 0, block, 0, _key, _lastBlock, BLOCK_SIZE);
|
||||
out.write(block);
|
||||
System.arraycopy(block, 0, _lastBlock, 0, BLOCK_SIZE);
|
||||
_cumulativePadding += paddingBytes;
|
||||
_cumulativeWritten += encrypted.length;
|
||||
_cumulativeWritten += BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ package net.i2p.crypto;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@@ -33,104 +34,63 @@ public class CryptixAESEngine extends AESEngine {
|
||||
super(context);
|
||||
_log = context.logManager().getLog(CryptixAESEngine.class);
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte payload[], SessionKey sessionKey, byte initializationVector[]) {
|
||||
if ((initializationVector == null) || (payload == null) || (payload.length <= 0) || (sessionKey == null)
|
||||
|| (initializationVector.length != 16)) return null;
|
||||
|
||||
public void encrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int length) {
|
||||
if ( (payload == null) || (out == null) || (sessionKey == null) || (iv == null) || (iv.length != 16) )
|
||||
throw new NullPointerException("invalid args to aes");
|
||||
if (payload.length < payloadIndex + length)
|
||||
throw new IllegalArgumentException("Payload is too short");
|
||||
if (out.length < outIndex + length)
|
||||
throw new IllegalArgumentException("Output is too short");
|
||||
if (length <= 0)
|
||||
throw new IllegalArgumentException("Length is too small");
|
||||
if (length % 16 != 0)
|
||||
throw new IllegalArgumentException("Only lengths mod 16 are supported here");
|
||||
|
||||
if (USE_FAKE_CRYPTO) {
|
||||
_log.warn("AES Crypto disabled! Using trivial XOR");
|
||||
byte rv[] = new byte[payload.length];
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = (byte) (payload[i] ^ FAKE_KEY);
|
||||
return rv;
|
||||
System.arraycopy(payload, payloadIndex, out, outIndex, length);
|
||||
return;
|
||||
}
|
||||
|
||||
int numblock = length / 16;
|
||||
|
||||
DataHelper.xor(iv, 0, payload, payloadIndex, out, outIndex, 16);
|
||||
encryptBlock(out, outIndex, sessionKey, out, outIndex);
|
||||
for (int x = 1; x < numblock; x++) {
|
||||
DataHelper.xor(out, outIndex + (x-1) * 16, payload, payloadIndex + x * 16, out, outIndex + x * 16, 16);
|
||||
encryptBlock(out, outIndex + x * 16, sessionKey, out, outIndex + x * 16);
|
||||
}
|
||||
}
|
||||
|
||||
public void decrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int length) {
|
||||
if ((iv== null) || (payload == null) || (payload.length <= 0) || (sessionKey == null)
|
||||
|| (iv.length != 16))
|
||||
throw new IllegalArgumentException("bad setup");
|
||||
|
||||
if (USE_FAKE_CRYPTO) {
|
||||
_log.warn("AES Crypto disabled! Using trivial XOR");
|
||||
System.arraycopy(payload, payloadIndex, out, outIndex, length);
|
||||
return ;
|
||||
}
|
||||
|
||||
int numblock = payload.length / 16;
|
||||
if (payload.length % 16 != 0) numblock++;
|
||||
byte[][] plain = new byte[numblock][16];
|
||||
for (int x = 0; x < numblock; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
plain[x][y] = payload[x * 16 + y];
|
||||
}
|
||||
}
|
||||
|
||||
byte[][] cipher = new byte[numblock][16];
|
||||
cipher[0] = encrypt(xor(initializationVector, plain[0]), sessionKey);
|
||||
decryptBlock(payload, 0, sessionKey, out, 0);
|
||||
DataHelper.xor(out, 0, iv, 0, out, 0, 16);
|
||||
for (int x = 1; x < numblock; x++) {
|
||||
cipher[x] = encrypt(xor(cipher[x - 1], plain[x]), sessionKey);
|
||||
decryptBlock(payload, x * 16, sessionKey, out, x * 16);
|
||||
DataHelper.xor(out, x * 16, payload, (x - 1) * 16, out, x * 16, 16);
|
||||
}
|
||||
|
||||
byte[] ret = new byte[numblock * 16];
|
||||
for (int x = 0; x < numblock; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
ret[x * 16 + y] = cipher[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte payload[], SessionKey sessionKey, byte initializationVector[]) {
|
||||
if ((initializationVector == null) || (payload == null) || (payload.length <= 0) || (sessionKey == null)
|
||||
|| (initializationVector.length != 16)) return null;
|
||||
|
||||
if (USE_FAKE_CRYPTO) {
|
||||
_log.warn("AES Crypto disabled! Using trivial XOR");
|
||||
byte rv[] = new byte[payload.length];
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = (byte) (payload[i] ^ FAKE_KEY);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int numblock = payload.length / 16;
|
||||
if (payload.length % 16 != 0) numblock++;
|
||||
byte[][] cipher = new byte[numblock][16];
|
||||
for (int x = 0; x < numblock; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
cipher[x][y] = payload[x * 16 + y];
|
||||
}
|
||||
}
|
||||
|
||||
byte[][] plain = new byte[numblock][16];
|
||||
plain[0] = xor(decrypt(cipher[0], sessionKey), initializationVector);
|
||||
for (int x = 1; x < numblock; x++) {
|
||||
plain[x] = xor(decrypt(cipher[x], sessionKey), cipher[x - 1]);
|
||||
}
|
||||
|
||||
byte[] ret = new byte[numblock * 16];
|
||||
for (int x = 0; x < numblock; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
ret[x * 16 + y] = plain[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
final static byte[] xor(byte[] a, byte[] b) {
|
||||
if ((a == null) || (b == null) || (a.length != b.length)) return null;
|
||||
byte[] ret = new byte[a.length];
|
||||
for (int x = 0; x < a.length; x++) {
|
||||
ret[x] = (byte) (a[x] ^ b[x]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Encrypt the payload with the session key
|
||||
* @param payload data to be encrypted
|
||||
* @param sessionKey private esession key to encrypt to
|
||||
* @return encrypted data
|
||||
*/
|
||||
final byte[] encrypt(byte payload[], SessionKey sessionKey) {
|
||||
final void encryptBlock(byte payload[], int inIndex, SessionKey sessionKey, byte out[], int outIndex) {
|
||||
try {
|
||||
Object key = CryptixRijndael_Algorithm.makeKey(sessionKey.getData(), 16);
|
||||
byte rv[] = new byte[payload.length];
|
||||
CryptixRijndael_Algorithm.blockEncrypt(payload, rv, 0, key, 16);
|
||||
return rv;
|
||||
CryptixRijndael_Algorithm.blockEncrypt(payload, out, inIndex, outIndex, key, 16);
|
||||
} catch (InvalidKeyException ike) {
|
||||
_log.error("Invalid key", ike);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,15 +99,55 @@ public class CryptixAESEngine extends AESEngine {
|
||||
* @param sessionKey private session key
|
||||
* @return unencrypted data
|
||||
*/
|
||||
final byte[] decrypt(byte payload[], SessionKey sessionKey) {
|
||||
final void decryptBlock(byte payload[], int inIndex, SessionKey sessionKey, byte rv[], int outIndex) {
|
||||
try {
|
||||
Object key = CryptixRijndael_Algorithm.makeKey(sessionKey.getData(), 16);
|
||||
byte rv[] = new byte[payload.length];
|
||||
CryptixRijndael_Algorithm.blockDecrypt(payload, rv, 0, key, 16);
|
||||
return rv;
|
||||
CryptixRijndael_Algorithm.blockDecrypt(payload, rv, inIndex, outIndex, key, 16);
|
||||
} catch (InvalidKeyException ike) {
|
||||
_log.error("Invalid key", ike);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
try {
|
||||
testEDBlock(ctx);
|
||||
testED(ctx);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||
}
|
||||
private static void testED(I2PAppContext ctx) {
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[128];
|
||||
byte encrypted[] = new byte[128];
|
||||
byte decrypted[] = new byte[128];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encrypt(orig, 0, encrypted, 0, key, iv, orig.length);
|
||||
aes.decrypt(encrypted, 0, decrypted, 0, key, iv, encrypted.length);
|
||||
if (!DataHelper.eq(decrypted,orig))
|
||||
throw new RuntimeException("full D(E(orig)) != orig");
|
||||
else
|
||||
System.out.println("full D(E(orig)) == orig");
|
||||
}
|
||||
private static void testEDBlock(I2PAppContext ctx) {
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[16];
|
||||
byte encrypted[] = new byte[16];
|
||||
byte decrypted[] = new byte[16];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encryptBlock(orig, 0, key, encrypted, 0);
|
||||
aes.decryptBlock(encrypted, 0, key, decrypted, 0);
|
||||
if (!DataHelper.eq(decrypted,orig))
|
||||
throw new RuntimeException("block D(E(orig)) != orig");
|
||||
else
|
||||
System.out.println("block D(E(orig)) == orig");
|
||||
}
|
||||
}
|
||||
@@ -382,7 +382,7 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
* @param inOffset Index of in from which to start considering data.
|
||||
* @param sessionKey The session key to use for encryption.
|
||||
*/
|
||||
public static final void blockEncrypt(byte[] in, byte[] result, int inOffset, Object sessionKey) {
|
||||
public static final void blockEncrypt(byte[] in, byte[] result, int inOffset, int outOffset, Object sessionKey) {
|
||||
if (_RDEBUG) trace(_IN, "blockEncrypt(" + in + ", " + inOffset + ", " + sessionKey + ")");
|
||||
int[][] Ke = (int[][]) ((Object[]) sessionKey)[0]; // extract encryption round keys
|
||||
int ROUNDS = Ke.length - 1;
|
||||
@@ -417,25 +417,25 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
// last round is special
|
||||
Ker = Ke[ROUNDS];
|
||||
int tt = Ker[0];
|
||||
result[0] = (byte) (_S[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[1] = (byte) (_S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[2] = (byte) (_S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[3] = (byte) (_S[t3 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_S[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_S[t3 & 0xFF] ^ tt);
|
||||
tt = Ker[1];
|
||||
result[4] = (byte) (_S[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[5] = (byte) (_S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[6] = (byte) (_S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[7] = (byte) (_S[t0 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_S[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_S[t0 & 0xFF] ^ tt);
|
||||
tt = Ker[2];
|
||||
result[8] = (byte) (_S[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[9] = (byte) (_S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[10] = (byte) (_S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[11] = (byte) (_S[t1 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_S[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_S[t1 & 0xFF] ^ tt);
|
||||
tt = Ker[3];
|
||||
result[12] = (byte) (_S[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[13] = (byte) (_S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[14] = (byte) (_S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[15] = (byte) (_S[t2 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_S[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_S[t2 & 0xFF] ^ tt);
|
||||
if (_RDEBUG && _debuglevel > 6) {
|
||||
System.out.println("CT=" + toString(result));
|
||||
System.out.println();
|
||||
@@ -452,7 +452,7 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
* @param inOffset Index of in from which to start considering data.
|
||||
* @param sessionKey The session key to use for decryption.
|
||||
*/
|
||||
public static final void blockDecrypt(byte[] in, byte[] result, int inOffset, Object sessionKey) {
|
||||
public static final void blockDecrypt(byte[] in, byte[] result, int inOffset, int outOffset, Object sessionKey) {
|
||||
if (_RDEBUG) trace(_IN, "blockDecrypt(" + in + ", " + inOffset + ", " + sessionKey + ")");
|
||||
int[][] Kd = (int[][]) ((Object[]) sessionKey)[1]; // extract decryption round keys
|
||||
int ROUNDS = Kd.length - 1;
|
||||
@@ -487,25 +487,25 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
// last round is special
|
||||
Kdr = Kd[ROUNDS];
|
||||
int tt = Kdr[0];
|
||||
result[0] = (byte) (_Si[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[1] = (byte) (_Si[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[2] = (byte) (_Si[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[3] = (byte) (_Si[t1 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_Si[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_Si[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_Si[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_Si[t1 & 0xFF] ^ tt);
|
||||
tt = Kdr[1];
|
||||
result[4] = (byte) (_Si[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[5] = (byte) (_Si[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[6] = (byte) (_Si[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[7] = (byte) (_Si[t2 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_Si[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_Si[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_Si[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_Si[t2 & 0xFF] ^ tt);
|
||||
tt = Kdr[2];
|
||||
result[8] = (byte) (_Si[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[9] = (byte) (_Si[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[10] = (byte) (_Si[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[11] = (byte) (_Si[t3 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_Si[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_Si[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_Si[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_Si[t3 & 0xFF] ^ tt);
|
||||
tt = Kdr[3];
|
||||
result[12] = (byte) (_Si[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[13] = (byte) (_Si[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[14] = (byte) (_Si[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[15] = (byte) (_Si[t0 & 0xFF] ^ tt);
|
||||
result[outOffset++] = (byte) (_Si[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
|
||||
result[outOffset++] = (byte) (_Si[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
|
||||
result[outOffset++] = (byte) (_Si[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
|
||||
result[outOffset++] = (byte) (_Si[t0 & 0xFF] ^ tt);
|
||||
if (_RDEBUG && _debuglevel > 6) {
|
||||
System.out.println("PT=" + toString(result));
|
||||
System.out.println();
|
||||
@@ -618,9 +618,9 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
* @param sessionKey The session key to use for encryption.
|
||||
* @param blockSize The block size in bytes of this Rijndael.
|
||||
*/
|
||||
public static final void blockEncrypt(byte[] in, byte[] result, int inOffset, Object sessionKey, int blockSize) {
|
||||
public static final void blockEncrypt(byte[] in, byte[] result, int inOffset, int outOffset, Object sessionKey, int blockSize) {
|
||||
if (blockSize == _BLOCK_SIZE) {
|
||||
blockEncrypt(in, result, inOffset, sessionKey);
|
||||
blockEncrypt(in, result, inOffset, outOffset, sessionKey);
|
||||
return;
|
||||
}
|
||||
if (_RDEBUG) trace(_IN, "blockEncrypt(" + in + ", " + inOffset + ", " + sessionKey + ", " + blockSize + ")");
|
||||
@@ -636,7 +636,8 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
int[] a = new int[BC];
|
||||
int[] t = new int[BC]; // temporary work array
|
||||
int i;
|
||||
int j = 0, tt;
|
||||
int j = outOffset;
|
||||
int tt;
|
||||
|
||||
for (i = 0; i < BC; i++)
|
||||
// plaintext to ints + key
|
||||
@@ -673,9 +674,9 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
* @param sessionKey The session key to use for decryption.
|
||||
* @param blockSize The block size in bytes of this Rijndael.
|
||||
*/
|
||||
public static final void blockDecrypt(byte[] in, byte[] result, int inOffset, Object sessionKey, int blockSize) {
|
||||
public static final void blockDecrypt(byte[] in, byte[] result, int inOffset, int outOffset, Object sessionKey, int blockSize) {
|
||||
if (blockSize == _BLOCK_SIZE) {
|
||||
blockDecrypt(in, result, inOffset, sessionKey);
|
||||
blockDecrypt(in, result, inOffset, outOffset, sessionKey);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -692,7 +693,8 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
int[] a = new int[BC];
|
||||
int[] t = new int[BC]; // temporary work array
|
||||
int i;
|
||||
int j = 0, tt;
|
||||
int j = outOffset;
|
||||
int tt;
|
||||
|
||||
for (i = 0; i < BC; i++)
|
||||
// ciphertext to ints + key
|
||||
@@ -749,7 +751,7 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
System.out.println("PT=" + toString(pt));
|
||||
}
|
||||
byte[] ct = new byte[_BLOCK_SIZE];
|
||||
blockEncrypt(pt, ct, 0, key, _BLOCK_SIZE);
|
||||
blockEncrypt(pt, ct, 0, 0, key, _BLOCK_SIZE);
|
||||
|
||||
if (_RDEBUG && _debuglevel > 6) {
|
||||
System.out.println("Intermediate Plaintext Values (Decryption)");
|
||||
@@ -757,7 +759,7 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor
|
||||
System.out.println("CT=" + toString(ct));
|
||||
}
|
||||
byte[] cpt = new byte[_BLOCK_SIZE];
|
||||
blockDecrypt(ct, cpt, 0, key, _BLOCK_SIZE);
|
||||
blockDecrypt(ct, cpt, 0, 0, key, _BLOCK_SIZE);
|
||||
|
||||
ok = areEqual(pt, cpt);
|
||||
if (!ok) throw new RuntimeException("Symmetric operation failed");
|
||||
|
||||
@@ -13,8 +13,13 @@ import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PThread;
|
||||
@@ -135,7 +140,62 @@ public class DHSessionKeyBuilder {
|
||||
_sessionKey = null;
|
||||
_extraExchangedBytes = new ByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Conduct a DH exchange over the streams, returning the resulting data.
|
||||
*
|
||||
* @return exchanged data
|
||||
* @throws IOException if there is an error (but does not close the streams
|
||||
*/
|
||||
public static DHSessionKeyBuilder exchangeKeys(InputStream in, OutputStream out) throws IOException {
|
||||
DHSessionKeyBuilder builder = new DHSessionKeyBuilder();
|
||||
|
||||
// send: X
|
||||
writeBigI(out, builder.getMyPublicValue());
|
||||
|
||||
// read: Y
|
||||
BigInteger Y = readBigI(in);
|
||||
if (Y == null) return null;
|
||||
builder.setPeerPublicValue(Y);
|
||||
return builder;
|
||||
}
|
||||
|
||||
static BigInteger readBigI(InputStream in) throws IOException {
|
||||
byte Y[] = new byte[256];
|
||||
int read = DataHelper.read(in, Y);
|
||||
if (read != 256) {
|
||||
return null;
|
||||
}
|
||||
if (1 == (Y[0] & 0x80)) {
|
||||
// high bit set, need to inject an additional byte to keep 2s complement
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("High bit set");
|
||||
byte Y2[] = new byte[257];
|
||||
System.arraycopy(Y, 0, Y2, 1, 256);
|
||||
Y = Y2;
|
||||
}
|
||||
return new NativeBigInteger(Y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the integer as a 256 byte value. This left pads with 0s so
|
||||
* to keep in 2s complement, and if it is already 257 bytes (due to
|
||||
* the sign bit) ignore that first byte.
|
||||
*/
|
||||
static void writeBigI(OutputStream out, BigInteger val) throws IOException {
|
||||
byte x[] = val.toByteArray();
|
||||
for (int i = x.length; i < 256; i++)
|
||||
out.write(0);
|
||||
if (x.length == 257)
|
||||
out.write(x, 1, 256);
|
||||
else if (x.length == 256)
|
||||
out.write(x);
|
||||
else if (x.length > 257)
|
||||
throw new IllegalArgumentException("Value is too large! length="+x.length);
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private static final int getSize() {
|
||||
synchronized (_builders) {
|
||||
return _builders.size();
|
||||
@@ -292,8 +352,10 @@ public class DHSessionKeyBuilder {
|
||||
byte iv[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(iv);
|
||||
String origVal = "1234567890123456"; // 16 bytes max using AESEngine
|
||||
byte enc[] = ctx.AESEngine().encrypt(origVal.getBytes(), key1, iv);
|
||||
byte dec[] = ctx.AESEngine().decrypt(enc, key2, iv);
|
||||
byte enc[] = new byte[16];
|
||||
byte dec[] = new byte[16];
|
||||
ctx.aes().encrypt(origVal.getBytes(), 0, enc, 0, key1, iv, 16);
|
||||
ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16);
|
||||
String tranVal = new String(dec);
|
||||
if (origVal.equals(tranVal))
|
||||
_log.debug("**Success: D(E(val)) == val");
|
||||
|
||||
@@ -248,7 +248,8 @@ public class ElGamalAESEngine {
|
||||
SessionKey foundKey) throws DataFormatException {
|
||||
//_log.debug("iv for decryption: " + DataHelper.toString(iv, 16));
|
||||
//_log.debug("decrypting AES block. encr.length = " + (encrypted == null? -1 : encrypted.length) + " sentTag: " + DataHelper.toString(sentTag, 32));
|
||||
byte decrypted[] = _context.AESEngine().decrypt(encrypted, key, iv);
|
||||
byte decrypted[] = new byte[encrypted.length];
|
||||
_context.aes().decrypt(encrypted, 0, decrypted, 0, key, iv, encrypted.length);
|
||||
//Hash h = _context.sha().calculateHash(decrypted);
|
||||
//_log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32));
|
||||
try {
|
||||
@@ -503,7 +504,8 @@ public class ElGamalAESEngine {
|
||||
byte aesUnencr[] = aesSrc.toByteArray();
|
||||
//Hash h = _context.sha().calculateHash(aesUnencr);
|
||||
//_log.debug("Hash of entire aes block before encryption: (len=" + aesUnencr.length + ")\n" + DataHelper.toString(h.getData(), 32));
|
||||
byte aesEncr[] = _context.AESEngine().encrypt(aesUnencr, key, iv);
|
||||
byte aesEncr[] = new byte[aesUnencr.length];
|
||||
_context.aes().encrypt(aesUnencr, 0, aesEncr, 0, key, iv, aesEncr.length);
|
||||
//_log.debug("Encrypted length: " + aesEncr.length);
|
||||
return aesEncr;
|
||||
} catch (IOException ioe) {
|
||||
|
||||
@@ -12,12 +12,11 @@ package net.i2p.data;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
@@ -96,24 +95,28 @@ public class DataHelper {
|
||||
*/
|
||||
public static void writeProperties(OutputStream rawStream, Properties props)
|
||||
throws DataFormatException, IOException {
|
||||
OrderedProperties p = new OrderedProperties();
|
||||
if (props != null) p.putAll(props);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
|
||||
for (Iterator iter = p.keySet().iterator(); iter.hasNext();) {
|
||||
String key = (String) iter.next();
|
||||
String val = p.getProperty(key);
|
||||
// now make sure they're in UTF-8
|
||||
//key = new String(key.getBytes(), "UTF-8");
|
||||
//val = new String(val.getBytes(), "UTF-8");
|
||||
writeString(baos, key);
|
||||
baos.write(_equalBytes);
|
||||
writeString(baos, val);
|
||||
baos.write(_semicolonBytes);
|
||||
if (props != null) {
|
||||
OrderedProperties p = new OrderedProperties();
|
||||
p.putAll(props);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
|
||||
for (Iterator iter = p.keySet().iterator(); iter.hasNext();) {
|
||||
String key = (String) iter.next();
|
||||
String val = p.getProperty(key);
|
||||
// now make sure they're in UTF-8
|
||||
//key = new String(key.getBytes(), "UTF-8");
|
||||
//val = new String(val.getBytes(), "UTF-8");
|
||||
writeString(baos, key);
|
||||
baos.write(_equalBytes);
|
||||
writeString(baos, val);
|
||||
baos.write(_semicolonBytes);
|
||||
}
|
||||
baos.close();
|
||||
byte propBytes[] = baos.toByteArray();
|
||||
writeLong(rawStream, 2, propBytes.length);
|
||||
rawStream.write(propBytes);
|
||||
} else {
|
||||
writeLong(rawStream, 2, 0);
|
||||
}
|
||||
baos.close();
|
||||
byte propBytes[] = baos.toByteArray();
|
||||
writeLong(rawStream, 2, propBytes.length);
|
||||
rawStream.write(propBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,12 +463,38 @@ public class DataHelper {
|
||||
|
||||
public final static byte[] xor(byte lhs[], byte rhs[]) {
|
||||
if ((lhs == null) || (rhs == null) || (lhs.length != rhs.length)) return null;
|
||||
byte rv[] = new byte[lhs.length];
|
||||
|
||||
byte diff[] = new byte[lhs.length];
|
||||
for (int i = 0; i < lhs.length; i++)
|
||||
diff[i] = (byte) (lhs[i] ^ rhs[i]);
|
||||
xor(lhs, 0, rhs, 0, diff, 0, lhs.length);
|
||||
return diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* xor the lhs with the rhs, storing the result in out.
|
||||
*
|
||||
* @param lhs one of the source arrays
|
||||
* @param startLeft starting index in the lhs array to begin the xor
|
||||
* @param rhs the other source array
|
||||
* @param startRight starting index in the rhs array to begin the xor
|
||||
* @param out output array
|
||||
* @param startOut starting index in the out array to store the result
|
||||
* @param len how many bytes into the various arrays to xor
|
||||
*/
|
||||
public final static void xor(byte lhs[], int startLeft, byte rhs[], int startRight, byte out[], int startOut, int len) {
|
||||
if ( (lhs == null) || (rhs == null) || (out == null) )
|
||||
throw new NullPointerException("Invalid params to xor (" + lhs + ", " + rhs + ", " + out + ")");
|
||||
if (lhs.length < startLeft + len)
|
||||
throw new IllegalArgumentException("Left hand side is too short");
|
||||
if (rhs.length < startRight + len)
|
||||
throw new IllegalArgumentException("Right hand side is too short");
|
||||
if (out.length < startOut + len)
|
||||
throw new IllegalArgumentException("Result is too short");
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
out[startOut + i] = (byte) (lhs[startLeft + i] ^ rhs[startRight + i]);
|
||||
}
|
||||
|
||||
//
|
||||
// The following hashcode helpers make it simpler to write consistently hashing
|
||||
// functions for objects based on their value, not JVM memory address
|
||||
@@ -607,33 +636,4 @@ public class DataHelper {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in the last few lines of a (newline delimited) textfile, or null if
|
||||
* the file doesn't exist.
|
||||
*
|
||||
*/
|
||||
public static String readTextFile(String filename, int maxNumLines) {
|
||||
File f = new File(filename);
|
||||
if (!f.exists()) return null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(f);
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
|
||||
List lines = new ArrayList(maxNumLines);
|
||||
String line = null;
|
||||
while ( (line = in.readLine()) != null) {
|
||||
lines.add(line);
|
||||
while (lines.size() > maxNumLines)
|
||||
lines.remove(0);
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(lines.size() * 80);
|
||||
for (int i = 0; i < lines.size(); i++)
|
||||
buf.append((String)lines.get(i)).append('\n');
|
||||
return buf.toString();
|
||||
} catch (IOException ioe) {
|
||||
return null;
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ public class RouterInfo extends DataStructureImpl {
|
||||
if (bytes == null) throw new DataFormatException("Not enough data to sign");
|
||||
// now sign with the key
|
||||
Signature sig = DSAEngine.getInstance().sign(bytes, key);
|
||||
if (sig == null) throw new DataFormatException("Not enough data to sign, or other signature failure");
|
||||
setSignature(sig);
|
||||
//_log.debug("Signed " + SHA256Generator.getInstance().calculateHash(bytes).toBase64() + " with " + key);
|
||||
//_log.debug("verify ok? " + DSAEngine.getInstance().verifySignature(sig, bytes, getIdentity().getSigningPublicKey()));
|
||||
@@ -321,6 +322,22 @@ public class RouterInfo extends DataStructureImpl {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pull the first workable target address for the given transport
|
||||
*
|
||||
*/
|
||||
public RouterAddress getTargetAddress(String transportStyle) {
|
||||
synchronized (_addresses) {
|
||||
for (Iterator iter = _addresses.iterator(); iter.hasNext(); ) {
|
||||
RouterAddress addr = (RouterAddress)iter.next();
|
||||
if (addr.getTransportStyle().equals(transportStyle))
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually validate the signature
|
||||
|
||||
@@ -28,7 +28,10 @@ public class SessionKey extends DataStructureImpl {
|
||||
public final static int KEYSIZE_BYTES = 32;
|
||||
|
||||
public SessionKey() {
|
||||
setData(null);
|
||||
this(null);
|
||||
}
|
||||
public SessionKey(byte data[]) {
|
||||
setData(data);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
|
||||
@@ -25,7 +25,7 @@ public class Timestamper implements Runnable {
|
||||
|
||||
private static final int DEFAULT_QUERY_FREQUENCY = 5*60*1000;
|
||||
private static final String DEFAULT_SERVER_LIST = "pool.ntp.org, pool.ntp.org";
|
||||
private static final boolean DEFAULT_DISABLED = false;
|
||||
private static final boolean DEFAULT_DISABLED = true;
|
||||
|
||||
public static final String PROP_QUERY_FREQUENCY = "time.queryFrequencyMs";
|
||||
public static final String PROP_SERVER_LIST = "time.sntpServerList";
|
||||
|
||||
171
core/java/src/net/i2p/util/FileUtil.java
Normal file
171
core/java/src/net/i2p/util/FileUtil.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* General helper methods for messing with files
|
||||
*
|
||||
*/
|
||||
public class FileUtil {
|
||||
/**
|
||||
* Delete the path as well as any files or directories underneath it.
|
||||
*
|
||||
* @param path path to the directory being deleted
|
||||
* @param failIfNotEmpty if true, do not delete anything if the directory
|
||||
* is not empty (and return false)
|
||||
* @return true if the path no longer exists (aka was removed),
|
||||
* false if it remains
|
||||
*/
|
||||
public static final boolean rmdir(String path, boolean failIfNotEmpty) {
|
||||
return rmdir(new File(path), failIfNotEmpty);
|
||||
}
|
||||
/**
|
||||
* Delete the path as well as any files or directories underneath it.
|
||||
*
|
||||
* @param target the file or directory being deleted
|
||||
* @param failIfNotEmpty if true, do not delete anything if the directory
|
||||
* is not empty (and return false)
|
||||
* @return true if the path no longer exists (aka was removed),
|
||||
* false if it remains
|
||||
*/
|
||||
public static final boolean rmdir(File target, boolean failIfNotEmpty) {
|
||||
if (!target.exists()) {
|
||||
//System.out.println("info: target does not exist [" + target.getPath() + "]");
|
||||
return true;
|
||||
}
|
||||
if (!target.isDirectory()) {
|
||||
//System.out.println("info: target is not a directory [" + target.getPath() + "]");
|
||||
return target.delete();
|
||||
} else {
|
||||
File children[] = target.listFiles();
|
||||
if (children == null) {
|
||||
//System.out.println("info: target null children [" + target.getPath() + "]");
|
||||
return false;
|
||||
}
|
||||
if ( (failIfNotEmpty) && (children.length > 0) ) {
|
||||
//System.out.println("info: target is not emtpy[" + target.getPath() + "]");
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
if (!rmdir(children[i], failIfNotEmpty))
|
||||
return false;
|
||||
|
||||
//System.out.println("info: target removed recursively [" + children[i].getPath() + "]");
|
||||
}
|
||||
return target.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean extractZip(File zipfile, File targetDir) {
|
||||
try {
|
||||
byte buf[] = new byte[16*1024];
|
||||
ZipFile zip = new ZipFile(zipfile);
|
||||
Enumeration entries = zip.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry)entries.nextElement();
|
||||
if (entry.getName().indexOf("..") != -1) {
|
||||
System.err.println("ERROR: Refusing to extract a zip entry with '..' in it [" + entry.getName() + "]");
|
||||
return false;
|
||||
}
|
||||
File target = new File(targetDir, entry.getName());
|
||||
File parent = target.getParentFile();
|
||||
if ( (parent != null) && (!parent.exists()) ) {
|
||||
boolean parentsOk = parent.mkdirs();
|
||||
if (!parentsOk) {
|
||||
System.err.println("ERROR: Unable to create the parent dir for " + entry.getName() + ": [" + parent.getAbsolutePath() + "]");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (entry.isDirectory()) {
|
||||
if (!target.exists()) {
|
||||
boolean created = target.mkdirs();
|
||||
if (!created) {
|
||||
System.err.println("ERROR: Unable to create the directory [" + entry.getName() + "]");
|
||||
return false;
|
||||
} else {
|
||||
System.err.println("INFO: Creating directory [" + entry.getName() + "]");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
InputStream in = zip.getInputStream(entry);
|
||||
FileOutputStream fos = new FileOutputStream(target);
|
||||
int read = 0;
|
||||
while ( (read = in.read(buf)) != -1) {
|
||||
fos.write(buf, 0, read);
|
||||
}
|
||||
fos.close();
|
||||
in.close();
|
||||
|
||||
System.err.println("INFO: File [" + entry.getName() + "] extracted");
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("ERROR: Error extracting the zip entry (" + entry.getName() + "]");
|
||||
ioe.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
zip.close();
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("ERROR: Unable to extract the zip file");
|
||||
ioe.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in the last few lines of a (newline delimited) textfile, or null if
|
||||
* the file doesn't exist.
|
||||
*
|
||||
*/
|
||||
public static String readTextFile(String filename, int maxNumLines) {
|
||||
File f = new File(filename);
|
||||
if (!f.exists()) return null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(f);
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
|
||||
List lines = new ArrayList(maxNumLines);
|
||||
String line = null;
|
||||
while ( (line = in.readLine()) != null) {
|
||||
lines.add(line);
|
||||
while (lines.size() > maxNumLines)
|
||||
lines.remove(0);
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(lines.size() * 80);
|
||||
for (int i = 0; i < lines.size(); i++)
|
||||
buf.append((String)lines.get(i)).append('\n');
|
||||
return buf.toString();
|
||||
} catch (IOException ioe) {
|
||||
return null;
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
testRmdir();
|
||||
}
|
||||
private static void testRmdir() {
|
||||
File t = new File("rmdirTest/test/subdir/blah");
|
||||
boolean created = t.mkdirs();
|
||||
if (!t.exists()) throw new RuntimeException("Unable to create test");
|
||||
boolean deleted = FileUtil.rmdir("rmdirTest", false);
|
||||
if (!deleted)
|
||||
System.err.println("FAIL: unable to delete rmdirTest");
|
||||
else
|
||||
System.out.println("PASS: rmdirTest deleted");
|
||||
}
|
||||
}
|
||||
@@ -246,8 +246,8 @@ public class LogManager {
|
||||
File cfgFile = new File(_location);
|
||||
if (!cfgFile.exists()) {
|
||||
if (!_alreadyNoticedMissingConfig) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Log file " + _location + " does not exist");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Log file " + _location + " does not exist");
|
||||
System.err.println("Log file " + _location + " does not exist");
|
||||
_alreadyNoticedMissingConfig = true;
|
||||
}
|
||||
@@ -447,19 +447,18 @@ public class LogManager {
|
||||
if (!Character.isDigit(mod)) v = size.substring(0, size.length() - 1);
|
||||
int val = Integer.parseInt(v);
|
||||
switch (mod) {
|
||||
case 'K':
|
||||
val *= 1024;
|
||||
break;
|
||||
case 'M':
|
||||
val *= 1024 * 1024;
|
||||
break;
|
||||
case 'G':
|
||||
val *= 1024 * 1024 * 1024;
|
||||
break;
|
||||
case 'T':
|
||||
// because we can
|
||||
val *= 1024 * 1024 * 1024 * 1024;
|
||||
break;
|
||||
case 'K':
|
||||
val *= 1024;
|
||||
break;
|
||||
case 'M':
|
||||
val *= 1024 * 1024;
|
||||
break;
|
||||
case 'G':
|
||||
val *= 1024 * 1024 * 1024;
|
||||
break;
|
||||
default:
|
||||
// blah, noop
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
} catch (Throwable t) {
|
||||
|
||||
@@ -485,7 +485,7 @@ public class NativeBigInteger extends BigInteger {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
InputStream libStream = resource.openStream();
|
||||
outFile = File.createTempFile(_libPrefix + "jbigi", "lib.tmp" + _libSuffix);
|
||||
outFile = new File(_libPrefix + "jbigi" + _libSuffix);
|
||||
fos = new FileOutputStream(outFile);
|
||||
byte buf[] = new byte[4096*1024];
|
||||
while (true) {
|
||||
@@ -514,10 +514,6 @@ public class NativeBigInteger extends BigInteger {
|
||||
if (fos != null) {
|
||||
try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
if (outFile != null) {
|
||||
if (!outFile.delete())
|
||||
outFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,8 @@ public class ShellCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private final static int BUFFER_SIZE = 1024;
|
||||
|
||||
/**
|
||||
* Reads data from a <code>java.io.InputStream</code> and writes it to
|
||||
* <code>STDOUT</code>.
|
||||
@@ -112,8 +114,6 @@ public class ShellCommand {
|
||||
*/
|
||||
private class StreamReader extends Thread {
|
||||
|
||||
final int BUFFER_SIZE = 1024;
|
||||
|
||||
private BufferedReader bufferedReader;
|
||||
private InputStreamReader inputStreamReader;
|
||||
|
||||
@@ -339,6 +339,20 @@ public class ShellCommand {
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (args.length <= 0) {
|
||||
System.err.println("Usage: ShellCommand commandline");
|
||||
return;
|
||||
}
|
||||
ShellCommand cmd = new ShellCommand();
|
||||
StringBuffer command = new StringBuffer(64);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
command.append("\"").append(args[i]).append("\" ");
|
||||
}
|
||||
cmd.execute(command.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
private boolean execute(String shellCommand, boolean consumeOutput, boolean waitForExitStatus) {
|
||||
|
||||
StreamConsumer processStderrConsumer;
|
||||
|
||||
@@ -64,6 +64,8 @@ public class SimpleTimer {
|
||||
|
||||
private class SimpleTimerRunner implements Runnable {
|
||||
public void run() {
|
||||
List eventsToFire = new ArrayList(1);
|
||||
List timesToRemove = new ArrayList(1);
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (_events) {
|
||||
@@ -71,34 +73,48 @@ public class SimpleTimer {
|
||||
_events.wait();
|
||||
long now = System.currentTimeMillis();
|
||||
long nextEventDelay = -1;
|
||||
List removed = null;
|
||||
for (Iterator iter = _events.keySet().iterator(); iter.hasNext(); ) {
|
||||
Long when = (Long)iter.next();
|
||||
if (when.longValue() <= now) {
|
||||
TimedEvent evt = (TimedEvent)_events.get(when);
|
||||
try {
|
||||
evt.timeReached();
|
||||
} catch (Throwable t) {
|
||||
log("wtf, event borked: " + evt, t);
|
||||
}
|
||||
if (removed == null)
|
||||
removed = new ArrayList(1);
|
||||
removed.add(when);
|
||||
eventsToFire.add(evt);
|
||||
timesToRemove.add(when);
|
||||
} else {
|
||||
nextEventDelay = when.longValue() - now;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removed != null) {
|
||||
for (int i = 0; i < removed.size(); i++)
|
||||
_events.remove(removed.get(i));
|
||||
if (timesToRemove.size() > 0) {
|
||||
for (int i = 0; i < timesToRemove.size(); i++)
|
||||
_events.remove(timesToRemove.get(i));
|
||||
} else {
|
||||
if (nextEventDelay != -1)
|
||||
_events.wait(nextEventDelay);
|
||||
else
|
||||
_events.wait();
|
||||
}
|
||||
if (nextEventDelay != -1)
|
||||
_events.wait(nextEventDelay);
|
||||
else
|
||||
_events.wait();
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore
|
||||
} catch (Throwable t) {
|
||||
if (_log != null) {
|
||||
_log.log(Log.CRIT, "Uncaught exception in the SimpleTimer!", t);
|
||||
} else {
|
||||
System.err.println("Uncaught exception in SimpleTimer");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < eventsToFire.size(); i++) {
|
||||
TimedEvent evt = (TimedEvent)eventsToFire.get(i);
|
||||
try {
|
||||
evt.timeReached();
|
||||
} catch (Throwable t) {
|
||||
log("wtf, event borked: " + evt, t);
|
||||
}
|
||||
}
|
||||
eventsToFire.clear();
|
||||
timesToRemove.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,22 +72,28 @@ public class AES256Bench {
|
||||
iv[x] = (byte)civ[x];
|
||||
}
|
||||
|
||||
byte[] e = _context.AESEngine().encrypt(plain, key, iv);
|
||||
byte[] d = _context.AESEngine().decrypt(e, key, iv);
|
||||
byte[] e = new byte[plain.length];
|
||||
_context.aes().encrypt(plain, 0, e, 0, key, iv, plain.length);
|
||||
byte[] d = new byte[e.length];
|
||||
_context.aes().decrypt(e, 0, d, 0, key, iv, d.length);
|
||||
boolean same = true;
|
||||
for (int x = 0; x < d.length; x++) {
|
||||
if (plain[x] != d[x]) {
|
||||
same = false;
|
||||
throw new RuntimeException("Failed decrypt at " + x);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Standard test D(E(value)) == value? " + same);
|
||||
if (!same) throw new RuntimeException("moo");
|
||||
|
||||
plain = "1234567890123456".getBytes();
|
||||
e = _context.AESEngine().encrypt(plain, key, iv);
|
||||
d = _context.AESEngine().decrypt(e, key, iv);
|
||||
e = new byte[plain.length];
|
||||
_context.aes().encrypt(plain, 0, e, 0, key, iv, plain.length);
|
||||
d = new byte[e.length];
|
||||
_context.aes().decrypt(e, 0, d, 0, key, iv, d.length);
|
||||
same = DataHelper.eq(plain, d);
|
||||
System.out.println("Different value test D(E(value)) == value? " + same);
|
||||
if (!same) throw new RuntimeException("moo");
|
||||
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
@@ -104,9 +110,11 @@ public class AES256Bench {
|
||||
message[i] = (byte)((i%26)+'a');
|
||||
for (int x = 0; x < times; x++) {
|
||||
long startencrypt = System.currentTimeMillis();
|
||||
e = _context.AESEngine().encrypt(message, key, iv);
|
||||
e = new byte[message.length];
|
||||
d = new byte[e.length];
|
||||
_context.aes().encrypt(message, 0, e, 0, key, iv, message.length);
|
||||
long endencryptstartdecrypt = System.currentTimeMillis();
|
||||
d = _context.AESEngine().decrypt(e, key, iv);
|
||||
_context.aes().decrypt(e, 0, d, 0, key, iv, d.length);
|
||||
long enddecrypt = System.currentTimeMillis();
|
||||
System.out.print(".");
|
||||
encrypttime += endencryptstartdecrypt - startencrypt;
|
||||
|
||||
@@ -145,8 +145,10 @@ class ElGamalAESEngineTest {
|
||||
String msg = "Hello world01234012345678901234501234567890123450123456789012345";
|
||||
h = SHA256Generator.getInstance().calculateHash(msg.getBytes());
|
||||
_log.debug("Hash of entire aes block before encryption: \n" + DataHelper.toString(h.getData(), 32));
|
||||
byte aesEncr[] = _context.AESEngine().encrypt(msg.getBytes(), sessionKey, iv);
|
||||
byte aesDecr[] = _context.AESEngine().decrypt(aesEncr, sessionKey, iv);
|
||||
byte aesEncr[] = new byte[msg.getBytes().length];
|
||||
byte aesDecr[] = new byte[aesEncr.length];
|
||||
_context.aes().encrypt(msg.getBytes(), 0, aesEncr, 0, sessionKey, iv, aesEncr.length);
|
||||
_context.aes().decrypt(aesEncr, 0, aesDecr, 0, sessionKey, iv, aesEncr.length);
|
||||
h = SHA256Generator.getInstance().calculateHash(aesDecr);
|
||||
_log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32));
|
||||
if (msg.equals(new String(aesDecr))) {
|
||||
|
||||
150
history.txt
150
history.txt
@@ -1,4 +1,152 @@
|
||||
$Id: history.txt,v 1.4 2004/09/03 11:52:27 hypercubus Exp $
|
||||
$Id: history.txt,v 1.23 2004/09/30 01:57:22 jrandom Exp $
|
||||
|
||||
* 2004-09-30 0.4.1 released (not backwards compatible)
|
||||
|
||||
2004-09-30 jrandom
|
||||
* Bundle the configuration necessary to run an eepsite out of the box
|
||||
with Jetty - simply edit ./eepsite/docroot/index.html and give people
|
||||
the key listed on the I2PTunnel configuration page, and its up.
|
||||
* Router console cleanup, and some (off by default) tunnels -
|
||||
smtp.postman.i2p (port 7659), pop.postman.i2p (port 7660), and
|
||||
irc.baffled.i2p (port 7661)
|
||||
|
||||
2004-09-29 jrandom
|
||||
* Always wipe the Jetty work directory on startup, so that web updates
|
||||
are reflected immediately (Jetty does not honor the cache across
|
||||
multiple executions)
|
||||
|
||||
2004-09-27 jrandom
|
||||
* Limit the number of connection tags saved to 10,000. This is a huge
|
||||
limit, but consumes no more than 1MB of RAM. For now, we drop them
|
||||
randomly after reaching that size, forcing those dropped peers to use
|
||||
a full DH negotiation.
|
||||
* HTML cleanup in the console.
|
||||
|
||||
2004-09-26 jrandom
|
||||
* Complete rewrite of the TCP transport with IP autodetection and
|
||||
low CPU overhead reconnections. More concise connectivity errors
|
||||
are listed on the /oldconsole.jsp as well. The IP autodetection works
|
||||
by listening to the first person who tells you what your IP address is
|
||||
when you have not defined one yourself and you have no other TCP
|
||||
connections.
|
||||
* Update to the I2NP message format to add transparent verification at
|
||||
the I2NP level (beyond standard TCP verification).
|
||||
* Remove a potential weakness in our AESEngine's safeEncrypt and safeDecrypt
|
||||
implementation (rather than verifying with E(H(key)), we now verify with
|
||||
E(H(iv))).
|
||||
* The above changes are NOT BACKWARDS COMPATIBLE.
|
||||
* Removed all of the old unused PHTTP code.
|
||||
* Refactor various methods and clean up some javadoc.
|
||||
|
||||
2004-09-21 jrandom
|
||||
* Have two tiers of hosts.txt files - the standard "hosts.txt" and
|
||||
the new "userhosts.txt". Updates to I2P will only overwrite the former,
|
||||
but values stored in the later take precedence. Both are queried on
|
||||
lookup.
|
||||
|
||||
2004-09-16 jrandom
|
||||
* Refactor the TCP transport to deal with changing identities gracefully,
|
||||
and to prevent some wasted effort by keeping track of what host+port
|
||||
combinations we are connected to (rather than just the identities). Also
|
||||
catch a few configuration errors earlier.
|
||||
* Removed no longer relevent methods from the Transport API that were
|
||||
exposing ideas that probably shouldn't be exposed.
|
||||
* Removed the 0.4.0.1 specific files from i2pupdate.zip (relating to script
|
||||
updates)
|
||||
|
||||
2004-09-13 jrandom
|
||||
* Update for the SDK reconnection to deal with overflow.
|
||||
* Web improvements (@ not # on the /logs.jsp [thanks ugha!] and fixed the
|
||||
rounding on lifetime bandwidth used [thanks gott!]).
|
||||
|
||||
* 2004-09-08 0.4.0.1 released
|
||||
|
||||
2004-09-08 jrandom
|
||||
* Updated the "Active:" peer count to display the # of connections as well
|
||||
as the number of recently active router identities.
|
||||
* Implement some basic updating code - on startup, if there is a file named
|
||||
"i2pupdate.zip" in the I2P installation directory, extract it, delete it,
|
||||
then restart.
|
||||
* Added an ugly little script to allow launching the router on win9x
|
||||
machines without a dos box (using javaw to run a .bat file).
|
||||
* Logging updates.
|
||||
* Updated VERSION constants to 0.4.0.1
|
||||
|
||||
2004-09-08 hypercubus
|
||||
* Bugfix: Running the installer as a non-privileged user on Red Hat (and
|
||||
hopefully any other affected *nix systems) now properly discards non-
|
||||
essential directories after installation.
|
||||
* Support for Win9x in the installer and postinstall.bat.
|
||||
* Changed the name of the default installation directory on all platforms
|
||||
from "I2P" to "i2p" in the installer.
|
||||
* Changed "wrapper.conf" to "wrapper.config" for naming consistency with the
|
||||
other configuration files.
|
||||
|
||||
2004-09-07 cervantes:
|
||||
* Proxy recursion disabled by default (strict)
|
||||
* Password Authentication for session commands
|
||||
* Support for http://path?i2paddresshelper=BASE64
|
||||
* Support for http://i2p/BASE64/path syntax
|
||||
|
||||
2004-09-07 jrandom
|
||||
* Make sure that peers placed in the 'fast' group are ones we both know
|
||||
how to reach and have been able to reach recently. These peers may
|
||||
still be placed in the 'high capacity' group however (though that group
|
||||
is only queried if the 'fast' group is too small)
|
||||
* Include some updates to the ProgileOrganizer's CLI.
|
||||
|
||||
2004-09-07 jrandom
|
||||
* Disable the timestamper by default for all applications except the router
|
||||
(enable via -Dtime.disabled=false)
|
||||
* Simplify the retrieval of the full destination with text based browsers.
|
||||
* Bundle the updated wrapper.config and hosts.txt in the i2pupdate.tar.bz2
|
||||
|
||||
2004-09-07 jrandom
|
||||
* Write the native libraries to the current directory when they are loaded
|
||||
from a resource, and load them from that file on subsequent runs (in
|
||||
turn, we no longer *cough* delete the running libraries...)
|
||||
* Added support for a graceful restart.
|
||||
* Added new pseudo-shutdown hook specific to the router, allowing
|
||||
applications to request tasks to be run when the router shuts down. We
|
||||
use this for integration with the service manager, since otherwise a
|
||||
graceful shutdown would cause a timeout, followed by a forced hard
|
||||
shutdown.
|
||||
* Made the capacity calculator a bit more dynamic by not outright ignoring
|
||||
the otherwise valid capacity data for a period with a single rejected
|
||||
tunnel (except for the 10 minute period). In addition, peers with an
|
||||
equal capacity are ordered by speed rather than by their hashes.
|
||||
* Cleaned up the SimpleTimer, addressing some threading and synchronization
|
||||
issues.
|
||||
* When an I2PTunnel client or httpclient is explicitly closed, destroy the
|
||||
associated session (unless there are other clients using it), and deal
|
||||
with a closed session when starting a new I2PTunnel instance.
|
||||
* Refactoring and logging.
|
||||
|
||||
2004-09-06 jrandom
|
||||
* Address a race condition in the key management code that would manifest
|
||||
itself as a corrupt router identity.
|
||||
* Properly clear old transport addresses from being displayed on the old
|
||||
console after soft restarts.
|
||||
* Properly refuse to load the client applications more than once in the
|
||||
same JVM.
|
||||
* Added support for a graceful restart (a graceful shutdown followed by a
|
||||
full JVM restart - useful for restarting client apps).
|
||||
* More defensive programming, HTML cleanup, logging
|
||||
* wrapper.config cleanup of duplicate lines
|
||||
|
||||
2004-09-04 jrandom
|
||||
* Added some basic guards to prevent multiple instances from running.
|
||||
Specifically, a file "router.ping" in the install directory which is
|
||||
written to once a minute - if that file exists and has been modified
|
||||
within the last minute, refuse to start up. In turn, adjust the
|
||||
service wrapper to wait a minute before restarting a crashed JVM.
|
||||
* Create a "work" directory in the I2P install dir which Jetty will
|
||||
use for all of its temporary files.
|
||||
* Tell the browser not to cache most of the router console's pages.
|
||||
|
||||
2004-09-04 jrandom
|
||||
* Update the SDK to automatically reconnect indefinitely with an
|
||||
exponential delay on retries (capped at 5 minutes).
|
||||
|
||||
* 2004-09-03 0.4 released
|
||||
|
||||
|
||||
38
hosts.txt
38
hosts.txt
@@ -1,6 +1,21 @@
|
||||
; TC's hosts.txt guaranteed freshness
|
||||
; $Id: hosts.txt,v 1.33 2004/08/23 02:01:10 jrandom Exp $
|
||||
; $Id: hosts.txt,v 1.51 2004/09/22 19:08:51 jrandom Exp $
|
||||
; changelog:
|
||||
; (1.74) added jabber-2.i2p
|
||||
; (1.73) added jake.i2p
|
||||
; (1.72) added anonymnet.i2p sasquotch.i2p orz.i2p microbleu.i2p {www,smtp,pop3}.postman.i2p
|
||||
; (1.71) added curiosity.i2p
|
||||
; (1.70) added freeciv.nightblade.i2p
|
||||
; (1.69) added xolotl.i2p
|
||||
; (1.68) added modulus.i2p
|
||||
; (1.67) added eepdot.i2p
|
||||
; (1.66) removed datagram_test.i2p
|
||||
; (1.65) added socks1.tor.i2p
|
||||
; (1.64) added sugadude.i2p
|
||||
; (1.63) added files.i2p
|
||||
; (1.62) added beyond.i2p
|
||||
; (1.61) added gott.i2p
|
||||
; (1.60) added linuxagent.i2p
|
||||
; (1.59) added www.i2p, dev.i2p, and cvs.i2p, removed i2pcvs.i2p
|
||||
; (1.58) updated lucky.i2p (after not checking ID, but, c'mon...)
|
||||
; (1.57) added firerabbit.i2p
|
||||
@@ -134,9 +149,28 @@ freshcoffee.i2p=bljvyRLSf2lCPJYJ49iGJ7RxTppQfJHh0UviwxeFUwfznUYZ3nnVZhqDKtfKLSt8
|
||||
stasher.i2p=WsfNc~1sP-eCU5XRoPoyYFwJZ-BrrN29rs89fYAs2kFIyCbsKYeA9rYbD3O1sFCD~kLUC1DELoTwQlHas7JkDkEPXO1plDjzKm8l1iTsPyQmeEVW2Uy6LXOibT6FsdIfoh59G4yfCsEZ~dsxtZZR2ICDb3sRKC8Vx9lZOz72AfBATYQ0S2oQd2iVAjIb0wC0HaVw1XOqhKCmMjWtQhT0qxtkx7ky9ZG1ZAhKeCX4SkCy5YvGeUuCWgPpFLR6D3Hn074Qmtg8g1nAFhlsZ2NiY2OSwNtVM3f2lL6~l4O~xi5oOV7OAtQr5tKywa0SC53hJAAk2VI6HwiexTEwswnaSYwlyW47pO-onpc3sguCmbBWHbxJDzCE5eoi8iFGOH~Awl~ieI6vkvPnGtjvXM4t0jDe3FnrbYCZeSqToKOgIYz0f8iVVbSsh7UVdSepN5tIL~ljIoZIiG6VH37H1ju4loRiADr2wyWWlI94YvZB8rmgUHTPuE9YCijVwmXQNky5AAAA
|
||||
brittanyworld.i2p=tJaK0vA6NNBjyGTjGqHr4k9005aiRToLxP~LIA-WXrjRaWgglh6s8CuE8o60i6i~isELPMAZJGSdPNAP~d2OVEOVu9yXom8xpQyX~xc8gVOhTXi3PvjlCDcG09mFfzPm3XJFJR00EkBcfa2ssaXqOX3vXiR-aGdObmCBngNHeh0sgUJTnfOKFUXRN1leXdWj9ADBPk2iCEvLM7Rrt-vFdr0slrIY0ILzBBK65fZenZtf5QQwskyBeLljpUBbTo21tCSUs89U6yXheYiakR3cQgTDbr9MrcRv8bWiNCKRnoVb5HVrPFZZDk5zCvpMK-zV7YmoO0qYK2AWgnGGZ2PI4ycL7sAHZ~QJixw~7UYtslrisMHKbWAvZfRf4MwFhbKH9RVb2ft2vtSXOz5h7lXtVpPv-xeqoJlclBSLYNt5Ji1iZuFOJFEnjUc3WhSFDph2Tz72PkyU-qXoydrv~JQK7kY5GpjDZ2whqrHjk4ceyQs4jTRfpwbkt~qrQ7AzKnpkAAAA
|
||||
files.nickster.i2p=C-A1MrwV~WC3ld5mDKW57EpaFmIUv5LQThPL~OAOE63Psej8GhH-m61P3yII0NxVJrkKcTa3CZfnPkQCVXkTD2gv2qpZuiX3j4vGJFuQYByKwzuTJ7Ucff9XeO9A~kaXFg9JwMmkzHJZ37X~tKIr-EfHA23mMmUrvmsemAkCOxTHPab33WEkQgBPfTfL9BOSaEzG362OerU7O2QBWjDHrAoMBztHOx4s61pSKMDky71o2fTi4TgoVcOL1oRzprsf5BV9BiY5TRtY7uvYp7-93uct0EAVu686IrM~RzqGuHhSm9TGtEFC6UyMMcn6dxD7q6srI-kR807umEUO8ILNCF79pVZWmA0sBN16wyq-~LtX45dun0UFKDiYyJXcrdN9wyRkro3oZImjW0bLxP5YhMw1C8HhTBSWhDmuJVucZByWqM~Es9pSVql1NX0EU96iqFtWHOEbw9XoT~eBhnqYdQ-PnB79wFWaFFxq-0X89FqxEvl79R7Nqjb46BEkzjoQAAAA
|
||||
datagram_test.i2p=8iJSGzSY8BOFcGohooX94PWiRB3VZYPmLfSBorLTzVC3tmviLcEngN8e8U9kuVTxiQ7Za6HMESzzgnZvKOmL2jD~yon5zNGDShICJv134bX7odSzqbFG5xwpfwRJ8jQvUEnS0bg3BCfK9vmVnqpixd~8qnGThr5KzQxXfI72NcQYlbszp2BOLhGjxDFh5fQpy6Vm8d1R4GF4RGGTaKXANQ9I49LND10xYNE9BayxrUQrkzCDMMI1JXyoR2N~WwuoFK3RzKSrSTMcGbZpZgLZjo47jSqD9ssJPcD94hAllTtk5iTajLhXhoSCFSzpyrAxuRxhHEl8OKIxaNA5DqZMLo7KqfrwSkyRvUyqeFXnzz8DZq8YXu9GeXzkzPhnQdFEiOSV6ypJndv7rVJ1ccarDLdbxEBFZgl4LUux-Aemt4FfuNOvnKzr3OdOX4eT8TvO0kQKwA4NLs0noqiHMzDSUijNGtHv0npvMgT9dO~UIxLHV~sYqIl4t58bSTqJWRATAAAA
|
||||
firerabbit.i2p=LKJIXNQIeR8axYRjcneFIBBWEUbvqMpgQbcc5-QRXLzB49ypTR3o7cx~7iJKxQP~WY~sL-lAnbvl8HmyJa9AOurV4rVBcxGCSLdb7A2pLCmS-WAOP76Nr4ncQFegjRuzDf015QfsXhJq6F~trAisEI6JIIcjOn4ArWFA~cboLPh75GurFNLBE8zegREAjk3bureR3C2ND5KDxz618gzKj0kS6rGwZPcUsrwyiefNrokaWtCuTNQd9Pw-myN6yoYh9UsdAWY2yOXkupGCTjKHXxEgBYg09w6fsHU7I-kg5cFqrmnmFhLWMd3gSmE~ziuHCqacd8uOtJbzxLIEoaUZmCiA1swrrKnIvRMkmW0WxS0XxBwwDLsZSXymAuVcpCUpwshZ9m7eLzSSrhV7Oii4jk~Y49XqfwHzBU2HoHlSsrTV7vydtsdN6j4W-FO1xd2-wUcvQyTqiHINPpl92dOWfsO0OdQYaB5tdq74cXMFXtO1y-vH86u2nJMECZg-mfWDAAAA
|
||||
lucky.i2p=E8BejPR-eZzUIkyMNfNJ-qZ97H9Ym9OXPS0PIFR-C7xlljf-aniVbnp8KUvEuCeC1c4Zk4tihOEYCx54y1svpk3GXjrAJ3-3-i92xgUPXNa0lWkV7JELmsfoK0ZsByZzxg4Jjl4dNe9PgT8CEwHrJqNZGKn5MzTm66PbXBS96zK7ApRU5d3ZzQepmTAcvI2VgqueYhkFNG3DT6C5vVnFsPcLq9uuWtSyDot6egDKvkGv8O3AvvMhOFFs4DX3C3L2YOedu01YwAXL9zCi7gs9jpDG9YuYDCM1xsiNfgvZG36bDeqmviG6RiT3gvEuypUfWbVsU9uBnHiyu4CoMVpgGEei0PrYJqeioLwja97w~PR8jRg-psdWQco7JS~rohcHuuflClLlW6oKkwgJFayjvYN0Uj5Os~SH-t9vIEVz5OGge16UK9i1jfItKzFiyggGTVeDH9mL3Dl7pkZufOf7ywbl6URnzlgRick6awNYFQwamrF5gQ~F~eKPyN7dNIbnAAAA
|
||||
www.i2p=Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA
|
||||
dev.i2p=NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA
|
||||
cvs.i2p=dIvSbo35u0bc-5Vp0Wqs4YvarZS6l-y-URwOgH~NrRfQJ6mQmnfcmBJ1XPWswSHEGeRchK8l89xMLe7uI9cBCzIu9eJnCalBr-PwaRtTQyPXGDLxfI23DTpS36sEg0noZaQaFH4LPITFMiVBTXAGMfe4ID9foHpGPS2WXmpyJaArWQRDn9g2xUVD5tTQWmgtuEgq84y5zwPPpPG548CS-CpOelaOsnwZfH83~9TeZZuMdIUXzHyaqqIE7PjMabqSWfR366QMUJmsfz00HdP0Tk~T9lbVDwtOQgkv~I6TeMX4WyT4C8klmGpBvpRXpMhImdzutUvG8-UbxDo-VdvELwErlc5lMsZ-SYjTuE5jHJkYFuNLI8vlC7pzESxClUFrUYX5cc7b~ZJmlH1OYTTFzlwr4mEbd1EFGoGPb4fFbtMCtgd409Zo56FsomQMXn6R~9ay~pidnA1AWy3HuHcDAzN5Ec5WXdoZoeBuOR8Ks1Y3~yOcSeMXoqA3kan4AcdXAAAA
|
||||
linuxagent.i2p=OE-WAF6jzHUbUF7eytgiIaIKWh~oGf3c8~q-fUBbM2WntbXO7AhpU0QmZ~1lZIiQfzO-2Xyr0e-2VQBNexw73iOPLDII7mLv6xUnZmaKm-QPdvDEI9-ILPWgpMGJubAgA4ZmDgIUg2dSQ19Eq8lp5bwkuIUuU8Jd6JS1fvX-87G7PjcrE7vKM-Ty2gCnp7cWsadl8qYEkXLf5-CIr3LjGM-B-G~NoIqPf56df9ayHVguqT1f0c-d00qY80kUvb8DJ-X6VR9TNut6dKqRajI0earbkALP~wdoFggIIebqm1UXeI1tYROcrb155z4qu-4Nb~q4wzNAI9AVjNboIk50P2X0TrLNmjL9RWCrvHCt-r2ZV35Skpka4YmxATU59jSPw8jhXw1TgM-5DRswEtmOdxJMpkQU~iu~TJWmmcVvpkqyNMqXiqtOKqEgLTj8gOfNaITH0kdMVvXPKmYPTFimWu64T0VGBsqS~PQ50JxtteUP5FZv-dXluL8EbhtwQ7mLAAAA
|
||||
gott.i2p=BxciUZkGQwi6Sj1Ucg5GGagDdwujlj8ClePa4~3d-1nnRJsBhTNJtvs-UuQYY77gPGNlpNk9dt02mxeS7f~pEC4E1KxJH9mhnf0OlIGB4hOOhDlXokAaKE2u1E-vVCDJlZCq32r~Ne53w-L2m5h5FAq5Bx7NXrTzWAEPgAlC8A2wASJWIF-EKOX5kfkkYoF6sKZqam5CxAAAMAUwmnbD--7wo8d2mz0C-c~oE7hzuHsg2J8yME5Zd~-FOZUxkoNCBJdfrVlVRn9~6685zqpaotL-SIqFK6~28ZCNMNCtnZcZZLeG2gZxq2pe8HtgzDrMMSx45vs3JLUp8Bap6~D9oFX0o7k2DQm-5R9D5NWhsJgol5Ny~8ABTXBpW~WQQOuKxE5xJauXM5rQia2yyXgldfOyGjxYnkrTGu6LaxlLmhyAva3ZbOO0mtLvrKLZebLKCYUxP7~TtNmSWEAzPKFYbjdZ~NjE0q4TanLFBaWotefPmy3IuAc8Mr7PbCvi4GmdAAAA
|
||||
beyond.i2p=Gy9wxnDgcaNO8b-1gZTAn4GKWiMZHLSuOpXF9SSrVVO5Gx791OwZVNg9mMHvIkSekWuqtJwIRCArfXtaQNNe4ZJfl2bVNEKJonfXM9HLbNoJiSgmg-x75xYLXb04NDYhIbHJ4zSEpDFufjk1kI35XJo~32~qYynDMbYX9b3QtNfFfcBrOzH5iObTsMBBe5f2zEpjl1UWNGuKYa1tVHef65z6WCr16TUYSj5uDnUyTWWkwrgDZbTnRRlz--BQ9y4WiCgzQyMvRaNU-T6aPj6P9HlQIhV7efttpb2IRLpSKepIYG66ohBhI1n2G2dd18UHdR~PWNIy8x7AsCczlqnfh4lcJdiQqrNHQtpOI3XfM5gLM5sKLwrxbsQwB-6dnhonztTd1o9TWhTuA1FSlk3nRQ22E1~pQRh0sexgWjk1oa0Qr6kOojkY955aL6ZnD7RJx3fbeZ9JAy6s5uxYXuE1wkGQNUVEvi15jgVB8zk4GaB8ME6tdWVtcBTMjEqvulyEAAAA
|
||||
files.i2p=1rI0OWp83VhVRyMiZkPmw~mEo-CVu548n4uJLsHJW4eNzQfQ~k8SSFGCMc0-YmOW8zvB1AmO1~hTy9qrT4-5rkVxvy7XTwK9-Mvb8N9fKvxr89yBitQvBwhsRKNScMBcV-qsauGd1F~wV~eb0BFjfZG2pyB~-AYuqZrqmoEf48Q~aXn5IKnIXkb8RmKbJNAws3opW3Tvbb-cHMhth3noc9QEpCJzzPZ6~hjjh0FTcPFiFAgaRIL81YcSfMTG7eTg2X20~5j4Em4GY6n8zHw6S5hbBuSMp~udmz11Bvc3QMcbfPMYhMxGMaqWUN8yN3kJwjk8griosz0o6XE~NcUvVXKZELW7jNmURd5e2a-zkSwjlOzoRi3OQhdeGypbUM0c-0-2OxOMJM~yw0bRingvRHT02Xr11nhyZRbysSMxFfxMY5doNKvJk~H7XhCaXCn0LtP7pd9JU9NPKzxIqbP8W0dZFP8C217yRmAHTfxbMmuYaQZenEkWmUVqlTyO-4NBAAAA
|
||||
sugadude.i2p=PIV8bZaIH4wRqzlzVLX1mDkELhLFdyLlKxcd2nUrJvd0YeTByls6LGFZ7wr0-9MT7cb3Ee23U1BApgm0~jT5bzFGIQOvx7AT8o0uMy~fcP1lhzo4lNwD5bHnf9OXe59FzORC3s79bwFmTtMCrEoYvQXCGherxwFfXywRPrJ2x0AjfjungiwX3vrndMdol1SDWTLdxTSARLPgLmswz47gGm4dOipjHBSGOm5bdgZBD6di8YGxHrB072QfXxBVSGzTgtQNnK4qAsZv1YbETk2CQ1nOKpCj0Zjkcnc1trTFOpUQKeOp6kiGCriAn8Ezbu1yuf2fiDAmPenFf8bDR7fNFR7kMDcKsbiht7fFi0wjPdE4Lx5H2PFyTuiw3~-osNsXFLtjvaeIV4P99vZRof1avADgp5k4pC8fEPKWfwXGPPFJjYEbWPE4VxmxcP93Iq-CMZfSd8fPeZNeBz8qL~n9IXJoXjO0G3nouQ7d1ZF4okVRO8FmZ91Umpy79v2I4sYFAAAA
|
||||
socks1.tor.i2p=sl3oda7CJe3TN1JVoALIuoRAe--qYgDwo0A8PrUGaaWQ2xXiWYaTV7~FQOmv13JRCtbO-8rhOfGWnV-qia4CtRxH6nR6fytW~uJKRP4hbjhfvBuS1QdX2GwWlbgJdV8VT3OpJAe5iuKYCFnnSbVG2VZajtsoKJxHY748h1zhIh4YaMBGqoodQJrnvYWd4HJJ-ZauE-s-K2zWOTJ-EKZNp9UZr5DWDV3P5JTSruc7vyKiDVFra~-JT8mjnWBE9GKy1HiJKAe2UyKHBVjvJ9iL4bJ3HLH-z3oIP5KmW7s4czTq2fdO7yhssLMKxaGqhzsNViWv8FtvLJtHkTsprVQBeS2Eeqiw3iwcC4DGP4dUkj2Ex7DPqvxlA58Df0INgNz-kUPuURf0ZSK45v-s7F0f03BbwIu5eErLZhQckxs9tX6twSPXk2RaceOMA0-eKlbCh3FcpbFbfcimjOTcmpeUN7s-7C-XfM1vazIaIpTADwzZ9Ocs5TV~CU8TPyxZkx8FAAAA
|
||||
eepdot.i2p=IXWmPK6689w4d2j-B-zQRdgG6md6UdvDZz9e3MnEWaoU7SiHk8Yrw4-2MSavhycFDkQNdpdJgYVhK0Ve8aF4TNf88KdI5SY4nl079CrjhTaNoQiUxOTJIUzTWGrDmNITfoV7PAjGWoMjw5dOcbK~PMpMTlOx9w8CtFEHU2cG4Gdcpu5NFpv6a5FWZNO-GRYrWfW1laZBviaE1Twwva-thbY~G5un9JFAoQZ88mS2JRKrxFuy1P1xCEEEiLvJfOcHVdL-0ebQV5q5Cwlyvrkki1se4URzlgF-FjQjTiaS0kbtHv6NkG-R19poUQu-ktMdMdDf2RLFBJPtyTvbyteyeXnI4LjGxSzQ8eH3txelIZKXwCRPYFNqutAmoQMqLf~NLDPtIq3QGp798sBbt3nooOKGEk3RVcJDwEzx~t3Qj6DWEA0xwSm56YYG84EYT2itIYGH8J4epFjGdV3zfWiME~QHLKfAwwkY-JdCiaDTk7RPfY1jkBw~SyI1jTYrX-PgAAAA
|
||||
modulus.i2p=HL47CwJWiovjoHMTK~2tK6~sYEghJapUNkeqOdnkWFsf985N8eCpRUQtz7fFJZrHCTHjqeO5hxvcFye~Jjtf~id7pFlaotkpmbnx75x5HCiTIBLTUfbPurjhTXNK3A0JFxQ5lmYd8S5WqNykdaZGHjhfDSC~PUcfJA398S611e2D5se1LKAp0qFFhbNi69Unovj7HdXYJLiATDhewt7tY6mMa-p3BeTcvu26MhET4itYBhzp12AKiqWrEQM-4tpCmK5K7gxECHOTuMtZu7SEVc4CYAgBIsILtT0YA84441o8h0kpsKGDPFuszMWtz5XSIFlO7mwpu6PCmBx6FZbaZFSQ8CghxqhrWGnGIno-Lr9vKeTpD-AT7rqwuUrZHfd3yhGhOA7i0nM6Uh~qXbvFkzK83kyyxbX4InjAZ4g897LixiCc2qj6~eeh1c9oNcZ01-ho5U7lXUo5WrfG1-N7DeH2xkWGzFrjlZ3dXP8w~f7osxtth596Jz~cY8xNacMuAAAA
|
||||
xolotl.i2p=byBX2FzIeKKRoUStOzidJ6jni4dkWBNK4x3khxgNo8NlJ8HqLl2MlgxlRsvhTHQy5L1GvTC9DYpnW0tE22Kl9QkPIGPikBLvwePT82gsRCxXOJ6CF8JiK0h9~giTOrRmguIo7d8DpDF3Sw7a9VVJf~9Dxs4IMCMPre36rPdmqkYSTZcfITfWCG1M1xnxQz9OuB6YKnnYcLvccSAcOTrWFEeiPHC0CsAo1EmJekmEGCK3lkNBRomfw05uhLqA4mFQgZbvHfSDhDv1eEUeQq8YBk4-vi4AsRjdmgLL4yduqoYnLgTYL6OvWuJ60EdxPkuZUzW8~5MGZfwKQLc4G0YmAjgLlQi1sdXT4HFFLNRvG2GO956Eay9Z3eLO2K7EvxY0C9MQ5n0LullF5NJD-V509h7kBPuItUC0haicVHXXwcXW-Lx36biz8apA9D24vMWvq4KLystsrtMetH1q1oyS4jA5BXWf~6FA~eCoZrX4lgnHJ6MHPCEmlUcQPrEvApIyAAAA
|
||||
freeciv.nightblade.i2p=mDlAeW1BD7ictjta8G0YwebMBmATFIWVXrVF6gpm3A13NMi1LIaq5da~zuQBWD3BLYmblE-3-U4snRHttVJBr-e9jAvy7ZBskGqie30JbzPbTBzLJWqdpaKzahI-eiezoDgVyhOstCBbjFc3CW~ckiLfj4MVS2nCV7qgujSWHho8mspb8lS0uJJk0XQImYx4QWY7KFCz2CaHY8JX~m05~81hTdJLZUjhDVBXsjj0wW-lE8mDZckiCn7ZaRSASBhFHiZnB6aGdY32Ltad6SjH0LngOcVbR43DYSHODabD6igb90c00wruQRMFarQSBBAk31uWnjftggllcA0X77NILD0PKG8RGa2fRcqyyVveGgYWhsl8vInVI-q-xI1PWairamHkzd-du58cmxzkqYZQR~XX5tPR3lQ-avScr0HgxHkMuTZSxEh72BcQP-qw2m0mPDrE445EPw3ipk8pRQi6H8lS0kCfDi8DBEygnqoLIqu35wrpEICCyog1buvppZTfAAAA
|
||||
curiosity.i2p=pka8sWaYxpm1U9gX6F7WJ56Kl12Y~Fks1w0O3DnpE2bfRUZldWpFdtnB6mHhqyinZKJWJVwVR92uFpQPdLtwjfCQtVzw7zXpndXG05QeRk4viRd6mxRua8xBgc2IFhXRXUDP3sSZT6aKFyP6S-R8yGkXID5fxrO~um5aBmHGalDohXHdPxbqrBbSWqjKHr35f7zSiJkCCRxDMGqWkrVuzoZIhJIVeRZxYaubKW9R-oJdmDqhtQeP7Au7IFzno66-fa9gsGWCWAyoJe0dk4tKGZA~Q-qlwW1I3esAnp2LPwlkrqPL-A5xqw1Gdwgh93rKGtUV41wKlhubfEiUXbkDgw6RLcpxXKbQxkJPUGum2-B9QVraAanVB1NDsW2nJvK0lb7SGgEHrENHW~Z5X8CANURb5PHR4CRcp~xwrbS3DPYAoiah7Rd7-PqcbXHxSu5jl4sVm3pZYKbo8V-PLKxIYzSWUhrmj1wGRTizeml0xvl5ysoDc5p2srCT-T4ihrKrAAAA
|
||||
anonymnet.i2p=Iku15m2pHtAfphzLKbhptluZuJ2FSst-b6WaiP-DWLue579sGChPuZEVxnbriFouidM4hw2Kvud1AeAYm632kDZZzIBf5EyCEdAPwc9R6cfBqe2N4hcvAXyWH9jevGMNe~NMOnjNvl8rKm2bGcEprvo1FPXKA1Ene2ATPViBVg-2xQyuZs9ZcU8rSi9~PrtG05zepAwfAGM2kIhNdF4biECXT-SLSxkU9An3GtAZjNkRMdiMPSY94mZWEalFbscuL8mlhl4xFg7XsnA1TEn6KaMnBjuf3FV9XSlXZ7pUD87BrRZYFHA0ujw5FqGu~-qLuIkbUpyhYz2rIHxNNJHm9l3T8yvumCanwr39xvganMLAD4nw~i0PKqQ5tLx0WBo64-GMz8Rbhfkhhj4a09qeR6OmDMwiyHoBgv9NDM6TCYBbLFMjf6X3wbcap4oOTNXvO3RG5T7kF-1RJ2IH6V3SwL9JpdH51fTo2WgBL9cESCvGntRM9g~EFyGyMoBAcmilAAAA
|
||||
sasquotch.i2p=6Hv24DvlxKauUfLHN4cPJd13cRyFq1wqaCb95r7fCYvhdFzluuZLDBYCM3w9GM3EVyAXS8uz0BCy9ZYncWXCsFQYejkTj~pTJEo5QjM1DszuUAGvDrqlm21e-ZwzEY817dIQCp9dQShfSnP41J~jVktE3ryMmtzAnCIZ~nMUejc9wManQG4muxuyUADdIiBIp-MXOAdXeEaaP0~5WPZhf0okm6uJd~fvO4h1Sy-CQuuJzWKYzDOvHFu-~9ONYQV8EdP4wovC15uHgX79YwAd8bpNTcfzJN9ypr9cQ0zGxYzDuK9LHaSD5MXQ8Hu2RgIrKUfb~osG4MQuYalBkUr3dpLzXLEokNIPk~BI~fI9AuG27wLI47fvOUB8Zbu1J9rSgz-J-~x8Tp4UFvRKDJ2N~5rj9mMdm9iO~U8DJvkOjjRraXhwqh3YcrnhHLPia10jvu72dAGi~S4bxiHuEcDn1JZIj64Jb6TC6xfhwEn-uoE~dqXdbr0MMoVcDsOP5dPjAAAA
|
||||
orz.i2p=GALU66G3Deh71g1COXAWKQvwVB2ULbf6ALTvc-vNHfZ~jkLhGpxmXOlVOu17hfWhB~whwj-~Hn7dxLgbXO1WXb-xmvKKIgxUssDosoSbM2v~LgzJq~iIkeoN9VQe4tz2pMql1-f3kV8-AHZIILR7tY61TjDLQbZSVhT0S7FIcTQulbct8wjP-p4Dvp4XUUFXJDRqIpZB9beNALEO-SYpFuadDeavDY4iUhNcERDXlj38ginXceHm5SXaiUNTr~qXzNNuR0r5FsAgjHLuy3UgnxM2aL~j7PXBieNL~mLs~YcYRYvZVtG~SXKQjUqw5iUJYYutgqHsiT7IrQKZ~FgvIYJWaZBgF-84WsfHgCw6jECkiiLgUxh676iNqMSfTkp0KMgjt~ekU9aWpZdiaD5KV2-phiuVMdEVbXCGfLnwSqWIQIrSAAXvsjL8ew7sCbtBOriGKUzeL~rBBltL6gSVdxn92fVdSz2XWGExvaT856ahgOtD8RFqCQTAUm~63xuSAAAA
|
||||
microbleu.i2p=V-3EgQik4jTtYyE4OXHBNl2kslSh-1g7SvtKvt-xzm32Q0zt07meIq2Brj1tkv~xll8t1gyfvy0Wn1n7Pcf4tlSEQ2KfJm6oHv-ZIovxewn420yl8cLgbB-dtoiY84fRxl8pS2GTHL~SOFOzussSSocKIBay71ODyhe4mJdtFA76LY6ycgsFIxK4U~Hb5YcIbenO3-94Oc7PXaRt4XmQ-7C9ZKAJXhLdlQGF3407gituMrhnppwQMSQP2ULJEBiLNtB7h1KasNn0Ao~HNf7bsJyCB29YGgIESIIAZxrBFNsjOpYg4WE3iWfzU-C0ohOCIvQhMXS0jPitke9R7Oor8TmJNagfZVnE2zg2oIPP8uKqf~kFTugeI3dUrlfdSYr-rvzEGzRMOFIT9GBEXnuNPnX3tUHD0LNewP-D3VvnT6Pu~0kc7s8gyjc5~gI3vj8gn8gQnnFnz6BTYfqLufF7UQnJtEKrCi1eAG8Dnbc6vaoA9qoAEXAtN5SFXiprqwBvAAAA
|
||||
www.postman.i2p=r8Ti6CtRJtSNAhxaoJuHZnbhAhjrbHIzMAVsuCNmLA7NO78mHvqLMk0HjQXou5fpnE40rCz5mxg-Zfz6J6B0rpE-UiqiozIC1cM-H-XM09Ftu6Ta97BeQ5MdrjtzJlagwXNM1Cn8k35UAdJQR2CfHQfJv0BUGVmkU8-D42fLqAVuRU9WpmA44YNMXJMT7kSqiZxKPdnXbpfst2h6ERLqGbqgCEToaH6NOyA8Lu4FJbOfkzfhrVIWHCiqn1FaAUK2Ie1POhfo8blfhQ1NdgkxGnTeaD1MJolI1qatpBWpsuiPlfMy7rxzTmP2dwpi-QQEdISi8U2eag3jsKGopQXwyn7Rx4zPQd82e9LCpiXWg2HVco1QV4H9z2alSHVJkWU-jC7jzQkDe-Iws-ZfEhKENRDps9Ev93KU-5-fohZZ614Ia0iDUs9RxP3mOM-RTiers~2B7Iq5-6hNMEoIzPzGbMKrrLs1Bos6LoZmIwGRS5pvlAis7usHjmBCy2hwqvi8AAAA
|
||||
smtp.postman.i2p=AUVlGWmbU0qNUBGvu1ls5OQcdZNjq7k1OPzqkhheGlc3HoQFi97-3BZevo4ThjL0WxHoBIMagAfXjAEm7EegzYqkfGtQ5TpEVAxg01eIGO-Lqq46MqbOFX~edpgi9StZIAPaXJps0MPtSfh0FsL-N5PTW2nqkITrMPxOuhyl8CvAdR~TxHSImMI5nNzCW39xkDrEBx5Mkn1s~xm2XdhyttG2z~g6~nec4X3rpV0sO1Fq2T1sgaKcHWUvJofzUV1y~bKnltJEB~KZpkkOxjz3SdcJzn8SPblyWAm3SUiAVY8ev2XwSaLl7-xe2bQtrnjbPfpHZ50yhGY-00wTcXEfSgt20DkibP7xg3cSAcVFla2IiGeJc~4WTCP3vkBipTnSFdNr3Ez2kCEa50kMiRfDkIk4S2E64~JBrgyNURXL4YNC~FV7qaK2gqHUJkhRiRQP2Hbq2lDygJGFjr2vIi0TBoZ0lWaX6cu8Jywhp-jZgrvun-F~n87iRvnNjkjuG6BYAAAA
|
||||
pop.postman.i2p=W4ZehJpFv9HnM4qnWb6c305H1vWRoghgSz~UXVVl7AM6cNYPU~DHzI0ezxyYIcsywhDvRdSvN5QQSyb2t-waFRaoMxmub9Z68uvcNPjAyG1Hc-igVbcmiGKo1RwXXO1JTzaAFE8NB2mvZmpksPDks0ugcd3AzBrrkxsqt8KLYSXBc7hDM59YUGl0j59NUZoE3tJgZlQ~fYr4P4P9VetBgVQ5mJFpwF~RvM2frx9zQ2SonCSTNFR88MEUJ6EoZUTDG-iz6mUVv2qOanAD1ZfSmmMZpbtFLovqvUGv8JLxFhFdkNmt3AmIZzPjmvrAu2X~VnAhX80Wrvba8df9w0qtplH5LYBykmN~wndjcQxOH7~LbGeJ-8q4DHf-DSDPFyn6L4uCk35kCSGXjEf1f44DSHU338Wiagn9ut7twiFSf8NLXvKV2-uWmx~twDLTd9cEjCEBm7ZXMaqWTK1kOGj0nlybm~mgMW-~IRnb6alnR0GMxAE-6fnWS52PJtmWU0ToAAAA
|
||||
jake.i2p=BzdF-Ib~jWRj9i1hypIasw67yv0YDEdCqloJr4Qq2Wvkt56slqzd0Qri6FQnWsGfTpmilvGI1H-7WAyU5KXc~nQ7F7KB~Im9cI1mIeMKeGK4Yzb6jV5SHctDZw2j1hqMpdjU76r45WiOgiAaNFin10SJ8IriNqce9VehnOupB53tpvoj1GnEIyxxaOsSDmxIakFZ8MsLW~s9wyxnlfvP-iOXLMpM6Achhcmxj-DWDcjwK-6rvLYoG6SY5vmpPNzhuyAa-8di8N3zBxL6WTf1Ox9UQrpXXZ1luYDUNxpFfPjzl9ZPpv4Ax6QzJvWn8B85GYs9ZkS1bpbtbbmQ1DTlOpwFMmidr0vaf68hNGvVY5yUgPZy28s8jvrz4AMEfAGlsozRkxr2JRwm3Oj3dqeW6ICKRwnThkjnXnGhQiIDV~bDfkgBzWvh4TyIYm5NBwAYFZdSx81Eno4sthfElFTeSDj0TjCKegNmAd6t4D82JMk8abws0MC-pIqaNLZRU1YVAAAA
|
||||
jabber-2.i2p=62UDEWG936i-w144HMYX~1aiRnvIkRg2Rbjor3KXUPfKaPXx6A6R54nhLYVI0Zt3Y6bquRIlvZd1KKb6VnQ~GbPhDKvOIzrSP~G7IajZOdncG4QlsuJYwOVVOSVAkR55pxdwwVHXkoR4~4hlahYGvGAayvvDxxWojr-dWg-IIUnEv8hjjstUfphSy~Jx17de0G~8n0DSZ~YKu83Cnu9sSydoXqqczq3KChFDjfUYtohNiZA8lXfrfv5K3pEeTOCemE1rDflPGu~5fawk3G1xNetuZQCKdkFNSxtkRpj3Vm2ej1ApLUi92zog3ekBbxEwfiP0DfC4BvdwgAimVGH8MpXS4BijlDNNbCWak6Pdr24OqVwLJXzWfqb11WFH-mc2JYJCPhJCvESYs~iK3JOZ0QzbW9F-495oB6RD-9guK9bBQHC1lMsNVhaj3Mh8gohKghvy2MrTNbirHKDjyyiAj5RrT1OjWoZNBMvXPEZEtEowuzZptP-tTf19mhGfPFOjAAAA
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$Id: install-headless.txt,v 1.1 2004/09/01 21:20:03 jrandom Exp $
|
||||
$Id: install-headless.txt,v 1.2 2004/09/02 01:54:37 jrandom Exp $
|
||||
Headless I2P installation instructions
|
||||
|
||||
1) tar xjf i2p.tar.bz2 (you've already done this)
|
||||
@@ -9,9 +9,6 @@ Headless I2P installation instructions
|
||||
If you're having trouble, swing by http://forum.i2p.net/, check the
|
||||
website at http://www.i2p.net/, or get on irc://irc.freenode.net/#i2p
|
||||
|
||||
To have I2P run on startup as a daemon, after the above, run:
|
||||
sh install_i2p_service_unix
|
||||
|
||||
To run I2P explicitly:
|
||||
sh i2prouter start
|
||||
|
||||
@@ -24,9 +21,6 @@ To stop the router (immediately):
|
||||
To uninstall I2P:
|
||||
rm -rf $i2pInstallDir
|
||||
|
||||
To remove the daemon setup, run:
|
||||
sh uninstall_i2p_service_unix
|
||||
|
||||
Supported JVMs:
|
||||
Windows: Latest available from http://java.sun.com/ (1.3+ supported)
|
||||
Linux: Latest available from http://java.sun.com/ (1.3+ supported)
|
||||
|
||||
@@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
|
||||
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
|
||||
@@ -3,8 +3,8 @@
|
||||
<processing>
|
||||
<job name="Launching I2P...">
|
||||
<os family="windows" />
|
||||
<executefile name="cmd.exe">
|
||||
<arg>/c</arg><arg>"$INSTALL_PATH\postinstall.bat"</arg>
|
||||
<executefile name="$INSTALL_PATH\postinstall.bat">
|
||||
<arg>$INSTALL_PATH</arg>
|
||||
</executefile>
|
||||
</job>
|
||||
<job name="Launching I2P...">
|
||||
|
||||
@@ -13,3 +13,8 @@ clientApp.1.args=sam.keys 127.0.0.1 7656 i2cp.tcp.host=localhost i2cp.tcp.port=7
|
||||
clientApp.2.main=net.i2p.i2ptunnel.TunnelControllerGroup
|
||||
clientApp.2.name=Tunnels
|
||||
clientApp.2.args=i2ptunnel.config
|
||||
|
||||
# run our own eepsite with a seperate jetty instance
|
||||
clientApp.3.main=org.mortbay.jetty.Server
|
||||
clientApp.3.name=eepsite
|
||||
clientApp.3.args=eepsite/jetty.xml
|
||||
24
installer/resources/eepsite_index.html
Normal file
24
installer/resources/eepsite_index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to your eepsite</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to your eepsite</h1>
|
||||
|
||||
<p>This is your eepsite - simply edit the files under ./eepsite/docroot/
|
||||
and they'll be reachable. The 'key' to your eepsite that you need to
|
||||
give to other people is shown on the I2PTunnel configuration
|
||||
<a href="http://localhost:7657/i2ptunnel/">configuration page</a>). </p>
|
||||
<p>
|
||||
If you have any standard java web applications (.war files) such as
|
||||
<a href="http://wiki.blojsom.com/wiki/display/blojsom/About%2Bblojsom">blojsom</a>
|
||||
or <a href="http://snipsnap.org/space/start">SnipSnap</a>, simply drop their .war
|
||||
file into ./eepsite/webapps/ and they'll be reachable at
|
||||
http://$yourEeepsite/warFileName/</p>
|
||||
|
||||
<p>You can also reach your eepsite locally through
|
||||
<a href="http://localhost:7658/">http://localhost:7658/</a>. If you
|
||||
want to change the port number, edit the file ./eepsite/jetty.xml and
|
||||
update the I2PTunnel configuration accordingly.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -18,7 +18,7 @@ APP_LONG_NAME="I2P Service"
|
||||
|
||||
# Wrapper
|
||||
WRAPPER_CMD="./i2psvc"
|
||||
WRAPPER_CONF="wrapper.conf"
|
||||
WRAPPER_CONF="wrapper.config"
|
||||
|
||||
# Priority at which to run the wrapper. See "man nice" for valid priorities.
|
||||
# nice is only used if a priority is specified.
|
||||
|
||||
@@ -28,7 +28,7 @@ rem
|
||||
:conf
|
||||
set _WRAPPER_CONF="%~f1"
|
||||
if not %_WRAPPER_CONF%=="" goto startup
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.conf"
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.config"
|
||||
|
||||
rem
|
||||
rem Start the Wrapper
|
||||
|
||||
5
installer/resources/i2prouter_win9x.bat
Normal file
5
installer/resources/i2prouter_win9x.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
setlocal
|
||||
REM Isn't it great the lengths we go through to launch a task without a dos box?
|
||||
start javaw -cp lib\i2p.jar net.i2p.util.ShellCommand i2prouter.bat
|
||||
exit
|
||||
@@ -8,7 +8,7 @@ tunnel.0.proxyList=squid.i2p,www1.squid.i2p
|
||||
tunnel.0.i2cpHost=localhost
|
||||
tunnel.0.i2cpPort=7654
|
||||
tunnel.0.option.tunnels.depthInbound=2
|
||||
tunnel.0.option.tunnels.numTunnels=2
|
||||
tunnel.0.option.tunnels.numInbound=2
|
||||
tunnel.0.startOnLoad=true
|
||||
|
||||
# irc
|
||||
@@ -21,7 +21,7 @@ tunnel.1.targetDestination=irc.duck.i2p
|
||||
tunnel.1.i2cpHost=localhost
|
||||
tunnel.1.i2cpPort=7654
|
||||
tunnel.1.option.tunnels.depthInbound=2
|
||||
tunnel.1.option.tunnels.numTunnels=2
|
||||
tunnel.1.option.tunnels.numInbound=2
|
||||
tunnel.1.startOnLoad=true
|
||||
|
||||
# I2P's cvs server
|
||||
@@ -34,18 +34,57 @@ tunnel.2.targetDestination=cvs.i2p
|
||||
tunnel.2.i2cpHost=localhost
|
||||
tunnel.2.i2cpPort=7654
|
||||
tunnel.2.option.tunnels.depthInbound=2
|
||||
tunnel.2.option.tunnels.numTunnels=2
|
||||
tunnel.2.option.tunnels.numInbound=2
|
||||
tunnel.2.startOnLoad=false
|
||||
|
||||
# local eepserver
|
||||
#tunnel.3.name=eepsite
|
||||
#tunnel.3.description=My eepsite
|
||||
#tunnel.3.type=server
|
||||
#tunnel.3.targetHost=localhost
|
||||
#tunnel.3.targetPort=8000
|
||||
#tunnel.3.privKeyFile=eepPriv.dat
|
||||
#tunnel.3.i2cpHost=localhost
|
||||
#tunnel.3.i2cpPort=7654
|
||||
#tunnel.3.option.tunnels.depthInbound=2
|
||||
#tunnel.3.option.tunnels.numTunnels=2
|
||||
#tunnel.3.startOnLoad=true
|
||||
tunnel.3.name=eepsite
|
||||
tunnel.3.description=My eepsite
|
||||
tunnel.3.type=server
|
||||
tunnel.3.targetHost=localhost
|
||||
tunnel.3.targetPort=7658
|
||||
tunnel.3.privKeyFile=eepsite/eepPriv.dat
|
||||
tunnel.3.i2cpHost=localhost
|
||||
tunnel.3.i2cpPort=7654
|
||||
tunnel.3.option.tunnels.depthInbound=2
|
||||
tunnel.3.option.tunnels.numInbound=2
|
||||
tunnel.3.startOnLoad=true
|
||||
|
||||
# postman's SMTP server - see www.postman.i2p
|
||||
tunnel.4.description=smtp server
|
||||
tunnel.4.i2cpHost=localhost
|
||||
tunnel.4.i2cpPort=7654
|
||||
tunnel.4.interface=127.0.0.1
|
||||
tunnel.4.listenPort=7659
|
||||
tunnel.4.name=smtp.postman.i2p
|
||||
tunnel.4.option.tunnels.depthInbound=2
|
||||
tunnel.4.option.tunnels.numInbound=2
|
||||
tunnel.4.startOnLoad=false
|
||||
tunnel.4.targetDestination=smtp.postman.i2p
|
||||
tunnel.4.type=client
|
||||
|
||||
# postman's POP3 server - see www.postman.i2p
|
||||
tunnel.5.name=pop3.postman.i2p
|
||||
tunnel.5.description=pop3 server
|
||||
tunnel.5.i2cpHost=localhost
|
||||
tunnel.5.i2cpPort=7654
|
||||
tunnel.5.interface=127.0.0.1
|
||||
tunnel.5.listenPort=7660
|
||||
tunnel.5.option.tunnels.depthInbound=2
|
||||
tunnel.5.option.tunnels.numInbound=2
|
||||
tunnel.5.startOnLoad=false
|
||||
tunnel.5.targetDestination=pop.postman.i2p
|
||||
tunnel.5.type=client
|
||||
|
||||
# another irc server, linked with irc.duck.i2p and IIP
|
||||
tunnel.6.description=irc.baffled.i2p
|
||||
tunnel.6.i2cpHost=localhost
|
||||
tunnel.6.i2cpPort=7654
|
||||
tunnel.6.interface=localhost
|
||||
tunnel.6.listenPort=7661
|
||||
tunnel.6.name=irc.baffled.i2p
|
||||
tunnel.6.option.tunnels.depthInbound=2
|
||||
tunnel.6.option.tunnels.numInbound=2
|
||||
tunnel.6.startOnLoad=false
|
||||
tunnel.6.targetDestination=irc.baffled.i2p
|
||||
tunnel.6.type=client
|
||||
|
||||
@@ -23,7 +23,7 @@ rem
|
||||
:conf
|
||||
set _WRAPPER_CONF="%~f1"
|
||||
if not %_WRAPPER_CONF%=="" goto startup
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.conf"
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.config"
|
||||
|
||||
rem
|
||||
rem Install the Wrapper as an NT service.
|
||||
|
||||
160
installer/resources/jetty.xml
Normal file
160
installer/resources/jetty.xml
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
|
||||
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty Server -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Request Listeners -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add and configure a HTTP listener to port 8080 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Call name="addListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.SocketListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.util.InetAddrPort">
|
||||
<Set name="host">127.0.0.1</Set>
|
||||
<Set name="port">7658</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="MinThreads">3</Set>
|
||||
<Set name="MaxThreads">10</Set>
|
||||
<Set name="MaxIdleTimeMs">30000</Set>
|
||||
<Set name="LowResourcePersistTimeMs">1000</Set>
|
||||
<Set name="ConfidentialPort">8443</Set>
|
||||
<Set name="IntegralPort">8443</Set>
|
||||
<Set name="PoolName">main</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a HTTPS SSL listener on port 8443 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<Call name="addListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.SunJsseListener">
|
||||
<Set name="Port">8443</Set>
|
||||
<Set name="PoolName">main</Set>
|
||||
<Set name="Keystore"><SystemProperty name="jetty.home" default="."/>/etc/demokeystore</Set>
|
||||
<Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
|
||||
<Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
|
||||
<Set name="NonPersistentUserAgent">MSIE 5</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a AJP13 listener on port 8009 -->
|
||||
<!-- This protocol can be used with mod_jk in apache, IIS etc. -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!--
|
||||
<Call name="addListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.ajp.AJP13Listener">
|
||||
<Set name="PoolName">ajp</Set>
|
||||
<Set name="Port">8009</Set>
|
||||
<Set name="MinThreads">3</Set>
|
||||
<Set name="MaxThreads">20</Set>
|
||||
<Set name="MaxIdleTimeMs">0</Set>
|
||||
<Set name="confidentialPort">443</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Contexts -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a all web application within the webapps directory. -->
|
||||
<!-- + No virtual host specified -->
|
||||
<!-- + Look in the webapps directory relative to jetty.home or . -->
|
||||
<!-- + Use the webdefault.xml resource for the defaults descriptor -->
|
||||
<!-- + Upack the war file -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Set name="rootWebApp">root</Set>
|
||||
<Call name="addWebApplications">
|
||||
<Arg></Arg>
|
||||
<Arg>./eepsite/webapps/</Arg>
|
||||
<Arg>./eepsite/webdefault.xml</Arg>
|
||||
<Arg type="boolean">true</Arg>
|
||||
</Call>
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add and configure a specific web application -->
|
||||
<!-- + Set Unpack WAR files -->
|
||||
<!-- + Set Default Descriptor. Resource, file or URL -->
|
||||
<!-- + Set Virtual Hosts. A Null host or empty array means all hosts -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<Call name="addWebApplication">
|
||||
<Arg>/context</Arg>
|
||||
<Arg>./webapps/root</Arg>
|
||||
|
||||
<Set name="extractWAR">false</Set>
|
||||
|
||||
<Set name="defaultsDescriptor">org/mortbay/jetty/servlet/webdefault.xml</Set>
|
||||
|
||||
<Set name="virtualHosts">
|
||||
<Array type="java.lang.String">
|
||||
<Item></Item>
|
||||
<Item>127.0.0.1</Item>
|
||||
<Item>localhost</Item>
|
||||
<Item>www.acme.com</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
<Call name="addContext">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.HttpContext">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Set name="resourceBase">./eepsite/docroot</Set>
|
||||
<Call name="addHandler">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.handler.ResourceHandler">
|
||||
<Set name="redirectWelcome">FALSE</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Request Log -->
|
||||
<!-- =============================================================== -->
|
||||
<Set name="RequestLog">
|
||||
<New class="org.mortbay.http.NCSARequestLog">
|
||||
<Arg>./eepsite/logs/yyyy_mm_dd.request.log</Arg>
|
||||
<Set name="retainDays">90</Set>
|
||||
<Set name="append">true</Set>
|
||||
<Set name="extended">false</Set>
|
||||
<Set name="buffered">false</Set>
|
||||
<Set name="LogTimeZone">GMT</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Other Server Options -->
|
||||
<!-- =============================================================== -->
|
||||
<Set name="requestsPerGC">2000</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
|
||||
</Configure>
|
||||
@@ -12,10 +12,19 @@
|
||||
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
if "%OS%"=="Windows_NT" (
|
||||
set INSTALL_PATH=%~dp0
|
||||
) else (
|
||||
set INSTALL_PATH="%1"
|
||||
)
|
||||
|
||||
copy "%INSTALL_PATH%lib\wrapper\win32\I2Psvc.exe" "%INSTALL_PATH%"
|
||||
copy "%INSTALL_PATH%lib\wrapper\win32\wrapper.dll" "%INSTALL_PATH%lib"
|
||||
copy "%INSTALL_PATH%lib\wrapper\win32\wrapper.jar" "%INSTALL_PATH%lib"
|
||||
|
||||
if "%OS%"=="Windows_NT" (
|
||||
|
||||
del /f /q "%INSTALL_PATH%i2prouter"
|
||||
:: del /f /q "%INSTALL_PATH%install_i2p_service_unix"
|
||||
del /f /q "%INSTALL_PATH%install-headless.txt"
|
||||
@@ -25,3 +34,19 @@ del /f /q "%INSTALL_PATH%postinstall.sh"
|
||||
del /f /q "%INSTALL_PATH%icons\*.xpm"
|
||||
rmdir /q /s "%INSTALL_PATH%lib\wrapper"
|
||||
start /b /i /d"%INSTALL_PATH%" i2prouter.bat
|
||||
|
||||
) else (
|
||||
|
||||
del "%INSTALL_PATH%i2prouter"
|
||||
:: del "%INSTALL_PATH%install_i2p_service_unix"
|
||||
del "%INSTALL_PATH%install_i2p_service_winnt.bat"
|
||||
del "%INSTALL_PATH%install-headless.txt"
|
||||
del "%INSTALL_PATH%osid"
|
||||
del "%INSTALL_PATH%postinstall.sh"
|
||||
:: del "%INSTALL_PATH%uninstall_i2p_service_unix"
|
||||
del "%INSTALL_PATH%uninstall_i2p_service_winnt.bat"
|
||||
del "%INSTALL_PATH%icons\*.xpm"
|
||||
deltree /Y "%INSTALL_PATH%lib\wrapper"
|
||||
start /M "%INSTALL_PATH%i2prouter.bat"
|
||||
|
||||
)
|
||||
|
||||
@@ -56,8 +56,8 @@ esac
|
||||
cp $wrapperpath/wrapper.jar ./lib/
|
||||
cp $wrapperpath/i2psvc .
|
||||
chmod 744 ./i2psvc
|
||||
rm -rdf ./icons
|
||||
rm -rdf ./lib/wrapper
|
||||
rm -rf ./icons
|
||||
rm -rf ./lib/wrapper
|
||||
rm -f ./lib/*.dll
|
||||
rm -f ./*.bat
|
||||
./i2prouter start
|
||||
|
||||
@@ -23,7 +23,7 @@ rem
|
||||
:conf
|
||||
set _WRAPPER_CONF="%~f1"
|
||||
if not %_WRAPPER_CONF%=="" goto startup
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.conf"
|
||||
set _WRAPPER_CONF="%_REALPATH%wrapper.config"
|
||||
|
||||
rem
|
||||
rem Uninstall the Wrapper as an NT service.
|
||||
|
||||
@@ -1,148 +1,148 @@
|
||||
#********************************************************************
|
||||
# Wrapper Properties
|
||||
#********************************************************************
|
||||
# Java Application
|
||||
wrapper.java.command=java
|
||||
|
||||
# Java Main class. This class must implement the WrapperListener interface
|
||||
# or guarantee that the WrapperManager class is initialized. Helper
|
||||
# classes are provided to do this for you. See the Integration section
|
||||
# of the documentation for details.
|
||||
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
|
||||
|
||||
# Java Classpath (include wrapper.jar) Add class path elements as
|
||||
# needed starting from 1
|
||||
wrapper.java.classpath.1=lib/ant.jar
|
||||
wrapper.java.classpath.2=lib/heartbeat.jar
|
||||
wrapper.java.classpath.3=lib/i2p.jar
|
||||
wrapper.java.classpath.4=lib/i2ptunnel.jar
|
||||
wrapper.java.classpath.5=lib/jasper-compiler.jar
|
||||
wrapper.java.classpath.6=lib/jasper-runtime.jar
|
||||
wrapper.java.classpath.7=lib/javax.servlet.jar
|
||||
wrapper.java.classpath.8=lib/jnet.jar
|
||||
wrapper.java.classpath.9=lib/mstreaming.jar
|
||||
wrapper.java.classpath.10=lib/netmonitor.jar
|
||||
wrapper.java.classpath.11=lib/org.mortbay.jetty.jar
|
||||
wrapper.java.classpath.12=lib/router.jar
|
||||
wrapper.java.classpath.13=lib/routerconsole.jar
|
||||
wrapper.java.classpath.14=lib/sam.jar
|
||||
wrapper.java.classpath.15=lib/wrapper.jar
|
||||
wrapper.java.classpath.16=lib/xercesImpl.jar
|
||||
wrapper.java.classpath.17=lib/xml-apis.jar
|
||||
wrapper.java.classpath.18=lib/jbigi.jar
|
||||
wrapper.java.classpath.19=lib/systray.jar
|
||||
wrapper.java.classpath.20=lib/systray4j.jar
|
||||
|
||||
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
|
||||
wrapper.java.library.path.1=.
|
||||
wrapper.java.library.path.2=lib
|
||||
|
||||
# Java Additional Parameters
|
||||
wrapper.java.additional.1=-DloggerFilenameOverride=logs/log-router-@.txt
|
||||
|
||||
# Initial Java Heap Size (in MB)
|
||||
#wrapper.java.initmemory=4
|
||||
|
||||
# Maximum Java Heap Size (in MB)
|
||||
#wrapper.java.maxmemory=32
|
||||
|
||||
# Application parameters. Add parameters as needed starting from 1
|
||||
wrapper.app.parameter.1=net.i2p.router.Router
|
||||
|
||||
#********************************************************************
|
||||
# Wrapper Logging Properties
|
||||
#********************************************************************
|
||||
# Format of output for the console. (See docs for formats)
|
||||
wrapper.console.format=PM
|
||||
|
||||
# Log Level for console output. (See docs for log levels)
|
||||
wrapper.console.loglevel=INFO
|
||||
|
||||
# Log file to use for wrapper output logging.
|
||||
wrapper.logfile=wrapper.log
|
||||
|
||||
# Format of output for the log file. (See docs for formats)
|
||||
wrapper.logfile.format=LPTM
|
||||
|
||||
# Log Level for log file output. (See docs for log levels)
|
||||
wrapper.logfile.loglevel=INFO
|
||||
|
||||
# Maximum size that the log file will be allowed to grow to before
|
||||
# the log is rolled. Size is specified in bytes. The default value
|
||||
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
|
||||
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
|
||||
wrapper.logfile.maxsize=1m
|
||||
|
||||
# Maximum number of rolled log files which will be allowed before old
|
||||
# files are deleted. The default value of 0 implies no limit.
|
||||
wrapper.logfile.maxfiles=2
|
||||
|
||||
# Log Level for sys/event log output. (See docs for log levels)
|
||||
wrapper.syslog.loglevel=NONE
|
||||
|
||||
# choose what to do if the JVM kills itself based on the exit code
|
||||
wrapper.on_exit.default=SHUTDOWN
|
||||
wrapper.on_exit.0=SHUTDOWN
|
||||
wrapper.on_exit.1=SHUTDOWN
|
||||
# OOM
|
||||
wrapper.on_exit.10=RESTART
|
||||
# graceful shutdown
|
||||
wrapper.on_exit.2=SHUTDOWN
|
||||
# hard shutdown
|
||||
wrapper.on_exit.3=SHUTDOWN
|
||||
# hard restart
|
||||
wrapper.on_exit.4=RESTART
|
||||
|
||||
# the router may take a few seconds to save state, etc
|
||||
wrapper.jvm_exit.timeout=60
|
||||
|
||||
# the router may take a few seconds to save state, etc
|
||||
wrapper.jvm_exit.timeout=30
|
||||
|
||||
# give the OS 30s to clear all the old sockets / etc before restarting
|
||||
#wrapper.restart.delay=30
|
||||
|
||||
# use the wrapper's internal timer thread. otherwise this would
|
||||
# force a restart of the router during daylight savings time as well
|
||||
# as any time that the OS clock changes
|
||||
wrapper.use_system_time=false
|
||||
|
||||
# pid file for the JVM
|
||||
wrapper.java.pidfile=routerjvm.pid
|
||||
# pid file for the service monitoring the JVM
|
||||
#
|
||||
# From i2prouter:
|
||||
#
|
||||
# PIDDIR="."
|
||||
# APP_NAME="i2p"
|
||||
# PIDFILE="$PIDDIR/$APP_NAME.pid"
|
||||
#
|
||||
# This means i2prouter looks for './i2p.pid'.
|
||||
wrapper.pidfile=i2p.pid
|
||||
|
||||
#********************************************************************
|
||||
# Wrapper NT Service Properties
|
||||
#********************************************************************
|
||||
# WARNING - Do not modify any of these properties when an application
|
||||
# using this configuration file has been installed as a service.
|
||||
# Please uninstall the service before modifying this section. The
|
||||
# service can then be reinstalled.
|
||||
|
||||
# Name of the service
|
||||
wrapper.ntservice.name=i2p
|
||||
|
||||
# Display name of the service
|
||||
wrapper.ntservice.displayname=I2P Service
|
||||
|
||||
# Description of the service
|
||||
wrapper.ntservice.description=The I2P router service
|
||||
|
||||
# Service dependencies. Add dependencies as needed starting from 1
|
||||
wrapper.ntservice.dependency.1=
|
||||
|
||||
# Mode in which the service is installed. AUTO_START or DEMAND_START
|
||||
wrapper.ntservice.starttype=AUTO_START
|
||||
|
||||
# Allow the service to interact with the desktop.
|
||||
wrapper.ntservice.interactive=true
|
||||
|
||||
#********************************************************************
|
||||
# Wrapper Properties
|
||||
#********************************************************************
|
||||
# Java Application
|
||||
wrapper.java.command=java
|
||||
|
||||
# Java Main class. This class must implement the WrapperListener interface
|
||||
# or guarantee that the WrapperManager class is initialized. Helper
|
||||
# classes are provided to do this for you. See the Integration section
|
||||
# of the documentation for details.
|
||||
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
|
||||
|
||||
# Java Classpath (include wrapper.jar) Add class path elements as
|
||||
# needed starting from 1
|
||||
wrapper.java.classpath.1=lib/ant.jar
|
||||
wrapper.java.classpath.2=lib/heartbeat.jar
|
||||
wrapper.java.classpath.3=lib/i2p.jar
|
||||
wrapper.java.classpath.4=lib/i2ptunnel.jar
|
||||
wrapper.java.classpath.5=lib/jasper-compiler.jar
|
||||
wrapper.java.classpath.6=lib/jasper-runtime.jar
|
||||
wrapper.java.classpath.7=lib/javax.servlet.jar
|
||||
wrapper.java.classpath.8=lib/jnet.jar
|
||||
wrapper.java.classpath.9=lib/mstreaming.jar
|
||||
wrapper.java.classpath.10=lib/netmonitor.jar
|
||||
wrapper.java.classpath.11=lib/org.mortbay.jetty.jar
|
||||
wrapper.java.classpath.12=lib/router.jar
|
||||
wrapper.java.classpath.13=lib/routerconsole.jar
|
||||
wrapper.java.classpath.14=lib/sam.jar
|
||||
wrapper.java.classpath.15=lib/wrapper.jar
|
||||
wrapper.java.classpath.16=lib/xercesImpl.jar
|
||||
wrapper.java.classpath.17=lib/xml-apis.jar
|
||||
wrapper.java.classpath.18=lib/jbigi.jar
|
||||
wrapper.java.classpath.19=lib/systray.jar
|
||||
wrapper.java.classpath.20=lib/systray4j.jar
|
||||
|
||||
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
|
||||
wrapper.java.library.path.1=.
|
||||
wrapper.java.library.path.2=lib
|
||||
|
||||
# Java Additional Parameters
|
||||
wrapper.java.additional.1=-DloggerFilenameOverride=logs/log-router-@.txt
|
||||
wrapper.java.additional.2=-Dorg.mortbay.http.Version.paranoid=true
|
||||
|
||||
# Initial Java Heap Size (in MB)
|
||||
#wrapper.java.initmemory=4
|
||||
|
||||
# Maximum Java Heap Size (in MB)
|
||||
#wrapper.java.maxmemory=32
|
||||
|
||||
# Application parameters. Add parameters as needed starting from 1
|
||||
wrapper.app.parameter.1=net.i2p.router.Router
|
||||
|
||||
#********************************************************************
|
||||
# Wrapper Logging Properties
|
||||
#********************************************************************
|
||||
# Format of output for the console. (See docs for formats)
|
||||
wrapper.console.format=PM
|
||||
|
||||
# Log Level for console output. (See docs for log levels)
|
||||
wrapper.console.loglevel=INFO
|
||||
|
||||
# Log file to use for wrapper output logging.
|
||||
wrapper.logfile=wrapper.log
|
||||
|
||||
# Format of output for the log file. (See docs for formats)
|
||||
wrapper.logfile.format=LPTM
|
||||
|
||||
# Log Level for log file output. (See docs for log levels)
|
||||
wrapper.logfile.loglevel=INFO
|
||||
|
||||
# Maximum size that the log file will be allowed to grow to before
|
||||
# the log is rolled. Size is specified in bytes. The default value
|
||||
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
|
||||
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
|
||||
wrapper.logfile.maxsize=1m
|
||||
|
||||
# Maximum number of rolled log files which will be allowed before old
|
||||
# files are deleted. The default value of 0 implies no limit.
|
||||
wrapper.logfile.maxfiles=2
|
||||
|
||||
# Log Level for sys/event log output. (See docs for log levels)
|
||||
wrapper.syslog.loglevel=NONE
|
||||
|
||||
# choose what to do if the JVM kills itself based on the exit code
|
||||
wrapper.on_exit.default=SHUTDOWN
|
||||
wrapper.on_exit.0=SHUTDOWN
|
||||
wrapper.on_exit.1=SHUTDOWN
|
||||
# OOM
|
||||
wrapper.on_exit.10=RESTART
|
||||
# graceful shutdown
|
||||
wrapper.on_exit.2=SHUTDOWN
|
||||
# hard shutdown
|
||||
wrapper.on_exit.3=SHUTDOWN
|
||||
# hard restart
|
||||
wrapper.on_exit.4=RESTART
|
||||
# hard restart
|
||||
wrapper.on_exit.5=RESTART
|
||||
|
||||
# the router may take a few seconds to save state, etc
|
||||
wrapper.jvm_exit.timeout=10
|
||||
|
||||
# give the OS 60s to clear all the old sockets / etc before restarting
|
||||
wrapper.restart.delay=60
|
||||
|
||||
# use the wrapper's internal timer thread. otherwise this would
|
||||
# force a restart of the router during daylight savings time as well
|
||||
# as any time that the OS clock changes
|
||||
wrapper.use_system_time=false
|
||||
|
||||
# pid file for the JVM
|
||||
wrapper.java.pidfile=routerjvm.pid
|
||||
# pid file for the service monitoring the JVM
|
||||
#
|
||||
# From i2prouter:
|
||||
#
|
||||
# PIDDIR="."
|
||||
# APP_NAME="i2p"
|
||||
# PIDFILE="$PIDDIR/$APP_NAME.pid"
|
||||
#
|
||||
# This means i2prouter looks for './i2p.pid'.
|
||||
wrapper.pidfile=i2p.pid
|
||||
|
||||
#********************************************************************
|
||||
# Wrapper NT Service Properties
|
||||
#********************************************************************
|
||||
# WARNING - Do not modify any of these properties when an application
|
||||
# using this configuration file has been installed as a service.
|
||||
# Please uninstall the service before modifying this section. The
|
||||
# service can then be reinstalled.
|
||||
|
||||
# Name of the service
|
||||
wrapper.ntservice.name=i2p
|
||||
|
||||
# Display name of the service
|
||||
wrapper.ntservice.displayname=I2P Service
|
||||
|
||||
# Description of the service
|
||||
wrapper.ntservice.description=The I2P router service
|
||||
|
||||
# Service dependencies. Add dependencies as needed starting from 1
|
||||
wrapper.ntservice.dependency.1=
|
||||
|
||||
# Mode in which the service is installed. AUTO_START or DEMAND_START
|
||||
wrapper.ntservice.starttype=AUTO_START
|
||||
|
||||
# Allow the service to interact with the desktop.
|
||||
wrapper.ntservice.interactive=true
|
||||
|
||||
135
projectplan.xml
Normal file
135
projectplan.xml
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="i2p" company="i2p" webLink="http://www.i2p.net/" view-date="1/9/2004" view-zoom="6" version="1.10">
|
||||
<!-- --> <description> </description>
|
||||
|
||||
<tasks color="#8cb6ce">
|
||||
<task id="0" name="TCP transport revamp" color="#8cb6ce" meeting="false" start="13/9/2004" duration="13" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="6" type="2"/>
|
||||
<task id="1" name="Refactor transport.tcp.*" color="#8cb6ce" meeting="false" start="13/9/2004" duration="4" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="2" type="2"/>
|
||||
</task>
|
||||
<task id="2" name="Session tags" color="#8cb6ce" meeting="false" start="17/9/2004" duration="2" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="4" type="2"/>
|
||||
</task>
|
||||
<task id="4" name="Autodetect IP on connect" color="#8cb6ce" meeting="false" start="19/9/2004" duration="2" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="5" type="2"/>
|
||||
</task>
|
||||
<task id="5" name="Web UI updates to notify errors" color="#8cb6ce" meeting="false" start="21/9/2004" duration="2" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="12" type="2"/>
|
||||
</task>
|
||||
<task id="12" name="QA/support" color="#8cb6ce" meeting="false" start="23/9/2004" duration="3" complete="0" fixed-start="false" priority="1" expand="true"/>
|
||||
</task>
|
||||
<task id="6" name="0.4.1" color="#8cb6ce" meeting="true" start="26/9/2004" duration="1" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="7" type="2"/>
|
||||
<depend id="8" type="2"/>
|
||||
</task>
|
||||
<task id="7" name="Tunnel revamp" color="#8cb6ce" meeting="false" start="27/9/2004" duration="15" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="11" type="2"/>
|
||||
<task id="8" name="Spec structures" color="#8cb6ce" meeting="false" start="27/9/2004" duration="2" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="10" type="2"/>
|
||||
</task>
|
||||
<task id="10" name="Tunnel length randomization and ordering" color="#8cb6ce" meeting="false" start="29/9/2004" duration="3" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="9" type="2"/>
|
||||
</task>
|
||||
<task id="9" name="Implement tunnel processing and building" color="#8cb6ce" meeting="false" start="2/10/2004" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="13" type="2"/>
|
||||
</task>
|
||||
<task id="13" name="QA/support" color="#8cb6ce" meeting="false" start="7/10/2004" duration="5" complete="0" fixed-start="false" priority="1" expand="true"/>
|
||||
</task>
|
||||
<task id="11" name="0.4.2" color="#8cb6ce" meeting="true" start="12/10/2004" duration="1" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="63" type="2"/>
|
||||
</task>
|
||||
<task id="62" name="Streaming lib" color="#8cb6ce" meeting="false" start="13/10/2004" duration="18" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<task id="63" name="Packet spec" color="#8cb6ce" meeting="false" start="13/10/2004" duration="3" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="64" type="2"/>
|
||||
</task>
|
||||
<task id="64" name="Implementation" color="#8cb6ce" meeting="false" start="16/10/2004" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="65" type="2"/>
|
||||
</task>
|
||||
<task id="65" name="QA/support" color="#8cb6ce" meeting="false" start="26/10/2004" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="66" type="2"/>
|
||||
</task>
|
||||
</task>
|
||||
<task id="66" name="0.4.3" color="#8cb6ce" meeting="true" start="31/10/2004" duration="1" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="69" type="2"/>
|
||||
</task>
|
||||
<task id="68" name="UDP transport" color="#8cb6ce" meeting="false" start="31/10/2004" duration="19" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<task id="69" name="Packet spec" color="#8cb6ce" meeting="false" start="31/10/2004" duration="3" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="70" type="2"/>
|
||||
</task>
|
||||
<task id="70" name="Implementation" color="#8cb6ce" meeting="false" start="2/11/2004" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="71" type="2"/>
|
||||
</task>
|
||||
<task id="71" name="QA/support" color="#8cb6ce" meeting="false" start="12/11/2004" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="72" type="2"/>
|
||||
<depend id="170" type="2"/>
|
||||
</task>
|
||||
</task>
|
||||
<task id="170" name="0.4.4" color="#8cb6ce" meeting="true" start="17/11/2004" duration="1" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="122" type="2"/>
|
||||
</task>
|
||||
<task id="55" name="Cleanup" color="#8cb6ce" meeting="false" start="18/11/2004" duration="21" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<task id="122" name="Code refactoring" color="#8cb6ce" meeting="false" start="18/11/2004" duration="7" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="56" type="2"/>
|
||||
</task>
|
||||
<task id="56" name="Site docs" color="#8cb6ce" meeting="false" start="25/11/2004" duration="7" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="57" type="2"/>
|
||||
</task>
|
||||
<task id="57" name="Code docs" color="#8cb6ce" meeting="false" start="2/12/2004" duration="7" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="54" type="2"/>
|
||||
</task>
|
||||
</task>
|
||||
<task id="54" name="1.0" color="#8cb6ce" meeting="true" start="9/12/2004" duration="2" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="67" type="2"/>
|
||||
</task>
|
||||
<task id="67" name="Support" color="#8cb6ce" meeting="false" start="11/12/2004" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="110" type="2"/>
|
||||
</task>
|
||||
<task id="109" name="Restricted routes" color="#8cb6ce" meeting="false" start="21/12/2004" duration="25" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<task id="110" name="Basic restricted routes" color="#8cb6ce" meeting="false" start="21/12/2004" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="111" type="2"/>
|
||||
</task>
|
||||
<task id="111" name="Trusted links" color="#8cb6ce" meeting="false" start="31/12/2004" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="112" type="2"/>
|
||||
</task>
|
||||
<task id="112" name="QA/support" color="#8cb6ce" meeting="false" start="5/1/2005" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="113" type="2"/>
|
||||
</task>
|
||||
</task>
|
||||
<task id="113" name="2.0" color="#8cb6ce" meeting="true" start="15/1/2005" duration="1" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="120" type="2"/>
|
||||
</task>
|
||||
<task id="120" name="Support" color="#8cb6ce" meeting="false" start="16/1/2005" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="115" type="2"/>
|
||||
</task>
|
||||
<task id="114" name="Mixing" color="#8cb6ce" meeting="false" start="26/1/2005" duration="26" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<task id="115" name="Tunnel throttles" color="#8cb6ce" meeting="false" start="26/1/2005" duration="3" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="116" type="2"/>
|
||||
</task>
|
||||
<task id="116" name="Tunnel pooling" color="#8cb6ce" meeting="false" start="29/1/2005" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="117" type="2"/>
|
||||
</task>
|
||||
<task id="117" name="Tunnel chaffing" color="#8cb6ce" meeting="false" start="3/2/2005" duration="3" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="118" type="2"/>
|
||||
</task>
|
||||
<task id="118" name="Garlic delays" color="#8cb6ce" meeting="false" start="6/2/2005" duration="5" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="119" type="2"/>
|
||||
</task>
|
||||
<task id="119" name="QA/support" color="#8cb6ce" meeting="false" start="11/2/2005" duration="10" complete="0" fixed-start="false" priority="1" expand="true">
|
||||
<depend id="121" type="2"/>
|
||||
</task>
|
||||
</task>
|
||||
<task id="121" name="3.0" color="#8cb6ce" meeting="true" start="21/2/2005" duration="1" complete="0" fixed-start="false" priority="1" expand="true"/>
|
||||
</tasks>
|
||||
|
||||
<resources>
|
||||
<resource id="0" name="jrandom" function="SoftwareDevelopment:2" contacts="" phone="" />
|
||||
</resources>
|
||||
|
||||
<allocations>
|
||||
</allocations>
|
||||
|
||||
|
||||
<roles roleset-name="Default"/>
|
||||
<roles roleset-name="SoftwareDevelopment"/>
|
||||
</project>
|
||||
19
readme.html
19
readme.html
@@ -43,9 +43,11 @@ to reach some of the following sites:</p>
|
||||
<ul>
|
||||
<li><a href="http://duck.i2p/">duck.i2p</a>: duck's eepsite, with links to other active sites</li>
|
||||
<li><a href="http://ugha.i2p/">ugha.i2p</a>: ugha's eepsite, a wiki that anyone can edit, and lots of links</li>
|
||||
<li><a href="http://forum.i2p/">forum.i2p</a>: an anonymous gateway to <a href="http://forum.i2p.net/">forum.i2p.net</a></li>
|
||||
<li><a href="http://forum.i2p/">forum.i2p</a>: a secure and anonymous connection to <a href="http://forum.i2p.net/">forum.i2p.net</a></li>
|
||||
<li><a href="http://www.i2p/">www.i2p</a>: a secure and anonymous connection to <a href="http://www.i2p.net/">www.i2p.net</a></li>
|
||||
<li><a href="http://dev.i2p/">dev.i2p</a>: a secure and anonymous connection to <a href="http://dev.i2p.net/">dev.i2p.net</a></li>
|
||||
<li><a href="http://fproxy.i2p/">fproxy.i2p</a> and <a href="http://fproxy2.i2p/">fproxy2.i2p</a>:
|
||||
public gateways into two different freenet nodes</li>
|
||||
a secure and anonymous connection to two different freenet nodes</li>
|
||||
</ul>
|
||||
|
||||
<p>The IRC proxy is a gateway to duck's anonymously hosted IRC server
|
||||
@@ -60,4 +62,17 @@ the <a href="/i2ptunnel/" target="_blank">I2PTunnel configuration interface</a>
|
||||
You can also go to that page if you want to add a new tunnel, such as if you want to run
|
||||
your own eepsite.</p>
|
||||
|
||||
<h2>Want your own eepsite?</h2>
|
||||
<p>In addition, we've configured some software to let you run your own eepsite - a
|
||||
<a href="http://jetty.mortbay.org/">Jetty</a> instance listening on
|
||||
<a href="http://localhost:7658/">http://localhost:7658/</a>. Simply place your files in
|
||||
the <code>eepsite/docroot/</code> directory (or any standard JSP/Servlet <code>.war</code>
|
||||
files under <code>eepsite/webapps</code>) and they'll show up. Your eepsite's
|
||||
<i>destination</i> (which uniquely and securly identifies it) is shown on the I2PTunnel
|
||||
<a href="/i2ptunnel/">configuration page</a> - if you want other people to see your eepsite,
|
||||
you need to give them that really huge string. Just paste it into the
|
||||
<a href="http://forum.i2p/viewforum.php?f=16">Eepsite announce</a> forum, add it to
|
||||
ugha's <a href="http://ugha.i2p/I2pLinks">wiki</a>, or paste it in the #i2p or #i2p-chat channels on
|
||||
IRC (be sure to split it into two lines, as its too long for one).</p>
|
||||
|
||||
<p><b>As a note, you can change this page by editing the file "docs/readme.html"</b></p>
|
||||
@@ -50,4 +50,7 @@ public interface I2NPMessage extends DataStructure {
|
||||
*
|
||||
*/
|
||||
public Date getMessageExpiration();
|
||||
|
||||
/** How large the message is, including any checksums */
|
||||
public int getSize();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package net.i2p.data.i2np;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -17,6 +18,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataStructureImpl;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@@ -72,12 +74,23 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
type = (int)DataHelper.readLong(in, 1);
|
||||
_uniqueId = DataHelper.readLong(in, 4);
|
||||
_expiration = DataHelper.readDate(in);
|
||||
int size = (int)DataHelper.readLong(in, 2);
|
||||
Hash h = new Hash();
|
||||
h.readBytes(in);
|
||||
byte data[] = new byte[size];
|
||||
int read = DataHelper.read(in, data);
|
||||
if (read != size)
|
||||
throw new I2NPMessageException("Payload is too short [" + read + ", wanted " + size + "]");
|
||||
Hash calc = _context.sha().calculateHash(data);
|
||||
if (!calc.equals(h))
|
||||
throw new I2NPMessageException("Hash does not match");
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
||||
readMessage(new ByteArrayInputStream(data), type);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new I2NPMessageException("Error reading the message header", dfe);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
||||
readMessage(in, type);
|
||||
}
|
||||
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
try {
|
||||
@@ -87,6 +100,9 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Writing bytes: type = " + getType() + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
||||
byte[] data = writeMessage();
|
||||
DataHelper.writeLong(out, 2, data.length);
|
||||
Hash h = _context.sha().calculateHash(data);
|
||||
h.writeBytes(out);
|
||||
out.write(data);
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw new DataFormatException("Error writing out the I2NP message data", ime);
|
||||
@@ -105,4 +121,15 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
*/
|
||||
public Date getMessageExpiration() { return _expiration; }
|
||||
public void setMessageExpiration(Date exp) { _expiration = exp; }
|
||||
|
||||
public int getSize() {
|
||||
try {
|
||||
byte msg[] = writeMessage();
|
||||
return msg.length + 43;
|
||||
} catch (IOException ioe) {
|
||||
return 0;
|
||||
} catch (I2NPMessageException ime) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class TunnelMessage extends I2NPMessageImpl {
|
||||
if ( (_tunnelId == null) || (_data == null) || (_data.length <= 0) )
|
||||
throw new I2NPMessageException("Not enough data to write out");
|
||||
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream(4096);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream(64+_data.length);
|
||||
try {
|
||||
_tunnelId.writeBytes(os);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
@@ -70,7 +70,7 @@ public abstract class ClientManagerFacade implements Service {
|
||||
*
|
||||
*/
|
||||
public abstract SessionConfig getClientSessionConfig(Destination dest);
|
||||
public void renderStatusHTML(OutputStream out) throws IOException { }
|
||||
public void renderStatusHTML(Writer out) throws IOException { }
|
||||
}
|
||||
|
||||
class DummyClientManagerFacade extends ClientManagerFacade {
|
||||
|
||||
@@ -9,8 +9,10 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -21,10 +23,13 @@ import java.util.Set;
|
||||
public abstract class CommSystemFacade implements Service {
|
||||
public abstract void processMessage(OutNetMessage msg);
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException { }
|
||||
public void renderStatusHTML(Writer out) throws IOException { }
|
||||
|
||||
/** Create the set of RouterAddress structures based on the router's config */
|
||||
public Set createAddresses() { return new HashSet(); }
|
||||
|
||||
public int countActivePeers() { return 0; }
|
||||
public List getMostRecentErrorMessages() { return Collections.EMPTY_LIST; }
|
||||
}
|
||||
|
||||
class DummyCommSystemFacade extends CommSystemFacade {
|
||||
|
||||
@@ -60,6 +60,13 @@ public class InNetMessagePool {
|
||||
I2NPMessage messageBody = msg.getMessage();
|
||||
msg.processingComplete();
|
||||
Date exp = messageBody.getMessageExpiration();
|
||||
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received inbound "
|
||||
+ " with id " + messageBody.getUniqueId()
|
||||
+ " expiring on " + exp
|
||||
+ " of type " + messageBody.getClass().getName());
|
||||
|
||||
boolean valid = _context.messageValidator().validateMessage(messageBody.getUniqueId(), exp.getTime());
|
||||
if (!valid) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -251,39 +251,41 @@ public class JobQueue {
|
||||
|
||||
void shutdown() {
|
||||
_alive = false;
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("current jobs: \n");
|
||||
for (Iterator iter = _queueRunners.values().iterator(); iter.hasNext(); ) {
|
||||
JobQueueRunner runner = (JobQueueRunner)iter.next();
|
||||
Job j = runner.getCurrentJob();
|
||||
|
||||
buf.append("Runner ").append(runner.getRunnerId()).append(": ");
|
||||
if (j == null) {
|
||||
buf.append("no current job ");
|
||||
} else {
|
||||
buf.append(j.toString());
|
||||
buf.append(" started ").append(_context.clock().now() - j.getTiming().getActualStart());
|
||||
buf.append("ms ago");
|
||||
}
|
||||
|
||||
j = runner.getLastJob();
|
||||
if (j == null) {
|
||||
buf.append("no last job");
|
||||
} else {
|
||||
buf.append(j.toString());
|
||||
buf.append(" started ").append(_context.clock().now() - j.getTiming().getActualStart());
|
||||
buf.append("ms ago and finished ");
|
||||
buf.append(_context.clock().now() - j.getTiming().getActualEnd());
|
||||
buf.append("ms ago");
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("current jobs: \n");
|
||||
for (Iterator iter = _queueRunners.values().iterator(); iter.hasNext(); ) {
|
||||
JobQueueRunner runner = (JobQueueRunner)iter.next();
|
||||
Job j = runner.getCurrentJob();
|
||||
|
||||
buf.append("Runner ").append(runner.getRunnerId()).append(": ");
|
||||
if (j == null) {
|
||||
buf.append("no current job ");
|
||||
} else {
|
||||
buf.append(j.toString());
|
||||
buf.append(" started ").append(_context.clock().now() - j.getTiming().getActualStart());
|
||||
buf.append("ms ago");
|
||||
}
|
||||
|
||||
j = runner.getLastJob();
|
||||
if (j == null) {
|
||||
buf.append("no last job");
|
||||
} else {
|
||||
buf.append(j.toString());
|
||||
buf.append(" started ").append(_context.clock().now() - j.getTiming().getActualStart());
|
||||
buf.append("ms ago and finished ");
|
||||
buf.append(_context.clock().now() - j.getTiming().getActualEnd());
|
||||
buf.append("ms ago");
|
||||
}
|
||||
}
|
||||
buf.append("\nready jobs: ").append(_readyJobs.size()).append("\n\t");
|
||||
for (int i = 0; i < _readyJobs.size(); i++)
|
||||
buf.append(_readyJobs.get(i).toString()).append("\n\t");
|
||||
buf.append("\n\ntimed jobs: ").append(_timedJobs.size()).append("\n\t");
|
||||
for (int i = 0; i < _timedJobs.size(); i++)
|
||||
buf.append(_timedJobs.get(i).toString()).append("\n\t");
|
||||
_log.log(Log.WARN, buf.toString());
|
||||
}
|
||||
buf.append("\nready jobs: ").append(_readyJobs.size()).append("\n\t");
|
||||
for (int i = 0; i < _readyJobs.size(); i++)
|
||||
buf.append(_readyJobs.get(i).toString()).append("\n\t");
|
||||
buf.append("\n\ntimed jobs: ").append(_timedJobs.size()).append("\n\t");
|
||||
for (int i = 0; i < _timedJobs.size(); i++)
|
||||
buf.append(_timedJobs.get(i).toString()).append("\n\t");
|
||||
_log.log(Log.CRIT, buf.toString());
|
||||
}
|
||||
boolean isAlive() { return _alive; }
|
||||
|
||||
@@ -556,18 +558,18 @@ public class JobQueue {
|
||||
// the remainder are utility methods for dumping status info
|
||||
////
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
ArrayList readyJobs = null;
|
||||
ArrayList timedJobs = null;
|
||||
ArrayList activeJobs = new ArrayList(1);
|
||||
ArrayList justFinishedJobs = new ArrayList(4);
|
||||
out.write("<!-- jobQueue rendering -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering -->\n");
|
||||
out.flush();
|
||||
synchronized (_readyJobs) { readyJobs = new ArrayList(_readyJobs); }
|
||||
out.write("<!-- jobQueue rendering: after readyJobs sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after readyJobs sync -->\n");
|
||||
out.flush();
|
||||
synchronized (_timedJobs) { timedJobs = new ArrayList(_timedJobs); }
|
||||
out.write("<!-- jobQueue rendering: after timedJobs sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after timedJobs sync -->\n");
|
||||
out.flush();
|
||||
int numRunners = 0;
|
||||
synchronized (_queueRunners) {
|
||||
@@ -584,7 +586,7 @@ public class JobQueue {
|
||||
numRunners = _queueRunners.size();
|
||||
}
|
||||
|
||||
out.write("<!-- jobQueue rendering: after queueRunners sync -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after queueRunners sync -->\n");
|
||||
out.flush();
|
||||
|
||||
StringBuffer buf = new StringBuffer(32*1024);
|
||||
@@ -615,6 +617,7 @@ public class JobQueue {
|
||||
buf.append(j.toString()).append("</li>\n");
|
||||
}
|
||||
buf.append("</ol>\n");
|
||||
out.flush();
|
||||
|
||||
buf.append("# timed jobs: ").append(timedJobs.size()).append("<ol>\n");
|
||||
TreeMap ordered = new TreeMap();
|
||||
@@ -629,15 +632,15 @@ public class JobQueue {
|
||||
}
|
||||
buf.append("</ol>\n");
|
||||
|
||||
out.write("<!-- jobQueue rendering: after main buffer, before stats -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after main buffer, before stats -->\n");
|
||||
out.flush();
|
||||
|
||||
getJobStats(buf);
|
||||
|
||||
out.write("<!-- jobQueue rendering: after stats -->\n".getBytes());
|
||||
out.write("<!-- jobQueue rendering: after stats -->\n");
|
||||
out.flush();
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
}
|
||||
|
||||
/** render the HTML for the job stats */
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@@ -38,8 +39,7 @@ public class KeyManager {
|
||||
private SigningPrivateKey _signingPrivateKey;
|
||||
private SigningPublicKey _signingPublicKey;
|
||||
private Map _leaseSetKeys; // Destination --> LeaseSetKeys
|
||||
private boolean _alreadyReadFromDisk;
|
||||
private boolean _pendingWrite;
|
||||
private SynchronizeKeysJob _synchronizeJob;
|
||||
|
||||
public final static String PROP_KEYDIR = "router.keyBackupDir";
|
||||
public final static String DEFAULT_KEYDIR = "keyBackup";
|
||||
@@ -47,43 +47,49 @@ public class KeyManager {
|
||||
private final static String KEYFILE_PUBLIC_ENC = "publicEncryption.key";
|
||||
private final static String KEYFILE_PRIVATE_SIGNING = "privateSigning.key";
|
||||
private final static String KEYFILE_PUBLIC_SIGNING = "publicSigning.key";
|
||||
private final static long DELAY = 30*1000;
|
||||
private final static long DELAY = 5*60*1000;
|
||||
|
||||
public KeyManager(RouterContext context) {
|
||||
_context = context;
|
||||
_log = _context.logManager().getLog(KeyManager.class);
|
||||
_synchronizeJob = new SynchronizeKeysJob();
|
||||
setPrivateKey(null);
|
||||
setPublicKey(null);
|
||||
setSigningPrivateKey(null);
|
||||
setSigningPublicKey(null);
|
||||
_leaseSetKeys = new HashMap();
|
||||
_alreadyReadFromDisk = false;
|
||||
_pendingWrite = false;
|
||||
_context.jobQueue().addJob(new SynchronizeKeysJob());
|
||||
}
|
||||
|
||||
public void startup() {
|
||||
queueWrite();
|
||||
}
|
||||
|
||||
/** Configure the router's private key */
|
||||
public void setPrivateKey(PrivateKey key) {
|
||||
_privateKey = key;
|
||||
_pendingWrite = true;
|
||||
if (key != null)
|
||||
queueWrite();
|
||||
}
|
||||
public PrivateKey getPrivateKey() { return _privateKey; }
|
||||
/** Configure the router's public key */
|
||||
public void setPublicKey(PublicKey key) {
|
||||
_publicKey = key;
|
||||
_pendingWrite = true;
|
||||
if (key != null)
|
||||
queueWrite();
|
||||
}
|
||||
public PublicKey getPublicKey() { return _publicKey; }
|
||||
/** Configure the router's signing private key */
|
||||
public void setSigningPrivateKey(SigningPrivateKey key) {
|
||||
_signingPrivateKey = key;
|
||||
_pendingWrite = true;
|
||||
if (key != null)
|
||||
queueWrite();
|
||||
}
|
||||
public SigningPrivateKey getSigningPrivateKey() { return _signingPrivateKey; }
|
||||
/** Configure the router's signing public key */
|
||||
public void setSigningPublicKey(SigningPublicKey key) {
|
||||
_signingPublicKey = key;
|
||||
_pendingWrite = true;
|
||||
if (key != null)
|
||||
queueWrite();
|
||||
}
|
||||
public SigningPublicKey getSigningPublicKey() { return _signingPublicKey; }
|
||||
|
||||
@@ -93,24 +99,27 @@ public class KeyManager {
|
||||
synchronized (_leaseSetKeys) {
|
||||
_leaseSetKeys.put(dest, keys);
|
||||
}
|
||||
_pendingWrite = true;
|
||||
if (dest != null)
|
||||
queueWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if we've never read the data from disk or if we've
|
||||
* updated data in memory.
|
||||
*/
|
||||
private boolean needsSync() {
|
||||
return !(_alreadyReadFromDisk && !_pendingWrite);
|
||||
private void queueWrite() {
|
||||
Clock cl = _context.clock();
|
||||
JobQueue q = _context.jobQueue();
|
||||
if ( (cl == null) || (q == null) ) return;
|
||||
_synchronizeJob.getTiming().setStartAfter(cl.now());
|
||||
q.addJob(_synchronizeJob);
|
||||
}
|
||||
|
||||
|
||||
public LeaseSetKeys unregisterKeys(Destination dest) {
|
||||
_log.info("Unregistering keys for destination " + dest.calculateHash().toBase64());
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Unregistering keys for destination " + dest.calculateHash().toBase64());
|
||||
LeaseSetKeys rv = null;
|
||||
synchronized (_leaseSetKeys) {
|
||||
rv = (LeaseSetKeys)_leaseSetKeys.remove(dest);
|
||||
}
|
||||
_pendingWrite = true;
|
||||
if (dest != null)
|
||||
queueWrite();
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -133,26 +142,27 @@ public class KeyManager {
|
||||
super(KeyManager.this._context);
|
||||
}
|
||||
public void runJob() {
|
||||
String keyDir = KeyManager.this._context.getProperty(PROP_KEYDIR);
|
||||
String keyDir = getContext().getProperty(PROP_KEYDIR);
|
||||
if (keyDir == null)
|
||||
keyDir = DEFAULT_KEYDIR;
|
||||
File dir = new File(keyDir);
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
if (dir.exists() && dir.isDirectory() && dir.canRead() && dir.canWrite())
|
||||
if (dir.exists() && dir.isDirectory() && dir.canRead() && dir.canWrite()) {
|
||||
syncKeys(dir);
|
||||
} else {
|
||||
_log.log(Log.CRIT, "Unable to synchronize keys in " + keyDir + " - permissions problem?");
|
||||
}
|
||||
|
||||
getTiming().setStartAfter(KeyManager.this._context.clock().now()+DELAY);
|
||||
KeyManager.this._context.jobQueue().addJob(this);
|
||||
}
|
||||
|
||||
private void syncKeys(File keyDir) {
|
||||
if (!needsSync()) return;
|
||||
syncPrivateKey(keyDir);
|
||||
syncPublicKey(keyDir);
|
||||
syncSigningKey(keyDir);
|
||||
syncVerificationKey(keyDir);
|
||||
_alreadyReadFromDisk = true;
|
||||
}
|
||||
|
||||
private void syncPrivateKey(File keyDir) {
|
||||
|
||||
@@ -131,8 +131,10 @@ public class MessageValidator {
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("Validated messages: ").append(_receivedIds.size());
|
||||
_log.log(Log.CRIT, buf.toString());
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("Validated messages: ").append(_receivedIds.size());
|
||||
_log.log(Log.WARN, buf.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -95,5 +95,5 @@ class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
|
||||
public Set findNearestRouters(Hash key, int maxNumRouters, Set peersToIgnore) { return new HashSet(_routers.values()); }
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {}
|
||||
public void renderStatusHTML(Writer out) throws IOException {}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Set;
|
||||
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.util.Log;
|
||||
@@ -34,6 +35,7 @@ public class OutNetMessage {
|
||||
private Log _log;
|
||||
private RouterContext _context;
|
||||
private RouterInfo _target;
|
||||
private Hash _targetHash;
|
||||
private I2NPMessage _message;
|
||||
/** cached message class name, for use after we discard the message */
|
||||
private String _messageType;
|
||||
@@ -121,6 +123,8 @@ public class OutNetMessage {
|
||||
*/
|
||||
public RouterInfo getTarget() { return _target; }
|
||||
public void setTarget(RouterInfo target) { _target = target; }
|
||||
public Hash getTargetHash() { return _targetHash; }
|
||||
public void setTargetHash(Hash target) { _targetHash = target; }
|
||||
/**
|
||||
* Specifies the message to be sent
|
||||
*
|
||||
|
||||
@@ -41,8 +41,18 @@ public class OutNetMessagePool {
|
||||
*
|
||||
*/
|
||||
public void add(OutNetMessage msg) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Adding outbound message to "
|
||||
+ msg.getTarget().getIdentity().getHash().toBase64().substring(0,6)
|
||||
+ " with id " + msg.getMessage().getUniqueId()
|
||||
+ " expiring on " + msg.getMessage().getMessageExpiration()
|
||||
+ " of type " + msg.getMessageType());
|
||||
|
||||
boolean valid = validate(msg);
|
||||
if (!valid) return;
|
||||
if (!valid) {
|
||||
_context.messageRegistry().unregisterPending(msg);
|
||||
return;
|
||||
}
|
||||
MessageSelector selector = msg.getReplySelector();
|
||||
if (selector != null) {
|
||||
_context.messageRegistry().registerPending(msg);
|
||||
|
||||
@@ -8,7 +8,7 @@ package net.i2p.router;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -31,6 +31,6 @@ class DummyPeerManagerFacade implements PeerManagerFacade {
|
||||
public void shutdown() {}
|
||||
public void startup() {}
|
||||
public void restart() {}
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
public List selectPeers(PeerSelectionCriteria criteria) { return null; }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@@ -30,6 +30,7 @@ import net.i2p.crypto.DHSessionKeyBuilder;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.i2np.GarlicMessage;
|
||||
import net.i2p.data.i2np.TunnelMessage;
|
||||
import net.i2p.router.message.GarlicMessageHandler;
|
||||
@@ -37,6 +38,7 @@ import net.i2p.router.message.TunnelMessageHandler;
|
||||
import net.i2p.router.startup.StartupJob;
|
||||
import net.i2p.stat.Rate;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@@ -55,9 +57,11 @@ public class Router {
|
||||
private SessionKeyPersistenceHelper _sessionKeyPersistenceHelper;
|
||||
private boolean _killVMOnEnd;
|
||||
private boolean _isAlive;
|
||||
private int _gracefulExitCode;
|
||||
private I2PThread.OOMEventListener _oomListener;
|
||||
private ShutdownHook _shutdownHook;
|
||||
private I2PThread _gracefulShutdownDetector;
|
||||
private Set _shutdownTasks;
|
||||
|
||||
public final static String PROP_CONFIG_FILE = "router.configLocation";
|
||||
|
||||
@@ -82,6 +86,14 @@ public class Router {
|
||||
public Router(Properties envProps) { this(null, envProps); }
|
||||
public Router(String configFilename) { this(configFilename, null); }
|
||||
public Router(String configFilename, Properties envProps) {
|
||||
if (!beginMarkingLiveliness(envProps)) {
|
||||
System.err.println("ERROR: There appears to be another router already running!");
|
||||
System.err.println(" Please make sure to shut down old instances before starting up");
|
||||
System.err.println(" a new one. If you are positive that no other instance is running,");
|
||||
System.err.println(" please delete the file " + getPingFile(envProps));
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
_config = new Properties();
|
||||
_context = new RouterContext(this, envProps);
|
||||
if (configFilename == null)
|
||||
@@ -114,6 +126,8 @@ public class Router {
|
||||
_gracefulShutdownDetector.setDaemon(true);
|
||||
_gracefulShutdownDetector.setName("Graceful shutdown hook");
|
||||
_gracefulShutdownDetector.start();
|
||||
|
||||
_shutdownTasks = new HashSet(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,6 +174,8 @@ public class Router {
|
||||
Runtime.getRuntime().addShutdownHook(_shutdownHook);
|
||||
I2PThread.addOOMEventListener(_oomListener);
|
||||
|
||||
_context.keyManager().startup();
|
||||
|
||||
readConfig();
|
||||
|
||||
setupHandlers();
|
||||
@@ -206,6 +222,38 @@ public class Router {
|
||||
}
|
||||
|
||||
public boolean isAlive() { return _isAlive; }
|
||||
|
||||
/**
|
||||
* Rebuild and republish our routerInfo since something significant
|
||||
* has changed.
|
||||
*/
|
||||
public void rebuildRouterInfo() {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Rebuilding new routerInfo");
|
||||
|
||||
RouterInfo ri = null;
|
||||
if (_routerInfo != null)
|
||||
ri = new RouterInfo(_routerInfo);
|
||||
else
|
||||
ri = new RouterInfo();
|
||||
|
||||
try {
|
||||
ri.setPublished(_context.clock().now());
|
||||
Properties stats = _context.statPublisher().publishStatistics();
|
||||
ri.setOptions(stats);
|
||||
ri.setAddresses(_context.commSystem().createAddresses());
|
||||
SigningPrivateKey key = _context.keyManager().getSigningPrivateKey();
|
||||
if (key == null) {
|
||||
_log.log(Log.CRIT, "Internal error - signing private key not known? wtf");
|
||||
return;
|
||||
}
|
||||
ri.sign(key);
|
||||
setRouterInfo(ri);
|
||||
_context.netDb().publish(ri);
|
||||
} catch (DataFormatException dfe) {
|
||||
_log.log(Log.CRIT, "Internal error - unable to sign our own address?!", dfe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* coallesce the stats framework every minute
|
||||
@@ -267,8 +315,8 @@ public class Router {
|
||||
_context.inNetMessagePool().registerHandlerJobBuilder(TunnelMessage.MESSAGE_TYPE, new TunnelMessageHandler(_context));
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
out.write(("<h1>Router console</h1>\n" +
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
out.write("<h1>Router console</h1>\n" +
|
||||
"<i><a href=\"/oldconsole.jsp\">console</a> | <a href=\"/oldstats.jsp\">stats</a></i><br>\n" +
|
||||
"<form action=\"/oldconsole.jsp\">" +
|
||||
"<select name=\"go\" onChange='location.href=this.value'>" +
|
||||
@@ -283,7 +331,7 @@ public class Router {
|
||||
"<option value=\"/oldconsole.jsp#netdb\">Network Database</option>\n" +
|
||||
"<option value=\"/oldconsole.jsp#logs\">Log messages</option>\n" +
|
||||
"</select> <input type=\"submit\" value=\"GO\" /> </form>" +
|
||||
"<hr />\n").getBytes());
|
||||
"<hr />\n");
|
||||
|
||||
StringBuffer buf = new StringBuffer(32*1024);
|
||||
|
||||
@@ -405,39 +453,39 @@ public class Router {
|
||||
buf.append("trying to transfer data. Lifetime averages count how many elephants there are on the moon [like anyone reads this text]</i>");
|
||||
buf.append("\n");
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
|
||||
_context.bandwidthLimiter().renderStatusHTML(out);
|
||||
|
||||
out.write("<hr /><a name=\"clients\"> </a>\n".getBytes());
|
||||
out.write("<hr /><a name=\"clients\"> </a>\n");
|
||||
|
||||
_context.clientManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"transports\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"transports\"> </a>\n");
|
||||
|
||||
_context.commSystem().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"profiles\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"profiles\"> </a>\n");
|
||||
|
||||
_context.peerManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"tunnels\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"tunnels\"> </a>\n");
|
||||
|
||||
_context.tunnelManager().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"jobs\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"jobs\"> </a>\n");
|
||||
|
||||
_context.jobQueue().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"shitlist\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"shitlist\"> </a>\n");
|
||||
|
||||
_context.shitlist().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"pending\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"pending\"> </a>\n");
|
||||
|
||||
_context.messageRegistry().renderStatusHTML(out);
|
||||
|
||||
out.write("\n<hr /><a name=\"netdb\"> </a>\n".getBytes());
|
||||
out.write("\n<hr /><a name=\"netdb\"> </a>\n");
|
||||
|
||||
_context.netDb().renderStatusHTML(out);
|
||||
|
||||
@@ -452,7 +500,8 @@ public class Router {
|
||||
buf.append("</pre></td></tr>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private static int MAX_MSG_LENGTH = 120;
|
||||
@@ -531,10 +580,17 @@ public class Router {
|
||||
buf.setLength(0);
|
||||
}
|
||||
|
||||
public void addShutdownTask(Runnable task) {
|
||||
synchronized (_shutdownTasks) {
|
||||
_shutdownTasks.add(task);
|
||||
}
|
||||
}
|
||||
|
||||
public static final int EXIT_GRACEFUL = 2;
|
||||
public static final int EXIT_HARD = 3;
|
||||
public static final int EXIT_OOM = 10;
|
||||
public static final int EXIT_HARD_RESTART = 4;
|
||||
public static final int EXIT_GRACEFUL_RESTART = 5;
|
||||
|
||||
public void shutdown(int exitCode) {
|
||||
_isAlive = false;
|
||||
@@ -550,10 +606,20 @@ public class Router {
|
||||
try { _context.messageRegistry().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message registry", t); }
|
||||
try { _context.messageValidator().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message validator", t); }
|
||||
try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); }
|
||||
_context.listContexts().remove(_context);
|
||||
RouterContext.listContexts().remove(_context);
|
||||
dumpStats();
|
||||
try {
|
||||
for (Iterator iter = _shutdownTasks.iterator(); iter.hasNext(); ) {
|
||||
Runnable task = (Runnable)iter.next();
|
||||
task.run();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
_log.log(Log.CRIT, "Error running shutdown task", t);
|
||||
}
|
||||
_log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete", new Exception("Shutdown"));
|
||||
try { _context.logManager().shutdown(); } catch (Throwable t) { }
|
||||
File f = new File(getPingFile());
|
||||
f.delete();
|
||||
if (_killVMOnEnd) {
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
Runtime.getRuntime().halt(exitCode);
|
||||
@@ -570,6 +636,10 @@ public class Router {
|
||||
*
|
||||
*/
|
||||
public void shutdownGracefully() {
|
||||
shutdownGracefully(EXIT_GRACEFUL);
|
||||
}
|
||||
public void shutdownGracefully(int exitCode) {
|
||||
_gracefulExitCode = exitCode;
|
||||
_config.setProperty(PROP_SHUTDOWN_IN_PROGRESS, "true");
|
||||
synchronized (_gracefulShutdownDetector) {
|
||||
_gracefulShutdownDetector.notifyAll();
|
||||
@@ -605,7 +675,7 @@ public class Router {
|
||||
if (_context.tunnelManager().getParticipatingCount() <= 0) {
|
||||
if (_log.shouldLog(Log.CRIT))
|
||||
_log.log(Log.CRIT, "Graceful shutdown progress - no more tunnels, safe to die");
|
||||
shutdown(EXIT_GRACEFUL);
|
||||
shutdown(_gracefulExitCode);
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
@@ -681,10 +751,103 @@ public class Router {
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
installUpdates();
|
||||
Router r = new Router();
|
||||
r.runRouter();
|
||||
}
|
||||
|
||||
private static final String UPDATE_FILE = "i2pupdate.zip";
|
||||
|
||||
private static void installUpdates() {
|
||||
File updateFile = new File(UPDATE_FILE);
|
||||
if (updateFile.exists()) {
|
||||
System.out.println("INFO: Update file exists [" + UPDATE_FILE + "] - installing");
|
||||
boolean ok = FileUtil.extractZip(updateFile, new File("."));
|
||||
if (ok)
|
||||
System.out.println("INFO: Update installed");
|
||||
else
|
||||
System.out.println("ERROR: Update failed!");
|
||||
boolean deleted = updateFile.delete();
|
||||
if (!deleted) {
|
||||
System.out.println("ERROR: Unable to delete the update file!");
|
||||
updateFile.deleteOnExit();
|
||||
}
|
||||
System.out.println("INFO: Restarting after update");
|
||||
System.exit(EXIT_HARD_RESTART);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getPingFile(Properties envProps) {
|
||||
if (envProps != null)
|
||||
return envProps.getProperty("router.pingFile", "router.ping");
|
||||
else
|
||||
return "router.ping";
|
||||
}
|
||||
private String getPingFile() {
|
||||
return _context.getProperty("router.pingFile", "router.ping");
|
||||
}
|
||||
|
||||
private static final long LIVELINESS_DELAY = 60*1000;
|
||||
|
||||
/**
|
||||
* Start a thread that will periodically update the file "router.ping", but if
|
||||
* that file already exists and was recently written to, return false as there is
|
||||
* another instance running
|
||||
*
|
||||
* @return true if the router is the only one running
|
||||
*/
|
||||
private boolean beginMarkingLiveliness(Properties envProps) {
|
||||
String filename = getPingFile(envProps);
|
||||
File f = new File(filename);
|
||||
if (f.exists()) {
|
||||
long lastWritten = f.lastModified();
|
||||
if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) {
|
||||
System.err.println("WARN: Old router was not shut down gracefully, deleting router.ping");
|
||||
f.delete();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// not an I2PThread for context creation issues
|
||||
Thread t = new Thread(new MarkLiveliness(f));
|
||||
t.setName("Mark router liveliness");
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
private class MarkLiveliness implements Runnable {
|
||||
private File _pingFile;
|
||||
public MarkLiveliness(File f) {
|
||||
_pingFile = f;
|
||||
}
|
||||
public void run() {
|
||||
_pingFile.deleteOnExit();
|
||||
do {
|
||||
ping();
|
||||
try { Thread.sleep(LIVELINESS_DELAY); } catch (InterruptedException ie) {}
|
||||
} while (_isAlive);
|
||||
_pingFile.delete();
|
||||
}
|
||||
|
||||
private void ping() {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(_pingFile);
|
||||
fos.write(("" + System.currentTimeMillis()).getBytes());
|
||||
} catch (IOException ioe) {
|
||||
if (_log != null) {
|
||||
_log.log(Log.CRIT, "Error writing to ping file", ioe);
|
||||
} else {
|
||||
System.err.println("Error writing to ping file");
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int __id = 0;
|
||||
private class ShutdownHook extends Thread {
|
||||
|
||||
@@ -65,11 +65,24 @@ public class RouterContext extends I2PAppContext {
|
||||
|
||||
public RouterContext(Router router) { this(router, null); }
|
||||
public RouterContext(Router router, Properties envProps) {
|
||||
super(envProps);
|
||||
super(filterProps(envProps));
|
||||
_router = router;
|
||||
initAll();
|
||||
_contexts.add(this);
|
||||
}
|
||||
/**
|
||||
* Unless we are explicitly disabling the timestamper, we want to use it.
|
||||
* We need this now as the new timestamper default is disabled (so we don't
|
||||
* have each I2PAppContext creating their own SNTP queries all the time)
|
||||
*
|
||||
*/
|
||||
static final Properties filterProps(Properties envProps) {
|
||||
if (envProps == null)
|
||||
envProps = new Properties();
|
||||
if (envProps.getProperty("time.disabled") == null)
|
||||
envProps.setProperty("time.disabled", "false");
|
||||
return envProps;
|
||||
}
|
||||
private void initAll() {
|
||||
_adminManager = new AdminManager(this);
|
||||
_clientManagerFacade = new ClientManagerFacadeImpl(this);
|
||||
|
||||
@@ -31,4 +31,15 @@ public interface RouterThrottle {
|
||||
*
|
||||
*/
|
||||
public boolean acceptNetDbLookupRequest(Hash key);
|
||||
|
||||
/** How backed up we are at the moment processing messages (in milliseconds) */
|
||||
public long getMessageDelay();
|
||||
/** How backed up our tunnels are at the moment (in milliseconds) */
|
||||
public long getTunnelLag();
|
||||
/**
|
||||
* How much faster (or if negative, slower) we are receiving data as
|
||||
* opposed to our longer term averages?
|
||||
*
|
||||
*/
|
||||
public double getInboundRateDelta();
|
||||
}
|
||||
|
||||
@@ -154,5 +154,35 @@ class RouterThrottleImpl implements RouterThrottle {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public long getMessageDelay() {
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return (long)delayRate.getAverageValue();
|
||||
}
|
||||
|
||||
public long getTunnelLag() {
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return (long)lagRate.getAverageValue();
|
||||
}
|
||||
|
||||
public double getInboundRateDelta() {
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.sendMessageSize");
|
||||
double nowBps = getBps(receiveRate.getRate(60*1000));
|
||||
double fiveMinBps = getBps(receiveRate.getRate(5*60*1000));
|
||||
double hourBps = getBps(receiveRate.getRate(60*60*1000));
|
||||
double dailyBps = getBps(receiveRate.getRate(24*60*60*1000));
|
||||
|
||||
if (nowBps < 0) return 0;
|
||||
if (dailyBps > 0) return nowBps - dailyBps;
|
||||
if (hourBps > 0) return nowBps - hourBps;
|
||||
if (fiveMinBps > 0) return nowBps - fiveMinBps;
|
||||
return 0;
|
||||
}
|
||||
private double getBps(Rate rate) {
|
||||
if (rate == null) return -1;
|
||||
double bytes = rate.getLastTotalValue();
|
||||
return (bytes*1000.0d)/rate.getPeriod();
|
||||
}
|
||||
|
||||
protected RouterContext getContext() { return _context; }
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.20 $ $Date: 2004/09/03 02:22:24 $";
|
||||
public final static String VERSION = "0.4";
|
||||
public final static long BUILD = 3;
|
||||
public final static String ID = "$Revision: 1.33 $ $Date: 2004/09/26 10:16:44 $";
|
||||
public final static String VERSION = "0.4.1";
|
||||
public final static long BUILD = 0;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Define the manageable service interface for the subsystems in the I2P router
|
||||
@@ -37,5 +37,5 @@ public interface Service {
|
||||
*/
|
||||
public void restart();
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException;
|
||||
public void renderStatusHTML(Writer out) throws IOException;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.crypto.PersistentSessionKeyManager;
|
||||
import net.i2p.crypto.SessionKeyManager;
|
||||
@@ -97,7 +97,7 @@ public class SessionKeyPersistenceHelper implements Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
|
||||
private class SessionKeyWriterJob extends JobImpl {
|
||||
public SessionKeyWriterJob() {
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -50,7 +50,10 @@ public class Shitlist {
|
||||
return shitlistRouter(peer, null);
|
||||
}
|
||||
public boolean shitlistRouter(Hash peer, String reason) {
|
||||
if (peer == null) return false;
|
||||
if (peer == null) {
|
||||
_log.error("wtf, why did we try to shitlist null?", new Exception("shitfaced"));
|
||||
return false;
|
||||
}
|
||||
if (_context.routerHash().equals(peer)) {
|
||||
_log.error("wtf, why did we try to shitlist ourselves?", new Exception("shitfaced"));
|
||||
return false;
|
||||
@@ -71,6 +74,7 @@ public class Shitlist {
|
||||
|
||||
//_context.netDb().fail(peer);
|
||||
_context.tunnelManager().peerFailed(peer);
|
||||
_context.messageRegistry().peerFailed(peer);
|
||||
return wasAlready;
|
||||
}
|
||||
|
||||
@@ -123,7 +127,7 @@ public class Shitlist {
|
||||
}
|
||||
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<h2>Shitlist</h2>");
|
||||
Map shitlist = null;
|
||||
@@ -152,6 +156,7 @@ public class Shitlist {
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</ul>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ package net.i2p.router;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
@@ -107,32 +107,33 @@ public class StatisticsManager implements Service {
|
||||
includeRate("jobQueue.jobLag", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("jobQueue.jobRun", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("crypto.elGamal.encrypt", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
includeRate("crypto.garlic.decryptFail", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
//includeRate("crypto.garlic.decryptFail", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("tunnel.unknownTunnelTimeLeft", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("jobQueue.readyJobs", stats, new long[] { 60*1000, 60*60*1000 });
|
||||
//includeRate("jobQueue.droppedJobs", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("inNetPool.dropped", stats, new long[] { 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.outboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.inboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.outboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.inboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.participatingMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("tunnel.expiredAfterAcceptTime", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.participatingMessagesProcessedActive", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("tunnel.expiredAfterAcceptTime", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("tunnel.bytesAllocatedAtAccept", stats, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
includeRate("netDb.lookupsReceived", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.lookupsHandled", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.lookupsMatched", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.storeSent", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("netDb.storeSent", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("netDb.successPeers", stats, new long[] { 60*60*1000 });
|
||||
includeRate("netDb.failedPeers", stats, new long[] { 60*60*1000 });
|
||||
includeRate("router.throttleNetDbDoSSend", stats, new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
includeRate("router.throttleNetDbDoS", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("router.throttleNetDbDoSSend", stats, new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
//includeRate("router.throttleNetDbDoS", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("netDb.searchCount", stats, new long[] { 3*60*60*1000});
|
||||
//includeRate("netDb.searchMessageCount", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
//includeRate("inNetMessage.timeToDiscard", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
//includeRate("outNetMessage.timeToDiscard", stats, new long[] { 5*60*1000, 10*60*1000, 60*60*1000 });
|
||||
includeRate("router.throttleNetworkCause", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
includeRate("transport.receiveMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("router.throttleNetworkCause", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.receiveMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageSize", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageSmall", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.sendMessageMedium", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
@@ -141,6 +142,10 @@ public class StatisticsManager implements Service {
|
||||
//includeRate("transport.receiveMessageMedium", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
//includeRate("transport.receiveMessageLarge", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||
includeRate("client.sendAckTime", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.sendsPerFailure", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionTunnel", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionMessage", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
includeRate("client.timeoutCongestionInbound", stats, new long[] { 60*60*1000, 24*60*60*1000l }, true);
|
||||
stats.setProperty("stat_uptime", DataHelper.formatDuration(_context.router().getUptime()));
|
||||
stats.setProperty("stat__rateKey", "avg;maxAvg;pctLifetime;[sat;satLim;maxSat;maxSatLim;][num;lifetimeFreq;maxFreq]");
|
||||
_log.debug("Publishing peer rankings");
|
||||
@@ -266,5 +271,5 @@ public class StatisticsManager implements Service {
|
||||
private final String num(double num) { synchronized (_fmt) { return _fmt.format(num); } }
|
||||
private final String pct(double num) { synchronized (_pct) { return _pct.format(num); } }
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.i2p.router.admin;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.Service;
|
||||
@@ -20,7 +20,7 @@ public class AdminManager implements Service {
|
||||
_log = context.logManager().getLog(AdminManager.class);
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) { }
|
||||
public void renderStatusHTML(Writer out) { }
|
||||
|
||||
public void shutdown() {
|
||||
if (_listener != null) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
@@ -47,7 +48,7 @@ class AdminRunner implements Runnable {
|
||||
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
_generator.generateStatsPage(out);
|
||||
_generator.generateStatsPage(new OutputStreamWriter(out));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@@ -61,7 +62,7 @@ class AdminRunner implements Runnable {
|
||||
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
||||
try {
|
||||
out.write("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n".getBytes());
|
||||
_context.router().renderStatusHTML(out);
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(out));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.router.admin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -27,13 +28,13 @@ public class StatsGenerator {
|
||||
_log = context.logManager().getLog(StatsGenerator.class);
|
||||
}
|
||||
|
||||
public void generateStatsPage(OutputStream out) throws IOException {
|
||||
public void generateStatsPage(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h1>Router statistics</h1>");
|
||||
buf.append("<i><a href=\"/oldconsole.jsp\">console</a> | <a href=\"/oldstats.jsp\">stats</a></i><hr />");
|
||||
buf.append("<form action=\"/oldstats.jsp\">");
|
||||
buf.append("<select name=\"go\" onChange='location.href=this.value'>");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
Map groups = _context.statManager().getStatsByGroup();
|
||||
@@ -50,7 +51,7 @@ public class StatsGenerator {
|
||||
buf.append(stat);
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
buf.append("</select> <input type=\"submit\" value=\"GO\" />");
|
||||
@@ -61,7 +62,7 @@ public class StatsGenerator {
|
||||
buf.append(DataHelper.formatDuration(uptime));
|
||||
buf.append("). The data gathered is quantized over a 1 minute period, so should just be used as an estimate<p />");
|
||||
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) {
|
||||
@@ -73,7 +74,7 @@ public class StatsGenerator {
|
||||
buf.append(group);
|
||||
buf.append("</a></h2>");
|
||||
buf.append("<ul>");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
|
||||
String stat = (String)statIter.next();
|
||||
@@ -86,11 +87,12 @@ public class StatsGenerator {
|
||||
renderFrequency(stat, buf);
|
||||
else
|
||||
renderRate(stat, buf);
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
out.write("</ul><hr />".getBytes());
|
||||
out.write("</ul><hr />");
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void renderFrequency(String name, StringBuffer buf) {
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router.client;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -332,7 +332,7 @@ public class ClientManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(8*1024);
|
||||
buf.append("<u><b>Local destinations</b></u><br />");
|
||||
|
||||
@@ -376,7 +376,8 @@ public class ClientManager {
|
||||
}
|
||||
|
||||
buf.append("\n<hr />\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void messageReceived(ClientMessage msg) {
|
||||
|
||||
@@ -9,7 +9,7 @@ package net.i2p.router.client;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
@@ -158,7 +158,7 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
if (_manager != null)
|
||||
_manager.renderStatusHTML(out);
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ public class HandleTunnelMessageJob extends JobImpl {
|
||||
byte iv[] = new byte[16];
|
||||
Hash h = getContext().sha().calculateHash(key.getData());
|
||||
System.arraycopy(h.getData(), 0, iv, 0, iv.length);
|
||||
byte decrypted[] = getContext().AESEngine().safeDecrypt(encryptedMessage, key, iv);
|
||||
byte decrypted[] = getContext().aes().safeDecrypt(encryptedMessage, key, iv);
|
||||
if (decrypted == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error decrypting the message", getAddedBy());
|
||||
@@ -429,7 +429,7 @@ public class HandleTunnelMessageJob extends JobImpl {
|
||||
byte iv[] = new byte[16];
|
||||
Hash h = getContext().sha().calculateHash(key.getData());
|
||||
System.arraycopy(h.getData(), 0, iv, 0, iv.length);
|
||||
byte decrypted[] = getContext().AESEngine().safeDecrypt(encryptedInstructions, key, iv);
|
||||
byte decrypted[] = getContext().aes().safeDecrypt(encryptedInstructions, key, iv);
|
||||
if (decrypted == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error decrypting the instructions", getAddedBy());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user