Compare commits

..

63 Commits

Author SHA1 Message Date
jrandom
178b229d66 *cough* (oops) 2004-09-30 16:44:46 +00:00
jrandom
276493da65 * 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-30 15:58:54 +00:00
jrandom
e85dadfef2 added jabber-2.i2p 2004-09-30 13:25:31 +00:00
jrandom
1c70efb350 added eepsite info 2004-09-30 13:23:01 +00:00
jrandom
6804a0c564 * always flush the console output (duh)
* deal with some degenerate situations with identities changing and auto IP detection
* some catch-alls for cleaning up the registry on degenerate tunnels
* lots of logging
2004-09-30 13:10:02 +00:00
jrandom
6eb7ecc2d4 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.
plus minor bugfixes / refactoring / logging
2004-09-30 06:57:22 +00:00
jrandom
f4956b06b6 be more careful on startup 2004-09-30 06:51:28 +00:00
jrandom
9a2f7c2660 include the timeouts due to inability to find the leaseSet 2004-09-30 00:51:35 +00:00
jrandom
b6017c558a * updated stats:
- sendsPerFailure: how many partial sends we make when they all fail
- timeoutCongestionInbound: describes how much faster than our average speed we were receiving data when each partial send timed out (in Bps)
- timeoutCongestionMessage: our send processing time when each partial send timed out (in ms)
- timeoutCongestionTunnel: our tunnel test time when each partial send timed out (in ms)
- participatingMessagesProcessedActive: # of messages more than the (most recent) average that a tunnel we were participating in transmitted (for tunnels with more than the average)
* updated to use Writer for rendering the console, so we can do partial writes (and hopefully help debug some kooky threading bugs on kaffe)
2004-09-29 22:54:38 +00:00
jrandom
62ed6c6a58 * updated stats:
- sendsPerFailure: how many partial sends we make when they all fail
- timeoutCongestionInbound: describes how much faster than our average speed we were receiving data when each partial send timed out (in Bps)
- timeoutCongestionMessage: our send processing time when each partial send timed out (in ms)
- timeoutCongestionTunnel: our tunnel test time when each partial send timed out (in ms)
- participatingMessagesProcessedActive: # of messages more than the (most recent) average that a tunnel we were participating in transmitted (for tunnels with more than the average)
* updated to use Writer for rendering the console, so we can do partial writes (and hopefully help debug some kooky threading bugs on kaffe)
2004-09-29 22:49:19 +00:00
jrandom
24966c812f javad0c 2004-09-29 20:12:26 +00:00
jrandom
ea8dc2e0af *nix daemon scripts are gone 2004-09-29 19:38:15 +00:00
jrandom
010b285e67 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)
in addition, refactor various file ops out of the DataHelper into FileUtil
2004-09-29 19:34:02 +00:00
jrandom
774231f347 * started reducing the temporary buffers created within various crypto methods , as we've
got some pretty heavy GC churn when under load.  rough estimate is we allocate 5-8x as
much data as we need, copying it all over the place before forwarding it (or processing it).
this should cut down a few of those copies, but not enough yet.  it'd be great to get that
down to 2x.
* lots of logging
2004-09-28 20:33:23 +00:00
jrandom
ff1dfd8f25 let the algorithm handle writing the output to various places in the output array (so we can cut down on temporary memory allocation) 2004-09-28 16:38:24 +00:00
jrandom
2741ac195d * protocol doc & impl cleanup
* more defensive programming
* more javadoc updates
2004-09-28 08:34:48 +00:00
jrandom
cf780e296e bugfixes for autodetection/update of IP address 2004-09-27 18:05:28 +00:00
jrandom
0361246db0 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-27 07:57:43 +00:00
jrandom
63355ecd5b more tcp transport updates (getting closer to the old functionality)
* avoid bad peers
* shitlist appropriately
* include the bandwidth limiter
* add socket timeouts
* deal with *cough* closing connections
* javadocs
2004-09-26 18:11:39 +00:00
jrandom
0f54ba59fb die phttp die 2004-09-26 15:32:24 +00:00
jrandom
b67b243ebd the following isn't the end of the 0.4.1 updates, as there are still more things left to clean
up and debug in the new tcp transport, but it all works, and i dont like having big changes
sitting on my local machine (and there's no real need for branching atm)
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-26 15:16:44 +00:00
jrandom
4c29c20613 javadoc fix 2004-09-26 14:50:49 +00:00
mpc
4c2619d948 minor changes 2004-09-24 21:08:00 +00:00
jrandom
ea5662a4a2 another minor semantic jikes warning 2004-09-23 01:21:33 +00:00
jrandom
7c1ce777a1 cleanup per jikes' whining (overloaded var names, val overflow, etc) 2004-09-23 01:13:22 +00:00
jrandom
3bb85f2d61 add some logical exit values (useful for scripting).thanks xolo! 2004-09-23 01:05:40 +00:00
jrandom
93e36b3113 added jake.i2p 2004-09-23 00:08:51 +00:00
jrandom
932fb670e3 added anonymnet.i2p sasquotch.i2p orz.i2p microbleu.i2p www/smtp/pop3.postman.i2p 2004-09-22 23:58:37 +00:00
jrandom
54dce61a95 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-22 00:10:26 +00:00
jrandom
e686c0e0a2 added curiosity.i2p 2004-09-17 19:47:58 +00:00
jrandom
05acf32f39 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-16 23:55:12 +00:00
mpc
67064012c9 added freeciv.nightblade.i2p 2004-09-16 20:50:26 +00:00
jrandom
10e93c3b1b rename (wtf was i thinking "Calculator"...) 2004-09-16 02:04:40 +00:00
jrandom
5b2ec1cbb5 moved udp transport to 0.4.4 instead of 1.1 2004-09-14 19:52:46 +00:00
jrandom
972f701c5c ganttproject.sf.net based plan 2004-09-14 02:19:33 +00:00
jrandom
51285efbc3 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-13 03:08:16 +00:00
jrandom
e2635705f9 added xolotl.i2p 2004-09-11 01:25:24 +00:00
jrandom
7762107543 added modulus.i2p 2004-09-10 04:11:15 +00:00
jrandom
9123ad89c8 added links to www.i2p and dev.i2p (thanks pseudonym) 2004-09-09 04:10:25 +00:00
jrandom
39f3d6cc80 (release in the next hour or so)
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-09 02:26:42 +00:00
jrandom
af5665f67c revert the last 2 changes 2004-09-08 22:25:54 +00:00
hypercubus
c2175cc692 corrected submission date 2004-09-08 22:15:43 +00:00
hypercubus
1ef371a467 reversing accidental reversion 2004-09-08 22:08:24 +00:00
hypercubus
58461ff5bb * 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-08 22:04:13 +00:00
jrandom
665959da90 added eepdot.i2p 2004-09-08 07:46:21 +00:00
sunshine
8e63974f94 removed datagram_test.i2p 2004-09-08 07:45:11 +00:00
hypercubus
eae86f54ba Updates by 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-08 07:25:09 +00:00
jrandom
30128a122d added socks1.tor.i2p 2004-09-08 00:00:28 +00:00
hypercubus
56e22a39ac added sugadude.i2p 2004-09-07 22:30:53 +00:00
jrandom
6ceb330baa 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 22:13:11 +00:00
jrandom
f30509c7ba if i only had a brain... (thanks duck) 2004-09-07 20:54:44 +00:00
jrandom
9489136bd6 fix the build (thanks duck) 2004-09-07 20:39:42 +00:00
jrandom
05cd3d736b 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 09:49:02 +00:00
jrandom
29b17772e5 dup entry 2004-09-07 07:23:49 +00:00
jrandom
6151d63eac 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.
    * Handle a bug in the SimpleTimer with requeued tasks.
    * 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-07 07:17:02 +00:00
jrandom
e57aa68854 added files.i2p 2004-09-07 00:38:19 +00:00
jrandom
73fa6d9bd0 added beyond.i2p 2004-09-06 06:04:15 +00:00
jrandom
da3c4b87c1 (oops, forgot to up the build # on the last round) 2004-09-06 05:21:26 +00:00
jrandom
0eedc1b128 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-06 05:20:40 +00:00
jrandom
db339d40de 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 21:54:08 +00:00
jrandom
f72aa7884d added gott.i2p 2004-09-04 10:25:31 +00:00
jrandom
1434f1bb40 added linuxagent.i2p 2004-09-04 10:01:58 +00:00
jrandom
6bc92b26a7 2004-09-04 jrandom
* Update the SDK to automatically reconnect indefinitely with an
      exponential delay on retries (capped at 5 minutes).
2004-09-04 05:41:42 +00:00
139 changed files with 6232 additions and 4099 deletions

View File

@@ -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();

View File

@@ -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();

View File

@@ -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");
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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)
*
*/

View File

@@ -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" />

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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());
}
}

View File

@@ -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>";
}

View File

@@ -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();
}

View File

@@ -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 {

View File

@@ -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";
}
}

View File

@@ -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 />

View File

@@ -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 />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"));
}%>

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -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 />

View File

@@ -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;

View File

@@ -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);

View File

@@ -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">

View File

@@ -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();
}
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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()) + "]: "; }

View File

@@ -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());

View File

@@ -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) {

View File

@@ -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));
}
}

View File

@@ -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();

View File

@@ -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;
}
}

View File

@@ -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");
}
}

View File

@@ -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");

View File

@@ -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");

View File

@@ -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) {

View File

@@ -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) {}
}
}
}

View File

@@ -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

View File

@@ -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() {

View File

@@ -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";

View 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");
}
}

View File

@@ -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) {

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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))) {

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -1 +1 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>

View File

@@ -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...">

View File

@@ -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

View 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>

View File

@@ -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.

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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.

View 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>

View File

@@ -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"
)

View File

@@ -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

View File

@@ -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.

View File

@@ -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
View 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&#47;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&#47;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&#47;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&#47;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&#47;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&#47;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>

View File

@@ -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>

View File

@@ -50,4 +50,7 @@ public interface I2NPMessage extends DataStructure {
*
*/
public Date getMessageExpiration();
/** How large the message is, including any checksums */
public int getSize();
}

View File

@@ -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;
}
}
}

View File

@@ -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))

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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))

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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());
}
}
}

View File

@@ -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 {}
}

View File

@@ -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
*

View File

@@ -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);

View File

@@ -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; }
}

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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; }
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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() {

View File

@@ -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();
}
}

View File

@@ -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) { }
}

View File

@@ -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) {

View File

@@ -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))

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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