diff --git a/apps/httptunnel/java/src/net/i2p/httptunnel/SocketManagerProducer.java b/apps/httptunnel/java/src/net/i2p/httptunnel/SocketManagerProducer.java index 083b6107695dc5d57a819e2499638a4e121dbac3..745b73222a0ba4905478b402411167fb90509416 100644 --- a/apps/httptunnel/java/src/net/i2p/httptunnel/SocketManagerProducer.java +++ b/apps/httptunnel/java/src/net/i2p/httptunnel/SocketManagerProducer.java @@ -1,7 +1,12 @@ package net.i2p.httptunnel; -import java.util.*; -import net.i2p.client.streaming.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Properties; + +import net.i2p.client.streaming.I2PSocketManager; +import net.i2p.client.streaming.I2PSocketManagerFactory; /** * Produces SocketManagers in a thread and gives them to those who diff --git a/apps/httptunnel/java/src/net/i2p/httptunnel/filter/ChainFilter.java b/apps/httptunnel/java/src/net/i2p/httptunnel/filter/ChainFilter.java index a9a94b6454d19209da434c904373ac419c96f067..b2c9efeaa1fdc7cd9080e33ebb3ec7d86185e80b 100644 --- a/apps/httptunnel/java/src/net/i2p/httptunnel/filter/ChainFilter.java +++ b/apps/httptunnel/java/src/net/i2p/httptunnel/filter/ChainFilter.java @@ -1,9 +1,11 @@ package net.i2p.httptunnel.filter; -import net.i2p.util.Log; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; -import java.io.*; -import java.util.*; +import net.i2p.util.Log; /** * Chain multiple filters. Decorator pattern... diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index 2bdee7d528bbf4b2a794b8feb3b7eda8fb34c04d..07a9c7d036e4492c626af80ecd48df18b72f319e 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -50,7 +50,6 @@ import java.util.Set; import java.util.StringTokenizer; import net.i2p.I2PException; -import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel; import net.i2p.client.I2PClient; import net.i2p.client.I2PClientFactory; import net.i2p.client.naming.NamingService; @@ -58,6 +57,7 @@ import net.i2p.data.Base64; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; +import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel; import net.i2p.util.EventDispatcher; import net.i2p.util.EventDispatcherImpl; import net.i2p.util.Log; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index e63cd9878358bd6c992a9103008fa71206ba2ec3..30be946029dfd0107b4c49d236af2228a9801cfa 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -20,8 +20,8 @@ import net.i2p.client.streaming.I2PSocketManagerFactory; import net.i2p.client.streaming.I2PSocketOptions; import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runnable { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java index 00425359590c482423b17dbdab6642149ae3d51f..1f152194eb398caab5c89dbc03f011d394249104 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java @@ -13,9 +13,9 @@ import java.util.HashMap; import net.i2p.client.I2PSession; import net.i2p.client.streaming.I2PSocket; -import net.i2p.util.Log; import net.i2p.util.Clock; import net.i2p.util.I2PThread; +import net.i2p.util.Log; public class I2PTunnelRunner extends I2PThread { private final static Log _log = new Log(I2PTunnelRunner.class); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index acc6a5082ce15676a5e18ed5dee60f9e41a1b54f..401c23e81cb4efa891cf43344c3e0dfde359ce81 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -11,7 +11,8 @@ import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; -import java.util.*; +import java.util.Iterator; +import java.util.Properties; import net.i2p.I2PException; import net.i2p.client.I2PClient; @@ -22,8 +23,8 @@ import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManagerFactory; import net.i2p.data.Base64; import net.i2p.util.EventDispatcher; -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; public class I2PTunnelServer extends I2PTunnelTask implements Runnable { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java index 48f0b16b152a908e196b36f7ca7faa61c04c9b81..39e069e7380d253ef3308b0edf16e9f5be46e78a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java @@ -14,8 +14,8 @@ import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; public class I2Ping extends I2PTunnelTask implements Runnable { private final static Log _log = new Log(I2Ping.class); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java index e264d87ef15f32e025a946fe8f786fd6bd5a72e7..ff281ae7db95bf8ea4f69d23a26ae95022fda0f2 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java @@ -3,15 +3,14 @@ */ package net.i2p.i2ptunnel; -import net.i2p.util.Log; - -import java.util.StringTokenizer; - -import java.net.Socket; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.io.BufferedReader; import java.io.OutputStream; +import java.net.Socket; +import java.util.StringTokenizer; + +import net.i2p.util.Log; /** * Runner thread that reads commands from the socket and fires off commands to diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java index 75894359b26b481f6eb9c063bfa9d39b322e19bb..77a2c8949b7804adecce42e79d2c8d84fa145a9a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java @@ -8,14 +8,13 @@ package net.i2p.i2ptunnel.socks; import java.net.Socket; +import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManagerFactory; import net.i2p.client.streaming.I2PSocketOptions; import net.i2p.data.DataFormatException; -import net.i2p.I2PException; import net.i2p.i2ptunnel.I2PTunnel; - import net.i2p.util.Log; /** diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java index 6bee2a8e262c5b812a3daad5ff34a89403bf3352..a3a96e12b2d0a691e96d34074e053d31e0d2c81c 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocket.java @@ -1,10 +1,10 @@ package net.i2p.client.streaming; -import net.i2p.data.Destination; - +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; + +import net.i2p.data.Destination; /** * Minimalistic adapter between the socket api and I2PTunnel's way. diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketImpl.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketImpl.java index 0accb2a6ec193fba77912cb2bc0ce5848b514c8b..74d4cbb976703f1215f756909f08995e306d413a 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketImpl.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketImpl.java @@ -8,8 +8,8 @@ import java.io.OutputStream; import net.i2p.I2PException; import net.i2p.client.I2PSessionException; import net.i2p.data.Destination; -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; /** * Initial stub implementation for the socket diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java index 2aa1828a339b3ab9aa11d4868994840259e76749..578e5499270b66bfc003c9b5bd5a962da99ae0b0 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java @@ -1,20 +1,19 @@ package net.i2p.client.streaming; -import net.i2p.client.I2PSession; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import net.i2p.I2PException; import net.i2p.client.I2PClient; import net.i2p.client.I2PClientFactory; +import net.i2p.client.I2PSession; import net.i2p.client.I2PSessionException; -import net.i2p.I2PException; import net.i2p.data.Destination; import net.i2p.util.Log; -import java.io.InputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import java.util.Properties; - /** * Simplify the creation of I2PSession and transient I2P Destination objects if * necessary to create a socket manager. This class is most likely how classes diff --git a/apps/phttprelay/java/src/net/i2p/phttprelay/PHTTPRelayServlet.java b/apps/phttprelay/java/src/net/i2p/phttprelay/PHTTPRelayServlet.java index 6c4365fc866a9d03a11fb4298f8aadd4451da0c3..2cec78304ebf03e805cb0dba06bd494de90f7aa1 100644 --- a/apps/phttprelay/java/src/net/i2p/phttprelay/PHTTPRelayServlet.java +++ b/apps/phttprelay/java/src/net/i2p/phttprelay/PHTTPRelayServlet.java @@ -8,15 +8,15 @@ package net.i2p.phttprelay; * */ -import net.i2p.util.Log; +import java.io.File; +import java.io.IOException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.io.IOException; +import net.i2p.util.Log; abstract class PHTTPRelayServlet extends HttpServlet { private Log _log = new Log(getClass()); diff --git a/apps/tests/echotester/EchoTester.java b/apps/tests/echotester/EchoTester.java index 4f09678c378bfdd526a87c3a29ec520d3b83772b..d2344848fdbba91bd8c5db18023753311d8f3a90 100644 --- a/apps/tests/echotester/EchoTester.java +++ b/apps/tests/echotester/EchoTester.java @@ -8,8 +8,15 @@ * Licensed unter GNU General Public License. */ -import java.io.*; -import java.net.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.ConnectException; +import java.net.Socket; +import java.net.SocketException; /** * The main engine for the EchoTester. diff --git a/core/java/src/net/i2p/CoreVersion.java b/core/java/src/net/i2p/CoreVersion.java index e86c9353a40a89501c6e1c88443b69f0e64677a5..915dd8e2ec7d78c8cf92520f4ca72819a059c569 100644 --- a/core/java/src/net/i2p/CoreVersion.java +++ b/core/java/src/net/i2p/CoreVersion.java @@ -1,4 +1,5 @@ package net.i2p; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -13,10 +14,11 @@ package net.i2p; * */ public class CoreVersion { - public final static String ID = "$Revision: 1.33 $ $Date: 2004/04/04 13:40:34 $"; + public final static String ID = "$Revision: 1.1 $ $Date: 2004/04/07 23:48:42 $"; public final static String VERSION = "0.3.0.3"; + public static void main(String args[]) { - System.out.println("I2P Core version: " + VERSION); - System.out.println("ID: " + ID); + System.out.println("I2P Core version: " + VERSION); + System.out.println("ID: " + ID); } } \ No newline at end of file diff --git a/core/java/src/net/i2p/I2PException.java b/core/java/src/net/i2p/I2PException.java index 671ea426c1fb5205badeee0ed6e9161461ff408b..5eb38012806eb0722a2771a1d45e0d8f7feaca9a 100644 --- a/core/java/src/net/i2p/I2PException.java +++ b/core/java/src/net/i2p/I2PException.java @@ -1,4 +1,5 @@ package net.i2p; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -18,31 +19,32 @@ import java.io.PrintWriter; */ public class I2PException extends Exception { private Throwable _source; - + public I2PException() { this(null, null); } + public I2PException(String msg) { this(msg, null); } + public I2PException(String msg, Throwable source) { super(msg); _source = source; } - + public void printStackTrace() { - if (_source != null) - _source.printStackTrace(); + if (_source != null) _source.printStackTrace(); super.printStackTrace(); } + public void printStackTrace(PrintStream ps) { - if (_source != null) - _source.printStackTrace(ps); - super.printStackTrace(ps); + if (_source != null) _source.printStackTrace(ps); + super.printStackTrace(ps); } + public void printStackTrace(PrintWriter pw) { - if (_source != null) - _source.printStackTrace(pw); - super.printStackTrace(pw); + if (_source != null) _source.printStackTrace(pw); + super.printStackTrace(pw); } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/ATalk.java b/core/java/src/net/i2p/client/ATalk.java index b4e9e1b205228ef632a97cd83ecc752413e75658..53fc937e4d2963c60183cf13a27fbf1f70bc7df7 100644 --- a/core/java/src/net/i2p/client/ATalk.java +++ b/core/java/src/net/i2p/client/ATalk.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -26,10 +27,10 @@ import java.util.Properties; import net.i2p.I2PException; import net.i2p.data.DataFormatException; import net.i2p.data.Destination; +import net.i2p.util.Clock; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.LogManager; -import net.i2p.util.Clock; /** * ATalk - anonymous talk, demonstrating a trivial I2P usage scenario. @@ -59,27 +60,39 @@ public class ATalk implements I2PSessionListener, Runnable { /** string that messages must begin with to be treated as files */ private final static String FILE_COMMAND = ".file: "; /** the, erm, manual */ - private final static String MANUAL = - "ATalk: Anonymous Talk, a demo program for the Invisible Internet Project SDK" + NL + - "To generate a new destination:" + NL + - "\tATalk [fileToSavePrivateKeyIn] [fileToSavePublicKeyIn]" + NL + - "To talk to another destination:" + NL + - "\tATalk [myPrivateKeyFile] [peerPublicKey] [shouldLogToScreen]" + NL + - "shouldLogToScreen is 'true' or 'false', depending on whether you want log info on the screen" + NL + - "When talking to another destination, messages are sent after you hit return" + NL + - "To send a file, send a message saying:" + NL + - "\t" + FILE_COMMAND + "[filenameToSend]" + NL + - "The peer will then recieve the file and be notified of where it has been saved" + NL + - "To end the talk session, enter a period on a line by itself and hit return" + NL; + private final static String MANUAL = "ATalk: Anonymous Talk, a demo program for the Invisible Internet Project SDK" + + NL + + "To generate a new destination:" + + NL + + "\tATalk [fileToSavePrivateKeyIn] [fileToSavePublicKeyIn]" + + NL + + "To talk to another destination:" + + NL + + "\tATalk [myPrivateKeyFile] [peerPublicKey] [shouldLogToScreen]" + + NL + + "shouldLogToScreen is 'true' or 'false', depending on whether you want log info on the screen" + + NL + + "When talking to another destination, messages are sent after you hit return" + + NL + + "To send a file, send a message saying:" + + NL + + "\t" + + FILE_COMMAND + + "[filenameToSend]" + + NL + + "The peer will then recieve the file and be notified of where it has been saved" + + NL + + "To end the talk session, enter a period on a line by itself and hit return" + + NL; public final static String PROP_CONFIG_LOCATION = "configFile"; private static final SimpleDateFormat _fmt = new SimpleDateFormat("hh:mm:ss.SSS"); - + /** Construct the talk engine, but don't connect yet */ public ATalk(String myKeyFile, String theirDestFile) { - _myKeyFile = myKeyFile; - _theirDestinationFile = theirDestFile; + _myKeyFile = myKeyFile; + _theirDestinationFile = theirDestFile; } - + /** Actually start up the connection to the I2P network. * Successful connect does not mean the peer is online or reachable. * @@ -88,102 +101,102 @@ public class ATalk implements I2PSessionListener, Runnable { * @throws I2PSessionException if there is a problem contacting the I2P router */ public void connect() throws IOException, I2PSessionException, DataFormatException { - I2PClient client = I2PClientFactory.createClient(); - File myFile = new File(_myKeyFile); - Properties props = new Properties(); - String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "atalk.config"); - try { - props.load(new FileInputStream(configLocation)); - } catch (FileNotFoundException fnfe) { - _log.warn("Unable to load up the ATalk config file " + configLocation); - } - // Provide any router or client API configuration here. - if (!props.containsKey(I2PClient.PROP_TCP_HOST)) - props.setProperty(I2PClient.PROP_TCP_HOST, "localhost"); - if (!props.containsKey(I2PClient.PROP_TCP_PORT)) - props.setProperty(I2PClient.PROP_TCP_PORT, "7654"); - if (!props.containsKey(I2PClient.PROP_RELIABILITY)) - props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT); - _session = client.createSession(new FileInputStream(myFile), props); - _session.setSessionListener(this); - _session.connect(); - - File peerDestFile = new File(_theirDestinationFile); - _peerDestination = new Destination(); - _peerDestination.readBytes(new FileInputStream(peerDestFile)); - return; + I2PClient client = I2PClientFactory.createClient(); + File myFile = new File(_myKeyFile); + Properties props = new Properties(); + String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "atalk.config"); + try { + props.load(new FileInputStream(configLocation)); + } catch (FileNotFoundException fnfe) { + _log.warn("Unable to load up the ATalk config file " + configLocation); + } + // Provide any router or client API configuration here. + if (!props.containsKey(I2PClient.PROP_TCP_HOST)) props.setProperty(I2PClient.PROP_TCP_HOST, "localhost"); + if (!props.containsKey(I2PClient.PROP_TCP_PORT)) props.setProperty(I2PClient.PROP_TCP_PORT, "7654"); + if (!props.containsKey(I2PClient.PROP_RELIABILITY)) + props.setProperty(I2PClient.PROP_RELIABILITY, + I2PClient.PROP_RELIABILITY_BEST_EFFORT); + _session = client.createSession(new FileInputStream(myFile), props); + _session.setSessionListener(this); + _session.connect(); + + File peerDestFile = new File(_theirDestinationFile); + _peerDestination = new Destination(); + _peerDestination.readBytes(new FileInputStream(peerDestFile)); + return; } - + /** Actual bulk processing of the application, reading in user input, * sending messages, and displaying results. When this function exits, the * application is complete. * */ public void run() { - try { - connect(); - _in = new BufferedReader(new InputStreamReader(System.in)); - _out = new BufferedWriter(new OutputStreamWriter(System.out)); - - _out.write("Starting up anonymous talk session"+NL); - - while (true) { - String line = _in.readLine(); - if ( (line == null) || (line.trim().length() <= 0) ) - continue; - if (".".equals(line)) { - boolean ok = _session.sendMessage(_peerDestination, ("Peer disconnected at " + now()).getBytes()); - // ignore ok, we're closing - break; - } - if (line.startsWith(FILE_COMMAND) && (line.trim().length() > FILE_COMMAND.length())) { - try { - String file = line.substring(FILE_COMMAND.length()); - boolean sent = sendFile(file); - if (!sent) { - _out.write("Failed sending the file: " + file+NL); - } - } catch (IOException ioe) { - _out.write("Error sending the file: " + ioe.getMessage()+NL); - _log.error("Error sending the file", ioe); - } - } else { - boolean ok = _session.sendMessage(_peerDestination, ("[" + now() + "] " + line).getBytes()); - if (!ok) { - _out.write("Failed sending message. Peer disconnected?" + NL); - } - } - } - } catch (IOException ioe) { - _log.error("Error running", ioe); - } catch (I2PSessionException ise) { - _log.error("Error communicating", ise); - } catch (DataFormatException dfe) { - _log.error("Peer destination file is not valid", dfe); - } finally { - try { - _log.debug("Exiting anonymous talk session"); - if (_out != null) - _out.write("Exiting anonymous talk session"); - } catch (IOException ioe) { - // ignored - } - if (_session != null) { - try { - _session.destroySession(); - } catch (I2PSessionException ise) { - // ignored - } - } - try { Thread.sleep(5000); } catch (InterruptedException ie) {} - } + try { + connect(); + _in = new BufferedReader(new InputStreamReader(System.in)); + _out = new BufferedWriter(new OutputStreamWriter(System.out)); + + _out.write("Starting up anonymous talk session" + NL); + + while (true) { + String line = _in.readLine(); + if ((line == null) || (line.trim().length() <= 0)) continue; + if (".".equals(line)) { + boolean ok = _session.sendMessage(_peerDestination, ("Peer disconnected at " + now()).getBytes()); + // ignore ok, we're closing + break; + } + if (line.startsWith(FILE_COMMAND) && (line.trim().length() > FILE_COMMAND.length())) { + try { + String file = line.substring(FILE_COMMAND.length()); + boolean sent = sendFile(file); + if (!sent) { + _out.write("Failed sending the file: " + file + NL); + } + } catch (IOException ioe) { + _out.write("Error sending the file: " + ioe.getMessage() + NL); + _log.error("Error sending the file", ioe); + } + } else { + boolean ok = _session.sendMessage(_peerDestination, ("[" + now() + "] " + line).getBytes()); + if (!ok) { + _out.write("Failed sending message. Peer disconnected?" + NL); + } + } + } + } catch (IOException ioe) { + _log.error("Error running", ioe); + } catch (I2PSessionException ise) { + _log.error("Error communicating", ise); + } catch (DataFormatException dfe) { + _log.error("Peer destination file is not valid", dfe); + } finally { + try { + _log.debug("Exiting anonymous talk session"); + if (_out != null) _out.write("Exiting anonymous talk session"); + } catch (IOException ioe) { + // ignored + } + if (_session != null) { + try { + _session.destroySession(); + } catch (I2PSessionException ise) { + // ignored + } + } + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + } } - + private String now() { - Date now = new Date(Clock.getInstance().now()); - return _fmt.format(now); + Date now = new Date(Clock.getInstance().now()); + return _fmt.format(now); } - + /** Send the given file to the current peer. This works by sending a message * saying ".file: filename\nbodyOfFile", where filename is the name of the file * (which the recipient will be shown), and the bodyOfFile is the set of raw @@ -193,35 +206,34 @@ public class ATalk implements I2PSessionListener, Runnable { * @return false if the file could not be sent to the peer */ private boolean sendFile(String filename) throws IOException, I2PSessionException { - _log.debug("Sending file [" + filename + "]"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); - baos.write((FILE_COMMAND + filename+"\n").getBytes()); - FileInputStream fin = new FileInputStream(filename); - byte buf[] = new byte[4096]; - try { - while (true) { - int len = fin.read(buf); - if (len == -1) - break; - baos.write(buf, 0, len); - } - } catch (IOException ioe) { - _log.debug("Failed reading the file", ioe); - return false; - } - baos.close(); - byte val[] = baos.toByteArray(); - _log.debug("Sending " + filename + " with a full payload of " + val.length); - try { - boolean rv = _session.sendMessage(_peerDestination, val); - _log.debug("Sending " + filename + " complete: rv = " + rv); - return rv; - } catch (Throwable t) { - _log.error("Error sending file", t); - return false; - } + _log.debug("Sending file [" + filename + "]"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + baos.write((FILE_COMMAND + filename + "\n").getBytes()); + FileInputStream fin = new FileInputStream(filename); + byte buf[] = new byte[4096]; + try { + while (true) { + int len = fin.read(buf); + if (len == -1) break; + baos.write(buf, 0, len); + } + } catch (IOException ioe) { + _log.debug("Failed reading the file", ioe); + return false; + } + baos.close(); + byte val[] = baos.toByteArray(); + _log.debug("Sending " + filename + " with a full payload of " + val.length); + try { + boolean rv = _session.sendMessage(_peerDestination, val); + _log.debug("Sending " + filename + " complete: rv = " + rv); + return rv; + } catch (Throwable t) { + _log.error("Error sending file", t); + return false; + } } - + /** I2PSessionListener.messageAvailable requires this method to be called whenever * I2P wants to tell the session that a message is available. ATalk always grabs * the message immediately and either processes it as a "send file" command (passing @@ -230,27 +242,27 @@ public class ATalk implements I2PSessionListener, Runnable { * */ public void messageAvailable(I2PSession session, int msgId, long size) { - _log.debug("Message available: id = " + msgId + " size = " + size); - try { - byte msg[] = session.receiveMessage(msgId); - // inefficient way to just read the first line of text, but its easy - BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(msg))); - String line = reader.readLine(); - if (line.startsWith(FILE_COMMAND)) { - handleRecieveFile(line, msg); - } else { - // not a file command, so just plop 'er out on the screen - _out.write(now() + " --> " + new String(msg)); - _out.write(NL); - _out.flush(); - } - } catch (I2PSessionException ise) { - _log.error("Error fetching available message", ise); - } catch (IOException ioe) { - _log.error("Error writing out the message", ioe); - } + _log.debug("Message available: id = " + msgId + " size = " + size); + try { + byte msg[] = session.receiveMessage(msgId); + // inefficient way to just read the first line of text, but its easy + BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(msg))); + String line = reader.readLine(); + if (line.startsWith(FILE_COMMAND)) { + handleRecieveFile(line, msg); + } else { + // not a file command, so just plop 'er out on the screen + _out.write(now() + " --> " + new String(msg)); + _out.write(NL); + _out.flush(); + } + } catch (I2PSessionException ise) { + _log.error("Error fetching available message", ise); + } catch (IOException ioe) { + _log.error("Error writing out the message", ioe); + } } - + /** React to a file being sent our way from the peer via {@link #sendFile sendFile} * by saving the file to a temporary location and displaying where, what, and how large * it is. @@ -261,48 +273,56 @@ public class ATalk implements I2PSessionListener, Runnable { * @param msg the entire message recieved, including the firstline */ private void handleRecieveFile(String firstline, byte msg[]) throws IOException { - _log.debug("handleRecieveFile called"); - File f = File.createTempFile("recieve", ".dat", new File(".")); - FileOutputStream fos = new FileOutputStream(f); - int lineLen = firstline.getBytes().length+"\n".getBytes().length; - int lenToCopy = msg.length - lineLen; - byte buf[] = new byte[lenToCopy]; - System.arraycopy(msg, lineLen, buf, 0, lenToCopy); - fos.write(buf); - fos.close(); - String name = firstline.substring(FILE_COMMAND.length()); - _out.write("Recieved a file called [" + name + "] of size [" + lenToCopy + "] bytes, saved as [" + f.getAbsolutePath() + "]" + NL); - _out.flush(); + _log.debug("handleRecieveFile called"); + File f = File.createTempFile("recieve", ".dat", new File(".")); + FileOutputStream fos = new FileOutputStream(f); + int lineLen = firstline.getBytes().length + "\n".getBytes().length; + int lenToCopy = msg.length - lineLen; + byte buf[] = new byte[lenToCopy]; + System.arraycopy(msg, lineLen, buf, 0, lenToCopy); + fos.write(buf); + fos.close(); + String name = firstline.substring(FILE_COMMAND.length()); + _out.write("Recieved a file called [" + name + "] of size [" + lenToCopy + "] bytes, saved as [" + + f.getAbsolutePath() + "]" + NL); + _out.flush(); } - + /** driver */ public static void main(String args[]) { - if (args.length == 2) { - String myKeyFile = args[0]; - String myDestinationFile = args[1]; - boolean success = generateKeys(myKeyFile, myDestinationFile); - if (success) - _log.debug("Keys generated (private key file: " + myKeyFile + " destination file: " + myDestinationFile + ")"); - else - _log.debug("Keys generation failed"); - try { Thread.sleep(5000); } catch (InterruptedException ie) {} - } else if (args.length == 3) { - _log.debug("Starting chat"); - String myKeyfile = args[0]; - String peerDestFile = args[1]; - String shouldLog = args[2]; - if (Boolean.TRUE.toString().equalsIgnoreCase(shouldLog)) - LogManager.getInstance().setDisplayOnScreen(true); - else - LogManager.getInstance().setDisplayOnScreen(false); - String logFile = args[2]; - Thread talkThread = new I2PThread(new ATalk(myKeyfile, peerDestFile)); - talkThread.start(); - } else { - System.out.println(MANUAL); - try { Thread.sleep(5000); } catch (InterruptedException ie) {} - System.exit(-1); - } + if (args.length == 2) { + String myKeyFile = args[0]; + String myDestinationFile = args[1]; + boolean success = generateKeys(myKeyFile, myDestinationFile); + if (success) + _log.debug("Keys generated (private key file: " + myKeyFile + " destination file: " + myDestinationFile + + ")"); + else + _log.debug("Keys generation failed"); + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + } else if (args.length == 3) { + _log.debug("Starting chat"); + String myKeyfile = args[0]; + String peerDestFile = args[1]; + String shouldLog = args[2]; + if (Boolean.TRUE.toString().equalsIgnoreCase(shouldLog)) + LogManager.getInstance().setDisplayOnScreen(true); + else + LogManager.getInstance().setDisplayOnScreen(false); + String logFile = args[2]; + Thread talkThread = new I2PThread(new ATalk(myKeyfile, peerDestFile)); + talkThread.start(); + } else { + System.out.println(MANUAL); + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + System.exit(-1); + } } /** Generate a new Destination, saving that destination and the associated @@ -314,25 +334,33 @@ public class ATalk implements I2PSessionListener, Runnable { * @param destinationFile file in which the Destination is serialized in */ private static boolean generateKeys(String privKeyFile, String destinationFile) { - try { - Destination d = I2PClientFactory.createClient().createDestination(new FileOutputStream(privKeyFile)); - FileOutputStream fos = new FileOutputStream(destinationFile); - d.writeBytes(fos); - fos.flush(); - fos.close(); - return true; - } catch (IOException ioe) { - _log.error("Error generating keys", ioe); - } catch (I2PException ipe) { - _log.error("Error generating keys", ipe); - } - return false; + try { + Destination d = I2PClientFactory.createClient().createDestination(new FileOutputStream(privKeyFile)); + FileOutputStream fos = new FileOutputStream(destinationFile); + d.writeBytes(fos); + fos.flush(); + fos.close(); + return true; + } catch (IOException ioe) { + _log.error("Error generating keys", ioe); + } catch (I2PException ipe) { + _log.error("Error generating keys", ipe); + } + return false; } - + /** required by {@link I2PSessionListener I2PSessionListener} to notify of disconnect */ - public void disconnected(I2PSession session) { _log.debug("Disconnected"); } + public void disconnected(I2PSession session) { + _log.debug("Disconnected"); + } + /** required by {@link I2PSessionListener I2PSessionListener} to notify of error */ - public void errorOccurred(I2PSession session, String message, Throwable error) { _log.debug("Error occurred: " + message, error); } + public void errorOccurred(I2PSession session, String message, Throwable error) { + _log.debug("Error occurred: " + message, error); + } + /** required by {@link I2PSessionListener I2PSessionListener} to notify of abuse */ - public void reportAbuse(I2PSession session, int severity) { _log.debug("Abuse reported of severity " + severity); } + public void reportAbuse(I2PSession session, int severity) { + _log.debug("Abuse reported of severity " + severity); + } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/ConnectionRunner.java b/core/java/src/net/i2p/client/ConnectionRunner.java index 9a5ac6296e9ae61ff4bc45a7511af868d5943ada..3b7c0218cfbabe0083cca80dbb39d944c2cd6388 100644 --- a/core/java/src/net/i2p/client/ConnectionRunner.java +++ b/core/java/src/net/i2p/client/ConnectionRunner.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,47 +9,42 @@ package net.i2p.client; * */ -import net.i2p.util.Log; -import net.i2p.util.Clock; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import net.i2p.crypto.KeyGenerator; +import net.i2p.data.Certificate; +import net.i2p.data.Destination; +import net.i2p.data.Payload; +import net.i2p.data.PublicKey; +import net.i2p.data.RouterIdentity; +import net.i2p.data.SigningPublicKey; +import net.i2p.data.TunnelId; +import net.i2p.data.i2cp.CreateSessionMessage; +import net.i2p.data.i2cp.DisconnectMessage; import net.i2p.data.i2cp.I2CPMessage; -import net.i2p.data.i2cp.I2CPMessageReader; import net.i2p.data.i2cp.I2CPMessageException; -import net.i2p.data.i2cp.SessionStatusMessage; -import net.i2p.data.i2cp.SendMessageMessage; -import net.i2p.data.i2cp.CreateSessionMessage; +import net.i2p.data.i2cp.I2CPMessageReader; +import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.data.i2cp.MessageStatusMessage; -import net.i2p.data.i2cp.DisconnectMessage; import net.i2p.data.i2cp.ReceiveMessageBeginMessage; import net.i2p.data.i2cp.ReceiveMessageEndMessage; -import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.data.i2cp.RequestLeaseSetMessage; -import net.i2p.data.i2cp.SessionId; -import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.SendMessageMessage; import net.i2p.data.i2cp.SessionConfig; - -import net.i2p.data.Destination; -import net.i2p.data.Payload; -import net.i2p.data.TunnelId; -import net.i2p.data.RouterIdentity; -import net.i2p.data.PublicKey; -import net.i2p.data.SigningPublicKey; -import net.i2p.data.Certificate; - -import net.i2p.crypto.KeyGenerator; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.HashSet; -import java.util.Collections; -import java.util.Iterator; -import java.util.Date; - -import java.net.Socket; - -import java.io.OutputStream; -import java.io.IOException; +import net.i2p.data.i2cp.SessionId; +import net.i2p.data.i2cp.SessionStatusMessage; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Run the server side of a connection as part of the TestServer. This class @@ -83,31 +79,49 @@ class ConnectionRunner implements I2CPMessageReader.I2CPMessageEventListener { /** next available message id */ private static int _messageId = 0; private SessionConfig _config; - + private Object _sessionIdLock = new Object(); private Object _messageIdLock = new Object(); + // this *should* be mod 65536, but UnsignedInteger is still b0rked. FIXME - protected int getNextSessionId() { synchronized (_sessionIdLock) { int id = (++_id)%32767; _id = id; return id; } } + protected int getNextSessionId() { + synchronized (_sessionIdLock) { + int id = (++_id) % 32767; + _id = id; + return id; + } + } + // this *should* be mod 65536, but UnsignedInteger is still b0rked. FIXME - protected int getNextMessageId() { synchronized (_messageIdLock) { int id = (++_messageId)%32767; _messageId = id; return id; } } - protected SessionId getSessionId() { return _sessionId; } - + protected int getNextMessageId() { + synchronized (_messageIdLock) { + int id = (++_messageId) % 32767; + _messageId = id; + return id; + } + } + + protected SessionId getSessionId() { + return _sessionId; + } + protected ConnectionRunner getRunner(Destination dest) { - return (ConnectionRunner)_connections.get(dest); + return (ConnectionRunner) _connections.get(dest); } + protected Set getRunnerDestinations() { - return new HashSet(_connections.keySet()); + return new HashSet(_connections.keySet()); } - + /** * Create a new runner against the given socket * */ public ConnectionRunner(Socket socket) { - _socket = socket; - _config = null; + _socket = socket; + _config = null; } - + /** * Actually run the connection - listen for I2CP messages and respond. This * is the main driver for this class, though it gets all its meat from the @@ -115,16 +129,16 @@ class ConnectionRunner implements I2CPMessageReader.I2CPMessageEventListener { * */ public void doYourThing() throws IOException { - I2CPMessageReader reader = new I2CPMessageReader(_socket.getInputStream(), this); - _out = _socket.getOutputStream(); - reader.startReading(); + I2CPMessageReader reader = new I2CPMessageReader(_socket.getInputStream(), this); + _out = _socket.getOutputStream(); + reader.startReading(); } - + /** * Recieve notifiation that the peer disconnected */ public void disconnected(I2CPMessageReader reader) { - _log.info("Disconnected"); + _log.info("Disconnected"); } /** @@ -132,166 +146,170 @@ class ConnectionRunner implements I2CPMessageReader.I2CPMessageEventListener { * */ public void messageReceived(I2CPMessageReader reader, I2CPMessage message) { - _log.info("Message recieved: \n" + message); - switch (message.getType()) { - case CreateSessionMessage.MESSAGE_TYPE: - handleCreateSession(reader, (CreateSessionMessage)message); - break; - case SendMessageMessage.MESSAGE_TYPE: - handleSendMessage(reader, (SendMessageMessage)message); - break; - case ReceiveMessageBeginMessage.MESSAGE_TYPE: - handleReceiveBegin(reader, (ReceiveMessageBeginMessage)message); - break; - case ReceiveMessageEndMessage.MESSAGE_TYPE: - handleReceiveEnd(reader, (ReceiveMessageEndMessage)message); - break; - } + _log.info("Message recieved: \n" + message); + switch (message.getType()) { + case CreateSessionMessage.MESSAGE_TYPE: + handleCreateSession(reader, (CreateSessionMessage) message); + break; + case SendMessageMessage.MESSAGE_TYPE: + handleSendMessage(reader, (SendMessageMessage) message); + break; + case ReceiveMessageBeginMessage.MESSAGE_TYPE: + handleReceiveBegin(reader, (ReceiveMessageBeginMessage) message); + break; + case ReceiveMessageEndMessage.MESSAGE_TYPE: + handleReceiveEnd(reader, (ReceiveMessageEndMessage) message); + break; + } } - + /** * Handle a CreateSessionMessage * */ protected void handleCreateSession(I2CPMessageReader reader, CreateSessionMessage message) { - if (message.getSessionConfig().verifySignature()) { - _log.debug("Signature verified correctly on create session message"); - } else { - _log.error("Signature verification *FAILED* on a create session message. Hijack attempt?"); - DisconnectMessage msg = new DisconnectMessage(); - msg.setReason("Invalid signature on CreateSessionMessage"); - try { - doSend(msg); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the disconnect message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the disconnect message", ioe); - } - return; - } - SessionStatusMessage msg = new SessionStatusMessage(); - SessionId id = new SessionId(); - id.setSessionId(getNextSessionId()); // should be mod 65535, but UnsignedInteger isn't fixed yet. FIXME. - _sessionId = id; - msg.setSessionId(id); - msg.setStatus(SessionStatusMessage.STATUS_CREATED); - try { - doSend(msg); - _connections.put(message.getSessionConfig().getDestination(), this); - _config = message.getSessionConfig(); - sessionCreated(); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the session status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the session status message", ioe); - } - - // lets also request a new fake lease - RequestLeaseSetMessage rlsm = new RequestLeaseSetMessage(); - rlsm.setEndDate(new Date(Clock.getInstance().now() + 60*60*1000)); - rlsm.setSessionId(id); - RouterIdentity ri = new RouterIdentity(); - Object rikeys[] = KeyGenerator.getInstance().generatePKIKeypair(); - Object riSigningkeys[] = KeyGenerator.getInstance().generateSigningKeypair(); - ri.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null)); - ri.setPublicKey((PublicKey)rikeys[0]); - ri.setSigningPublicKey((SigningPublicKey)riSigningkeys[0]); - TunnelId tunnel = new TunnelId(); - tunnel.setTunnelId(42); - rlsm.addEndpoint(ri, tunnel); - try { - doSend(rlsm); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the request for a lease set", ime); - } catch (IOException ioe) { - _log.error("Error writing out the request for a lease set", ioe); - } - + if (message.getSessionConfig().verifySignature()) { + _log.debug("Signature verified correctly on create session message"); + } else { + _log.error("Signature verification *FAILED* on a create session message. Hijack attempt?"); + DisconnectMessage msg = new DisconnectMessage(); + msg.setReason("Invalid signature on CreateSessionMessage"); + try { + doSend(msg); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the disconnect message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the disconnect message", ioe); + } + return; + } + SessionStatusMessage msg = new SessionStatusMessage(); + SessionId id = new SessionId(); + id.setSessionId(getNextSessionId()); // should be mod 65535, but UnsignedInteger isn't fixed yet. FIXME. + _sessionId = id; + msg.setSessionId(id); + msg.setStatus(SessionStatusMessage.STATUS_CREATED); + try { + doSend(msg); + _connections.put(message.getSessionConfig().getDestination(), this); + _config = message.getSessionConfig(); + sessionCreated(); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the session status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the session status message", ioe); + } + + // lets also request a new fake lease + RequestLeaseSetMessage rlsm = new RequestLeaseSetMessage(); + rlsm.setEndDate(new Date(Clock.getInstance().now() + 60 * 60 * 1000)); + rlsm.setSessionId(id); + RouterIdentity ri = new RouterIdentity(); + Object rikeys[] = KeyGenerator.getInstance().generatePKIKeypair(); + Object riSigningkeys[] = KeyGenerator.getInstance().generateSigningKeypair(); + ri.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null)); + ri.setPublicKey((PublicKey) rikeys[0]); + ri.setSigningPublicKey((SigningPublicKey) riSigningkeys[0]); + TunnelId tunnel = new TunnelId(); + tunnel.setTunnelId(42); + rlsm.addEndpoint(ri, tunnel); + try { + doSend(rlsm); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the request for a lease set", ime); + } catch (IOException ioe) { + _log.error("Error writing out the request for a lease set", ioe); + } + + } + + protected void sessionCreated() { } - - protected void sessionCreated() { } - protected SessionConfig getConfig() { return _config; } - + + protected SessionConfig getConfig() { + return _config; + } + /** * Handle a SendMessageMessage * */ protected void handleSendMessage(I2CPMessageReader reader, SendMessageMessage message) { - _log.debug("handleSendMessage called"); - Payload payload = message.getPayload(); - Destination dest = message.getDestination(); - MessageId id = new MessageId(); - id.setMessageId(getNextMessageId()); - _log.debug("** Recieving message [" + id.getMessageId() + "] with payload: " + "[" + payload + "]"); - _messages.put(id, payload); - MessageStatusMessage status = new MessageStatusMessage(); - status.setMessageId(id); - status.setSessionId(message.getSessionId()); - status.setSize(0L); - status.setNonce(message.getNonce()); - status.setStatus(MessageStatusMessage.STATUS_SEND_ACCEPTED); - try { - doSend(status); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the message status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the message status message", ioe); - } - distributeMessageToPeer(status, dest, id); + _log.debug("handleSendMessage called"); + Payload payload = message.getPayload(); + Destination dest = message.getDestination(); + MessageId id = new MessageId(); + id.setMessageId(getNextMessageId()); + _log.debug("** Recieving message [" + id.getMessageId() + "] with payload: " + "[" + payload + "]"); + _messages.put(id, payload); + MessageStatusMessage status = new MessageStatusMessage(); + status.setMessageId(id); + status.setSessionId(message.getSessionId()); + status.setSize(0L); + status.setNonce(message.getNonce()); + status.setStatus(MessageStatusMessage.STATUS_SEND_ACCEPTED); + try { + doSend(status); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the message status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the message status message", ioe); + } + distributeMessageToPeer(status, dest, id); } - + /** * distribute the message to the destination, passing on the appropriate status * messages to the sender of the SendMessageMessage * */ private void distributeMessageToPeer(MessageStatusMessage status, Destination dest, MessageId id) { - ConnectionRunner runner = (ConnectionRunner)_connections.get(dest); - if (runner == null) { - distributeNonLocal(status, dest, id); - } else { - distributeLocal(runner, status, dest, id); - } - _log.debug("Done handling send message"); + ConnectionRunner runner = (ConnectionRunner) _connections.get(dest); + if (runner == null) { + distributeNonLocal(status, dest, id); + } else { + distributeLocal(runner, status, dest, id); + } + _log.debug("Done handling send message"); } - + protected void distributeLocal(ConnectionRunner runner, MessageStatusMessage status, Destination dest, MessageId id) { - if (runner.messageAvailable(id, 0L)) { - status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); - status.setNonce(2); - try { - doSend(status); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the success status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the success status message", ioe); - } - _log.debug("Guaranteed success with the status message sent"); - } else { - status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); - try { - doSend(status); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the failure status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the failure status message", ioe); - } - _log.debug("Guaranteed failure since messageAvailable failed"); - } + if (runner.messageAvailable(id, 0L)) { + status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); + status.setNonce(2); + try { + doSend(status); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the success status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the success status message", ioe); + } + _log.debug("Guaranteed success with the status message sent"); + } else { + status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); + try { + doSend(status); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the failure status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the failure status message", ioe); + } + _log.debug("Guaranteed failure since messageAvailable failed"); + } } - + protected void distributeNonLocal(MessageStatusMessage status, Destination dest, MessageId id) { - status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); - try { - doSend(status); - } catch (I2CPMessageException ime) { - _log.error("Error writing out the failure status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the failure status message", ioe); - } - _log.debug("Guaranteed failure!"); + status.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); + try { + doSend(status); + } catch (I2CPMessageException ime) { + _log.error("Error writing out the failure status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the failure status message", ioe); + } + _log.debug("Guaranteed failure!"); } - + /** * The client asked for a message, so we send it to them. This currently * does not do any security checking (like making sure they're the one to @@ -300,30 +318,31 @@ class ConnectionRunner implements I2CPMessageReader.I2CPMessageEventListener { * */ public void handleReceiveBegin(I2CPMessageReader reader, ReceiveMessageBeginMessage message) { - _log.debug("Handling recieve begin: id = " + message.getMessageId()); - MessagePayloadMessage msg = new MessagePayloadMessage(); - msg.setMessageId(message.getMessageId()); - msg.setSessionId(_sessionId); - Payload payload = (Payload)_messages.get(message.getMessageId()); - if (payload == null) { - _log.error("Payload for message id [" + message.getMessageId() + "] is null! Unknown message id?", new Exception("Error, null payload")); - StringBuffer buf = new StringBuffer(); - for (Iterator iter = _messages.keySet().iterator(); iter.hasNext(); ) { - buf.append("messageId: ").append(iter.next()).append(", "); - } - _log.error("Known message IDs: " + buf.toString()); - return; - } - msg.setPayload(payload); - try { - doSend(msg); - } catch (IOException ioe) { - _log.error("Error delivering the payload", ioe); - } catch (I2CPMessageException ime) { - _log.error("Error delivering the payload", ime); - } + _log.debug("Handling recieve begin: id = " + message.getMessageId()); + MessagePayloadMessage msg = new MessagePayloadMessage(); + msg.setMessageId(message.getMessageId()); + msg.setSessionId(_sessionId); + Payload payload = (Payload) _messages.get(message.getMessageId()); + if (payload == null) { + _log.error("Payload for message id [" + message.getMessageId() + "] is null! Unknown message id?", + new Exception("Error, null payload")); + StringBuffer buf = new StringBuffer(); + for (Iterator iter = _messages.keySet().iterator(); iter.hasNext();) { + buf.append("messageId: ").append(iter.next()).append(", "); + } + _log.error("Known message IDs: " + buf.toString()); + return; + } + msg.setPayload(payload); + try { + doSend(msg); + } catch (IOException ioe) { + _log.error("Error delivering the payload", ioe); + } catch (I2CPMessageException ime) { + _log.error("Error delivering the payload", ime); + } } - + /** * The client told us that the message has been recieved completely. This currently * does not do any security checking prior to removing the message from the @@ -331,45 +350,46 @@ class ConnectionRunner implements I2CPMessageReader.I2CPMessageEventListener { * */ public void handleReceiveEnd(I2CPMessageReader reader, ReceiveMessageEndMessage message) { - _messages.remove(message.getMessageId()); + _messages.remove(message.getMessageId()); } - + /** * Deliver notification to the client that the given message is available. * This is called from the ConnectionRunner the message was sent from. * */ public boolean messageAvailable(MessageId id, long size) { - MessageStatusMessage msg = new MessageStatusMessage(); - msg.setMessageId(id); - msg.setSessionId(_sessionId); - msg.setSize(size); - msg.setNonce(1); - msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE); - try { - doSend(msg); - return true; - } catch (I2CPMessageException ime) { - _log.error("Error writing out the message status message", ime); - } catch (IOException ioe) { - _log.error("Error writing out the message status message", ioe); - } - return false; + MessageStatusMessage msg = new MessageStatusMessage(); + msg.setMessageId(id); + msg.setSessionId(_sessionId); + msg.setSize(size); + msg.setNonce(1); + msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE); + try { + doSend(msg); + return true; + } catch (I2CPMessageException ime) { + _log.error("Error writing out the message status message", ime); + } catch (IOException ioe) { + _log.error("Error writing out the message status message", ioe); + } + return false; } - + /** * Handle notifiation that there was an error * */ public void readError(I2CPMessageReader reader, Exception error) { - _log.info("Error occurred", error); + _log.info("Error occurred", error); } private Object _sendLock = new Object(); + protected void doSend(I2CPMessage msg) throws I2CPMessageException, IOException { - synchronized (_sendLock) { - msg.writeMessage(_out); - _out.flush(); - } + synchronized (_sendLock) { + msg.writeMessage(_out); + _out.flush(); + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/DisconnectMessageHandler.java b/core/java/src/net/i2p/client/DisconnectMessageHandler.java index b757317e640ed3081e01ec29cc57c4d7ebd6394b..004128bb0b22385e486e51a297a443cd48dbf6f1 100644 --- a/core/java/src/net/i2p/client/DisconnectMessageHandler.java +++ b/core/java/src/net/i2p/client/DisconnectMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,7 +9,8 @@ package net.i2p.client; * */ -import net.i2p.data.i2cp.*; +import net.i2p.data.i2cp.DisconnectMessage; +import net.i2p.data.i2cp.I2CPMessage; /** * Handle I2CP disconnect messages from the router @@ -19,6 +21,7 @@ class DisconnectMessageHandler extends HandlerImpl { public DisconnectMessageHandler() { super(DisconnectMessage.MESSAGE_TYPE); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { _log.debug("Handle message " + message); session.destroySession(false); diff --git a/core/java/src/net/i2p/client/HandlerImpl.java b/core/java/src/net/i2p/client/HandlerImpl.java index c38e94937dab56f0d30249b8527019300f5c25a4..0337f0dad2b72411549e98ebdd3e9faaf9739c40 100644 --- a/core/java/src/net/i2p/client/HandlerImpl.java +++ b/core/java/src/net/i2p/client/HandlerImpl.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -18,9 +19,13 @@ import net.i2p.util.Log; abstract class HandlerImpl implements I2CPMessageHandler { protected Log _log; private int _type; + public HandlerImpl(int type) { _type = type; _log = new Log(getClass()); } - public int getType() { return _type; } -} + + public int getType() { + return _type; + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2CPMessageHandler.java b/core/java/src/net/i2p/client/I2CPMessageHandler.java index ddaa760d76dcb36924bac71e3de46fb715bbc453..a0f14f8378af01bbbcc97874b26dca94acb9b8c3 100644 --- a/core/java/src/net/i2p/client/I2CPMessageHandler.java +++ b/core/java/src/net/i2p/client/I2CPMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -17,5 +18,6 @@ import net.i2p.data.i2cp.I2CPMessage; */ interface I2CPMessageHandler { public int getType(); + public void handleMessage(I2CPMessage message, I2PSessionImpl session); } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2CPMessageProducer.java b/core/java/src/net/i2p/client/I2CPMessageProducer.java index 03e1b88bf2783e439e44ef1154429d02f7b4510e..a6432f601cabe68728c49c19b2c362da28e82d55 100644 --- a/core/java/src/net/i2p/client/I2CPMessageProducer.java +++ b/core/java/src/net/i2p/client/I2CPMessageProducer.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -40,7 +41,7 @@ import net.i2p.util.RandomSource; class I2CPMessageProducer { private final static Log _log = new Log(I2CPMessageProducer.class); private final static RandomSource _rand = RandomSource.getInstance(); - + /** * Send all the messages that a client needs to send to a router to establish * a new session. @@ -58,68 +59,69 @@ class I2CPMessageProducer { msg.setSessionConfig(cfg); session.sendMessage(msg); } - + /** * Send messages to the router destroying the session and disconnecting * */ public void disconnect(I2PSessionImpl session) throws I2PSessionException { - DestroySessionMessage dmsg = new DestroySessionMessage(); - dmsg.setSessionId(session.getSessionId()); - session.sendMessage(dmsg); - // use DisconnectMessage only if we fail and drop connection... - // todo: update the code to fire off DisconnectMessage on socket error + DestroySessionMessage dmsg = new DestroySessionMessage(); + dmsg.setSessionId(session.getSessionId()); + session.sendMessage(dmsg); + // use DisconnectMessage only if we fail and drop connection... + // todo: update the code to fire off DisconnectMessage on socket error //DisconnectMessage msg = new DisconnectMessage(); //msg.setReason("Destroy called"); //session.sendMessage(msg); } - + /** * Package up and send the payload to the router for delivery * */ - public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag, SessionKey key, Set tags, SessionKey newKey) throws I2PSessionException { + public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag, + SessionKey key, Set tags, SessionKey newKey) throws I2PSessionException { SendMessageMessage msg = new SendMessageMessage(); msg.setDestination(dest); msg.setSessionId(session.getSessionId()); - msg.setNonce(nonce); + msg.setNonce(nonce); Payload data = createPayload(dest, payload, tag, key, tags, newKey); msg.setPayload(data); session.sendMessage(msg); } - + /** * Create a new signed payload and send it off to the destination * */ - private Payload createPayload(Destination dest, byte[] payload, SessionTag tag, SessionKey key, Set tags, SessionKey newKey) throws I2PSessionException { - if (dest == null) - throw new I2PSessionException("No destination specified"); - if (payload == null) - throw new I2PSessionException("No payload specified"); + private Payload createPayload(Destination dest, byte[] payload, SessionTag tag, SessionKey key, Set tags, + SessionKey newKey) throws I2PSessionException { + if (dest == null) throw new I2PSessionException("No destination specified"); + if (payload == null) throw new I2PSessionException("No payload specified"); + + Payload data = new Payload(); + // randomize padding + int size = payload.length + RandomSource.getInstance().nextInt(1024); + byte encr[] = ElGamalAESEngine.encrypt(payload, dest.getPublicKey(), key, tags, tag, newKey, size); + // yes, in an intelligent component, newTags would be queued for confirmation along with key, and + // generateNewTags would only generate tags if necessary - Payload data = new Payload(); - // randomize padding - int size = payload.length + RandomSource.getInstance().nextInt(1024); - byte encr[] = ElGamalAESEngine.encrypt(payload, dest.getPublicKey(), key, tags, tag, newKey, size); - // yes, in an intelligent component, newTags would be queued for confirmation along with key, and - // generateNewTags would only generate tags if necessary - - data.setEncryptedData(encr); - _log.debug("Encrypting the payload to public key " + dest.getPublicKey().toBase64() + "\nPayload: " + data.calculateHash()); - return data; + data.setEncryptedData(encr); + _log.debug("Encrypting the payload to public key " + dest.getPublicKey().toBase64() + "\nPayload: " + + data.calculateHash()); + return data; } - + private static Set generateNewTags() { - Set tags = new HashSet(); - for (int i = 0; i < 10; i++) { - byte tag[] = new byte[SessionTag.BYTE_LENGTH]; - RandomSource.getInstance().nextBytes(tag); - tags.add(new SessionTag(tag)); - } - return tags; + Set tags = new HashSet(); + for (int i = 0; i < 10; i++) { + byte tag[] = new byte[SessionTag.BYTE_LENGTH]; + RandomSource.getInstance().nextBytes(tag); + tags.add(new SessionTag(tag)); + } + return tags; } - + /** * Send an abuse message to the router */ @@ -136,18 +138,19 @@ class I2CPMessageProducer { msg.setSeverity(sv); session.sendMessage(msg); } - + /** * Create a new signed leaseSet in response to a request to do so and send it * to the router * */ - public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, PrivateKey priv) throws I2PSessionException { + public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, PrivateKey priv) + throws I2PSessionException { CreateLeaseSetMessage msg = new CreateLeaseSetMessage(); - msg.setLeaseSet(leaseSet); - msg.setPrivateKey(priv); - msg.setSigningPrivateKey(signingPriv); - msg.setSessionId(session.getSessionId()); + msg.setLeaseSet(leaseSet); + msg.setPrivateKey(priv); + msg.setSigningPrivateKey(signingPriv); + msg.setSessionId(session.getSessionId()); session.sendMessage(msg); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PClient.java b/core/java/src/net/i2p/client/I2PClient.java index 794221cf10f5b17d266d84ee0f4da9c026f692c9..9a732c3dba0a20fdf9d36560937c8886c254de1f 100644 --- a/core/java/src/net/i2p/client/I2PClient.java +++ b/core/java/src/net/i2p/client/I2PClient.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,16 +9,15 @@ package net.i2p.client; * */ -import net.i2p.I2PException; -import net.i2p.data.Destination; -import net.i2p.data.Certificate; - +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - import java.util.Properties; +import net.i2p.I2PException; +import net.i2p.data.Certificate; +import net.i2p.data.Destination; + /** * Define the standard means of interacting with the I2P system * @@ -34,10 +34,10 @@ public interface I2PClient { public final static String PROP_RELIABILITY_BEST_EFFORT = "BestEffort"; /** Reliability value: guaranteed */ public final static String PROP_RELIABILITY_GUARANTEED = "Guaranteed"; - + /** protocol flag that must be sent when opening the i2cp connection to the router */ public final static int PROTOCOL_BYTE = 0x2A; - + /** Create a new client session for the Destination stored at the destKeyStream * using the specified options to both connect to the router, to instruct * the router how to handle the new session, and to configure the end to end @@ -46,16 +46,16 @@ public interface I2PClient { * @param options set of options to configure the router with * @return new session allowing a Destination to recieve all of its messages and send messages to any other Destination. */ - public I2PSession createSession(InputStream destKeyStream, Properties options) throws I2PSessionException; - + public I2PSession createSession(InputStream destKeyStream, Properties options) throws I2PSessionException; + /** Create a new destination with the default certificate creation properties and store * it, along with the private encryption and signing keys at the specified location * @param destKeyStream create a new destination and write out the object to the given stream, * formatted as Destination, PrivateKey, and SigningPrivateKey * @return new destination */ - public Destination createDestination(OutputStream destKeyStream) throws I2PException, IOException; - + public Destination createDestination(OutputStream destKeyStream) throws I2PException, IOException; + /** Create a new destination with the given certificate and store it, along with the private * encryption and signing keys at the specified location * diff --git a/core/java/src/net/i2p/client/I2PClientFactory.java b/core/java/src/net/i2p/client/I2PClientFactory.java index d9fa216bcd8dc25c57292b56cae97b0a70c8763c..86fbdaa8cede51d439c66f99efc76ec87bbc50d9 100644 --- a/core/java/src/net/i2p/client/I2PClientFactory.java +++ b/core/java/src/net/i2p/client/I2PClientFactory.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -19,5 +20,5 @@ public class I2PClientFactory { */ public static I2PClient createClient() { return new I2PClientImpl(); - } + } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PClientImpl.java b/core/java/src/net/i2p/client/I2PClientImpl.java index de01de514727e822065bcc3a705621fea8271d83..1771f0cfe3642d9b3f3410387afb50453b52f22a 100644 --- a/core/java/src/net/i2p/client/I2PClientImpl.java +++ b/core/java/src/net/i2p/client/I2PClientImpl.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -37,7 +38,7 @@ class I2PClientImpl implements I2PClient { cert.setPayload(null); return createDestination(destKeyStream, cert); } - + /** * Create the destination with the given payload and write it out along with * the PrivateKey and SigningPrivateKey to the destKeyStream @@ -48,28 +49,28 @@ class I2PClientImpl implements I2PClient { d.setCertificate(cert); PublicKey publicKey = new PublicKey(); Object keypair[] = KeyGenerator.getInstance().generatePKIKeypair(); - publicKey = (PublicKey)keypair[0]; - PrivateKey privateKey = (PrivateKey)keypair[1]; - Object signingKeys[] = KeyGenerator.getInstance().generateSigningKeypair(); - SigningPublicKey signingPubKey = (SigningPublicKey)signingKeys[0]; - SigningPrivateKey signingPrivKey = (SigningPrivateKey)signingKeys[1]; + publicKey = (PublicKey) keypair[0]; + PrivateKey privateKey = (PrivateKey) keypair[1]; + Object signingKeys[] = KeyGenerator.getInstance().generateSigningKeypair(); + SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0]; + SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1]; d.setPublicKey(publicKey); d.setSigningPublicKey(signingPubKey); - + d.writeBytes(destKeyStream); privateKey.writeBytes(destKeyStream); signingPrivKey.writeBytes(destKeyStream); destKeyStream.flush(); - + return d; } - + /** * Create a new session (though do not connect it yet) * */ public I2PSession createSession(InputStream destKeyStream, Properties options) throws I2PSessionException { //return new I2PSessionImpl(destKeyStream, options); // not thread safe - return new I2PSessionImpl2(destKeyStream, options); // thread safe + return new I2PSessionImpl2(destKeyStream, options); // thread safe } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PClientMessageHandlerMap.java b/core/java/src/net/i2p/client/I2PClientMessageHandlerMap.java index e056c549aa5d5d313e4decd26ccc2feeef32c1c4..61d0db159c0aa1517b05c8c50533aee79eb26082 100644 --- a/core/java/src/net/i2p/client/I2PClientMessageHandlerMap.java +++ b/core/java/src/net/i2p/client/I2PClientMessageHandlerMap.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,11 +9,16 @@ package net.i2p.client; * */ -import net.i2p.data.i2cp.*; -import net.i2p.util.Log; - -import java.util.Map; import java.util.HashMap; +import java.util.Map; + +import net.i2p.data.i2cp.DisconnectMessage; +import net.i2p.data.i2cp.MessagePayloadMessage; +import net.i2p.data.i2cp.MessageStatusMessage; +import net.i2p.data.i2cp.RequestLeaseSetMessage; +import net.i2p.data.i2cp.SessionStatusMessage; +import net.i2p.data.i2cp.SetDateMessage; +import net.i2p.util.Log; /** * Contains a map of message handlers that a session will want to use @@ -23,7 +29,7 @@ class I2PClientMessageHandlerMap { private final static Log _log = new Log(I2PClientMessageHandlerMap.class); /** map of message type id --> I2CPMessageHandler */ private static Map _handlers; - + static { _handlers = new HashMap(); _handlers.put(new Integer(DisconnectMessage.MESSAGE_TYPE), new DisconnectMessageHandler()); @@ -33,9 +39,9 @@ class I2PClientMessageHandlerMap { _handlers.put(new Integer(MessageStatusMessage.MESSAGE_TYPE), new MessageStatusMessageHandler()); _handlers.put(new Integer(SetDateMessage.MESSAGE_TYPE), new SetDateMessageHandler()); } - + public static I2CPMessageHandler getHandler(int messageTypeId) { - I2CPMessageHandler handler = (I2CPMessageHandler)_handlers.get(new Integer(messageTypeId)); + I2CPMessageHandler handler = (I2CPMessageHandler) _handlers.get(new Integer(messageTypeId)); return handler; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PSession.java b/core/java/src/net/i2p/client/I2PSession.java index 6354d3cdb119ab9ce215d9cb7cfa9b136b1586b1..61219eeadb4a0db20bb02a28e3bff67d31605351 100644 --- a/core/java/src/net/i2p/client/I2PSession.java +++ b/core/java/src/net/i2p/client/I2PSession.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -11,8 +12,8 @@ package net.i2p.client; import java.util.Set; import net.i2p.data.Destination; -import net.i2p.data.SessionKey; import net.i2p.data.PrivateKey; +import net.i2p.data.SessionKey; import net.i2p.data.SigningPrivateKey; /** @@ -30,6 +31,7 @@ public interface I2PSession { * @return whether it was accepted by the router for delivery or not */ public boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException; + /** * Like sendMessage above, except the key used and the tags sent are exposed to the * application. <p /> @@ -57,15 +59,16 @@ public interface I2PSession { * the contents of the set is ignored during the call, but afterwards it contains a set of SessionTag * objects that were sent along side the given keyUsed. */ - public boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) throws I2PSessionException; - + public boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) + throws I2PSessionException; + /** Receive a message that the router has notified the client about, returning * the payload. * @param msgId message to fetch * @return unencrypted body of the message */ public byte[] receiveMessage(int msgId) throws I2PSessionException; - + /** Instruct the router that the message received was abusive (including how * abusive on a 1-100 scale) in the hopes the router can do something to * minimize receiving abusive messages like that in the future. @@ -73,39 +76,39 @@ public interface I2PSession { * @param severity how abusive */ public void reportAbuse(int msgId, int severity) throws I2PSessionException; - + /** Instruct the I2PSession where it should send event notifications * @param lsnr listener to retrieve events */ public void setSessionListener(I2PSessionListener lsnr); - + /** * Tear down the session and release any resources. * */ public void destroySession() throws I2PSessionException; - + /** * Actually connect the session and start recieving/sending messages * */ public void connect() throws I2PSessionException; - + /** * Retrieve the Destination this session serves as the endpoint for. * Returns null if no destination is available. * */ public Destination getMyDestination(); - + /** * Retrieve the decryption PrivateKey associated with the Destination * */ public PrivateKey getDecryptionKey(); - + /** * Retrieve the signing SigningPrivateKey associated with the Destination */ public SigningPrivateKey getPrivateKey(); -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PSessionException.java b/core/java/src/net/i2p/client/I2PSessionException.java index f69c07d03b165da096ecbfc43343abb29b6ee352..573d97e8d2ffb47c0593456224b39121a10fd476 100644 --- a/core/java/src/net/i2p/client/I2PSessionException.java +++ b/core/java/src/net/i2p/client/I2PSessionException.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,8 +9,8 @@ package net.i2p.client; * */ -import net.i2p.util.Log; import net.i2p.I2PException; +import net.i2p.util.Log; /** * Thrown when there is a problem doing something on the session @@ -18,10 +19,11 @@ import net.i2p.I2PException; */ public class I2PSessionException extends I2PException { private final static Log _log = new Log(I2PSessionException.class); - + public I2PSessionException(String msg, Throwable t) { super(msg, t); } + public I2PSessionException(String msg) { super(msg); } diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 31c563e4468ec46e543ec496ee2ca52310705f3d..49edb148ca8a646abb52a676cb9a6361b4c8fabc 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -59,7 +60,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa private SessionId _sessionId; /** currently granted lease set, or null */ private LeaseSet _leaseSet; - + /** hostname of router */ private String _hostname; /** port num to router */ @@ -70,37 +71,37 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa private I2CPMessageReader _reader; /** where we pipe our messages */ private OutputStream _out; - + /** who we send events to */ private I2PSessionListener _sessionListener; - + /** class that generates new messages */ protected I2CPMessageProducer _producer; /** map of integer --> MessagePayloadMessage */ Map _availableMessages; - + /** MessageStatusMessage status from the most recent send that hasn't been consumed */ private List _receivedStatus; private int _totalReconnectAttempts; - + /** monitor for waiting until a lease set has been granted */ private Object _leaseSetWait = new Object(); - + /** whether the session connection has already been closed (or not yet opened) */ private boolean _closed; - + /** have we received the current date from the router yet? */ private boolean _dateReceived; /** lock that we wait upon, that the SetDateMessageHandler notifies */ private Object _dateReceivedLock = new Object(); - + void dateUpdated() { - _dateReceived = true; - synchronized (_dateReceivedLock) { - _dateReceivedLock.notifyAll(); - } + _dateReceived = true; + synchronized (_dateReceivedLock) { + _dateReceivedLock.notifyAll(); + } } - + /** * Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey * from the destKeyStream, and using the specified options to connect to the router @@ -108,7 +109,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * @throws I2PSessionException if there is a problem loading the private keys or */ public I2PSessionImpl(InputStream destKeyStream, Properties options) throws I2PSessionException { - _closed = true; + _closed = true; _producer = new I2CPMessageProducer(); _availableMessages = new HashMap(); try { @@ -120,11 +121,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa } loadConfig(options); _sessionId = null; - _receivedStatus = new LinkedList(); - _leaseSet = null; - _totalReconnectAttempts = 0; + _receivedStatus = new LinkedList(); + _leaseSet = null; + _totalReconnectAttempts = 0; } - + /** * Parse the config for anything we know about * @@ -133,51 +134,61 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa _options = new Properties(); _options.putAll(filter(options)); _hostname = _options.getProperty(I2PClient.PROP_TCP_HOST, "localhost"); - String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, TestServer.LISTEN_PORT+""); + String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, TestServer.LISTEN_PORT + ""); try { _portNum = Integer.parseInt(portNum); } catch (NumberFormatException nfe) { - if (_log.shouldLog(Log.WARN)) _log.warn("Invalid port number specified, defaulting to "+TestServer.LISTEN_PORT, nfe); + if (_log.shouldLog(Log.WARN)) + _log.warn("Invalid port number specified, defaulting to " + + TestServer.LISTEN_PORT, nfe); _portNum = TestServer.LISTEN_PORT; } } - + private static Properties filter(Properties options) { - Properties rv = new Properties(); - for (Iterator iter = options.keySet().iterator(); iter.hasNext(); ) { - String key = (String)iter.next(); - String val = options.getProperty(key); - if (key.startsWith("java")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping java.* property: " + key); - } else if (key.startsWith("user")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping user.* property: " + key); - } else if (key.startsWith("os")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping os.* property: " + key); - } else if (key.startsWith("sun")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping sun.* property: " + key); - } else if (key.startsWith("file")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping file.* property: " + key); - } else if (key.startsWith("line")) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping line.* property: " + key); - } else if ( (key.length() > 255) || (val.length() > 255) ) { - if (_log.shouldLog(Log.WARN)) _log.warn("Not passing on property [" + key + "] in the session configuration as the value is too long (max = 255): " + val); - } else { - rv.setProperty(key, val); - } - } - return rv; - } - - void setLeaseSet(LeaseSet ls) { - _leaseSet = ls; - if (ls != null) { - synchronized (_leaseSetWait) { - _leaseSetWait.notifyAll(); - } - } - } - LeaseSet getLeaseSet() { return _leaseSet; } - + Properties rv = new Properties(); + for (Iterator iter = options.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = options.getProperty(key); + if (key.startsWith("java")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping java.* property: " + key); + } else if (key.startsWith("user")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping user.* property: " + key); + } else if (key.startsWith("os")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping os.* property: " + key); + } else if (key.startsWith("sun")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping sun.* property: " + key); + } else if (key.startsWith("file")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping file.* property: " + key); + } else if (key.startsWith("line")) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping line.* property: " + key); + } else if ((key.length() > 255) || (val.length() > 255)) { + if (_log.shouldLog(Log.WARN)) + _log + .warn("Not passing on property [" + + key + + "] in the session configuration as the value is too long (max = 255): " + + val); + } else { + rv.setProperty(key, val); + } + } + return rv; + } + + void setLeaseSet(LeaseSet ls) { + _leaseSet = ls; + if (ls != null) { + synchronized (_leaseSetWait) { + _leaseSetWait.notifyAll(); + } + } + } + + LeaseSet getLeaseSet() { + return _leaseSet; + } + /** * Load up the destKeyFile for our Destination, PrivateKey, and SigningPrivateKey * @@ -192,7 +203,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa _privateKey.readBytes(destKeyStream); _signingPrivateKey.readBytes(destKeyStream); } - + /** * Connect to the router and establish a session. This call blocks until * a session is granted. @@ -201,70 +212,79 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * not reachable */ public void connect() throws I2PSessionException { - _closed = false; - long startConnect = Clock.getInstance().now(); + _closed = false; + long startConnect = Clock.getInstance().now(); try { - if (_log.shouldLog(Log.DEBUG)) _log.debug("connect begin to " + _hostname + ":" + _portNum); - _socket = new Socket(_hostname, _portNum); - _out = _socket.getOutputStream(); - synchronized (_out) { - _out.write(I2PClient.PROTOCOL_BYTE); - } - InputStream in = _socket.getInputStream(); - _reader = new I2CPMessageReader(in, this); - if (_log.shouldLog(Log.DEBUG)) _log.debug("before startReading"); - _reader.startReading(); - - if (_log.shouldLog(Log.DEBUG)) _log.debug("Before getDate"); - sendMessage(new GetDateMessage()); - if (_log.shouldLog(Log.DEBUG)) _log.debug("After getDate / begin waiting for a response"); - while (!_dateReceived) { - try { - synchronized (_dateReceivedLock) { _dateReceivedLock.wait(1000); } - } catch (InterruptedException ie) {} - } - if (_log.shouldLog(Log.DEBUG)) _log.debug("After received a SetDate response"); - - if (_log.shouldLog(Log.DEBUG)) _log.debug("Before producer.connect()"); - _producer.connect(this); - if (_log.shouldLog(Log.DEBUG)) _log.debug("After producer.connect()"); - - // wait until we have created a lease set - while (_leaseSet == null) { - synchronized (_leaseSetWait) { - try { _leaseSetWait.wait(1000); } catch (InterruptedException ie) {} - } - } - long connected = Clock.getInstance().now(); - if (_log.shouldLog(Log.INFO)) _log.info("Lease set created with inbound tunnels after " + (connected-startConnect) + "ms - ready to participate in the network!"); + if (_log.shouldLog(Log.DEBUG)) _log.debug("connect begin to " + _hostname + ":" + _portNum); + _socket = new Socket(_hostname, _portNum); + _out = _socket.getOutputStream(); + synchronized (_out) { + _out.write(I2PClient.PROTOCOL_BYTE); + } + InputStream in = _socket.getInputStream(); + _reader = new I2CPMessageReader(in, this); + if (_log.shouldLog(Log.DEBUG)) _log.debug("before startReading"); + _reader.startReading(); + + if (_log.shouldLog(Log.DEBUG)) _log.debug("Before getDate"); + sendMessage(new GetDateMessage()); + if (_log.shouldLog(Log.DEBUG)) _log.debug("After getDate / begin waiting for a response"); + while (!_dateReceived) { + try { + synchronized (_dateReceivedLock) { + _dateReceivedLock.wait(1000); + } + } catch (InterruptedException ie) { + } + } + if (_log.shouldLog(Log.DEBUG)) _log.debug("After received a SetDate response"); + + if (_log.shouldLog(Log.DEBUG)) _log.debug("Before producer.connect()"); + _producer.connect(this); + if (_log.shouldLog(Log.DEBUG)) _log.debug("After producer.connect()"); + + // wait until we have created a lease set + while (_leaseSet == null) { + synchronized (_leaseSetWait) { + try { + _leaseSetWait.wait(1000); + } catch (InterruptedException ie) { + } + } + } + long connected = Clock.getInstance().now(); + if (_log.shouldLog(Log.INFO)) + _log.info("Lease set created with inbound tunnels after " + + (connected - startConnect) + + "ms - ready to participate in the network!"); } catch (UnknownHostException uhe) { - _closed = true; + _closed = true; throw new I2PSessionException("Invalid session configuration", uhe); } catch (IOException ioe) { - _closed = true; + _closed = true; throw new I2PSessionException("Problem connecting to " + _hostname + " on port " + _portNum, ioe); } } - + /** * Pull the unencrypted data from the message that we've already prefetched and * notified the user that its available. * */ public byte[] receiveMessage(int msgId) throws I2PSessionException { - MessagePayloadMessage msg = (MessagePayloadMessage)_availableMessages.remove(new Integer(msgId)); + MessagePayloadMessage msg = (MessagePayloadMessage) _availableMessages.remove(new Integer(msgId)); if (msg == null) return null; return msg.getPayload().getUnencryptedData(); } - + /** * Report abuse with regards to the given messageId */ public void reportAbuse(int msgId, int severity) throws I2PSessionException { - if (isClosed()) throw new I2PSessionException("Already closed"); + if (isClosed()) throw new I2PSessionException("Already closed"); _producer.reportAbuse(this, msgId, severity); } - + /** * Send the data to the destination. * TODO: this currently always returns true, regardless of whether the message was @@ -272,43 +292,49 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * */ public abstract boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException; - public abstract boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) throws I2PSessionException; + + public abstract boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) + throws I2PSessionException; + public abstract void receiveStatus(int msgId, long nonce, int status); - + protected boolean isGuaranteed() { - return I2PClient.PROP_RELIABILITY_GUARANTEED.equals(_options.getProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_GUARANTEED)); + return I2PClient.PROP_RELIABILITY_GUARANTEED + .equals(_options.getProperty(I2PClient.PROP_RELIABILITY, + I2PClient.PROP_RELIABILITY_GUARANTEED)); } - + protected static final Set createNewTags(int num) { - Set tags = new HashSet(); - for (int i = 0; i < num; i++) - tags.add(new SessionTag(true)); - return tags; + Set tags = new HashSet(); + for (int i = 0; i < num; i++) + tags.add(new SessionTag(true)); + return tags; } - + /** * Recieve a payload message and let the app know its available */ public void addNewMessage(MessagePayloadMessage msg) { _availableMessages.put(new Integer(msg.getMessageId().getMessageId()), msg); final int id = msg.getMessageId().getMessageId(); - byte data[] = msg.getPayload().getUnencryptedData(); - if ( (data == null) || (data.length <= 0) ) { - if (_log.shouldLog(Log.ERROR)) _log.error("addNewMessage of a message with no unencrypted data", new Exception("Empty message")); - } else { - final long size = data.length; - Thread notifier = new I2PThread(new Runnable() { - public void run() { - if (_sessionListener != null) - _sessionListener.messageAvailable(I2PSessionImpl.this, id, size); - } - }); - notifier.setName("Notifier [" + _sessionId + "/" + id + "]"); - notifier.setDaemon(true); - notifier.start(); - } - } - + byte data[] = msg.getPayload().getUnencryptedData(); + if ((data == null) || (data.length <= 0)) { + if (_log.shouldLog(Log.ERROR)) + _log.error("addNewMessage of a message with no unencrypted data", + new Exception("Empty message")); + } else { + final long size = data.length; + Thread notifier = new I2PThread(new Runnable() { + public void run() { + if (_sessionListener != null) _sessionListener.messageAvailable(I2PSessionImpl.this, id, size); + } + }); + notifier.setName("Notifier [" + _sessionId + "/" + id + "]"); + notifier.setDaemon(true); + notifier.start(); + } + } + /** * Recieve notification of some I2CP message and handle it if possible * @@ -316,177 +342,208 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa public void messageReceived(I2CPMessageReader reader, I2CPMessage message) { I2CPMessageHandler handler = I2PClientMessageHandlerMap.getHandler(message.getType()); if (handler == null) { - if (_log.shouldLog(Log.WARN)) _log.warn("Unknown message or unhandleable message received: type = " + message.getType()); + if (_log.shouldLog(Log.WARN)) + _log.warn("Unknown message or unhandleable message received: type = " + + message.getType()); } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Message received of type " + message.getType() + " to be handled by " + handler); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Message received of type " + message.getType() + + " to be handled by " + handler); handler.handleMessage(message, this); } } - + /** * Recieve notifiation of an error reading the I2CP stream * */ public void readError(I2CPMessageReader reader, Exception error) { propogateError("There was an error reading data", error); - disconnect(); + disconnect(); } - + /** * Retrieve the destination of the session */ - public Destination getMyDestination() { return _myDestination; } + public Destination getMyDestination() { + return _myDestination; + } + /** * Retrieve the decryption PrivateKey */ - public PrivateKey getDecryptionKey() { return _privateKey; } + public PrivateKey getDecryptionKey() { + return _privateKey; + } + /** * Retrieve the signing SigningPrivateKey */ - public SigningPrivateKey getPrivateKey() { return _signingPrivateKey; } + public SigningPrivateKey getPrivateKey() { + return _signingPrivateKey; + } + /** * Retrieve the helper that generates I2CP messages */ - I2CPMessageProducer getProducer() { return _producer; } + I2CPMessageProducer getProducer() { + return _producer; + } + /** * Retrieve the configuration options */ - Properties getOptions() { return _options; } + Properties getOptions() { + return _options; + } + /** * Retrieve the session's ID */ - SessionId getSessionId() { return _sessionId; } + SessionId getSessionId() { + return _sessionId; + } + /** * Configure the session's ID */ - void setSessionId(SessionId id) { - _sessionId = id; + void setSessionId(SessionId id) { + _sessionId = id; } - + /** configure the listener */ - public void setSessionListener(I2PSessionListener lsnr) { _sessionListener = lsnr; } - + public void setSessionListener(I2PSessionListener lsnr) { + _sessionListener = lsnr; + } + /** has the session been closed (or not yet connected)? */ - public boolean isClosed() { return _closed; } - + public boolean isClosed() { + return _closed; + } + /** * Deliver an I2CP message to the router * * @throws I2PSessionException if the message is malformed or there is an error writing it out */ void sendMessage(I2CPMessage message) throws I2PSessionException { - if (isClosed()) throw new I2PSessionException("Already closed"); - + if (isClosed()) throw new I2PSessionException("Already closed"); + try { - synchronized(_out) { - message.writeMessage(_out); - _out.flush(); - } - if (_log.shouldLog(Log.DEBUG)) _log.debug("Message written out and flushed"); + synchronized (_out) { + message.writeMessage(_out); + _out.flush(); + } + if (_log.shouldLog(Log.DEBUG)) _log.debug("Message written out and flushed"); } catch (I2CPMessageException ime) { throw new I2PSessionException("Error writing out the message", ime); } catch (IOException ioe) { throw new I2PSessionException("Error writing out the message", ioe); } } - + /** * Pass off the error to the listener */ void propogateError(String msg, Throwable error) { - if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred: " + msg, error); - if (_sessionListener != null) - _sessionListener.errorOccurred(this, msg, error); + if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred: " + msg, error); + if (_sessionListener != null) _sessionListener.errorOccurred(this, msg, error); } - + /** * Tear down the session, and do NOT reconnect */ - public void destroySession() { destroySession(true); } + public void destroySession() { + destroySession(true); + } + public void destroySession(boolean sendDisconnect) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Destroy the session", new Exception("DestroySession()")); - _closed = true; - if (sendDisconnect) { - try { - _producer.disconnect(this); - } catch (I2PSessionException ipe) { - propogateError("Error destroying the session", ipe); - } - } + if (_log.shouldLog(Log.DEBUG)) _log.debug("Destroy the session", new Exception("DestroySession()")); + _closed = true; + if (sendDisconnect) { + try { + _producer.disconnect(this); + } catch (I2PSessionException ipe) { + propogateError("Error destroying the session", ipe); + } + } closeSocket(); - if (_sessionListener != null) - _sessionListener.disconnected(this); + if (_sessionListener != null) _sessionListener.disconnected(this); } - + /** * Close the socket carefully * */ private void closeSocket() { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Closing the socket", new Exception("closeSocket")); - _closed = true; - if (_reader != null) - _reader.stopReading(); - _reader = null; - + if (_log.shouldLog(Log.DEBUG)) _log.debug("Closing the socket", new Exception("closeSocket")); + _closed = true; + if (_reader != null) _reader.stopReading(); + _reader = null; + if (_socket != null) { - try { + try { _socket.close(); } catch (IOException ioe) { propogateError("Caught an IO error closing the socket. ignored", ioe); } finally { - _socket = null; // so when propogateError calls closeSocket, it doesnt loop - } + _socket = null; // so when propogateError calls closeSocket, it doesnt loop + } } } - + /** * Recieve notification that the I2CP connection was disconnected */ public void disconnected(I2CPMessageReader reader) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnected", new Exception("Disconnected")); - disconnect(); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnected", new Exception("Disconnected")); + disconnect(); } - + protected void disconnect() { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnect() called", new Exception("Disconnect")); - if (shouldReconnect()) { - if (reconnect()) { - if (_log.shouldLog(Log.INFO)) _log.info("I2CP reconnection successful"); - return; - } else { - _log.error("I2CP reconnection failed"); - } - } - - _log.error("Disconned from the router, and not trying to reconnect further. I hope you're not hoping anything else will happen"); - if (_sessionListener != null) - _sessionListener.disconnected(this); - - closeSocket(); - } - + if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnect() called", new Exception("Disconnect")); + if (shouldReconnect()) { + if (reconnect()) { + if (_log.shouldLog(Log.INFO)) _log.info("I2CP reconnection successful"); + return; + } else { + _log.error("I2CP reconnection failed"); + } + } + + _log + .error("Disconned from the router, and not trying to reconnect further. I hope you're not hoping anything else will happen"); + if (_sessionListener != null) _sessionListener.disconnected(this); + + closeSocket(); + } + private final static int MAX_RECONNECT_ATTEMPTS = 1; private final static int MAX_TOTAL_RECONNECT_ATTEMPTS = 3; - - protected boolean shouldReconnect() { return true; } + + protected boolean shouldReconnect() { + return true; + } + protected boolean reconnect() { - closeSocket(); - if (_totalReconnectAttempts < MAX_TOTAL_RECONNECT_ATTEMPTS) { - _totalReconnectAttempts++; - } else { - if (_log.shouldLog(Log.CRIT)) _log.log(Log.CRIT, "Max number of reconnects exceeded [" + _totalReconnectAttempts + "], we give up!"); - return false; - } - if (_log.shouldLog(Log.INFO)) _log.info("Reconnecting..."); - for (int i = 0; i < MAX_RECONNECT_ATTEMPTS; i++) { - try { - connect(); - return true; - } catch (I2PSessionException ise) { - if (_log.shouldLog(Log.ERROR)) _log.error("Error reconnecting on attempt " + i, ise); - } - } - return false; + closeSocket(); + if (_totalReconnectAttempts < MAX_TOTAL_RECONNECT_ATTEMPTS) { + _totalReconnectAttempts++; + } else { + if (_log.shouldLog(Log.CRIT)) + _log.log(Log.CRIT, "Max number of reconnects exceeded [" + + _totalReconnectAttempts + "], we give up!"); + return false; + } + if (_log.shouldLog(Log.INFO)) _log.info("Reconnecting..."); + for (int i = 0; i < MAX_RECONNECT_ATTEMPTS; i++) { + try { + connect(); + return true; + } catch (I2PSessionException ise) { + if (_log.shouldLog(Log.ERROR)) _log.error("Error reconnecting on attempt " + i, ise); + } + } + return false; } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PSessionImpl2.java b/core/java/src/net/i2p/client/I2PSessionImpl2.java index dda10617b4f1011d8a1dfd3181dedd76dc6b9828..85fd558b73515789053a16ae328a0a7cc07364bc 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl2.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl2.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -16,10 +17,10 @@ import java.util.Set; import net.i2p.crypto.KeyGenerator; import net.i2p.crypto.SessionKeyManager; +import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; -import net.i2p.data.DataHelper; import net.i2p.data.i2cp.MessageId; import net.i2p.data.i2cp.MessageStatusMessage; import net.i2p.util.Clock; @@ -33,14 +34,14 @@ import net.i2p.util.RandomSource; */ class I2PSessionImpl2 extends I2PSessionImpl { private final static Log _log = new Log(I2PSessionImpl2.class); - + /** set of MessageState objects, representing all of the messages in the process of being sent */ private Set _sendingStates; /** max # seconds to wait for confirmation of the message send */ - private final static long SEND_TIMEOUT = 60*1000; // 60 seconds to send + private final static long SEND_TIMEOUT = 60 * 1000; // 60 seconds to send /** should we gzip each payload prior to sending it? */ private final static boolean SHOULD_COMPRESS = true; - + /** * Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey * from the destKeyStream, and using the specified options to connect to the router @@ -48,240 +49,270 @@ class I2PSessionImpl2 extends I2PSessionImpl { * @throws I2PSessionException if there is a problem loading the private keys or */ public I2PSessionImpl2(InputStream destKeyStream, Properties options) throws I2PSessionException { - super(destKeyStream, options); - _sendingStates = new HashSet(32); + super(destKeyStream, options); + _sendingStates = new HashSet(32); } - - protected long getTimeout() { return SEND_TIMEOUT; } - + + protected long getTimeout() { + return SEND_TIMEOUT; + } + public void destroySession(boolean sendDisconnect) { - clearStates(); - super.destroySession(sendDisconnect); + clearStates(); + super.destroySession(sendDisconnect); } - + public boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException { - return sendMessage(dest, payload, new SessionKey(), new HashSet(64)); + return sendMessage(dest, payload, new SessionKey(), new HashSet(64)); } - - public boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) throws I2PSessionException { - if (isClosed()) throw new I2PSessionException("Already closed"); - if (SHOULD_COMPRESS) - payload = DataHelper.compress(payload); - if (isGuaranteed()) { - return sendGuaranteed(dest, payload, keyUsed, tagsSent); - } else { - return sendBestEffort(dest, payload, keyUsed, tagsSent); - } + + public boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) + throws I2PSessionException { + if (isClosed()) throw new I2PSessionException("Already closed"); + if (SHOULD_COMPRESS) payload = DataHelper.compress(payload); + if (isGuaranteed()) { + return sendGuaranteed(dest, payload, keyUsed, tagsSent); + } else { + return sendBestEffort(dest, payload, keyUsed, tagsSent); + } } - + /** * pull the unencrypted AND DECOMPRESSED data */ public byte[] receiveMessage(int msgId) throws I2PSessionException { - byte compressed[] = super.receiveMessage(msgId); - if (SHOULD_COMPRESS) - return DataHelper.decompress(compressed); - else - return compressed; + byte compressed[] = super.receiveMessage(msgId); + if (SHOULD_COMPRESS) + return DataHelper.decompress(compressed); + else + return compressed; } - - - private boolean sendBestEffort(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent) throws I2PSessionException { - SessionKey key = SessionKeyManager.getInstance().getCurrentKey(dest.getPublicKey()); - if (key == null) - key = SessionKeyManager.getInstance().createSession(dest.getPublicKey()); - SessionTag tag = SessionKeyManager.getInstance().consumeNextAvailableTag(dest.getPublicKey(), key); - Set sentTags = null; - if (SessionKeyManager.getInstance().getAvailableTags(dest.getPublicKey(), key) < 10) { - sentTags = createNewTags(50); - } else if (SessionKeyManager.getInstance().getAvailableTimeLeft(dest.getPublicKey(), key) < 30*1000) { - // if we have > 10 tags, but they expire in under 30 seconds, we want more - sentTags = createNewTags(50); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones"); - } - SessionKey newKey = null; - if (false) // rekey - newKey = KeyGenerator.getInstance().generateSessionKey(); - long nonce = (long)RandomSource.getInstance().nextInt(Integer.MAX_VALUE); - MessageState state = new MessageState(nonce); - state.setKey(key); - state.setTags(sentTags); - state.setNewKey(newKey); - state.setTo(dest); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key); + private boolean sendBestEffort(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent) + throws I2PSessionException { + SessionKey key = SessionKeyManager.getInstance().getCurrentKey(dest.getPublicKey()); + if (key == null) key = SessionKeyManager.getInstance().createSession(dest.getPublicKey()); + SessionTag tag = SessionKeyManager.getInstance().consumeNextAvailableTag(dest.getPublicKey(), key); + Set sentTags = null; + if (SessionKeyManager.getInstance().getAvailableTags(dest.getPublicKey(), key) < 10) { + sentTags = createNewTags(50); + } else if (SessionKeyManager.getInstance().getAvailableTimeLeft(dest.getPublicKey(), key) < 30 * 1000) { + // if we have > 10 tags, but they expire in under 30 seconds, we want more + sentTags = createNewTags(50); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones"); + } + SessionKey newKey = null; + if (false) // rekey + newKey = KeyGenerator.getInstance().generateSessionKey(); - if (keyUsed != null) { - if (newKey != null) - keyUsed.setData(newKey.getData()); - else - keyUsed.setData(key.getData()); - } - if (tagsSent != null) { - if (sentTags != null) { - tagsSent.addAll(sentTags); - } - } + long nonce = (long) RandomSource.getInstance().nextInt(Integer.MAX_VALUE); + MessageState state = new MessageState(nonce); + state.setKey(key); + state.setTags(sentTags); + state.setNewKey(newKey); + state.setTo(dest); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key); - synchronized (_sendingStates) { - _sendingStates.add(state); - } - if (_log.shouldLog(Log.DEBUG)) _log.debug("Adding sending state " + state.getMessageId() + " / " + state.getNonce()); - _producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey); - state.waitFor(MessageStatusMessage.STATUS_SEND_ACCEPTED, Clock.getInstance().now() + getTimeout()); - synchronized (_sendingStates) { - _sendingStates.remove(state); - } - boolean found = state.received(MessageStatusMessage.STATUS_SEND_ACCEPTED); - if (_log.shouldLog(Log.DEBUG)) _log.debug("After waitFor sending state " + state.getMessageId().getMessageId() + " / " + state.getNonce() + " found = " + found); - if (found) { - if (_log.shouldLog(Log.INFO)) _log.info("Message sent after " + state.getElapsed() + "ms with " + payload.length + " bytes"); - } else { - if (_log.shouldLog(Log.INFO)) _log.info("Message send failed after " + state.getElapsed() + "ms with " + payload.length + " bytes"); - if (_log.shouldLog(Log.ERROR)) _log.error("Never received *accepted* from the router! dropping and reconnecting"); - disconnect(); - return false; - } - return found; + if (keyUsed != null) { + if (newKey != null) + keyUsed.setData(newKey.getData()); + else + keyUsed.setData(key.getData()); + } + if (tagsSent != null) { + if (sentTags != null) { + tagsSent.addAll(sentTags); + } + } + + synchronized (_sendingStates) { + _sendingStates.add(state); + } + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Adding sending state " + state.getMessageId() + " / " + + state.getNonce()); + _producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey); + state.waitFor(MessageStatusMessage.STATUS_SEND_ACCEPTED, Clock.getInstance().now() + getTimeout()); + synchronized (_sendingStates) { + _sendingStates.remove(state); + } + boolean found = state.received(MessageStatusMessage.STATUS_SEND_ACCEPTED); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("After waitFor sending state " + state.getMessageId().getMessageId() + + " / " + state.getNonce() + " found = " + found); + if (found) { + if (_log.shouldLog(Log.INFO)) + _log.info("Message sent after " + state.getElapsed() + "ms with " + + payload.length + " bytes"); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("Message send failed after " + state.getElapsed() + "ms with " + + payload.length + " bytes"); + if (_log.shouldLog(Log.ERROR)) + _log + .error("Never received *accepted* from the router! dropping and reconnecting"); + disconnect(); + return false; + } + return found; } - - private boolean sendGuaranteed(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent) throws I2PSessionException { - SessionKey key = SessionKeyManager.getInstance().getCurrentKey(dest.getPublicKey()); - if (key == null) - key = SessionKeyManager.getInstance().createSession(dest.getPublicKey()); - SessionTag tag = SessionKeyManager.getInstance().consumeNextAvailableTag(dest.getPublicKey(), key); - Set sentTags = null; - if (SessionKeyManager.getInstance().getAvailableTags(dest.getPublicKey(), key) < 10) { - sentTags = createNewTags(50); - } else if (SessionKeyManager.getInstance().getAvailableTimeLeft(dest.getPublicKey(), key) < 30*1000) { - // if we have > 10 tags, but they expire in under 30 seconds, we want more - sentTags = createNewTags(50); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones"); - } - SessionKey newKey = null; - if (false) // rekey - newKey = KeyGenerator.getInstance().generateSessionKey(); - long nonce = (long)RandomSource.getInstance().nextInt(Integer.MAX_VALUE); - MessageState state = new MessageState(nonce); - state.setKey(key); - state.setTags(sentTags); - state.setNewKey(newKey); - state.setTo(dest); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key); + private boolean sendGuaranteed(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent) + throws I2PSessionException { + SessionKey key = SessionKeyManager.getInstance().getCurrentKey(dest.getPublicKey()); + if (key == null) key = SessionKeyManager.getInstance().createSession(dest.getPublicKey()); + SessionTag tag = SessionKeyManager.getInstance().consumeNextAvailableTag(dest.getPublicKey(), key); + Set sentTags = null; + if (SessionKeyManager.getInstance().getAvailableTags(dest.getPublicKey(), key) < 10) { + sentTags = createNewTags(50); + } else if (SessionKeyManager.getInstance().getAvailableTimeLeft(dest.getPublicKey(), key) < 30 * 1000) { + // if we have > 10 tags, but they expire in under 30 seconds, we want more + sentTags = createNewTags(50); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones"); + } + SessionKey newKey = null; + if (false) // rekey + newKey = KeyGenerator.getInstance().generateSessionKey(); + + long nonce = (long) RandomSource.getInstance().nextInt(Integer.MAX_VALUE); + MessageState state = new MessageState(nonce); + state.setKey(key); + state.setTags(sentTags); + state.setNewKey(newKey); + state.setTo(dest); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key); + + if (keyUsed != null) { + if (newKey != null) + keyUsed.setData(newKey.getData()); + else + keyUsed.setData(key.getData()); + } + if (tagsSent != null) { + if (sentTags != null) { + tagsSent.addAll(sentTags); + } + } - if (keyUsed != null) { - if (newKey != null) - keyUsed.setData(newKey.getData()); - else - keyUsed.setData(key.getData()); - } - if (tagsSent != null) { - if (sentTags != null) { - tagsSent.addAll(sentTags); - } - } - + synchronized (_sendingStates) { + _sendingStates.add(state); + } + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Adding sending state " + state.getMessageId() + " / " + + state.getNonce()); + _producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey); + state.waitFor(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS, Clock.getInstance().now() + SEND_TIMEOUT); + synchronized (_sendingStates) { + _sendingStates.remove(state); + } + boolean found = state.received(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); + boolean accepted = state.received(MessageStatusMessage.STATUS_SEND_ACCEPTED); - synchronized (_sendingStates) { - _sendingStates.add(state); - } - if (_log.shouldLog(Log.DEBUG)) _log.debug("Adding sending state " + state.getMessageId() + " / " + state.getNonce()); - _producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey); - state.waitFor(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS, Clock.getInstance().now() + SEND_TIMEOUT); - synchronized (_sendingStates) { - _sendingStates.remove(state); - } - boolean found = state.received(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); - boolean accepted = state.received(MessageStatusMessage.STATUS_SEND_ACCEPTED); - - if ( (!accepted) || (state.getMessageId() == null) ) { - if (_log.shouldLog(Log.ERROR)) _log.error("State with nonce " + state.getNonce() + " was not accepted? (no messageId!!)"); - nackTags(state); - if (_log.shouldLog(Log.CRIT)) _log.log(Log.CRIT,"Disconnecting/reconnecting because we never were accepted!"); - disconnect(); - return false; - } - - if (_log.shouldLog(Log.DEBUG)) _log.debug("After waitFor sending state " + state.getMessageId().getMessageId() + " / " + state.getNonce() + " found = " + found); - if (found) { - if (_log.shouldLog(Log.INFO)) _log.info("Message sent after " + state.getElapsed() + "ms with " + payload.length + " bytes"); - ackTags(state); - } else { - if (_log.shouldLog(Log.INFO)) _log.info("Message send failed after " + state.getElapsed() + "ms with " + payload.length + " bytes"); - nackTags(state); - } - return found; + if ((!accepted) || (state.getMessageId() == null)) { + if (_log.shouldLog(Log.ERROR)) + _log.error("State with nonce " + state.getNonce() + + " was not accepted? (no messageId!!)"); + nackTags(state); + if (_log.shouldLog(Log.CRIT)) + _log.log(Log.CRIT, + "Disconnecting/reconnecting because we never were accepted!"); + disconnect(); + return false; + } + + if (_log.shouldLog(Log.DEBUG)) + _log.debug("After waitFor sending state " + state.getMessageId().getMessageId() + + " / " + state.getNonce() + " found = " + found); + if (found) { + if (_log.shouldLog(Log.INFO)) + _log.info("Message sent after " + state.getElapsed() + "ms with " + + payload.length + " bytes"); + ackTags(state); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("Message send failed after " + state.getElapsed() + "ms with " + + payload.length + " bytes"); + nackTags(state); + } + return found; } - - + private void ackTags(MessageState state) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("ack tags for msgId " + state.getMessageId() + " / " + state.getNonce() + " key = " + state.getKey() + ", tags = " + state.getTags()); - if ( (state.getTags() != null) && (state.getTags().size() > 0) ) { - if (state.getNewKey() == null) - SessionKeyManager.getInstance().tagsDelivered(state.getTo().getPublicKey(), state.getKey(), state.getTags()); - else - SessionKeyManager.getInstance().tagsDelivered(state.getTo().getPublicKey(), state.getNewKey(), state.getTags()); - } + if (_log.shouldLog(Log.DEBUG)) + _log.debug("ack tags for msgId " + state.getMessageId() + " / " + + state.getNonce() + " key = " + state.getKey() + ", tags = " + + state.getTags()); + if ((state.getTags() != null) && (state.getTags().size() > 0)) { + if (state.getNewKey() == null) + SessionKeyManager.getInstance().tagsDelivered(state.getTo().getPublicKey(), state.getKey(), + state.getTags()); + else + SessionKeyManager.getInstance().tagsDelivered(state.getTo().getPublicKey(), state.getNewKey(), + state.getTags()); + } } - + private void nackTags(MessageState state) { - if (_log.shouldLog(Log.INFO)) _log.info("nack tags for msgId " + state.getMessageId() + " / " + state.getNonce() + " key = " + state.getKey()); - SessionKeyManager.getInstance().failTags(state.getTo().getPublicKey()); + if (_log.shouldLog(Log.INFO)) + _log.info("nack tags for msgId " + state.getMessageId() + " / " + state.getNonce() + + " key = " + state.getKey()); + SessionKeyManager.getInstance().failTags(state.getTo().getPublicKey()); } - + public void receiveStatus(int msgId, long nonce, int status) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received status " + status + " for msgId " + msgId + " / " + nonce); - MessageState state = null; - synchronized (_sendingStates) { - for (Iterator iter = _sendingStates.iterator(); iter.hasNext(); ) { - state = (MessageState)iter.next(); - if (_log.shouldLog(Log.DEBUG)) _log.debug("State " + state.getMessageId() + " / " + state.getNonce()); - if (state.getNonce() == nonce) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state"); - break; - } else if ( (state.getMessageId() != null) && (state.getMessageId().getMessageId() == msgId) ) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state by msgId"); - break; - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("State does not match"); - state = null; - } - } - } - - if (state != null) { - if (state.getMessageId() == null) { - MessageId id = new MessageId(); - id.setMessageId(msgId); - state.setMessageId(id); - } - state.receive(status); - } else { - if (_log.shouldLog(Log.INFO)) _log.info("No matching state for messageId " + msgId + " / " + nonce + " w/ status = " + status); - } + if (_log.shouldLog(Log.DEBUG)) _log.debug("Received status " + status + " for msgId " + msgId + " / " + nonce); + MessageState state = null; + synchronized (_sendingStates) { + for (Iterator iter = _sendingStates.iterator(); iter.hasNext();) { + state = (MessageState) iter.next(); + if (_log.shouldLog(Log.DEBUG)) _log.debug("State " + state.getMessageId() + " / " + state.getNonce()); + if (state.getNonce() == nonce) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state"); + break; + } else if ((state.getMessageId() != null) && (state.getMessageId().getMessageId() == msgId)) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state by msgId"); + break; + } else { + if (_log.shouldLog(Log.DEBUG)) _log.debug("State does not match"); + state = null; + } + } + } + + if (state != null) { + if (state.getMessageId() == null) { + MessageId id = new MessageId(); + id.setMessageId(msgId); + state.setMessageId(id); + } + state.receive(status); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("No matching state for messageId " + msgId + " / " + nonce + + " w/ status = " + status); + } } - + /** * Called whenever we want to reconnect (used only in the superclass). We need * to override this to clear out the message state * */ protected boolean reconnect() { - // even if we succeed in reconnecting, we want to clear the old states, - // since this will be a new sessionId - clearStates(); - return super.reconnect(); + // even if we succeed in reconnecting, we want to clear the old states, + // since this will be a new sessionId + clearStates(); + return super.reconnect(); } - + private void clearStates() { - synchronized (_sendingStates) { - for (Iterator iter = _sendingStates.iterator(); iter.hasNext(); ) { - MessageState state = (MessageState)iter.next(); - state.cancel(); - } - if (_log.shouldLog(Log.INFO)) _log.info("Disconnecting " + _sendingStates.size() + " states"); - _sendingStates.clear(); - } + synchronized (_sendingStates) { + for (Iterator iter = _sendingStates.iterator(); iter.hasNext();) { + MessageState state = (MessageState) iter.next(); + state.cancel(); + } + if (_log.shouldLog(Log.INFO)) _log.info("Disconnecting " + _sendingStates.size() + " states"); + _sendingStates.clear(); + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/I2PSessionListener.java b/core/java/src/net/i2p/client/I2PSessionListener.java index 9403fc5f09da0c36acac3470e7c73502bc2960d9..4c78c65272141d49d3d9a5cc291142587034ba10 100644 --- a/core/java/src/net/i2p/client/I2PSessionListener.java +++ b/core/java/src/net/i2p/client/I2PSessionListener.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -22,20 +23,20 @@ public interface I2PSessionListener { * @param size size of the message */ void messageAvailable(I2PSession session, int msgId, long size); - + /** Instruct the client that the session specified seems to be under attack * and that the client may wish to move its destination to another router. * @param session session to report abuse to * @param severity how bad the abuse is */ void reportAbuse(I2PSession session, int severity); - + /** * Notify the client that the session has been terminated * */ void disconnected(I2PSession session); - + /** * Notify the client that some error occurred * diff --git a/core/java/src/net/i2p/client/MessagePayloadMessageHandler.java b/core/java/src/net/i2p/client/MessagePayloadMessageHandler.java index 4cfe85b6b2fb49d9bb392269f435030ef460a0a3..7d546de944467a1e174de89dcbc70988b3b84d56 100644 --- a/core/java/src/net/i2p/client/MessagePayloadMessageHandler.java +++ b/core/java/src/net/i2p/client/MessagePayloadMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -27,36 +28,39 @@ class MessagePayloadMessageHandler extends HandlerImpl { public MessagePayloadMessageHandler() { super(MessagePayloadMessage.MESSAGE_TYPE); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { _log.debug("Handle message " + message); try { - MessagePayloadMessage msg = (MessagePayloadMessage)message; + MessagePayloadMessage msg = (MessagePayloadMessage) message; MessageId id = msg.getMessageId(); Payload payload = decryptPayload(msg, session); session.addNewMessage(msg); - - ReceiveMessageEndMessage m = new ReceiveMessageEndMessage(); - m.setMessageId(id); - m.setSessionId(msg.getSessionId()); - session.sendMessage(m); + + ReceiveMessageEndMessage m = new ReceiveMessageEndMessage(); + m.setMessageId(id); + m.setSessionId(msg.getSessionId()); + session.sendMessage(m); } catch (DataFormatException dfe) { session.propogateError("Error handling a new payload message", dfe); } catch (I2PSessionException ise) { session.propogateError("Error handling a new payload message", ise); - } + } } - + /** * Decrypt the payload */ private Payload decryptPayload(MessagePayloadMessage msg, I2PSessionImpl session) throws DataFormatException { Payload payload = msg.getPayload(); byte[] data = ElGamalAESEngine.decrypt(payload.getEncryptedData(), session.getDecryptionKey()); - if (data == null) { - _log.error("Error decrypting the payload to public key " + session.getMyDestination().getPublicKey().toBase64() + "\nPayload: " + payload.calculateHash()); - throw new DataFormatException("Unable to decrypt the payload"); - } - payload.setUnencryptedData(data); + if (data == null) { + _log + .error("Error decrypting the payload to public key " + + session.getMyDestination().getPublicKey().toBase64() + "\nPayload: " + payload.calculateHash()); + throw new DataFormatException("Unable to decrypt the payload"); + } + payload.setUnencryptedData(data); return payload; } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/MessageState.java b/core/java/src/net/i2p/client/MessageState.java index 8748fccec161391206a68f78ccadddffc0e78708..ee7b1aae7beb7b5630c5db9d17790c0e4d0f294b 100644 --- a/core/java/src/net/i2p/client/MessageState.java +++ b/core/java/src/net/i2p/client/MessageState.java @@ -1,18 +1,17 @@ package net.i2p.client; -import net.i2p.data.i2cp.MessageId; -import net.i2p.data.i2cp.MessageStatusMessage; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; -import net.i2p.data.SessionKey; import net.i2p.data.Destination; -import net.i2p.util.Log; +import net.i2p.data.SessionKey; +import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.MessageStatusMessage; import net.i2p.util.Clock; - -import java.util.Set; -import java.util.HashSet; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; +import net.i2p.util.Log; /** * Contains the state of a payload message being sent to a peer @@ -30,179 +29,240 @@ class MessageState { private boolean _cancelled; private long _created; private Object _lock = new Object(); + public MessageState(long nonce) { - _nonce = nonce; - _id = null; - _receivedStatus = new HashSet(); - _cancelled = false; - _key = null; - _newKey = null; - _tags = null; - _to = null; - _created = Clock.getInstance().now(); + _nonce = nonce; + _id = null; + _receivedStatus = new HashSet(); + _cancelled = false; + _key = null; + _newKey = null; + _tags = null; + _to = null; + _created = Clock.getInstance().now(); } + public void receive(int status) { - synchronized (_receivedStatus) { - _receivedStatus.add(new Integer(status)); - } - synchronized (_lock) { - _lock.notifyAll(); - } - } - - public void setMessageId(MessageId id) { _id = id; } - public MessageId getMessageId() { return _id; } - public long getNonce() { return _nonce; } - public void setKey(SessionKey key) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key [" + _key + "] to [" + key + "]"); - _key = key; - } - public SessionKey getKey() { return _key; } - public void setNewKey(SessionKey key) { _newKey = key; } - public SessionKey getNewKey() { return _newKey; } - public void setTags(Set tags) { _tags = tags; } - public Set getTags() { return _tags; } - public void setTo(Destination dest) { _to = dest; } - public Destination getTo() { return _to; } - - public long getElapsed() { return Clock.getInstance().now() - _created; } + synchronized (_receivedStatus) { + _receivedStatus.add(new Integer(status)); + } + synchronized (_lock) { + _lock.notifyAll(); + } + } + + public void setMessageId(MessageId id) { + _id = id; + } + + public MessageId getMessageId() { + return _id; + } + + public long getNonce() { + return _nonce; + } + + public void setKey(SessionKey key) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key [" + _key + "] to [" + key + "]"); + _key = key; + } + + public SessionKey getKey() { + return _key; + } + + public void setNewKey(SessionKey key) { + _newKey = key; + } + + public SessionKey getNewKey() { + return _newKey; + } + + public void setTags(Set tags) { + _tags = tags; + } + + public Set getTags() { + return _tags; + } + + public void setTo(Destination dest) { + _to = dest; + } + + public Destination getTo() { + return _to; + } + + public long getElapsed() { + return Clock.getInstance().now() - _created; + } public void waitFor(int status, long expiration) { - while (true) { - if (_cancelled) return; - long timeToWait = expiration - Clock.getInstance().now(); - if (timeToWait <= 0) { - if (_log.shouldLog(Log.WARN)) _log.warn("Expired waiting for the status [" + status + "]"); - return; - } - if (isSuccess(status) || isFailure(status)) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received a confirm (one way or the other)"); - return; - } - if (timeToWait > 5000) { - timeToWait = 5000; - } - synchronized (_lock) { - try { - _lock.wait(timeToWait); - } catch (InterruptedException ie) {} - } - } + while (true) { + if (_cancelled) return; + long timeToWait = expiration - Clock.getInstance().now(); + if (timeToWait <= 0) { + if (_log.shouldLog(Log.WARN)) _log.warn("Expired waiting for the status [" + status + "]"); + return; + } + if (isSuccess(status) || isFailure(status)) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Received a confirm (one way or the other)"); + return; + } + if (timeToWait > 5000) { + timeToWait = 5000; + } + synchronized (_lock) { + try { + _lock.wait(timeToWait); + } catch (InterruptedException ie) { + } + } + } } private boolean isSuccess(int wantedStatus) { - List received = null; - synchronized (_receivedStatus) { - received = new ArrayList(_receivedStatus); - //_receivedStatus.clear(); - } - - boolean rv = false; - - if (_log.shouldLog(Log.DEBUG)) _log.debug("isSuccess(" + wantedStatus + "): " + received); - for (Iterator iter = received.iterator(); iter.hasNext(); ) { - Integer val = (Integer)iter.next(); - int recv = val.intValue(); - switch (recv) { - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: - if (_log.shouldLog(Log.WARN)) _log.warn("Received best effort failure after " + getElapsed() + " from " + this.toString()); - rv = false; - break; - case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: - if (_log.shouldLog(Log.WARN)) _log.warn("Received guaranteed failure after " + getElapsed() + " from " + this.toString()); - rv = false; - break; - case MessageStatusMessage.STATUS_SEND_ACCEPTED: - if (wantedStatus == MessageStatusMessage.STATUS_SEND_ACCEPTED) { - return true; // if we're only looking for accepted, take it directly (don't let any GUARANTEED_* override it) - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Got accepted, but we're waiting for more from " + this.toString()); - continue; - // ignore accepted, as we want something better - } - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received best effort success after " + getElapsed() + " from " + this.toString()); - if (wantedStatus == recv) { - rv = true; - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Not guaranteed success, but best effort after " + getElapsed() + " will do... from " + this.toString()); - rv = true; - } - break; - case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received guaranteed success after " + getElapsed() + " from " + this.toString()); - // even if we're waiting for best effort success, guaranteed is good enough - rv = true; - break; - case -1: - continue; - default: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]..."); - } - } - return rv; + List received = null; + synchronized (_receivedStatus) { + received = new ArrayList(_receivedStatus); + //_receivedStatus.clear(); + } + + boolean rv = false; + + if (_log.shouldLog(Log.DEBUG)) _log.debug("isSuccess(" + wantedStatus + "): " + received); + for (Iterator iter = received.iterator(); iter.hasNext();) { + Integer val = (Integer) iter.next(); + int recv = val.intValue(); + switch (recv) { + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: + if (_log.shouldLog(Log.WARN)) + _log.warn("Received best effort failure after " + getElapsed() + " from " + + this.toString()); + rv = false; + break; + case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: + if (_log.shouldLog(Log.WARN)) + _log.warn("Received guaranteed failure after " + getElapsed() + " from " + + this.toString()); + rv = false; + break; + case MessageStatusMessage.STATUS_SEND_ACCEPTED: + if (wantedStatus == MessageStatusMessage.STATUS_SEND_ACCEPTED) { + return true; // if we're only looking for accepted, take it directly (don't let any GUARANTEED_* override it) + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Got accepted, but we're waiting for more from " + + this.toString()); + continue; + // ignore accepted, as we want something better + } + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Received best effort success after " + getElapsed() + + " from " + this.toString()); + if (wantedStatus == recv) { + rv = true; + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Not guaranteed success, but best effort after " + + getElapsed() + " will do... from " + this.toString()); + rv = true; + } + break; + case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Received guaranteed success after " + getElapsed() + " from " + + this.toString()); + // even if we're waiting for best effort success, guaranteed is good enough + rv = true; + break; + case -1: + continue; + default: + if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]..."); + } + } + return rv; } + private boolean isFailure(int wantedStatus) { - List received = null; - synchronized (_receivedStatus) { - received = new ArrayList(_receivedStatus); - //_receivedStatus.clear(); - } - boolean rv = false; - - if (_log.shouldLog(Log.DEBUG)) _log.debug("isFailure(" + wantedStatus + "): " + received); - for (Iterator iter = received.iterator(); iter.hasNext(); ) { - Integer val = (Integer)iter.next(); - int recv = val.intValue(); - switch (recv) { - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: - if (_log.shouldLog(Log.DEBUG)) _log.warn("Received best effort failure after " + getElapsed() + " from " + this.toString()); - rv = true; - break; - case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: - if (_log.shouldLog(Log.DEBUG)) _log.warn("Received guaranteed failure after " + getElapsed() + " from " + this.toString()); - rv = true; - break; - case MessageStatusMessage.STATUS_SEND_ACCEPTED: - if (wantedStatus == MessageStatusMessage.STATUS_SEND_ACCEPTED) { - rv = false; - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Got accepted, but we're waiting for more from " + this.toString()); - continue; - // ignore accepted, as we want something better - } - break; - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received best effort success after " + getElapsed() + " from " + this.toString()); - if (wantedStatus == recv) { - rv = false; - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Not guaranteed success, but best effort after " + getElapsed() + " will do... from " + this.toString()); - rv = false; - } - break; - case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received guaranteed success after " + getElapsed() + " from " + this.toString()); - // even if we're waiting for best effort success, guaranteed is good enough - rv = false; - break; - case -1: - continue; - default: - if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]..."); - } - } - return rv; + List received = null; + synchronized (_receivedStatus) { + received = new ArrayList(_receivedStatus); + //_receivedStatus.clear(); + } + boolean rv = false; + + if (_log.shouldLog(Log.DEBUG)) _log.debug("isFailure(" + wantedStatus + "): " + received); + for (Iterator iter = received.iterator(); iter.hasNext();) { + Integer val = (Integer) iter.next(); + int recv = val.intValue(); + switch (recv) { + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: + if (_log.shouldLog(Log.DEBUG)) + _log.warn("Received best effort failure after " + getElapsed() + " from " + + this.toString()); + rv = true; + break; + case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: + if (_log.shouldLog(Log.DEBUG)) + _log.warn("Received guaranteed failure after " + getElapsed() + " from " + + this.toString()); + rv = true; + break; + case MessageStatusMessage.STATUS_SEND_ACCEPTED: + if (wantedStatus == MessageStatusMessage.STATUS_SEND_ACCEPTED) { + rv = false; + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Got accepted, but we're waiting for more from " + + this.toString()); + continue; + // ignore accepted, as we want something better + } + break; + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Received best effort success after " + getElapsed() + + " from " + this.toString()); + if (wantedStatus == recv) { + rv = false; + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Not guaranteed success, but best effort after " + + getElapsed() + " will do... from " + this.toString()); + rv = false; + } + break; + case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Received guaranteed success after " + getElapsed() + " from " + + this.toString()); + // even if we're waiting for best effort success, guaranteed is good enough + rv = false; + break; + case -1: + continue; + default: + if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]..."); + } + } + return rv; } /** true if the given status (or an equivilant) was received */ public boolean received(int status) { - return isSuccess(status); + return isSuccess(status); } + public void cancel() { - _cancelled = true; - synchronized (_lock) { - _lock.notifyAll(); - } + _cancelled = true; + synchronized (_lock) { + _lock.notifyAll(); + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/MessageStatusMessageHandler.java b/core/java/src/net/i2p/client/MessageStatusMessageHandler.java index df9929f8469c9ee979e8b438121e7bff9884ce19..a5d1c00ad890b3cd4d471e47ebf0e7a538f3d51b 100644 --- a/core/java/src/net/i2p/client/MessageStatusMessageHandler.java +++ b/core/java/src/net/i2p/client/MessageStatusMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,7 +9,9 @@ package net.i2p.client; * */ -import net.i2p.data.i2cp.*; +import net.i2p.data.i2cp.I2CPMessage; +import net.i2p.data.i2cp.MessageStatusMessage; +import net.i2p.data.i2cp.ReceiveMessageBeginMessage; /** * Handle I2CP MessageStatusMessages from the router. This currently only takes @@ -21,42 +24,44 @@ class MessageStatusMessageHandler extends HandlerImpl { public MessageStatusMessageHandler() { super(MessageStatusMessage.MESSAGE_TYPE); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { - boolean skipStatus = true; - if (I2PClient.PROP_RELIABILITY_GUARANTEED.equals(session.getOptions().getProperty( - I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT))) - skipStatus = false; + boolean skipStatus = true; + if (I2PClient.PROP_RELIABILITY_GUARANTEED.equals(session.getOptions() + .getProperty(I2PClient.PROP_RELIABILITY, + I2PClient.PROP_RELIABILITY_BEST_EFFORT))) + skipStatus = false; _log.debug("Handle message " + message); - MessageStatusMessage msg = (MessageStatusMessage)message; - switch (msg.getStatus()) { - case MessageStatusMessage.STATUS_AVAILABLE: - ReceiveMessageBeginMessage m = new ReceiveMessageBeginMessage(); - m.setMessageId(msg.getMessageId()); - m.setSessionId(msg.getSessionId()); - try { - session.sendMessage(m); - } catch (I2PSessionException ise) { - _log.error("Error asking for the message", ise); - } - return; - case MessageStatusMessage.STATUS_SEND_ACCEPTED: - session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); - // noop - return; - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: - case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: - _log.info("Message delivery succeeded for message " + msg.getMessageId()); - //if (!skipStatus) - session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); - return; - case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: - case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: - _log.info("Message delivery FAILED for message " + msg.getMessageId()); - //if (!skipStatus) - session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); - return; - default: - _log.error("Invalid message delivery status received: " + msg.getStatus()); - } + MessageStatusMessage msg = (MessageStatusMessage) message; + switch (msg.getStatus()) { + case MessageStatusMessage.STATUS_AVAILABLE: + ReceiveMessageBeginMessage m = new ReceiveMessageBeginMessage(); + m.setMessageId(msg.getMessageId()); + m.setSessionId(msg.getSessionId()); + try { + session.sendMessage(m); + } catch (I2PSessionException ise) { + _log.error("Error asking for the message", ise); + } + return; + case MessageStatusMessage.STATUS_SEND_ACCEPTED: + session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); + // noop + return; + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: + case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: + _log.info("Message delivery succeeded for message " + msg.getMessageId()); + //if (!skipStatus) + session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); + return; + case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE: + case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE: + _log.info("Message delivery FAILED for message " + msg.getMessageId()); + //if (!skipStatus) + session.receiveStatus(msg.getMessageId().getMessageId(), msg.getNonce(), msg.getStatus()); + return; + default: + _log.error("Invalid message delivery status received: " + msg.getStatus()); + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java index a10432f62220a215fc6f2d1426af6d7ccfafb891..7cc0c8690f70a1561d1278a71d991e6f9df79bc0 100644 --- a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java +++ b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -33,91 +34,100 @@ import net.i2p.util.Log; class RequestLeaseSetMessageHandler extends HandlerImpl { private final static Log _log = new Log(RequestLeaseSetMessageHandler.class); private Map _existingLeaseSets; - + public RequestLeaseSetMessageHandler() { super(RequestLeaseSetMessage.MESSAGE_TYPE); - _existingLeaseSets = new HashMap(32); + _existingLeaseSets = new HashMap(32); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { _log.debug("Handle message " + message); - RequestLeaseSetMessage msg = (RequestLeaseSetMessage)message; - LeaseSet leaseSet = new LeaseSet(); - for (int i = 0; i < msg.getEndpoints(); i++) { - Lease lease = new Lease(); - lease.setRouterIdentity(msg.getRouter(i)); - lease.setTunnelId(msg.getTunnelId(i)); - lease.setEndDate(msg.getEndDate()); - //lease.setStartDate(msg.getStartDate()); - leaseSet.addLease(lease); - } - // also, if this session is connected to multiple routers, include other leases here - leaseSet.setDestination(session.getMyDestination()); - - // reuse the old keys for the client - LeaseInfo li = null; - synchronized (_existingLeaseSets) { - if (_existingLeaseSets.containsKey(session.getMyDestination())) - li = (LeaseInfo)_existingLeaseSets.get(session.getMyDestination()); - } - if (li == null) { - li = new LeaseInfo(session.getMyDestination()); - synchronized (_existingLeaseSets) { - _existingLeaseSets.put(session.getMyDestination(), li); - } - _log.debug("Creating new leaseInfo keys", new Exception("new leaseInfo keys")); - } else { - _log.debug("Caching the old leaseInfo keys", new Exception("cached! w00t")); - } - - leaseSet.setEncryptionKey(li.getPublicKey()); - leaseSet.setSigningKey(li.getSigningPublicKey()); + RequestLeaseSetMessage msg = (RequestLeaseSetMessage) message; + LeaseSet leaseSet = new LeaseSet(); + for (int i = 0; i < msg.getEndpoints(); i++) { + Lease lease = new Lease(); + lease.setRouterIdentity(msg.getRouter(i)); + lease.setTunnelId(msg.getTunnelId(i)); + lease.setEndDate(msg.getEndDate()); + //lease.setStartDate(msg.getStartDate()); + leaseSet.addLease(lease); + } + // also, if this session is connected to multiple routers, include other leases here + leaseSet.setDestination(session.getMyDestination()); + + // reuse the old keys for the client + LeaseInfo li = null; + synchronized (_existingLeaseSets) { + if (_existingLeaseSets.containsKey(session.getMyDestination())) + li = (LeaseInfo) _existingLeaseSets.get(session.getMyDestination()); + } + if (li == null) { + li = new LeaseInfo(session.getMyDestination()); + synchronized (_existingLeaseSets) { + _existingLeaseSets.put(session.getMyDestination(), li); + } + _log.debug("Creating new leaseInfo keys", new Exception("new leaseInfo keys")); + } else { + _log.debug("Caching the old leaseInfo keys", new Exception("cached! w00t")); + } + + leaseSet.setEncryptionKey(li.getPublicKey()); + leaseSet.setSigningKey(li.getSigningPublicKey()); try { - leaseSet.sign(session.getPrivateKey()); - session.getProducer().createLeaseSet(session, leaseSet, li.getSigningPrivateKey(), li.getPrivateKey()); - session.setLeaseSet(leaseSet); + leaseSet.sign(session.getPrivateKey()); + session.getProducer().createLeaseSet(session, leaseSet, li.getSigningPrivateKey(), li.getPrivateKey()); + session.setLeaseSet(leaseSet); } catch (DataFormatException dfe) { session.propogateError("Error signing the leaseSet", dfe); } catch (I2PSessionException ise) { session.propogateError("Error sending the signed leaseSet", ise); } } - + private static class LeaseInfo { - private PublicKey _pubKey; - private PrivateKey _privKey; - private SigningPublicKey _signingPubKey; - private SigningPrivateKey _signingPrivKey; - private Destination _dest; - - public LeaseInfo(Destination dest) { - _dest = dest; - Object encKeys[] = KeyGenerator.getInstance().generatePKIKeypair(); - Object signKeys[] = KeyGenerator.getInstance().generateSigningKeypair(); - _pubKey = (PublicKey)encKeys[0]; - _privKey = (PrivateKey)encKeys[1]; - _signingPubKey = (SigningPublicKey)signKeys[0]; - _signingPrivKey = (SigningPrivateKey)signKeys[1]; - } - public PublicKey getPublicKey() { return _pubKey; } - public PrivateKey getPrivateKey() { return _privKey; } - public SigningPublicKey getSigningPublicKey() { return _signingPubKey; } - public SigningPrivateKey getSigningPrivateKey() { return _signingPrivKey; } - - public int hashCode() { - return DataHelper.hashCode(_pubKey) + - 7*DataHelper.hashCode(_privKey) + - 7*7*DataHelper.hashCode(_signingPubKey) + - 7*7*7*DataHelper.hashCode(_signingPrivKey); - } - - public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof LeaseInfo) ) - return false; - LeaseInfo li = (LeaseInfo)obj; - return DataHelper.eq(_pubKey, li.getPublicKey()) && - DataHelper.eq(_privKey, li.getPrivateKey()) && - DataHelper.eq(_signingPubKey, li.getSigningPublicKey()) && - DataHelper.eq(_signingPrivKey, li.getSigningPrivateKey()); - } + private PublicKey _pubKey; + private PrivateKey _privKey; + private SigningPublicKey _signingPubKey; + private SigningPrivateKey _signingPrivKey; + private Destination _dest; + + public LeaseInfo(Destination dest) { + _dest = dest; + Object encKeys[] = KeyGenerator.getInstance().generatePKIKeypair(); + Object signKeys[] = KeyGenerator.getInstance().generateSigningKeypair(); + _pubKey = (PublicKey) encKeys[0]; + _privKey = (PrivateKey) encKeys[1]; + _signingPubKey = (SigningPublicKey) signKeys[0]; + _signingPrivKey = (SigningPrivateKey) signKeys[1]; + } + + public PublicKey getPublicKey() { + return _pubKey; + } + + public PrivateKey getPrivateKey() { + return _privKey; + } + + public SigningPublicKey getSigningPublicKey() { + return _signingPubKey; + } + + public SigningPrivateKey getSigningPrivateKey() { + return _signingPrivKey; + } + + public int hashCode() { + return DataHelper.hashCode(_pubKey) + 7 * DataHelper.hashCode(_privKey) + 7 * 7 + * DataHelper.hashCode(_signingPubKey) + 7 * 7 * 7 * DataHelper.hashCode(_signingPrivKey); + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof LeaseInfo)) return false; + LeaseInfo li = (LeaseInfo) obj; + return DataHelper.eq(_pubKey, li.getPublicKey()) && DataHelper.eq(_privKey, li.getPrivateKey()) + && DataHelper.eq(_signingPubKey, li.getSigningPublicKey()) + && DataHelper.eq(_signingPrivKey, li.getSigningPrivateKey()); + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/SessionStatusMessageHandler.java b/core/java/src/net/i2p/client/SessionStatusMessageHandler.java index 8f347beeb7b11d07a80cc49325e7c9a39e9f5fad..1ba8164695f1f734b576c52699404c03a196bcf3 100644 --- a/core/java/src/net/i2p/client/SessionStatusMessageHandler.java +++ b/core/java/src/net/i2p/client/SessionStatusMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,7 +9,8 @@ package net.i2p.client; * */ -import net.i2p.data.i2cp.*; +import net.i2p.data.i2cp.I2CPMessage; +import net.i2p.data.i2cp.SessionStatusMessage; /** * Handle I2CP SessionStatusMessagese from the router, updating the session as @@ -20,26 +22,27 @@ class SessionStatusMessageHandler extends HandlerImpl { public SessionStatusMessageHandler() { super(SessionStatusMessage.MESSAGE_TYPE); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { _log.debug("Handle message " + message); - SessionStatusMessage msg = (SessionStatusMessage)message; + SessionStatusMessage msg = (SessionStatusMessage) message; session.setSessionId(msg.getSessionId()); switch (msg.getStatus()) { - case SessionStatusMessage.STATUS_CREATED: - _log.info("Session created successfully"); - break; - case SessionStatusMessage.STATUS_DESTROYED: - _log.info("Session destroyed"); - session.destroySession(); - break; - case SessionStatusMessage.STATUS_INVALID: - session.destroySession(); - break; - case SessionStatusMessage.STATUS_UPDATED: - _log.info("Session status updated"); - break; - default: - _log.warn("Unknown session status sent: " + msg.getStatus()); + case SessionStatusMessage.STATUS_CREATED: + _log.info("Session created successfully"); + break; + case SessionStatusMessage.STATUS_DESTROYED: + _log.info("Session destroyed"); + session.destroySession(); + break; + case SessionStatusMessage.STATUS_INVALID: + session.destroySession(); + break; + case SessionStatusMessage.STATUS_UPDATED: + _log.info("Session status updated"); + break; + default: + _log.warn("Unknown session status sent: " + msg.getStatus()); } return; } diff --git a/core/java/src/net/i2p/client/SetDateMessageHandler.java b/core/java/src/net/i2p/client/SetDateMessageHandler.java index 11923c2a334347aa83b9f786beaaf4dbd04bba85..63ff1ae51a9fff110d325d2a594bac01f6d049a8 100644 --- a/core/java/src/net/i2p/client/SetDateMessageHandler.java +++ b/core/java/src/net/i2p/client/SetDateMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,7 +9,8 @@ package net.i2p.client; * */ -import net.i2p.data.i2cp.*; +import net.i2p.data.i2cp.I2CPMessage; +import net.i2p.data.i2cp.SetDateMessage; import net.i2p.util.Clock; /** @@ -20,10 +22,11 @@ class SetDateMessageHandler extends HandlerImpl { public SetDateMessageHandler() { super(SetDateMessage.MESSAGE_TYPE); } + public void handleMessage(I2CPMessage message, I2PSessionImpl session) { _log.debug("Handle message " + message); - SetDateMessage msg = (SetDateMessage)message; - Clock.getInstance().setNow(msg.getDate().getTime()); - session.dateUpdated(); + SetDateMessage msg = (SetDateMessage) message; + Clock.getInstance().setNow(msg.getDate().getTime()); + session.dateUpdated(); } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/TestClient.java b/core/java/src/net/i2p/client/TestClient.java index ba32c050af78aaac4bff03779977039bf4522107..61a67f3b9f952f2bc657947e9e94aaa80d428fe3 100644 --- a/core/java/src/net/i2p/client/TestClient.java +++ b/core/java/src/net/i2p/client/TestClient.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -30,9 +31,9 @@ public class TestClient implements I2PSessionListener { private static Destination _dest1; private static Destination _dest2; private boolean _stillRunning; - + public void runTest(String keyfile, boolean isDest1) { - _stillRunning = true; + _stillRunning = true; try { I2PClient client = I2PClientFactory.createClient(); File file = new File(keyfile); @@ -54,68 +55,91 @@ public class TestClient implements I2PSessionListener { options.setProperty(I2PClient.PROP_TCP_PORT, System.getProperty(I2PClient.PROP_TCP_PORT)); I2PSession session = client.createSession(new FileInputStream(file), options); - session.setSessionListener(this); - _log.debug("Before connect..."); + session.setSessionListener(this); + _log.debug("Before connect..."); session.connect(); - _log.debug("Connected"); + _log.debug("Connected"); // wait until the other one is connected - while ( (_dest1 == null) || (_dest2 == null) ) - try { Thread.sleep(500); } catch (InterruptedException ie) {} - - if (isDest1) { - Destination otherD = (isDest1 ? _dest2 : _dest1); - boolean accepted = session.sendMessage(otherD, ("Hello other side. I am" + (isDest1 ? "" : " NOT") + " dest1").getBytes()); - } else { - while (_stillRunning) { - try { - _log.debug("waiting for a message..."); - Thread.sleep(1000); - } catch (InterruptedException ie) {} - } - try { Thread.sleep(5000); } catch (InterruptedException ie) {} - System.exit(0); - } + while ((_dest1 == null) || (_dest2 == null)) + try { + Thread.sleep(500); + } catch (InterruptedException ie) { + } + + if (isDest1) { + Destination otherD = (isDest1 ? _dest2 : _dest1); + boolean accepted = session + .sendMessage( + otherD, + ("Hello other side. I am" + (isDest1 ? "" : " NOT") + " dest1") + .getBytes()); + } else { + while (_stillRunning) { + try { + _log.debug("waiting for a message..."); + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + System.exit(0); + } //session.destroySession(); } catch (Exception e) { _log.error("Error running the test for isDest1? " + isDest1, e); } } - + public static void main(String args[]) { - doTest(); - try { Thread.sleep(30*1000); } catch (InterruptedException ie) {} + doTest(); + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException ie) { + } } + static void doTest() { - Thread test1 = new I2PThread(new Runnable() { public void run() { (new TestClient()).runTest("test1.keyfile", true); } } ); - Thread test2 = new I2PThread(new Runnable() { public void run() { (new TestClient()).runTest("test2.keyfile", false); } } ); + Thread test1 = new I2PThread(new Runnable() { + public void run() { + (new TestClient()).runTest("test1.keyfile", true); + } + }); + Thread test2 = new I2PThread(new Runnable() { + public void run() { + (new TestClient()).runTest("test2.keyfile", false); + } + }); test1.start(); test2.start(); _log.debug("Test threads started"); } - + public void disconnected(I2PSession session) { - _log.debug("Disconnected"); - _stillRunning = false; + _log.debug("Disconnected"); + _stillRunning = false; } - + public void errorOccurred(I2PSession session, String message, Throwable error) { - _log.debug("Error occurred: " + message, error); + _log.debug("Error occurred: " + message, error); } - + public void messageAvailable(I2PSession session, int msgId, long size) { - _log.debug("Message available for us! id = " + msgId + " of size " + size); - try { - byte msg[] = session.receiveMessage(msgId); - _log.debug("Content of message " + msgId+ ":\n"+new String(msg)); - _stillRunning = false; - } catch (I2PSessionException ise) { - _log.error("Error fetching available message", ise); - } + _log.debug("Message available for us! id = " + msgId + " of size " + size); + try { + byte msg[] = session.receiveMessage(msgId); + _log.debug("Content of message " + msgId + ":\n" + new String(msg)); + _stillRunning = false; + } catch (I2PSessionException ise) { + _log.error("Error fetching available message", ise); + } } - + public void reportAbuse(I2PSession session, int severity) { - _log.debug("Abuse reported of severity " + severity); + _log.debug("Abuse reported of severity " + severity); } - -} + +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/TestServer.java b/core/java/src/net/i2p/client/TestServer.java index aea8b0a99b63cd25c92209dbca5553299e9e7e90..b238efa38bccf7516f80a72b80313918e9b27f24 100644 --- a/core/java/src/net/i2p/client/TestServer.java +++ b/core/java/src/net/i2p/client/TestServer.java @@ -1,4 +1,5 @@ package net.i2p.client; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -27,9 +28,11 @@ public class TestServer implements Runnable { private final static Log _log = new Log(TestServer.class); private ServerSocket _socket; public static int LISTEN_PORT = 7654; - - protected void setPort(int port) { LISTEN_PORT = port; } - + + protected void setPort(int port) { + LISTEN_PORT = port; + } + /** * Start up the socket listener, listens for connections, and * fires those connections off via {@link #runConnection runConnection}. @@ -38,47 +41,49 @@ public class TestServer implements Runnable { * */ public void runServer() { - try { - _socket = new ServerSocket(LISTEN_PORT); - } catch (IOException ioe) { - _log.error("Error listening", ioe); - return; - } - while (true) { - try { - Socket socket = _socket.accept(); - runConnection(socket); - } catch (IOException ioe) { - _log.error("Server error accepting", ioe); - } - } + try { + _socket = new ServerSocket(LISTEN_PORT); + } catch (IOException ioe) { + _log.error("Error listening", ioe); + return; + } + while (true) { + try { + Socket socket = _socket.accept(); + runConnection(socket); + } catch (IOException ioe) { + _log.error("Server error accepting", ioe); + } + } } - + /** * Handle the connection by passing it off to a ConnectionRunner * */ protected void runConnection(Socket socket) throws IOException { - ConnectionRunner runner = new ConnectionRunner(socket); - runner.doYourThing(); + ConnectionRunner runner = new ConnectionRunner(socket); + runner.doYourThing(); } - - public void run() { runServer(); } - + + public void run() { + runServer(); + } + /** * Fire up the router - */ + */ public static void main(String args[]) { - if (args.length == 1) { - } else if (args.length == 2) { - try { - LISTEN_PORT = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - _log.error("Invalid port number specified (" + args[1] + "), using " + LISTEN_PORT, nfe); - } - } - TestServer server = new TestServer(); - Thread t = new I2PThread(server); - t.start(); + if (args.length == 1) { + } else if (args.length == 2) { + try { + LISTEN_PORT = Integer.parseInt(args[1]); + } catch (NumberFormatException nfe) { + _log.error("Invalid port number specified (" + args[1] + "), using " + LISTEN_PORT, nfe); + } + } + TestServer server = new TestServer(); + Thread t = new I2PThread(server); + t.start(); } } \ No newline at end of file diff --git a/core/java/src/net/i2p/client/naming/DummyNamingService.java b/core/java/src/net/i2p/client/naming/DummyNamingService.java index ea3bac13d7f0424a51ca0e4242af5f9889737e22..1bd18cd783ef6d68d7deba06be705e9a17533aac 100644 --- a/core/java/src/net/i2p/client/naming/DummyNamingService.java +++ b/core/java/src/net/i2p/client/naming/DummyNamingService.java @@ -1,23 +1,23 @@ -/* - * free (adj.): unencumbered; not under the control of others - * Written by mihi in 2004 and released into the public domain - * with no warranty of any kind, either expressed or implied. - * It probably won't make your computer catch on fire, or eat - * your children, but it might. Use at your own risk. - */ -package net.i2p.client.naming; - -import net.i2p.data.Destination; - -/** - * A Dummy naming service that can only handle base64 destinations. - */ -class DummyNamingService extends NamingService { - public Destination lookup(String hostname) { - return lookupBase64(hostname); - } - - public String reverseLookup(Destination dest) { - return null; - } -} +/* + * free (adj.): unencumbered; not under the control of others + * Written by mihi in 2004 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + */ +package net.i2p.client.naming; + +import net.i2p.data.Destination; + +/** + * A Dummy naming service that can only handle base64 destinations. + */ +class DummyNamingService extends NamingService { + public Destination lookup(String hostname) { + return lookupBase64(hostname); + } + + public String reverseLookup(Destination dest) { + return null; + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java index 21e5f601cfc2024b19d883cb82c157393e2b1106..636db1f0d2b1e2e60ce8d077eff4a496c0ae11b9 100644 --- a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java +++ b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java @@ -25,42 +25,44 @@ public class HostsTxtNamingService extends NamingService { * given file for hostname=destKey values when resolving names */ public final static String PROP_HOSTS_FILE = "i2p.hostsfile"; - + /** default hosts.txt filename */ public final static String DEFAULT_HOSTS_FILE = "hosts.txt"; private final static Log _log = new Log(HostsTxtNamingService.class); - + 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=System.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) {} - } - 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); + // Try to look it up in hosts.txt + // Reload file each time to catch changes. + // (and it's easier :P + String hostsfile = System.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) { + } + } + 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); } - + public String reverseLookup(Destination dest) { - return null; - } -} + return null; + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/client/naming/NamingService.java b/core/java/src/net/i2p/client/naming/NamingService.java index 2a9704569b1865c2eb6c2627f8311f9e695255f9..904d1e70929e2464ce46a0bc0d2de06194a12bb0 100644 --- a/core/java/src/net/i2p/client/naming/NamingService.java +++ b/core/java/src/net/i2p/client/naming/NamingService.java @@ -19,9 +19,8 @@ public abstract class NamingService { private final static Log _log = new Log(NamingService.class); private static final String PROP_IMPL = "i2p.naming.impl"; - private static final String DEFAULT_IMPL= - "net.i2p.client.naming.HostsTxtNamingService"; - + private static final String DEFAULT_IMPL = "net.i2p.client.naming.HostsTxtNamingService"; + /** * Look up a host name. * @return the Destination for this host name, or @@ -43,19 +42,18 @@ public abstract class NamingService { * implementations. */ protected Destination lookupBase64(String hostname) { - try { - Destination result = new Destination(); - result.fromBase64(hostname); - return result; - } catch (DataFormatException dfe) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Error translating [" + hostname + "]", dfe); - return null; - } + try { + Destination result = new Destination(); + result.fromBase64(hostname); + return result; + } catch (DataFormatException dfe) { + if (_log.shouldLog(Log.WARN)) _log.warn("Error translating [" + hostname + "]", dfe); + return null; + } } private static NamingService instance = null; - + /** * Get a naming service instance. This method ensures that there * will be only one naming service instance (singleton) as well as @@ -63,16 +61,15 @@ public abstract class NamingService { * property. */ public static synchronized NamingService getInstance() { - if (instance == null) { - String impl = System.getProperty(PROP_IMPL, - DEFAULT_IMPL); - try { - instance = (NamingService) Class.forName(impl).newInstance(); - } catch (Exception ex) { - _log.error("Cannot loadNaming service implementation", ex); - instance = new DummyNamingService(); // fallback - } - } - return instance; + if (instance == null) { + String impl = System.getProperty(PROP_IMPL, DEFAULT_IMPL); + try { + instance = (NamingService) Class.forName(impl).newInstance(); + } catch (Exception ex) { + _log.error("Cannot loadNaming service implementation", ex); + instance = new DummyNamingService(); // fallback + } + } + return instance; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/AESEngine.java b/core/java/src/net/i2p/crypto/AESEngine.java index b6b87d81121a726b757b4465bf13799a97c545e8..a96870d15f86e9c8343f9657469b1348e7d7d70d 100644 --- a/core/java/src/net/i2p/crypto/AESEngine.java +++ b/core/java/src/net/i2p/crypto/AESEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,137 +9,138 @@ package net.i2p.crypto; * */ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import net.i2p.data.DataFormatException; -import net.i2p.data.SessionKey; import net.i2p.data.DataHelper; import net.i2p.data.Hash; +import net.i2p.data.SessionKey; import net.i2p.util.Log; import net.i2p.util.RandomSource; -import java.io.IOException; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; - /** * Wrapper singleton for AES cypher operation. * * @author jrandom - */ + */ public class AESEngine { private final static Log _log = new Log(AESEngine.class); private static AESEngine _engine; static { - if ("off".equals(System.getProperty("i2p.encryption", "on"))) - _engine = new AESEngine(); - else - _engine = new CryptixAESEngine(); + if ("off".equals(System.getProperty("i2p.encryption", "on"))) + _engine = new AESEngine(); + else + _engine = new CryptixAESEngine(); + } + + public static AESEngine getInstance() { + return _engine; } - public static AESEngine getInstance() { return _engine; } /** Encrypt the payload with the session key * @param payload data to be encrypted * @param sessionKey private esession key to encrypt to * @param initializationVector IV for CBC * @return encrypted data - */ + */ public byte[] encrypt(byte payload[], SessionKey sessionKey, byte initializationVector[]) { - if ( (initializationVector == null) || (payload == null) || (sessionKey == null) || (initializationVector.length != 16) ) - return null; - - byte cyphertext[] = new byte[payload.length+(16-(payload.length%16))]; - _log.warn("Warning: AES is disabled"); - System.arraycopy(payload, 0, cyphertext, 0, payload.length); - return cyphertext; + if ((initializationVector == null) || (payload == null) || (sessionKey == null) + || (initializationVector.length != 16)) return null; + + byte cyphertext[] = new byte[payload.length + (16 - (payload.length % 16))]; + _log.warn("Warning: AES is disabled"); + System.arraycopy(payload, 0, cyphertext, 0, payload.length); + return cyphertext; } - + 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 = SHA256Generator.getInstance().calculateHash(sessionKey.getData()); - try { - h.writeBytes(baos); - DataHelper.writeLong(baos, 4, payload.length); - baos.write(payload); - byte tv[] = baos.toByteArray(); - baos.write(ElGamalAESEngine.getPadding(tv.length, paddedSize)); - } catch (IOException ioe) { - _log.error("Error writing data", ioe); - return null; - } catch (DataFormatException dfe) { - _log.error("Error writing data", dfe); - return null; - } - return encrypt(baos.toByteArray(), sessionKey, iv); + if ((iv == null) || (payload == null) || (sessionKey == null) || (iv.length != 16)) return null; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(paddedSize + 64); + Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData()); + try { + h.writeBytes(baos); + DataHelper.writeLong(baos, 4, payload.length); + baos.write(payload); + byte tv[] = baos.toByteArray(); + baos.write(ElGamalAESEngine.getPadding(tv.length, paddedSize)); + } catch (IOException ioe) { + _log.error("Error writing data", ioe); + return null; + } catch (DataFormatException dfe) { + _log.error("Error writing data", dfe); + return null; + } + return encrypt(baos.toByteArray(), sessionKey, iv); } 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); - if (decr == null) { - _log.error("Error decrypting the data - payload " + payload.length + " decrypted to null"); - return null; - } - ByteArrayInputStream bais = new ByteArrayInputStream(decr); - Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData()); - try { - Hash rh = new Hash(); - rh.readBytes(bais); - if (!h.equals(rh)) { - _log.error("Hash does not match [key=" + sessionKey + " / iv =" + DataHelper.toString(iv, iv.length) + "]", new Exception("Hash error")); - return null; - } - long len = DataHelper.readLong(bais, 4); - byte data[] = new byte[(int)len]; - int read = bais.read(data); - if (read != len) { - _log.error("Not enough to read"); - return null; - } - return data; - } catch (IOException ioe) { - _log.error("Error writing data", ioe); - return null; - } catch (DataFormatException dfe) { - _log.error("Error writing data", dfe); - return null; - } + if ((iv == null) || (payload == null) || (sessionKey == null) || (iv.length != 16)) return null; + + byte decr[] = decrypt(payload, sessionKey, iv); + if (decr == null) { + _log.error("Error decrypting the data - payload " + payload.length + " decrypted to null"); + return null; + } + ByteArrayInputStream bais = new ByteArrayInputStream(decr); + Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData()); + try { + Hash rh = new Hash(); + rh.readBytes(bais); + if (!h.equals(rh)) { + _log.error("Hash does not match [key=" + sessionKey + " / iv =" + DataHelper.toString(iv, iv.length) + + "]", new Exception("Hash error")); + return null; + } + long len = DataHelper.readLong(bais, 4); + byte data[] = new byte[(int) len]; + int read = bais.read(data); + if (read != len) { + _log.error("Not enough to read"); + return null; + } + return data; + } catch (IOException ioe) { + _log.error("Error writing data", ioe); + return null; + } catch (DataFormatException dfe) { + _log.error("Error writing data", dfe); + return null; + } } - /** 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]; - _log.warn("Warning: AES is disabled"); - return cyphertext; + */ + 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]; + _log.warn("Warning: AES is disabled"); + return cyphertext; } - + public static void main(String args[]) { - SessionKey key = KeyGenerator.getInstance().generateSessionKey(); - byte iv[] = new byte[16]; - RandomSource.getInstance().nextBytes(iv); - - byte sbuf[] = new byte[16]; - RandomSource.getInstance().nextBytes(sbuf); - byte se[] = AESEngine.getInstance().encrypt(sbuf, key, iv); - byte sd[] = AESEngine.getInstance().decrypt(se, key, iv); - _log.debug("Short test: " + DataHelper.eq(sd, sbuf)); - - byte lbuf[] = new byte[1024]; - RandomSource.getInstance().nextBytes(sbuf); - byte le[] = AESEngine.getInstance().safeEncrypt(lbuf, key, iv, 2048); - byte ld[] = AESEngine.getInstance().safeDecrypt(le, key, iv); - _log.debug("Long test: " + DataHelper.eq(ld, lbuf)); + SessionKey key = KeyGenerator.getInstance().generateSessionKey(); + byte iv[] = new byte[16]; + RandomSource.getInstance().nextBytes(iv); + + byte sbuf[] = new byte[16]; + RandomSource.getInstance().nextBytes(sbuf); + byte se[] = AESEngine.getInstance().encrypt(sbuf, key, iv); + byte sd[] = AESEngine.getInstance().decrypt(se, key, iv); + _log.debug("Short test: " + DataHelper.eq(sd, sbuf)); + + byte lbuf[] = new byte[1024]; + RandomSource.getInstance().nextBytes(sbuf); + byte le[] = AESEngine.getInstance().safeEncrypt(lbuf, key, iv, 2048); + byte ld[] = AESEngine.getInstance().safeDecrypt(le, key, iv); + _log.debug("Long test: " + DataHelper.eq(ld, lbuf)); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/AESInputStream.java b/core/java/src/net/i2p/crypto/AESInputStream.java index dd95a132b2267296d2b62d7cf6ffae4324e1883d..008b4576de88235abd3b02236894d14aadd40879 100644 --- a/core/java/src/net/i2p/crypto/AESInputStream.java +++ b/core/java/src/net/i2p/crypto/AESInputStream.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -20,8 +21,8 @@ import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.SessionKey; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; /** @@ -45,106 +46,118 @@ public class AESInputStream extends FilterInputStream { private long _cumulativePaddingStripped; // how many bytes have been stripped private ByteArrayOutputStream _encryptedBuf; // read from the stream but not yet decrypted - private List _readyBuf; // list of Bytes ready to be consumed, where index 0 is the first - + private List _readyBuf; // list of Bytes ready to be consumed, where index 0 is the first + private final static int BLOCK_SIZE = CryptixRijndael_Algorithm._BLOCK_SIZE; private final static int READ_SIZE = BLOCK_SIZE; - private final static int DECRYPT_SIZE = BLOCK_SIZE-1; - + private final static int DECRYPT_SIZE = BLOCK_SIZE - 1; + public AESInputStream(InputStream source, SessionKey key, byte iv[]) { - super(source); - _key = key; - _lastBlock = new byte[BLOCK_SIZE]; - System.arraycopy(iv, 0, _lastBlock, 0, BLOCK_SIZE); - _encryptedBuf = new ByteArrayOutputStream(BLOCK_SIZE); - _readyBuf = new LinkedList(); - _cumulativePaddingStripped = 0; - _eofFound = false; + super(source); + _key = key; + _lastBlock = new byte[BLOCK_SIZE]; + System.arraycopy(iv, 0, _lastBlock, 0, BLOCK_SIZE); + _encryptedBuf = new ByteArrayOutputStream(BLOCK_SIZE); + _readyBuf = new LinkedList(); + _cumulativePaddingStripped = 0; + _eofFound = false; } - - public int read() throws IOException { - while ( (!_eofFound) && (_readyBuf.size() <= 0) ) { - refill(READ_SIZE); - } - Integer nval = getNext(); - if (nval != null) { - return nval.intValue(); - } else { - //_log.debug("No byte available. eof? " + _eofFound); - if (_eofFound) - return -1; - else { - throw new IOException("Not EOF, but none available? " + _readyBuf.size() + "/" + _encryptedBuf.size() + "/" + _cumulativeRead + "... impossible"); - } - } + + public int read() throws IOException { + while ((!_eofFound) && (_readyBuf.size() <= 0)) { + refill(READ_SIZE); + } + Integer nval = getNext(); + if (nval != null) { + return nval.intValue(); + } else { + //_log.debug("No byte available. eof? " + _eofFound); + if (_eofFound) + return -1; + else { + throw new IOException("Not EOF, but none available? " + _readyBuf.size() + "/" + _encryptedBuf.size() + + "/" + _cumulativeRead + "... impossible"); + } + } } - + public int read(byte dest[]) throws IOException { - for (int i = 0; i < dest.length; i++) { - int val = read(); - if (val == -1) { - // no more to read... can they expect more? - if (_eofFound && (i == 0)) - return -1; - else - return i; - } else { - dest[i] = (byte)val; - } - } - _log.debug("Read the full buffer of size " + dest.length); - return dest.length; + for (int i = 0; i < dest.length; i++) { + int val = read(); + if (val == -1) { + // no more to read... can they expect more? + if (_eofFound && (i == 0)) + return -1; + else + return i; + } else { + dest[i] = (byte) val; + } + } + _log.debug("Read the full buffer of size " + dest.length); + return dest.length; } - - public int read(byte dest[], int off, int len) throws IOException { - byte buf[] = new byte[len]; - int read = read(buf); - if (read == -1) - return -1; - System.arraycopy(buf, 0, dest, off, read); - return read; + + public int read(byte dest[], int off, int len) throws IOException { + byte buf[] = new byte[len]; + int read = read(buf); + if (read == -1) return -1; + System.arraycopy(buf, 0, dest, off, read); + return read; + } + + public long skip(long numBytes) throws IOException { + for (long l = 0; l < numBytes; l++) { + int val = read(); + if (val == -1) return l; + } + return numBytes; } - public long skip(long numBytes) throws IOException { - for (long l = 0; l < numBytes; l++) { - int val = read(); - if (val == -1) - return l; - } - return numBytes; + + public int available() throws IOException { + return _readyBuf.size(); } - - public int available() throws IOException { return _readyBuf.size(); } - public void close() throws IOException { - //_log.debug("We have " + _encryptedBuf.size() + " available to decrypt... doing so"); - //decrypt(); - //byte buf[] = new byte[_readyBuf.size()]; - //for (int i = 0; i < buf.length; i++) - // buf[i] = ((Integer)_readyBuf.get(i)).byteValue(); - //_log.debug("After decrypt: readyBuf.size: " + _readyBuf.size() + "\n val:\t" + Base64.encode(buf)); - int ready = _readyBuf.size(); - int encrypted = _readyBuf.size(); - _readyBuf.clear(); - _encryptedBuf.reset(); - in.close(); - _log.debug("Cumulative bytes read from source/decrypted/stripped: " + _cumulativeRead + "/"+_cumulativePrepared +"/" + _cumulativePaddingStripped + "] remaining [" + ready + " ready, " + encrypted + " still encrypted]"); + + public void close() throws IOException { + //_log.debug("We have " + _encryptedBuf.size() + " available to decrypt... doing so"); + //decrypt(); + //byte buf[] = new byte[_readyBuf.size()]; + //for (int i = 0; i < buf.length; i++) + // buf[i] = ((Integer)_readyBuf.get(i)).byteValue(); + //_log.debug("After decrypt: readyBuf.size: " + _readyBuf.size() + "\n val:\t" + Base64.encode(buf)); + int ready = _readyBuf.size(); + int encrypted = _readyBuf.size(); + _readyBuf.clear(); + _encryptedBuf.reset(); + in.close(); + _log.debug("Cumulative bytes read from source/decrypted/stripped: " + _cumulativeRead + "/" + + _cumulativePrepared + "/" + _cumulativePaddingStripped + "] remaining [" + ready + " ready, " + + encrypted + " still encrypted]"); + } + + public void mark(int readLimit) { + } + + public void reset() throws IOException { + throw new IOException("Reset not supported"); + } + + public boolean markSupported() { + return false; } - public void mark(int readLimit) {} - public void reset() throws IOException { throw new IOException("Reset not supported"); } - public boolean markSupported() { return false; } - /** * Retrieve the next ready byte, or null if no bytes are ready. this does not refill or block * */ private Integer getNext() { - if (_readyBuf.size() > 0) { - return (Integer)_readyBuf.remove(0); - } else { - return null; - } + if (_readyBuf.size() > 0) { + return (Integer) _readyBuf.remove(0); + } else { + return null; + } } - + /** * Read at least one new byte from the underlying stream, and up to max new bytes, * but not necessarily enough for a new decrypted block. This blocks until at least @@ -152,32 +165,32 @@ public class AESInputStream extends FilterInputStream { * */ private void refill(int max) throws IOException { - if (!_eofFound) { - byte buf[] = new byte[max]; - int read = in.read(buf); - if (read == -1) { - _eofFound = true; - } else if (read > 0) { - //_log.debug("Read from the source stream " + read + " bytes"); - _cumulativeRead += read; - _encryptedBuf.write(buf, 0, read); - } - } - if (false) return; // true to keep the data for decrypt/display on close - if (_encryptedBuf.size() > 0) { - if (_encryptedBuf.size() >= DECRYPT_SIZE) { - //_log.debug("We have " + _encryptedBuf.size() + " available to decrypt... doing so"); - decrypt(); - //if (_encryptedBuf.size() > 0) - // _log.debug("Bytes left in the encrypted buffer after decrypt: " + _encryptedBuf.size()); - } else { - if (_eofFound) { - //_log.debug("EOF and not enough bytes to decrypt [size = " + _encryptedBuf.size() + " totalCumulative: " + _cumulativeRead + "/"+_cumulativePrepared +"]!"); - } else { - //_log.debug("Not enough bytes to decrypt [size = " + _encryptedBuf.size() + " totalCumulative: " + _cumulativeRead + "/"+_cumulativePrepared +"]"); - } - } - } + if (!_eofFound) { + byte buf[] = new byte[max]; + int read = in.read(buf); + if (read == -1) { + _eofFound = true; + } else if (read > 0) { + //_log.debug("Read from the source stream " + read + " bytes"); + _cumulativeRead += read; + _encryptedBuf.write(buf, 0, read); + } + } + if (false) return; // true to keep the data for decrypt/display on close + if (_encryptedBuf.size() > 0) { + if (_encryptedBuf.size() >= DECRYPT_SIZE) { + //_log.debug("We have " + _encryptedBuf.size() + " available to decrypt... doing so"); + decrypt(); + //if (_encryptedBuf.size() > 0) + // _log.debug("Bytes left in the encrypted buffer after decrypt: " + _encryptedBuf.size()); + } else { + if (_eofFound) { + //_log.debug("EOF and not enough bytes to decrypt [size = " + _encryptedBuf.size() + " totalCumulative: " + _cumulativeRead + "/"+_cumulativePrepared +"]!"); + } else { + //_log.debug("Not enough bytes to decrypt [size = " + _encryptedBuf.size() + " totalCumulative: " + _cumulativeRead + "/"+_cumulativePrepared +"]"); + } + } + } } /** @@ -186,52 +199,59 @@ public class AESInputStream extends FilterInputStream { * */ private void decrypt() throws IOException { - byte encrypted[] = _encryptedBuf.toByteArray(); - _encryptedBuf.reset(); - - if ( (encrypted == null) || (encrypted.length <= 0) ) - throw new IOException("Error decrypting - no data to decrypt"); - - int numBlocks = encrypted.length / BLOCK_SIZE; - if ( (encrypted.length % BLOCK_SIZE) != 0) { - // it was flushed / handled off the BLOCK_SIZE segments, so put the excess - // back into the _encryptedBuf for later handling - int trailing = encrypted.length % BLOCK_SIZE; - _encryptedBuf.write(encrypted, encrypted.length - trailing, trailing); - byte nencrypted[] = new byte[encrypted.length - trailing]; - System.arraycopy(encrypted, 0, nencrypted, 0, nencrypted.length); - encrypted = nencrypted; - _log.warn("Decrypt got odd segment - " + trailing + " bytes pushed back for later decryption - corrupted or slow data stream perhaps?"); - } else { - //_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[] = _engine.decrypt(block, _key, _lastBlock); - byte data[] = CryptixAESEngine.xor(decrypted, _lastBlock); - int cleaned[] = stripPadding(data); - for (int j = 0; j < cleaned.length; j++) { - if ( ((int)cleaned[j]) <= 0) { - cleaned[j] += 256; - //_log.error("(modified: " + cleaned[j] + ")"); - } - _readyBuf.add(new Integer(cleaned[j])); - } - _cumulativePrepared += cleaned.length; - //_log.debug("Updating last block for inputStream"); - System.arraycopy(decrypted, 0, _lastBlock, 0, BLOCK_SIZE); - } - - int remaining = encrypted.length % BLOCK_SIZE; - if (remaining != 0) { - _encryptedBuf.write(encrypted, encrypted.length-remaining, remaining); - _log.debug("After pushing " + remaining + " bytes back onto the buffer, lets delay 1s our action so we don't fast busy until the net transfers data"); - try { Thread.sleep(1000); } catch (InterruptedException ie) {} - } else { - //_log.debug("No remaining encrypted bytes beyond the block size"); - } + byte encrypted[] = _encryptedBuf.toByteArray(); + _encryptedBuf.reset(); + + if ((encrypted == null) || (encrypted.length <= 0)) + throw new IOException("Error decrypting - no data to decrypt"); + + int numBlocks = encrypted.length / BLOCK_SIZE; + if ((encrypted.length % BLOCK_SIZE) != 0) { + // it was flushed / handled off the BLOCK_SIZE segments, so put the excess + // back into the _encryptedBuf for later handling + int trailing = encrypted.length % BLOCK_SIZE; + _encryptedBuf.write(encrypted, encrypted.length - trailing, trailing); + byte nencrypted[] = new byte[encrypted.length - trailing]; + System.arraycopy(encrypted, 0, nencrypted, 0, nencrypted.length); + encrypted = nencrypted; + _log.warn("Decrypt got odd segment - " + trailing + + " bytes pushed back for later decryption - corrupted or slow data stream perhaps?"); + } else { + //_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[] = _engine.decrypt(block, _key, _lastBlock); + byte data[] = CryptixAESEngine.xor(decrypted, _lastBlock); + int cleaned[] = stripPadding(data); + for (int j = 0; j < cleaned.length; j++) { + if (((int) cleaned[j]) <= 0) { + cleaned[j] += 256; + //_log.error("(modified: " + cleaned[j] + ")"); + } + _readyBuf.add(new Integer(cleaned[j])); + } + _cumulativePrepared += cleaned.length; + //_log.debug("Updating last block for inputStream"); + System.arraycopy(decrypted, 0, _lastBlock, 0, BLOCK_SIZE); + } + + int remaining = encrypted.length % BLOCK_SIZE; + if (remaining != 0) { + _encryptedBuf.write(encrypted, encrypted.length - remaining, remaining); + _log + .debug("After pushing " + + remaining + + " bytes back onto the buffer, lets delay 1s our action so we don't fast busy until the net transfers data"); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } else { + //_log.debug("No remaining encrypted bytes beyond the block size"); + } } /** @@ -249,163 +269,167 @@ public class AESInputStream extends FilterInputStream { * */ private int[] stripPadding(byte data[]) throws IOException { - int numPadBytes = (int)data[data.length-1]; - if ( (numPadBytes >= data.length) || (numPadBytes <= 0) ) - throw new IOException("Invalid number of pad bytes"); - 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) { - throw new IOException("Incorrect padding on decryption: data["+i+"] = " + data[i] + " not " + numPadBytes); - } - } - } - for (int i = 0; i < rv.length; i++) - rv[i] = data[i]; - _cumulativePaddingStripped += numPadBytes; - return rv; + int numPadBytes = (int) data[data.length - 1]; + if ((numPadBytes >= data.length) || (numPadBytes <= 0)) throw new IOException("Invalid number of pad bytes"); + 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) { throw new IOException("Incorrect padding on decryption: data[" + i + + "] = " + data[i] + " not " + numPadBytes); } + } + } + for (int i = 0; i < rv.length; i++) + rv[i] = data[i]; + _cumulativePaddingStripped += numPadBytes; + return rv; + } + + int remainingBytes() { + return _encryptedBuf.size(); } - - int remainingBytes() { return _encryptedBuf.size(); } - int readyBytes() { return _readyBuf.size(); } - + + int readyBytes() { + return _readyBuf.size(); + } + /** * Test AESOutputStream/AESInputStream */ public static void main(String args[]) { - byte orig[] = new byte[1024*32]; - RandomSource.getInstance().nextBytes(orig); - //byte orig[] = "you are my sunshine, my only sunshine".getBytes(); - SessionKey key = KeyGenerator.getInstance().generateSessionKey(); - byte iv[] = "there once was a".getBytes(); - - for (int i = 0; i < 20; i++) { - runTest(orig, key, iv); - } - - _log.info("Done testing 32KB data"); - - orig = new byte[20]; - RandomSource.getInstance().nextBytes(orig); - for (int i = 0; i < 20; i++) { - runTest(orig, key, iv); - } - - _log.info("Done testing 20 byte data"); - - orig = new byte[3]; - RandomSource.getInstance().nextBytes(orig); - for (int i = 0; i < 20; i++) { - runTest(orig, key, iv); - } - - _log.info("Done testing 3 byte data"); - - orig = new byte[0]; - RandomSource.getInstance().nextBytes(orig); - for (int i = 0; i < 20; i++) { - runTest(orig, key, iv); - } - - _log.info("Done testing 0 byte data"); - - orig = new byte[32]; - RandomSource.getInstance().nextBytes(orig); - runOffsetTest(orig, key, iv); - - _log.info("Done testing offset test (it should have come back with a statement NOT EQUAL!)"); - - try { Thread.sleep(30*1000); } catch (InterruptedException ie) {} + byte orig[] = new byte[1024 * 32]; + RandomSource.getInstance().nextBytes(orig); + //byte orig[] = "you are my sunshine, my only sunshine".getBytes(); + SessionKey key = KeyGenerator.getInstance().generateSessionKey(); + byte iv[] = "there once was a".getBytes(); + + for (int i = 0; i < 20; i++) { + runTest(orig, key, iv); + } + + _log.info("Done testing 32KB data"); + + orig = new byte[20]; + RandomSource.getInstance().nextBytes(orig); + for (int i = 0; i < 20; i++) { + runTest(orig, key, iv); + } + + _log.info("Done testing 20 byte data"); + + orig = new byte[3]; + RandomSource.getInstance().nextBytes(orig); + for (int i = 0; i < 20; i++) { + runTest(orig, key, iv); + } + + _log.info("Done testing 3 byte data"); + + orig = new byte[0]; + RandomSource.getInstance().nextBytes(orig); + for (int i = 0; i < 20; i++) { + runTest(orig, key, iv); + } + + _log.info("Done testing 0 byte data"); + + orig = new byte[32]; + RandomSource.getInstance().nextBytes(orig); + runOffsetTest(orig, key, iv); + + _log.info("Done testing offset test (it should have come back with a statement NOT EQUAL!)"); + + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException ie) { + } } - + private static void runTest(byte orig[], SessionKey key, byte[] iv) { - try { - long start = Clock.getInstance().now(); - ByteArrayOutputStream origStream = new ByteArrayOutputStream(512); - AESOutputStream out = new AESOutputStream(origStream, key, iv); - out.write(orig); - out.close(); - - byte encrypted[] = origStream.toByteArray(); - long endE = Clock.getInstance().now(); - - ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encrypted); - AESInputStream in = new AESInputStream(encryptedStream, key, iv); - ByteArrayOutputStream baos = new ByteArrayOutputStream(512); - byte buf[] = new byte[1024*32]; - int read = DataHelper.read(in, buf); - if (read > 0) - baos.write(buf, 0, read); - in.close(); - byte fin[] = baos.toByteArray(); - long end = Clock.getInstance().now(); - Hash origHash = SHA256Generator.getInstance().calculateHash(orig); - - Hash newHash = SHA256Generator.getInstance().calculateHash(fin); - boolean eq = origHash.equals(newHash); - if (eq) - _log.info("Equal hashes. hash: " + origHash); - else - _log.error("NOT EQUAL! \norig: \t" + Base64.encode(orig) + "\nnew : \t" + Base64.encode(fin)); - boolean ok = DataHelper.eq(orig, fin); - _log.debug("EQ data? " + ok + " origLen: " + orig.length + " fin.length: " + fin.length); - _log.debug("Time to D(E(" + orig.length + ")): " + (end - start) + "ms"); - _log.debug("Time to E(" + orig.length + "): " + (endE - start) + "ms"); - _log.debug("Time to D(" + orig.length + "): " + (end - endE) + "ms"); - - } catch (Throwable t) { - _log.error("ERROR transferring", t); - } - //try { Thread.sleep(5000); } catch (Throwable t) {} + try { + long start = Clock.getInstance().now(); + ByteArrayOutputStream origStream = new ByteArrayOutputStream(512); + AESOutputStream out = new AESOutputStream(origStream, key, iv); + out.write(orig); + out.close(); + + byte encrypted[] = origStream.toByteArray(); + long endE = Clock.getInstance().now(); + + ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encrypted); + AESInputStream in = new AESInputStream(encryptedStream, key, iv); + ByteArrayOutputStream baos = new ByteArrayOutputStream(512); + byte buf[] = new byte[1024 * 32]; + int read = DataHelper.read(in, buf); + if (read > 0) baos.write(buf, 0, read); + in.close(); + byte fin[] = baos.toByteArray(); + long end = Clock.getInstance().now(); + Hash origHash = SHA256Generator.getInstance().calculateHash(orig); + + Hash newHash = SHA256Generator.getInstance().calculateHash(fin); + boolean eq = origHash.equals(newHash); + if (eq) + _log.info("Equal hashes. hash: " + origHash); + else + _log.error("NOT EQUAL! \norig: \t" + Base64.encode(orig) + "\nnew : \t" + Base64.encode(fin)); + boolean ok = DataHelper.eq(orig, fin); + _log.debug("EQ data? " + ok + " origLen: " + orig.length + " fin.length: " + fin.length); + _log.debug("Time to D(E(" + orig.length + ")): " + (end - start) + "ms"); + _log.debug("Time to E(" + orig.length + "): " + (endE - start) + "ms"); + _log.debug("Time to D(" + orig.length + "): " + (end - endE) + "ms"); + + } catch (Throwable t) { + _log.error("ERROR transferring", t); + } + //try { Thread.sleep(5000); } catch (Throwable t) {} } - + private static void runOffsetTest(byte orig[], SessionKey key, byte[] iv) { - try { - long start = Clock.getInstance().now(); - ByteArrayOutputStream origStream = new ByteArrayOutputStream(512); - AESOutputStream out = new AESOutputStream(origStream, key, iv); - out.write(orig); - out.close(); - - byte encrypted[] = origStream.toByteArray(); - long endE = Clock.getInstance().now(); - - _log.info("Encrypted segment length: " + encrypted.length); - byte encryptedSegment[] = new byte[40]; - System.arraycopy(encrypted, 0, encryptedSegment, 0, 40); - - ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encryptedSegment); - AESInputStream in = new AESInputStream(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(); - _log.info("Read: " + read); - if (read > 0) - baos.write(buf, 0, read); - in.close(); - byte fin[] = baos.toByteArray(); - _log.info("fin.length: " + fin.length + " remaining: " + remaining + " ready: " + readyBytes); - long end = Clock.getInstance().now(); - Hash origHash = SHA256Generator.getInstance().calculateHash(orig); - - Hash newHash = SHA256Generator.getInstance().calculateHash(fin); - boolean eq = origHash.equals(newHash); - if (eq) - _log.info("Equal hashes. hash: " + origHash); - else - _log.error("NOT EQUAL! \norig: \t" + Base64.encode(orig) + "\nnew : \t" + Base64.encode(fin)); - boolean ok = DataHelper.eq(orig, fin); - _log.debug("EQ data? " + ok + " origLen: " + orig.length + " fin.length: " + fin.length); - _log.debug("Time to D(E(" + orig.length + ")): " + (end - start) + "ms"); - _log.debug("Time to E(" + orig.length + "): " + (endE - start) + "ms"); - _log.debug("Time to D(" + orig.length + "): " + (end - endE) + "ms"); - - } catch (Throwable t) { - _log.error("ERROR transferring", t); - } - //try { Thread.sleep(5000); } catch (Throwable t) {} + try { + long start = Clock.getInstance().now(); + ByteArrayOutputStream origStream = new ByteArrayOutputStream(512); + AESOutputStream out = new AESOutputStream(origStream, key, iv); + out.write(orig); + out.close(); + + byte encrypted[] = origStream.toByteArray(); + long endE = Clock.getInstance().now(); + + _log.info("Encrypted segment length: " + encrypted.length); + byte encryptedSegment[] = new byte[40]; + System.arraycopy(encrypted, 0, encryptedSegment, 0, 40); + + ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encryptedSegment); + AESInputStream in = new AESInputStream(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(); + _log.info("Read: " + read); + if (read > 0) baos.write(buf, 0, read); + in.close(); + byte fin[] = baos.toByteArray(); + _log.info("fin.length: " + fin.length + " remaining: " + remaining + " ready: " + readyBytes); + long end = Clock.getInstance().now(); + Hash origHash = SHA256Generator.getInstance().calculateHash(orig); + + Hash newHash = SHA256Generator.getInstance().calculateHash(fin); + boolean eq = origHash.equals(newHash); + if (eq) + _log.info("Equal hashes. hash: " + origHash); + else + _log.error("NOT EQUAL! \norig: \t" + Base64.encode(orig) + "\nnew : \t" + Base64.encode(fin)); + boolean ok = DataHelper.eq(orig, fin); + _log.debug("EQ data? " + ok + " origLen: " + orig.length + " fin.length: " + fin.length); + _log.debug("Time to D(E(" + orig.length + ")): " + (end - start) + "ms"); + _log.debug("Time to E(" + orig.length + "): " + (endE - start) + "ms"); + _log.debug("Time to D(" + orig.length + "): " + (end - endE) + "ms"); + + } catch (Throwable t) { + _log.error("ERROR transferring", t); + } + //try { Thread.sleep(5000); } catch (Throwable t) {} } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/AESOutputStream.java b/core/java/src/net/i2p/crypto/AESOutputStream.java index 8c62f36ce5a5719d768f2173d2d89595cff0435e..c8d3c9d92723d315b09e165c6a907e7d79d05a86 100644 --- a/core/java/src/net/i2p/crypto/AESOutputStream.java +++ b/core/java/src/net/i2p/crypto/AESOutputStream.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -37,50 +38,54 @@ public class AESOutputStream extends FilterOutputStream { private long _cumulativePadding; // how many bytes of padding written public final static float EXPANSION_FACTOR = 1.0625f; // 6% overhead w/ the padding - + private final static int BLOCK_SIZE = CryptixRijndael_Algorithm._BLOCK_SIZE; private final static int MAX_BUF = 256; - + public AESOutputStream(OutputStream source, SessionKey key, byte[] iv) { - super(source); - _key = key; - _lastBlock = new byte[BLOCK_SIZE]; - System.arraycopy(iv, 0, _lastBlock, 0, BLOCK_SIZE); - _inBuf = new ByteArrayOutputStream(MAX_BUF); + super(source); + _key = key; + _lastBlock = new byte[BLOCK_SIZE]; + System.arraycopy(iv, 0, _lastBlock, 0, BLOCK_SIZE); + _inBuf = new ByteArrayOutputStream(MAX_BUF); } - - public void write(int val) throws IOException { - _cumulativeProvided++; - _inBuf.write(val); - if (_inBuf.size() > MAX_BUF) - doFlush(); + + public void write(int val) throws IOException { + _cumulativeProvided++; + _inBuf.write(val); + if (_inBuf.size() > MAX_BUF) doFlush(); } - public void write(byte src[]) throws IOException { - _cumulativeProvided += src.length; - _inBuf.write(src); - if (_inBuf.size() > MAX_BUF) - doFlush(); + + public void write(byte src[]) throws IOException { + _cumulativeProvided += src.length; + _inBuf.write(src); + if (_inBuf.size() > MAX_BUF) doFlush(); } - public void write(byte src[], int off, int len) throws IOException { - _cumulativeProvided += len; - _inBuf.write(src, off, len); - if (_inBuf.size() > MAX_BUF) - doFlush(); + + public void write(byte src[], int off, int len) throws IOException { + _cumulativeProvided += len; + _inBuf.write(src, off, len); + if (_inBuf.size() > MAX_BUF) doFlush(); } - - public void close() throws IOException { - flush(); - out.close(); - _inBuf.reset(); - _log.debug("Cumulative bytes provided to this stream / written out / padded: " + _cumulativeProvided + "/" + _cumulativeWritten + "/" + _cumulativePadding); + + public void close() throws IOException { + flush(); + out.close(); + _inBuf.reset(); + _log.debug("Cumulative bytes provided to this stream / written out / padded: " + _cumulativeProvided + "/" + + _cumulativeWritten + "/" + _cumulativePadding); } - public void flush() throws IOException { doFlush(); out.flush(); } - + + public void flush() throws IOException { + doFlush(); + out.flush(); + } + private void doFlush() throws IOException { - writeEncrypted(_inBuf.toByteArray()); - _inBuf.reset(); + writeEncrypted(_inBuf.toByteArray()); + _inBuf.reset(); } - + /** * Encrypt an arbitrary size array with AES using CBC and PKCS#5 padding, * write it to the stream, and set _lastBlock to the last encrypted @@ -92,34 +97,34 @@ public class AESOutputStream extends FilterOutputStream { * */ private void writeEncrypted(byte src[]) throws IOException { - if ( (src == null) || (src.length == 0) ) return; - 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[] = _engine.xor(block, _lastBlock); - byte encrypted[] = _engine.encrypt(data, _key, _lastBlock); - _cumulativeWritten += encrypted.length; - out.write(encrypted); - System.arraycopy(encrypted, encrypted.length-BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE); - _cumulativePadding++; - } - - if (src.length % 15 != 0) { - // we need to do non trivial padding - int remainingBytes = src.length-numBlocks*15; - int paddingBytes = BLOCK_SIZE - remainingBytes; - System.arraycopy(src, numBlocks*15, block, 0, remainingBytes); - Arrays.fill(block, remainingBytes, BLOCK_SIZE, (byte)paddingBytes); - byte data[] = _engine.xor(block, _lastBlock); - byte encrypted[] = _engine.encrypt(data, _key, _lastBlock); - out.write(encrypted); - System.arraycopy(encrypted, encrypted.length-BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE); - _cumulativePadding += paddingBytes; - _cumulativeWritten += encrypted.length; - } + if ((src == null) || (src.length == 0)) return; + 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[] = _engine.xor(block, _lastBlock); + byte encrypted[] = _engine.encrypt(data, _key, _lastBlock); + _cumulativeWritten += encrypted.length; + out.write(encrypted); + System.arraycopy(encrypted, encrypted.length - BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE); + _cumulativePadding++; + } + + if (src.length % 15 != 0) { + // we need to do non trivial padding + int remainingBytes = src.length - numBlocks * 15; + int paddingBytes = BLOCK_SIZE - remainingBytes; + System.arraycopy(src, numBlocks * 15, block, 0, remainingBytes); + Arrays.fill(block, remainingBytes, BLOCK_SIZE, (byte) paddingBytes); + byte data[] = _engine.xor(block, _lastBlock); + byte encrypted[] = _engine.encrypt(data, _key, _lastBlock); + out.write(encrypted); + System.arraycopy(encrypted, encrypted.length - BLOCK_SIZE, _lastBlock, 0, BLOCK_SIZE); + _cumulativePadding += paddingBytes; + _cumulativeWritten += encrypted.length; + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/CryptixAESEngine.java b/core/java/src/net/i2p/crypto/CryptixAESEngine.java index 51f23181fb41f0be1923c3ee88b648e422468f71..cd0337ed5748acd3ce4cd5f199d85dc203fa7ecd 100644 --- a/core/java/src/net/i2p/crypto/CryptixAESEngine.java +++ b/core/java/src/net/i2p/crypto/CryptixAESEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -20,7 +21,7 @@ import net.i2p.util.Log; * Only supports data of size mod 16 bytes - no inherent padding. * * @author jrandom, thecrypto - */ + */ public class CryptixAESEngine extends AESEngine { private final static Log _log = new Log(CryptixAESEngine.class); private final static CryptixRijndael_Algorithm _algo = new CryptixRijndael_Algorithm(); @@ -28,122 +29,119 @@ public class CryptixAESEngine extends AESEngine { private final static byte FAKE_KEY = 0x2A; public byte[] encrypt(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[][] 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); - for (int x = 1; x < numblock; x++) { - cipher[x] = encrypt(xor(cipher[x-1], plain[x]), sessionKey); - } - - 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; + 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[][] 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); + for (int x = 1; x < numblock; x++) { + cipher[x] = encrypt(xor(cipher[x - 1], plain[x]), sessionKey); + } + + 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; + 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; + + 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 static byte[] encrypt(byte payload[], SessionKey sessionKey) { - 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; - } catch (InvalidKeyException ike) { - _log.error("Invalid key", ike); - return null; - } + 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; + } catch (InvalidKeyException ike) { + _log.error("Invalid key", ike); + return null; + } } + /** decrypt the data with the session key provided * @param payload encrypted data * @param sessionKey private session key * @return unencrypted data - */ + */ final static byte[] decrypt(byte payload[], SessionKey sessionKey) { - 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; - } catch (InvalidKeyException ike) { - _log.error("Invalid key", ike); - return null; - } + 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; + } catch (InvalidKeyException ike) { + _log.error("Invalid key", ike); + return null; + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/CryptixRijndael_Algorithm.java b/core/java/src/net/i2p/crypto/CryptixRijndael_Algorithm.java index 2f22578dadd5f0eaf98df515c22ba3a07209d2d6..4f0078615b521f80870343c1b52e8bf23355e24b 100644 --- a/core/java/src/net/i2p/crypto/CryptixRijndael_Algorithm.java +++ b/core/java/src/net/i2p/crypto/CryptixRijndael_Algorithm.java @@ -4,10 +4,11 @@ */ package net.i2p.crypto; -import net.i2p.util.Clock; import java.io.PrintWriter; import java.security.InvalidKeyException; +import net.i2p.util.Clock; + //........................................................................... /** * Rijndael --pronounced Reindaal-- is a variable block-size (128-, 192- and @@ -28,35 +29,40 @@ import java.security.InvalidKeyException; */ public final class CryptixRijndael_Algorithm // implicit no-argument constructor { -// Debugging methods and variables -//........................................................................... + // Debugging methods and variables + //........................................................................... static final String _NAME = "Rijndael_Algorithm"; static final boolean _IN = true, _OUT = false; static final boolean _RDEBUG = false; static final int _debuglevel = 0; // RDEBUG ? Rijndael_Properties.getLevel(NAME): 0; -// static final PrintWriter err = RDEBUG ? Rijndael_Properties.getOutput() : null; + // static final PrintWriter err = RDEBUG ? Rijndael_Properties.getOutput() : null; static final PrintWriter _err = new PrintWriter(new java.io.OutputStreamWriter(System.err)); static final boolean _TRACE = false; // Rijndael_Properties.isTraceable(NAME); - static void debug (String s) { _err.println(">>> "+_NAME+": "+s); } - static void trace (boolean in, String s) { - if (_TRACE) _err.println((in?"==> ":"<== ")+_NAME+"."+s); + static void debug(String s) { + _err.println(">>> " + _NAME + ": " + s); } - static void trace (String s) { if (_TRACE) _err.println("<=> "+_NAME+"."+s); } + static void trace(boolean in, String s) { + if (_TRACE) _err.println((in ? "==> " : "<== ") + _NAME + "." + s); + } -// Constants and variables -//........................................................................... + static void trace(String s) { + if (_TRACE) _err.println("<=> " + _NAME + "." + s); + } + + // Constants and variables + //........................................................................... static final int _BLOCK_SIZE = 16; // default block size in bytes static final int[] _alog = new int[256]; - static final int[] _log = new int[256]; + static final int[] _log = new int[256]; - static final byte[] _S = new byte[256]; + static final byte[] _S = new byte[256]; static final byte[] _Si = new byte[256]; static final int[] _T1 = new int[256]; static final int[] _T2 = new int[256]; @@ -72,28 +78,24 @@ public final class CryptixRijndael_Algorithm // implicit no-argument constructor static final int[] _U4 = new int[256]; static final byte[] _rcon = new byte[30]; - static final int[][][] _shifts = new int[][][] { - { {0, 0}, {1, 3}, {2, 2}, {3, 1} }, - { {0, 0}, {1, 5}, {2, 4}, {3, 3} }, - { {0, 0}, {1, 7}, {3, 5}, {4, 4} } - }; - - private static final char[] _HEX_DIGITS = { - '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' - }; + static final int[][][] _shifts = new int[][][] { { { 0, 0}, { 1, 3}, { 2, 2}, { 3, 1}}, + { { 0, 0}, { 1, 5}, { 2, 4}, { 3, 3}}, + { { 0, 0}, { 1, 7}, { 3, 5}, { 4, 4}}}; + private static final char[] _HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F'}; -// Static code - to intialise S-boxes and T-boxes -//........................................................................... + // Static code - to intialise S-boxes and T-boxes + //........................................................................... static { long time = Clock.getInstance().now(); -if (_RDEBUG && _debuglevel > 6) { -System.out.println("Algorithm Name: Rijndael ver 0.1"); -System.out.println("Electronic Codebook (ECB) Mode"); -System.out.println(); -} + if (_RDEBUG && _debuglevel > 6) { + System.out.println("Algorithm Name: Rijndael ver 0.1"); + System.out.println("Electronic Codebook (ECB) Mode"); + System.out.println(); + } int ROOT = 0x11B; int i, j = 0; @@ -103,21 +105,15 @@ System.out.println(); // _alog[0] = 1; for (i = 1; i < 256; i++) { - j = (_alog[i-1] << 1) ^ _alog[i-1]; + j = (_alog[i - 1] << 1) ^ _alog[i - 1]; if ((j & 0x100) != 0) j ^= ROOT; _alog[i] = j; } - for (i = 1; i < 255; i++) _log[_alog[i]] = i; - byte[][] A = new byte[][] { - {1, 1, 1, 1, 1, 0, 0, 0}, - {0, 1, 1, 1, 1, 1, 0, 0}, - {0, 0, 1, 1, 1, 1, 1, 0}, - {0, 0, 0, 1, 1, 1, 1, 1}, - {1, 0, 0, 0, 1, 1, 1, 1}, - {1, 1, 0, 0, 0, 1, 1, 1}, - {1, 1, 1, 0, 0, 0, 1, 1}, - {1, 1, 1, 1, 0, 0, 0, 1} - }; + for (i = 1; i < 255; i++) + _log[_alog[i]] = i; + byte[][] A = new byte[][] { { 1, 1, 1, 1, 1, 0, 0, 0}, { 0, 1, 1, 1, 1, 1, 0, 0}, { 0, 0, 1, 1, 1, 1, 1, 0}, + { 0, 0, 0, 1, 1, 1, 1, 1}, { 1, 0, 0, 0, 1, 1, 1, 1}, { 1, 1, 0, 0, 0, 1, 1, 1}, + { 1, 1, 1, 0, 0, 0, 1, 1}, { 1, 1, 1, 1, 0, 0, 0, 1}}; byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1}; // @@ -129,7 +125,7 @@ System.out.println(); for (i = 2; i < 256; i++) { j = _alog[255 - _log[i]]; for (t = 0; t < 8; t++) - box[i][t] = (byte)((j >>> (7 - t)) & 0x01); + box[i][t] = (byte) ((j >>> (7 - t)) & 0x01); } // // affine transform: box[i] <- B + A*box[i] @@ -145,24 +141,20 @@ System.out.println(); // S-boxes and inverse S-boxes // for (i = 0; i < 256; i++) { - _S[i] = (byte)(cox[i][0] << 7); - for (t = 1; t < 8; t++) - _S[i] ^= cox[i][t] << (7-t); + _S[i] = (byte) (cox[i][0] << 7); + for (t = 1; t < 8; t++) + _S[i] ^= cox[i][t] << (7 - t); _Si[_S[i] & 0xFF] = (byte) i; } // // T-boxes // - byte[][] G = new byte[][] { - {2, 1, 1, 3}, - {3, 2, 1, 1}, - {1, 3, 2, 1}, - {1, 1, 3, 2} - }; + byte[][] G = new byte[][] { { 2, 1, 1, 3}, { 3, 2, 1, 1}, { 1, 3, 2, 1}, { 1, 1, 3, 2}}; byte[][] AA = new byte[4][8]; for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) AA[i][j] = G[i][j]; - AA[i][i+4] = 1; + for (j = 0; j < 4; j++) + AA[i][j] = G[i][j]; + AA[i][i + 4] = 1; } byte pivot, tmp; byte[][] iG = new byte[4][4]; @@ -184,18 +176,17 @@ System.out.println(); } } for (j = 0; j < 8; j++) - if (AA[i][j] != 0) - AA[i][j] = (byte) - _alog[(255 + _log[AA[i][j] & 0xFF] - _log[pivot & 0xFF]) % 255]; + if (AA[i][j] != 0) AA[i][j] = (byte) _alog[(255 + _log[AA[i][j] & 0xFF] - _log[pivot & 0xFF]) % 255]; for (t = 0; t < 4; t++) if (i != t) { - for (j = i+1; j < 8; j++) + for (j = i + 1; j < 8; j++) AA[t][j] ^= mul(AA[i][j], AA[t][i]); AA[t][i] = 0; } } for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) iG[i][j] = AA[i][j + 4]; + for (j = 0; j < 4; j++) + iG[i][j] = AA[i][j + 4]; int s; for (t = 0; t < 256; t++) { @@ -221,66 +212,145 @@ System.out.println(); // _rcon[0] = 1; int r = 1; - for (t = 1; t < 30; ) _rcon[t++] = (byte)(r = mul(2, r)); + for (t = 1; t < 30;) + _rcon[t++] = (byte) (r = mul(2, r)); time = Clock.getInstance().now() - time; -if (_RDEBUG && _debuglevel > 8) { -System.out.println("=========="); -System.out.println(); -System.out.println("Static Data"); -System.out.println(); -System.out.println("S[]:"); for(i=0;i<16;i++) { for(j=0;j<16;j++) System.out.print("0x"+byteToString(_S[i*16+j])+", "); System.out.println();} -System.out.println(); -System.out.println("Si[]:"); for(i=0;i<16;i++) { for(j=0;j<16;j++) System.out.print("0x"+byteToString(_Si[i*16+j])+", "); System.out.println();} - -System.out.println(); -System.out.println("iG[]:"); for(i=0;i<4;i++){for(j=0;j<4;j++) System.out.print("0x"+byteToString(iG[i][j])+", "); System.out.println();} - -System.out.println(); -System.out.println("T1[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T1[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T2[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T2[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T3[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T3[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T4[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T4[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T5[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T5[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T6[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T6[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T7[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T7[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("T8[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_T8[i*4+j])+", "); System.out.println();} - -System.out.println(); -System.out.println("U1[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_U1[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("U2[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_U2[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("U3[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_U3[i*4+j])+", "); System.out.println();} -System.out.println(); -System.out.println("U4[]:"); for(i=0;i<64;i++){for(j=0;j<4;j++) System.out.print("0x"+intToString(_U4[i*4+j])+", "); System.out.println();} - -System.out.println(); -System.out.println("rcon[]:"); for(i=0;i<5;i++){for(j=0;j<6;j++) System.out.print("0x"+byteToString(_rcon[i*6+j])+", "); System.out.println();} - -System.out.println(); -System.out.println("Total initialization time: "+time+" ms."); -System.out.println(); -} + if (_RDEBUG && _debuglevel > 8) { + System.out.println("=========="); + System.out.println(); + System.out.println("Static Data"); + System.out.println(); + System.out.println("S[]:"); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) + System.out.print("0x" + byteToString(_S[i * 16 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("Si[]:"); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) + System.out.print("0x" + byteToString(_Si[i * 16 + j]) + ", "); + System.out.println(); + } + + System.out.println(); + System.out.println("iG[]:"); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + byteToString(iG[i][j]) + ", "); + System.out.println(); + } + + System.out.println(); + System.out.println("T1[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T1[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T2[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T2[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T3[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T3[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T4[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T4[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T5[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T5[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T6[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T6[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T7[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T7[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("T8[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_T8[i * 4 + j]) + ", "); + System.out.println(); + } + + System.out.println(); + System.out.println("U1[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_U1[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("U2[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_U2[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("U3[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_U3[i * 4 + j]) + ", "); + System.out.println(); + } + System.out.println(); + System.out.println("U4[]:"); + for (i = 0; i < 64; i++) { + for (j = 0; j < 4; j++) + System.out.print("0x" + intToString(_U4[i * 4 + j]) + ", "); + System.out.println(); + } + + System.out.println(); + System.out.println("rcon[]:"); + for (i = 0; i < 5; i++) { + for (j = 0; j < 6; j++) + System.out.print("0x" + byteToString(_rcon[i * 6 + j]) + ", "); + System.out.println(); + } + + System.out.println(); + System.out.println("Total initialization time: " + time + " ms."); + System.out.println(); + } } // multiply two elements of GF(2^m) - static final int mul (int a, int b) { - return (a != 0 && b != 0) ? - _alog[(_log[a & 0xFF] + _log[b & 0xFF]) % 255] : - 0; + static final int mul(int a, int b) { + return (a != 0 && b != 0) ? _alog[(_log[a & 0xFF] + _log[b & 0xFF]) % 255] : 0; } // convenience method used in generating Transposition boxes - static final int mul4 (int a, byte[] b) { + static final int mul4(int a, byte[] b) { if (a == 0) return 0; a = _log[a & 0xFF]; int a0 = (b[0] != 0) ? _alog[(a + _log[b[0] & 0xFF]) % 255] & 0xFF : 0; @@ -290,9 +360,8 @@ System.out.println(); return a0 << 24 | a1 << 16 | a2 << 8 | a3; } - -// Basic API methods -//........................................................................... + // Basic API methods + //........................................................................... /** * Convenience method to expand a user-supplied key material into a @@ -301,7 +370,7 @@ System.out.println(); * @param k The 128/192/256-bit user-key to use. * @exception InvalidKeyException If the key is invalid. */ - public static final Object makeKey (byte[] k) throws InvalidKeyException { + public static final Object makeKey(byte[] k) throws InvalidKeyException { return makeKey(k, _BLOCK_SIZE); } @@ -315,84 +384,65 @@ System.out.println(); * @param sessionKey The session key to use for encryption. * @return The ciphertext generated from a plaintext using the session key. */ - public static final void - blockEncrypt (byte[] in, byte[] result, int inOffset, Object sessionKey) { -if (_RDEBUG) trace(_IN, "blockEncrypt("+in+", "+inOffset+", "+sessionKey+")"); + public static final void blockEncrypt(byte[] in, byte[] result, int inOffset, 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; int[] Ker = Ke[0]; // plaintext to ints + key - int t0 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Ker[0]; - int t1 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Ker[1]; - int t2 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Ker[2]; - int t3 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Ker[3]; + int t0 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Ker[0]; + int t1 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Ker[1]; + int t2 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Ker[2]; + int t3 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Ker[3]; int a0, a1, a2, a3; - for (int r = 1; r < ROUNDS; r++) { // apply round transforms + for (int r = 1; r < ROUNDS; r++) { // apply round transforms Ker = Ke[r]; - a0 = (_T1[(t0 >>> 24) & 0xFF] ^ - _T2[(t1 >>> 16) & 0xFF] ^ - _T3[(t2 >>> 8) & 0xFF] ^ - _T4[ t3 & 0xFF] ) ^ Ker[0]; - a1 = (_T1[(t1 >>> 24) & 0xFF] ^ - _T2[(t2 >>> 16) & 0xFF] ^ - _T3[(t3 >>> 8) & 0xFF] ^ - _T4[ t0 & 0xFF] ) ^ Ker[1]; - a2 = (_T1[(t2 >>> 24) & 0xFF] ^ - _T2[(t3 >>> 16) & 0xFF] ^ - _T3[(t0 >>> 8) & 0xFF] ^ - _T4[ t1 & 0xFF] ) ^ Ker[2]; - a3 = (_T1[(t3 >>> 24) & 0xFF] ^ - _T2[(t0 >>> 16) & 0xFF] ^ - _T3[(t1 >>> 8) & 0xFF] ^ - _T4[ t2 & 0xFF] ) ^ Ker[3]; + a0 = (_T1[(t0 >>> 24) & 0xFF] ^ _T2[(t1 >>> 16) & 0xFF] ^ _T3[(t2 >>> 8) & 0xFF] ^ _T4[t3 & 0xFF]) ^ Ker[0]; + a1 = (_T1[(t1 >>> 24) & 0xFF] ^ _T2[(t2 >>> 16) & 0xFF] ^ _T3[(t3 >>> 8) & 0xFF] ^ _T4[t0 & 0xFF]) ^ Ker[1]; + a2 = (_T1[(t2 >>> 24) & 0xFF] ^ _T2[(t3 >>> 16) & 0xFF] ^ _T3[(t0 >>> 8) & 0xFF] ^ _T4[t1 & 0xFF]) ^ Ker[2]; + a3 = (_T1[(t3 >>> 24) & 0xFF] ^ _T2[(t0 >>> 16) & 0xFF] ^ _T3[(t1 >>> 8) & 0xFF] ^ _T4[t2 & 0xFF]) ^ Ker[3]; t0 = a0; t1 = a1; t2 = a2; t3 = a3; -if (_RDEBUG && _debuglevel > 6) System.out.println("CT"+r+"="+intToString(t0)+intToString(t1)+intToString(t2)+intToString(t3)); + if (_RDEBUG && _debuglevel > 6) + System.out.println("CT" + r + "=" + intToString(t0) + intToString(t1) + intToString(t2) + + intToString(t3)); } // 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[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); 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[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); 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[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); 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 ); -if (_RDEBUG && _debuglevel > 6) { -System.out.println("CT="+toString(result)); -System.out.println(); -} -if (_RDEBUG) trace(_OUT, "blockEncrypt()"); + 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); + if (_RDEBUG && _debuglevel > 6) { + System.out.println("CT=" + toString(result)); + System.out.println(); + } + if (_RDEBUG) trace(_OUT, "blockEncrypt()"); } /** @@ -405,95 +455,79 @@ if (_RDEBUG) trace(_OUT, "blockEncrypt()"); * @param sessionKey The session key to use for decryption. * @return The plaintext generated from a ciphertext using the session key. */ - public static final void - blockDecrypt (byte[] in, byte[] result, int inOffset, Object sessionKey) { -if (_RDEBUG) trace(_IN, "blockDecrypt("+in+", "+inOffset+", "+sessionKey+")"); + public static final void blockDecrypt(byte[] in, byte[] result, int inOffset, 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; int[] Kdr = Kd[0]; // ciphertext to ints + key - int t0 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Kdr[0]; - int t1 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Kdr[1]; - int t2 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Kdr[2]; - int t3 = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Kdr[3]; + int t0 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Kdr[0]; + int t1 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Kdr[1]; + int t2 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Kdr[2]; + int t3 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Kdr[3]; int a0, a1, a2, a3; - for (int r = 1; r < ROUNDS; r++) { // apply round transforms + for (int r = 1; r < ROUNDS; r++) { // apply round transforms Kdr = Kd[r]; - a0 = (_T5[(t0 >>> 24) & 0xFF] ^ - _T6[(t3 >>> 16) & 0xFF] ^ - _T7[(t2 >>> 8) & 0xFF] ^ - _T8[ t1 & 0xFF] ) ^ Kdr[0]; - a1 = (_T5[(t1 >>> 24) & 0xFF] ^ - _T6[(t0 >>> 16) & 0xFF] ^ - _T7[(t3 >>> 8) & 0xFF] ^ - _T8[ t2 & 0xFF] ) ^ Kdr[1]; - a2 = (_T5[(t2 >>> 24) & 0xFF] ^ - _T6[(t1 >>> 16) & 0xFF] ^ - _T7[(t0 >>> 8) & 0xFF] ^ - _T8[ t3 & 0xFF] ) ^ Kdr[2]; - a3 = (_T5[(t3 >>> 24) & 0xFF] ^ - _T6[(t2 >>> 16) & 0xFF] ^ - _T7[(t1 >>> 8) & 0xFF] ^ - _T8[ t0 & 0xFF] ) ^ Kdr[3]; + a0 = (_T5[(t0 >>> 24) & 0xFF] ^ _T6[(t3 >>> 16) & 0xFF] ^ _T7[(t2 >>> 8) & 0xFF] ^ _T8[t1 & 0xFF]) ^ Kdr[0]; + a1 = (_T5[(t1 >>> 24) & 0xFF] ^ _T6[(t0 >>> 16) & 0xFF] ^ _T7[(t3 >>> 8) & 0xFF] ^ _T8[t2 & 0xFF]) ^ Kdr[1]; + a2 = (_T5[(t2 >>> 24) & 0xFF] ^ _T6[(t1 >>> 16) & 0xFF] ^ _T7[(t0 >>> 8) & 0xFF] ^ _T8[t3 & 0xFF]) ^ Kdr[2]; + a3 = (_T5[(t3 >>> 24) & 0xFF] ^ _T6[(t2 >>> 16) & 0xFF] ^ _T7[(t1 >>> 8) & 0xFF] ^ _T8[t0 & 0xFF]) ^ Kdr[3]; t0 = a0; t1 = a1; t2 = a2; t3 = a3; -if (_RDEBUG && _debuglevel > 6) System.out.println("PT"+r+"="+intToString(t0)+intToString(t1)+intToString(t2)+intToString(t3)); + if (_RDEBUG && _debuglevel > 6) + System.out.println("PT" + r + "=" + intToString(t0) + intToString(t1) + intToString(t2) + + intToString(t3)); } // 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[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); 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[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); 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[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); 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 ); -if (_RDEBUG && _debuglevel > 6) { -System.out.println("PT="+toString(result)); -System.out.println(); -} -if (_RDEBUG) trace(_OUT, "blockDecrypt()"); + 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); + if (_RDEBUG && _debuglevel > 6) { + System.out.println("PT=" + toString(result)); + System.out.println(); + } + if (_RDEBUG) trace(_OUT, "blockDecrypt()"); } /** A basic symmetric encryption/decryption test. */ - public static boolean self_test() { return self_test(_BLOCK_SIZE); } - + public static boolean self_test() { + return self_test(_BLOCK_SIZE); + } -// Rijndael own methods -//........................................................................... + // Rijndael own methods + //........................................................................... /** @return The default length in bytes of the Algorithm input block. */ - public static final int blockSize() { return _BLOCK_SIZE; } + public static final int blockSize() { + return _BLOCK_SIZE; + } /** * Expand a user-supplied key material into a session key. @@ -502,13 +536,11 @@ if (_RDEBUG) trace(_OUT, "blockDecrypt()"); * @param blockSize The block size in bytes of this Rijndael. * @exception InvalidKeyException If the key is invalid. */ - public static final /* synchronized */ Object makeKey (byte[] k, int blockSize) - throws InvalidKeyException { -if (_RDEBUG) trace(_IN, "makeKey("+k+", "+blockSize+")"); - if (k == null) - throw new InvalidKeyException("Empty key"); + public static final/* synchronized */Object makeKey(byte[] k, int blockSize) throws InvalidKeyException { + if (_RDEBUG) trace(_IN, "makeKey(" + k + ", " + blockSize + ")"); + if (k == null) throw new InvalidKeyException("Empty key"); if (!(k.length == 16 || k.length == 24 || k.length == 32)) - throw new InvalidKeyException("Incorrect key length"); + throw new InvalidKeyException("Incorrect key length"); int ROUNDS = getRounds(k.length, blockSize); int BC = blockSize / 4; int[][] Ke = new int[ROUNDS + 1][BC]; // encryption round keys @@ -519,11 +551,8 @@ if (_RDEBUG) trace(_IN, "makeKey("+k+", "+blockSize+")"); int i, j; // copy user material bytes into temporary ints - for (i = 0, j = 0; i < KC; ) - tk[i++] = (k[j++] & 0xFF) << 24 | - (k[j++] & 0xFF) << 16 | - (k[j++] & 0xFF) << 8 | - (k[j++] & 0xFF); + for (i = 0, j = 0; i < KC;) + tk[i++] = (k[j++] & 0xFF) << 24 | (k[j++] & 0xFF) << 16 | (k[j++] & 0xFF) << 8 | (k[j++] & 0xFF); // copy values into round key arrays int t = 0; for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { @@ -534,38 +563,34 @@ if (_RDEBUG) trace(_IN, "makeKey("+k+", "+blockSize+")"); while (t < ROUND_KEY_COUNT) { // extrapolate using phi (the round key evolution function) tt = tk[KC - 1]; - tk[0] ^= (_S[(tt >>> 16) & 0xFF] & 0xFF) << 24 ^ - (_S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^ - (_S[ tt & 0xFF] & 0xFF) << 8 ^ - (_S[(tt >>> 24) & 0xFF] & 0xFF) ^ - (_rcon[rconpointer++] & 0xFF) << 24; + tk[0] ^= (_S[(tt >>> 16) & 0xFF] & 0xFF) << 24 ^ (_S[(tt >>> 8) & 0xFF] & 0xFF) << 16 + ^ (_S[tt & 0xFF] & 0xFF) << 8 ^ (_S[(tt >>> 24) & 0xFF] & 0xFF) + ^ (_rcon[rconpointer++] & 0xFF) << 24; if (KC != 8) - for (i = 1, j = 0; i < KC; ) { - //tk[i++] ^= tk[j++]; - // The above line replaced with the code below in order to work around - // a bug in the kjc-1.4F java compiler (which has been reported). - tk[i] ^= tk[j++]; - i++; + for (i = 1, j = 0; i < KC;) { + //tk[i++] ^= tk[j++]; + // The above line replaced with the code below in order to work around + // a bug in the kjc-1.4F java compiler (which has been reported). + tk[i] ^= tk[j++]; + i++; } else { - for (i = 1, j = 0; i < KC / 2; ) { - //tk[i++] ^= tk[j++]; - // The above line replaced with the code below in order to work around - // a bug in the kjc-1.4F java compiler (which has been reported). - tk[i] ^= tk[j++]; - i++; + for (i = 1, j = 0; i < KC / 2;) { + //tk[i++] ^= tk[j++]; + // The above line replaced with the code below in order to work around + // a bug in the kjc-1.4F java compiler (which has been reported). + tk[i] ^= tk[j++]; + i++; } tt = tk[KC / 2 - 1]; - tk[KC / 2] ^= (_S[ tt & 0xFF] & 0xFF) ^ - (_S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^ - (_S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^ - (_S[(tt >>> 24) & 0xFF] & 0xFF) << 24; - for (j = KC / 2, i = j + 1; i < KC; ) { - //tk[i++] ^= tk[j++]; - // The above line replaced with the code below in order to work around - // a bug in the kjc-1.4F java compiler (which has been reported). - tk[i] ^= tk[j++]; - i++; + tk[KC / 2] ^= (_S[tt & 0xFF] & 0xFF) ^ (_S[(tt >>> 8) & 0xFF] & 0xFF) << 8 + ^ (_S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^ (_S[(tt >>> 24) & 0xFF] & 0xFF) << 24; + for (j = KC / 2, i = j + 1; i < KC;) { + //tk[i++] ^= tk[j++]; + // The above line replaced with the code below in order to work around + // a bug in the kjc-1.4F java compiler (which has been reported). + tk[i] ^= tk[j++]; + i++; } } // copy values into round key arrays @@ -574,18 +599,16 @@ if (_RDEBUG) trace(_IN, "makeKey("+k+", "+blockSize+")"); Kd[ROUNDS - (t / BC)][t % BC] = tk[j]; } } - for (int r = 1; r < ROUNDS; r++) // inverse MixColumn where needed + for (int r = 1; r < ROUNDS; r++) + // inverse MixColumn where needed for (j = 0; j < BC; j++) { tt = Kd[r][j]; - Kd[r][j] = _U1[(tt >>> 24) & 0xFF] ^ - _U2[(tt >>> 16) & 0xFF] ^ - _U3[(tt >>> 8) & 0xFF] ^ - _U4[ tt & 0xFF]; + Kd[r][j] = _U1[(tt >>> 24) & 0xFF] ^ _U2[(tt >>> 16) & 0xFF] ^ _U3[(tt >>> 8) & 0xFF] ^ _U4[tt & 0xFF]; } // assemble the encryption (Ke) and decryption (Kd) round keys into // one sessionKey object - Object[] sessionKey = new Object[] {Ke, Kd}; -if (_RDEBUG) trace(_OUT, "makeKey()"); + Object[] sessionKey = new Object[] { Ke, Kd}; + if (_RDEBUG) trace(_OUT, "makeKey()"); return sessionKey; } @@ -599,13 +622,12 @@ if (_RDEBUG) trace(_OUT, "makeKey()"); * @param blockSize The block size in bytes of this Rijndael. * @return The ciphertext generated from a plaintext using the session key. */ - 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, Object sessionKey, int blockSize) { if (blockSize == _BLOCK_SIZE) { blockEncrypt(in, result, inOffset, sessionKey); return; } -if (_RDEBUG) trace(_IN, "blockEncrypt("+in+", "+inOffset+", "+sessionKey+", "+blockSize+")"); + if (_RDEBUG) trace(_IN, "blockEncrypt(" + in + ", " + inOffset + ", " + sessionKey + ", " + blockSize + ")"); Object[] sKey = (Object[]) sessionKey; // extract encryption round keys int[][] Ke = (int[][]) sKey[0]; @@ -620,32 +642,30 @@ if (_RDEBUG) trace(_IN, "blockEncrypt("+in+", "+inOffset+", "+sessionKey+", "+bl int i; int j = 0, tt; - for (i = 0; i < BC; i++) // plaintext to ints + key - t[i] = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Ke[0][i]; - for (int r = 1; r < ROUNDS; r++) { // apply round transforms + for (i = 0; i < BC; i++) + // plaintext to ints + key + t[i] = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Ke[0][i]; + for (int r = 1; r < ROUNDS; r++) { // apply round transforms for (i = 0; i < BC; i++) - a[i] = (_T1[(t[ i ] >>> 24) & 0xFF] ^ - _T2[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ - _T3[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ - _T4[ t[(i + s3) % BC] & 0xFF] ) ^ Ke[r][i]; + a[i] = (_T1[(t[i] >>> 24) & 0xFF] ^ _T2[(t[(i + s1) % BC] >>> 16) & 0xFF] + ^ _T3[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ _T4[t[(i + s3) % BC] & 0xFF]) + ^ Ke[r][i]; System.arraycopy(a, 0, t, 0, BC); -if (_RDEBUG && _debuglevel > 6) System.out.println("CT"+r+"="+toString(t)); + if (_RDEBUG && _debuglevel > 6) System.out.println("CT" + r + "=" + toString(t)); } - for (i = 0; i < BC; i++) { // last round is special + for (i = 0; i < BC; i++) { // last round is special tt = Ke[ROUNDS][i]; - result[j++] = (byte)(_S[(t[ i ] >>> 24) & 0xFF] ^ (tt >>> 24)); - result[j++] = (byte)(_S[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ (tt >>> 16)); - result[j++] = (byte)(_S[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ (tt >>> 8)); - result[j++] = (byte)(_S[ t[(i + s3) % BC] & 0xFF] ^ tt); + result[j++] = (byte) (_S[(t[i] >>> 24) & 0xFF] ^ (tt >>> 24)); + result[j++] = (byte) (_S[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ (tt >>> 16)); + result[j++] = (byte) (_S[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ (tt >>> 8)); + result[j++] = (byte) (_S[t[(i + s3) % BC] & 0xFF] ^ tt); + } + if (_RDEBUG && _debuglevel > 6) { + System.out.println("CT=" + toString(result)); + System.out.println(); } -if (_RDEBUG && _debuglevel > 6) { -System.out.println("CT="+toString(result)); -System.out.println(); -} -if (_RDEBUG) trace(_OUT, "blockEncrypt()"); + if (_RDEBUG) trace(_OUT, "blockEncrypt()"); } /** @@ -658,14 +678,13 @@ if (_RDEBUG) trace(_OUT, "blockEncrypt()"); * @param blockSize The block size in bytes of this Rijndael. * @return The plaintext generated from a ciphertext using the session key. */ - 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, Object sessionKey, int blockSize) { if (blockSize == _BLOCK_SIZE) { blockDecrypt(in, result, inOffset, sessionKey); return; } -if (_RDEBUG) trace(_IN, "blockDecrypt("+in+", "+inOffset+", "+sessionKey+", "+blockSize+")"); + if (_RDEBUG) trace(_IN, "blockDecrypt(" + in + ", " + inOffset + ", " + sessionKey + ", " + blockSize + ")"); Object[] sKey = (Object[]) sessionKey; // extract decryption round keys int[][] Kd = (int[][]) sKey[1]; @@ -680,37 +699,35 @@ if (_RDEBUG) trace(_IN, "blockDecrypt("+in+", "+inOffset+", "+sessionKey+", "+bl int i; int j = 0, tt; - for (i = 0; i < BC; i++) // ciphertext to ints + key - t[i] = ((in[inOffset++] & 0xFF) << 24 | - (in[inOffset++] & 0xFF) << 16 | - (in[inOffset++] & 0xFF) << 8 | - (in[inOffset++] & 0xFF) ) ^ Kd[0][i]; - for (int r = 1; r < ROUNDS; r++) { // apply round transforms + for (i = 0; i < BC; i++) + // ciphertext to ints + key + t[i] = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF)) + ^ Kd[0][i]; + for (int r = 1; r < ROUNDS; r++) { // apply round transforms for (i = 0; i < BC; i++) - a[i] = (_T5[(t[ i ] >>> 24) & 0xFF] ^ - _T6[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ - _T7[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ - _T8[ t[(i + s3) % BC] & 0xFF] ) ^ Kd[r][i]; + a[i] = (_T5[(t[i] >>> 24) & 0xFF] ^ _T6[(t[(i + s1) % BC] >>> 16) & 0xFF] + ^ _T7[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ _T8[t[(i + s3) % BC] & 0xFF]) + ^ Kd[r][i]; System.arraycopy(a, 0, t, 0, BC); -if (_RDEBUG && _debuglevel > 6) System.out.println("PT"+r+"="+toString(t)); + if (_RDEBUG && _debuglevel > 6) System.out.println("PT" + r + "=" + toString(t)); } - for (i = 0; i < BC; i++) { // last round is special + for (i = 0; i < BC; i++) { // last round is special tt = Kd[ROUNDS][i]; - result[j++] = (byte)(_Si[(t[ i ] >>> 24) & 0xFF] ^ (tt >>> 24)); - result[j++] = (byte)(_Si[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ (tt >>> 16)); - result[j++] = (byte)(_Si[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ (tt >>> 8)); - result[j++] = (byte)(_Si[ t[(i + s3) % BC] & 0xFF] ^ tt); + result[j++] = (byte) (_Si[(t[i] >>> 24) & 0xFF] ^ (tt >>> 24)); + result[j++] = (byte) (_Si[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ (tt >>> 16)); + result[j++] = (byte) (_Si[(t[(i + s2) % BC] >>> 8) & 0xFF] ^ (tt >>> 8)); + result[j++] = (byte) (_Si[t[(i + s3) % BC] & 0xFF] ^ tt); } -if (_RDEBUG && _debuglevel > 6) { -System.out.println("PT="+toString(result)); -System.out.println(); -} -if (_RDEBUG) trace(_OUT, "blockDecrypt()"); + if (_RDEBUG && _debuglevel > 6) { + System.out.println("PT=" + toString(result)); + System.out.println(); + } + if (_RDEBUG) trace(_OUT, "blockDecrypt()"); } /** A basic symmetric encryption/decryption test for a given key size. */ - private static boolean self_test (int keysize) { -if (_RDEBUG) trace(_IN, "self_test("+keysize+")"); + private static boolean self_test(int keysize) { + if (_RDEBUG) trace(_IN, "self_test(" + keysize + ")"); boolean ok = false; try { byte[] kb = new byte[keysize]; @@ -722,43 +739,41 @@ if (_RDEBUG) trace(_IN, "self_test("+keysize+")"); for (i = 0; i < _BLOCK_SIZE; i++) pt[i] = (byte) i; -if (_RDEBUG && _debuglevel > 6) { -System.out.println("=========="); -System.out.println(); -System.out.println("KEYSIZE="+(8*keysize)); -System.out.println("KEY="+toString(kb)); -System.out.println(); -} + if (_RDEBUG && _debuglevel > 6) { + System.out.println("=========="); + System.out.println(); + System.out.println("KEYSIZE=" + (8 * keysize)); + System.out.println("KEY=" + toString(kb)); + System.out.println(); + } Object key = makeKey(kb, _BLOCK_SIZE); -if (_RDEBUG && _debuglevel > 6) { -System.out.println("Intermediate Ciphertext Values (Encryption)"); -System.out.println(); -System.out.println("PT="+toString(pt)); -} + if (_RDEBUG && _debuglevel > 6) { + System.out.println("Intermediate Ciphertext Values (Encryption)"); + System.out.println(); + System.out.println("PT=" + toString(pt)); + } byte[] ct = new byte[_BLOCK_SIZE]; blockEncrypt(pt, ct, 0, key, _BLOCK_SIZE); -if (_RDEBUG && _debuglevel > 6) { -System.out.println("Intermediate Plaintext Values (Decryption)"); -System.out.println(); -System.out.println("CT="+toString(ct)); -} + if (_RDEBUG && _debuglevel > 6) { + System.out.println("Intermediate Plaintext Values (Decryption)"); + System.out.println(); + System.out.println("CT=" + toString(ct)); + } byte[] cpt = new byte[_BLOCK_SIZE]; blockDecrypt(ct, cpt, 0, key, _BLOCK_SIZE); ok = areEqual(pt, cpt); - if (!ok) - throw new RuntimeException("Symmetric operation failed"); - } - catch (Exception x) { -if (_RDEBUG && _debuglevel > 0) { - debug("Exception encountered during self-test: " + x.getMessage()); - x.printStackTrace(); -} + if (!ok) throw new RuntimeException("Symmetric operation failed"); + } catch (Exception x) { + if (_RDEBUG && _debuglevel > 0) { + debug("Exception encountered during self-test: " + x.getMessage()); + x.printStackTrace(); + } } -if (_RDEBUG && _debuglevel > 0) debug("Self-test OK? " + ok); -if (_RDEBUG) trace(_OUT, "self_test()"); + if (_RDEBUG && _debuglevel > 0) debug("Self-test OK? " + ok); + if (_RDEBUG) trace(_OUT, "self_test()"); return ok; } @@ -770,33 +785,31 @@ if (_RDEBUG) trace(_OUT, "self_test()"); * @return The number of rounds for a given Rijndael's key and * block sizes. */ - public static final int getRounds (int keySize, int blockSize) { + public static final int getRounds(int keySize, int blockSize) { switch (keySize) { case 16: return blockSize == 16 ? 10 : (blockSize == 24 ? 12 : 14); case 24: return blockSize != 32 ? 12 : 14; - default: // 32 bytes = 256 bits + default: + // 32 bytes = 256 bits return 14; } } - -// utility static methods (from cryptix.util.core ArrayUtil and Hex classes) -//........................................................................... + // utility static methods (from cryptix.util.core ArrayUtil and Hex classes) + //........................................................................... /** * Compares two byte arrays for equality. * * @return true if the arrays have identical contents */ - private static final boolean areEqual (byte[] a, byte[] b) { + private static final boolean areEqual(byte[] a, byte[] b) { int aLength = a.length; - if (aLength != b.length) - return false; + if (aLength != b.length) return false; for (int i = 0; i < aLength; i++) - if (a[i] != b[i]) - return false; + if (a[i] != b[i]) return false; return true; } @@ -804,11 +817,8 @@ if (_RDEBUG) trace(_OUT, "self_test()"); * Returns a string of 2 hexadecimal digits (most significant * digit first) corresponding to the lowest 8 bits of <i>n</i>. */ - private static final String byteToString (int n) { - char[] buf = { - _HEX_DIGITS[(n >>> 4) & 0x0F], - _HEX_DIGITS[ n & 0x0F] - }; + private static final String byteToString(int n) { + char[] buf = { _HEX_DIGITS[(n >>> 4) & 0x0F], _HEX_DIGITS[n & 0x0F]}; return new String(buf); } @@ -817,7 +827,7 @@ if (_RDEBUG) trace(_OUT, "self_test()"); * digit first) corresponding to the integer <i>n</i>, which is * treated as unsigned. */ - private static final String intToString (int n) { + private static final String intToString(int n) { char[] buf = new char[8]; for (int i = 7; i >= 0; i--) { buf[i] = _HEX_DIGITS[n & 0x0F]; @@ -830,13 +840,13 @@ if (_RDEBUG) trace(_OUT, "self_test()"); * Returns a string of hexadecimal digits from a byte array. Each * byte is converted to 2 hex symbols. */ - private static final String toString (byte[] ba) { + private static final String toString(byte[] ba) { int length = ba.length; char[] buf = new char[length * 2]; - for (int i = 0, j = 0, k; i < length; ) { + for (int i = 0, j = 0, k; i < length;) { k = ba[i++]; buf[j++] = _HEX_DIGITS[(k >>> 4) & 0x0F]; - buf[j++] = _HEX_DIGITS[ k & 0x0F]; + buf[j++] = _HEX_DIGITS[k & 0x0F]; } return new String(buf); } @@ -845,7 +855,7 @@ if (_RDEBUG) trace(_OUT, "self_test()"); * Returns a string of hexadecimal digits from an integer array. Each * int is converted to 4 hex symbols. */ - private static final String toString (int[] ia) { + private static final String toString(int[] ia) { int length = ia.length; char[] buf = new char[length * 8]; for (int i = 0, j = 0, k; i < length; i++) { @@ -855,20 +865,19 @@ if (_RDEBUG) trace(_OUT, "self_test()"); buf[j++] = _HEX_DIGITS[(k >>> 20) & 0x0F]; buf[j++] = _HEX_DIGITS[(k >>> 16) & 0x0F]; buf[j++] = _HEX_DIGITS[(k >>> 12) & 0x0F]; - buf[j++] = _HEX_DIGITS[(k >>> 8) & 0x0F]; - buf[j++] = _HEX_DIGITS[(k >>> 4) & 0x0F]; - buf[j++] = _HEX_DIGITS[ k & 0x0F]; + buf[j++] = _HEX_DIGITS[(k >>> 8) & 0x0F]; + buf[j++] = _HEX_DIGITS[(k >>> 4) & 0x0F]; + buf[j++] = _HEX_DIGITS[k & 0x0F]; } return new String(buf); } + // main(): use to generate the Intermediate Values KAT + //........................................................................... -// main(): use to generate the Intermediate Values KAT -//........................................................................... - - public static void main (String[] args) { + public static void main(String[] args) { self_test(16); self_test(24); self_test(32); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/CryptoConstants.java b/core/java/src/net/i2p/crypto/CryptoConstants.java index 78b2a7d1321d89fece9b36bc9c43866baac2dbee..9650390746a2345b3f66eeeb05a567396c3c6b5d 100644 --- a/core/java/src/net/i2p/crypto/CryptoConstants.java +++ b/core/java/src/net/i2p/crypto/CryptoConstants.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * Copyright (c) 2003, TheCrypto * All rights reserved. @@ -29,6 +30,7 @@ package net.i2p.crypto; */ import java.math.BigInteger; + import net.i2p.util.NativeBigInteger; /** @@ -36,29 +38,29 @@ import net.i2p.util.NativeBigInteger; * http://www.ietf.org/proceedings/03mar/I-D/draft-ietf-ipsec-ike-modp-groups-05.txt */ public class CryptoConstants { - public static final BigInteger dsap = new NativeBigInteger( - "9c05b2aa960d9b97b8931963c9cc9e8c3026e9b8ed92fad0a69cc886d5bf8015fcadae31"+ - "a0ad18fab3f01b00a358de237655c4964afaa2b337e96ad316b9fb1cc564b5aec5b69a9f"+ - "f6c3e4548707fef8503d91dd8602e867e6d35d2235c1869ce2479c3b9d5401de04e0727f"+ - "b33d6511285d4cf29538d9e3b6051f5b22cc1c93", 16); - public static final BigInteger dsaq = new NativeBigInteger( - "a5dfc28fef4ca1e286744cd8eed9d29d684046b7", 16); - public static final BigInteger dsag = new NativeBigInteger( - "c1f4d27d40093b429e962d7223824e0bbc47e7c832a39236fc683af84889581075ff9082"+ - "ed32353d4374d7301cda1d23c431f4698599dda02451824ff369752593647cc3ddc197de"+ - "985e43d136cdcfc6bd5409cd2f450821142a5e6f8eb1c3ab5d0484b8129fcf17bce4f7f3"+ - "3321c3cb3dbb14a905e7b2b3e93be4708cbcc82", 16); - public static final BigInteger elgp = new NativeBigInteger( - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"+ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"+ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"+ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"+ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"+ - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"+ - "83655D23DCA3AD961C62F356208552BB9ED529077096966D"+ - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"+ - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"+ - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"+ - "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16); - public static final BigInteger elgg = new NativeBigInteger("2"); -} + public static final BigInteger dsap = new NativeBigInteger( + "9c05b2aa960d9b97b8931963c9cc9e8c3026e9b8ed92fad0a69cc886d5bf8015fcadae31" + + "a0ad18fab3f01b00a358de237655c4964afaa2b337e96ad316b9fb1cc564b5aec5b69a9f" + + "f6c3e4548707fef8503d91dd8602e867e6d35d2235c1869ce2479c3b9d5401de04e0727f" + + "b33d6511285d4cf29538d9e3b6051f5b22cc1c93", + 16); + public static final BigInteger dsaq = new NativeBigInteger("a5dfc28fef4ca1e286744cd8eed9d29d684046b7", 16); + public static final BigInteger dsag = new NativeBigInteger( + "c1f4d27d40093b429e962d7223824e0bbc47e7c832a39236fc683af84889581075ff9082" + + "ed32353d4374d7301cda1d23c431f4698599dda02451824ff369752593647cc3ddc197de" + + "985e43d136cdcfc6bd5409cd2f450821142a5e6f8eb1c3ab5d0484b8129fcf17bce4f7f3" + + "3321c3cb3dbb14a905e7b2b3e93be4708cbcc82", + 16); + public static final BigInteger elgp = new NativeBigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16); + public static final BigInteger elgg = new NativeBigInteger("2"); +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java index 022218420fd69f6ae9886db41598d8f06e8df53d..52d95285ac62fc2b0b00d25bf21d45c3b4b60370 100644 --- a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java +++ b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,18 +9,18 @@ package net.i2p.crypto; * */ -import net.i2p.data.SessionKey; -import net.i2p.data.ByteArray; -import net.i2p.util.RandomSource; -import net.i2p.util.Log; -import net.i2p.util.NativeBigInteger; -import net.i2p.util.Clock; -import net.i2p.util.I2PThread; import java.math.BigInteger; - import java.util.ArrayList; import java.util.List; +import net.i2p.data.ByteArray; +import net.i2p.data.SessionKey; +import net.i2p.util.Clock; +import net.i2p.util.I2PThread; +import net.i2p.util.Log; +import net.i2p.util.NativeBigInteger; +import net.i2p.util.RandomSource; + /** * Generate a new session key through a diffie hellman exchange. This uses the * constants defined in CryptoConstants, which causes the exchange to create a @@ -52,262 +53,303 @@ public class DHSessionKeyBuilder { private BigInteger _peerValue; private SessionKey _sessionKey; private ByteArray _extraExchangedBytes; // bytes after the session key from the DH exchange - + public final static String PROP_DH_PRECALC_MIN = "crypto.dh.precalc.min"; public final static String PROP_DH_PRECALC_MAX = "crypto.dh.precalc.max"; public final static String PROP_DH_PRECALC_DELAY = "crypto.dh.precalc.delay"; public final static String DEFAULT_DH_PRECALC_MIN = "5"; public final static String DEFAULT_DH_PRECALC_MAX = "10"; public final static String DEFAULT_DH_PRECALC_DELAY = "1000"; - - static { - try { - int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_MIN, DEFAULT_DH_PRECALC_MIN)); - MIN_NUM_BUILDERS = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_DH_PRECALC_MIN); - MIN_NUM_BUILDERS = val; - } - try { - int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_MAX, DEFAULT_DH_PRECALC_MAX)); - MAX_NUM_BUILDERS = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_DH_PRECALC_MAX); - MAX_NUM_BUILDERS = val; - } - try { - int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY)); - CALC_DELAY = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_DH_PRECALC_DELAY); - CALC_DELAY = val; - } - - if (_log.shouldLog(Log.DEBUG)) _log.debug("DH Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: " + CALC_DELAY + ")"); - - _precalcThread = new I2PThread(new DHSessionKeyBuilderPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS)); - _precalcThread.setName("DH Precalc"); - _precalcThread.setDaemon(true); - _precalcThread.setPriority(Thread.MIN_PRIORITY); - _precalcThread.start(); + + static { + try { + int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_MIN, DEFAULT_DH_PRECALC_MIN)); + MIN_NUM_BUILDERS = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_DH_PRECALC_MIN); + MIN_NUM_BUILDERS = val; + } + try { + int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_MAX, DEFAULT_DH_PRECALC_MAX)); + MAX_NUM_BUILDERS = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_DH_PRECALC_MAX); + MAX_NUM_BUILDERS = val; + } + try { + int val = Integer.parseInt(System.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY)); + CALC_DELAY = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_DH_PRECALC_DELAY); + CALC_DELAY = val; + } + + if (_log.shouldLog(Log.DEBUG)) + _log.debug("DH Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: " + + CALC_DELAY + ")"); + + _precalcThread = new I2PThread(new DHSessionKeyBuilderPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS)); + _precalcThread.setName("DH Precalc"); + _precalcThread.setDaemon(true); + _precalcThread.setPriority(Thread.MIN_PRIORITY); + _precalcThread.start(); } + /** * Construct a new DH key builder * */ public DHSessionKeyBuilder() { - this(false); - DHSessionKeyBuilder builder = null; - synchronized (_builders) { - if (_builders.size() > 0) { - builder = (DHSessionKeyBuilder)_builders.remove(0); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Removing a builder. # left = " + _builders.size()); - } else { - if (_log.shouldLog(Log.WARN)) _log.warn("NO MORE BUILDERS! creating one now"); - } - } - if (builder != null) { - _myPrivateValue = builder._myPrivateValue; - _myPublicValue = builder._myPublicValue; - _peerValue = builder._peerValue; - _sessionKey = builder._sessionKey; - _extraExchangedBytes = builder._extraExchangedBytes; - } else { - _myPrivateValue = null; - _myPublicValue = null; - _peerValue = null; - _sessionKey = null; - _myPublicValue = generateMyValue(); - _extraExchangedBytes = new ByteArray(); - } + this(false); + DHSessionKeyBuilder builder = null; + synchronized (_builders) { + if (_builders.size() > 0) { + builder = (DHSessionKeyBuilder) _builders.remove(0); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Removing a builder. # left = " + _builders.size()); + } else { + if (_log.shouldLog(Log.WARN)) _log.warn("NO MORE BUILDERS! creating one now"); + } + } + if (builder != null) { + _myPrivateValue = builder._myPrivateValue; + _myPublicValue = builder._myPublicValue; + _peerValue = builder._peerValue; + _sessionKey = builder._sessionKey; + _extraExchangedBytes = builder._extraExchangedBytes; + } else { + _myPrivateValue = null; + _myPublicValue = null; + _peerValue = null; + _sessionKey = null; + _myPublicValue = generateMyValue(); + _extraExchangedBytes = new ByteArray(); + } } - + public DHSessionKeyBuilder(boolean usePool) { - _myPrivateValue = null; - _myPublicValue = null; - _peerValue = null; - _sessionKey = null; - _extraExchangedBytes = new ByteArray(); + _myPrivateValue = null; + _myPublicValue = null; + _peerValue = null; + _sessionKey = null; + _extraExchangedBytes = new ByteArray(); + } + + private static final int getSize() { + synchronized (_builders) { + return _builders.size(); + } } - - private static final int getSize() { synchronized (_builders) { return _builders.size(); } } + private static final int addBuilder(DHSessionKeyBuilder builder) { - int sz = 0; - synchronized (_builders) { - _builders.add(builder); - sz = _builders.size(); - } - return sz; + int sz = 0; + synchronized (_builders) { + _builders.add(builder); + sz = _builders.size(); + } + return sz; } + /** * Create a new private value for the DH exchange, and return the number to * be exchanged, leaving the actual private value accessible through getMyPrivateValue() * */ public BigInteger generateMyValue() { - long start = Clock.getInstance().now(); - _myPrivateValue = new NativeBigInteger(2048, RandomSource.getInstance()); - BigInteger myValue = CryptoConstants.elgg.modPow(_myPrivateValue, CryptoConstants.elgp); - long end = Clock.getInstance().now(); - long diff = end - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took more than a second (" + diff + "ms) to generate local DH value"); - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Took " + diff + "ms to generate local DH value"); - } - return myValue; + long start = Clock.getInstance().now(); + _myPrivateValue = new NativeBigInteger(2048, RandomSource.getInstance()); + BigInteger myValue = CryptoConstants.elgg.modPow(_myPrivateValue, CryptoConstants.elgp); + long end = Clock.getInstance().now(); + long diff = end - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Took more than a second (" + diff + "ms) to generate local DH value"); + } else { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Took " + diff + "ms to generate local DH value"); + } + return myValue; } - + /** * Retrieve the private value used by the local participant in the DH exchange */ - public BigInteger getMyPrivateValue() { return _myPrivateValue; } + public BigInteger getMyPrivateValue() { + return _myPrivateValue; + } + /** * Retrieve the public value used by the local participant in the DH exchange, * generating it if necessary */ - public BigInteger getMyPublicValue() { - if (_myPublicValue == null) - _myPublicValue = generateMyValue(); - return _myPublicValue; + public BigInteger getMyPublicValue() { + if (_myPublicValue == null) _myPublicValue = generateMyValue(); + return _myPublicValue; } + /** * Specify the value given by the peer for use in the session key negotiation * */ - public void setPeerPublicValue(BigInteger peerVal) { _peerValue = peerVal; } - public BigInteger getPeerPublicValue() { return _peerValue; } - + public void setPeerPublicValue(BigInteger peerVal) { + _peerValue = peerVal; + } + + public BigInteger getPeerPublicValue() { + return _peerValue; + } + /** * Retrieve the session key, calculating it if necessary (and if possible). * * @return session key exchanged, or null if the exchange is not complete */ public SessionKey getSessionKey() { - if (_sessionKey != null) return _sessionKey; - if (_peerValue != null) { - if (_myPrivateValue == null) generateMyValue(); - _sessionKey = calculateSessionKey(_myPrivateValue, _peerValue); - } else { - System.err.println("Not ready yet.. privateValue and peerValue must be set (" + (_myPrivateValue != null ? "set":"null") + "," + (_peerValue != null ? "set":"null") + ")"); - } - return _sessionKey; + if (_sessionKey != null) return _sessionKey; + if (_peerValue != null) { + if (_myPrivateValue == null) generateMyValue(); + _sessionKey = calculateSessionKey(_myPrivateValue, _peerValue); + } else { + System.err.println("Not ready yet.. privateValue and peerValue must be set (" + + (_myPrivateValue != null ? "set" : "null") + "," + + (_peerValue != null ? "set" : "null") + ")"); + } + return _sessionKey; } - + /** * Retrieve the extra bytes beyond the session key resulting from the DH exchange. * If there aren't enough bytes (with all of them being consumed by the 32 byte key), * the SHA256 of the key itself is used. * */ - public ByteArray getExtraBytes() { return _extraExchangedBytes; } - + public ByteArray getExtraBytes() { + return _extraExchangedBytes; + } + /** * Calculate a session key based on the private value and the public peer value * */ private final SessionKey calculateSessionKey(BigInteger myPrivateValue, BigInteger publicPeerValue) { - long start = Clock.getInstance().now(); - SessionKey key = new SessionKey(); - BigInteger exchangedKey = publicPeerValue.modPow(myPrivateValue, CryptoConstants.elgp); - byte buf[] = exchangedKey.toByteArray(); - byte val[] = new byte[32]; - if (buf.length < val.length) { - System.arraycopy(buf, 0, val, 0, buf.length); - byte remaining[] = SHA256Generator.getInstance().calculateHash(val).getData(); - _extraExchangedBytes.setData(remaining); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Storing " + remaining.length + " bytes from the DH exchange by SHA256 the session key"); - } else { // (buf.length >= val.length) - System.arraycopy(buf, 0, val, 0, val.length); - byte remaining[] = new byte[buf.length - val.length]; - System.arraycopy(buf, val.length, remaining, 0, remaining.length); - _extraExchangedBytes.setData(remaining); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Storing " + remaining.length + " bytes from the end of the DH exchange"); - } - key.setData(val); - long end = Clock.getInstance().now(); - long diff = end - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Generating session key took too long ("+ diff +" ms"); - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Generating session key "+ diff +" ms"); - } - return key; + long start = Clock.getInstance().now(); + SessionKey key = new SessionKey(); + BigInteger exchangedKey = publicPeerValue.modPow(myPrivateValue, CryptoConstants.elgp); + byte buf[] = exchangedKey.toByteArray(); + byte val[] = new byte[32]; + if (buf.length < val.length) { + System.arraycopy(buf, 0, val, 0, buf.length); + byte remaining[] = SHA256Generator.getInstance().calculateHash(val).getData(); + _extraExchangedBytes.setData(remaining); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Storing " + remaining.length + " bytes from the DH exchange by SHA256 the session key"); + } else { // (buf.length >= val.length) + System.arraycopy(buf, 0, val, 0, val.length); + byte remaining[] = new byte[buf.length - val.length]; + System.arraycopy(buf, val.length, remaining, 0, remaining.length); + _extraExchangedBytes.setData(remaining); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Storing " + remaining.length + " bytes from the end of the DH exchange"); + } + key.setData(val); + long end = Clock.getInstance().now(); + long diff = end - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) _log.warn("Generating session key took too long (" + diff + " ms"); + } else { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Generating session key " + diff + " ms"); + } + return key; } - + public static void main(String args[]) { - RandomSource.getInstance().nextBoolean(); // warm it up - try { Thread.sleep(20*1000); } catch (InterruptedException ie) {} - _log.debug("\n\n\n\nBegin test\n"); - long negTime = 0; - for (int i = 0; i < 5; i++) { - long startNeg = Clock.getInstance().now(); - DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder(); - DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder(); - BigInteger pub1 = builder1.getMyPublicValue(); - builder2.setPeerPublicValue(pub1); - BigInteger pub2 = builder2.getMyPublicValue(); - builder1.setPeerPublicValue(pub2); - SessionKey key1 = builder1.getSessionKey(); - SessionKey key2 = builder2.getSessionKey(); - long endNeg = Clock.getInstance().now(); - negTime += endNeg - startNeg; - - if (!key1.equals(key2)) - _log.error("**ERROR: Keys do not match"); - else - _log.debug("**Success: Keys match"); + RandomSource.getInstance().nextBoolean(); // warm it up + try { + Thread.sleep(20 * 1000); + } catch (InterruptedException ie) { + } + _log.debug("\n\n\n\nBegin test\n"); + long negTime = 0; + for (int i = 0; i < 5; i++) { + long startNeg = Clock.getInstance().now(); + DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder(); + DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder(); + BigInteger pub1 = builder1.getMyPublicValue(); + builder2.setPeerPublicValue(pub1); + BigInteger pub2 = builder2.getMyPublicValue(); + builder1.setPeerPublicValue(pub2); + SessionKey key1 = builder1.getSessionKey(); + SessionKey key2 = builder2.getSessionKey(); + long endNeg = Clock.getInstance().now(); + negTime += endNeg - startNeg; - byte iv[] = new byte[16]; - RandomSource.getInstance().nextBytes(iv); - String origVal = "1234567890123456"; // 16 bytes max using AESEngine - byte enc[] = AESEngine.getInstance().encrypt(origVal.getBytes(), key1, iv); - byte dec[] = AESEngine.getInstance().decrypt(enc, key2, iv); - String tranVal = new String(dec); - if (origVal.equals(tranVal)) - _log.debug("**Success: D(E(val)) == val"); - else - _log.error("**ERROR: D(E(val)) != val [val=(" + tranVal + "), origVal=(" + origVal + ")"); - } - _log.debug("Negotiation time for 5 runs: " + negTime + " @ " + negTime/5l + "ms each"); - try { Thread.sleep(2000); } catch (InterruptedException ie) {} + if (!key1.equals(key2)) + _log.error("**ERROR: Keys do not match"); + else + _log.debug("**Success: Keys match"); + + byte iv[] = new byte[16]; + RandomSource.getInstance().nextBytes(iv); + String origVal = "1234567890123456"; // 16 bytes max using AESEngine + byte enc[] = AESEngine.getInstance().encrypt(origVal.getBytes(), key1, iv); + byte dec[] = AESEngine.getInstance().decrypt(enc, key2, iv); + String tranVal = new String(dec); + if (origVal.equals(tranVal)) + _log.debug("**Success: D(E(val)) == val"); + else + _log.error("**ERROR: D(E(val)) != val [val=(" + tranVal + "), origVal=(" + origVal + ")"); + } + _log.debug("Negotiation time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each"); + try { + Thread.sleep(2000); + } catch (InterruptedException ie) { + } } - + private static class DHSessionKeyBuilderPrecalcRunner implements Runnable { - private int _minSize; - private int _maxSize; - private DHSessionKeyBuilderPrecalcRunner(int minSize, int maxSize) { - _minSize = minSize; - _maxSize = maxSize; - } - public void run() { - while (true) { + private int _minSize; + private int _maxSize; + + private DHSessionKeyBuilderPrecalcRunner(int minSize, int maxSize) { + _minSize = minSize; + _maxSize = maxSize; + } + + public void run() { + while (true) { + + int curSize = 0; + long start = Clock.getInstance().now(); + int startSize = getSize(); + curSize = startSize; + while (curSize < _minSize) { + while (curSize < _maxSize) { + curSize = addBuilder(precalc(curSize)); + // for some relief... + try { + Thread.sleep(CALC_DELAY); + } catch (InterruptedException ie) { + } + } + } + long end = Clock.getInstance().now(); + int numCalc = curSize - startSize; + if (numCalc > 0) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Precalced " + numCalc + " to " + curSize + " in " + + (end - start - CALC_DELAY * numCalc) + "ms (not counting " + + (CALC_DELAY * numCalc) + "ms relief). now sleeping"); + } + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException ie) { + } + } + } - int curSize = 0; - long start = Clock.getInstance().now(); - int startSize = getSize(); - curSize = startSize; - while (curSize < _minSize) { - while (curSize < _maxSize) { - curSize = addBuilder(precalc(curSize)); - // for some relief... - try { Thread.sleep(CALC_DELAY); } catch (InterruptedException ie) {} - } - } - long end = Clock.getInstance().now(); - int numCalc = curSize - startSize; - if (numCalc > 0) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalced " + numCalc + " to " + curSize + " in " + (end-start-CALC_DELAY*numCalc) + "ms (not counting " + (CALC_DELAY*numCalc) + "ms relief). now sleeping"); - } - try { Thread.sleep(30*1000); } catch (InterruptedException ie) {} - } - } - - private DHSessionKeyBuilder precalc(int i) { - DHSessionKeyBuilder builder = new DHSessionKeyBuilder(false); - builder.getMyPublicValue(); - //_log.debug("Precalc " + i + " complete"); - return builder; - } + private DHSessionKeyBuilder precalc(int i) { + DHSessionKeyBuilder builder = new DHSessionKeyBuilder(false); + builder.getMyPublicValue(); + //_log.debug("Precalc " + i + " complete"); + return builder; + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/DSAEngine.java b/core/java/src/net/i2p/crypto/DSAEngine.java index 1b7ff8bac8b4fa6d07fea1cb298f870d25982c18..c19a28cc75dfe92d8fc2caf3b30d9a93c9138306 100644 --- a/core/java/src/net/i2p/crypto/DSAEngine.java +++ b/core/java/src/net/i2p/crypto/DSAEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * Copyright (c) 2003, TheCrypto * All rights reserved. @@ -28,254 +29,256 @@ package net.i2p.crypto; * POSSIBILITY OF SUCH DAMAGE. */ +import java.math.BigInteger; + +import net.i2p.data.Hash; import net.i2p.data.Signature; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; -import net.i2p.data.Hash; -import net.i2p.crypto.CryptoConstants; -import net.i2p.util.NativeBigInteger; -import net.i2p.util.RandomSource; import net.i2p.util.Clock; - import net.i2p.util.Log; - -import java.math.BigInteger; +import net.i2p.util.NativeBigInteger; +import net.i2p.util.RandomSource; public class DSAEngine { private final static Log _log = new Log(DSAEngine.class); private static DSAEngine _instance = new DSAEngine(); - public static DSAEngine getInstance() { return _instance; } - + + public static DSAEngine getInstance() { + return _instance; + } + public boolean verifySignature(Signature signature, byte signedData[], SigningPublicKey verifyingKey) { - long start = Clock.getInstance().now(); - - byte[] sigbytes = signature.getData(); - byte rbytes[] = new byte[20]; - byte sbytes[] = new byte[20]; - for (int x = 0; x < 40; x++) { - if (x < 20) { - rbytes[x] = sigbytes[x]; - } else { - sbytes[x-20] = sigbytes[x]; - } - } - BigInteger s = new NativeBigInteger(1, sbytes); - BigInteger r = new NativeBigInteger(1, rbytes); - BigInteger y = new NativeBigInteger(1, verifyingKey.getData()); - BigInteger w = s.modInverse(CryptoConstants.dsaq); - BigInteger u1 = ((new NativeBigInteger(1, calculateHash(signedData).getData())).multiply(w)).mod(CryptoConstants.dsaq); - BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq); - BigInteger v = ((CryptoConstants.dsag.modPow(u1, CryptoConstants.dsap)).multiply(y.modPow(u2, CryptoConstants.dsap))).mod(CryptoConstants.dsap).mod(CryptoConstants.dsaq); - - boolean ok = v.compareTo(r) == 0; - - long diff = Clock.getInstance().now() - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to verify the signature ("+ diff + "ms)"); - } - - return ok; + long start = Clock.getInstance().now(); + + byte[] sigbytes = signature.getData(); + byte rbytes[] = new byte[20]; + byte sbytes[] = new byte[20]; + for (int x = 0; x < 40; x++) { + if (x < 20) { + rbytes[x] = sigbytes[x]; + } else { + sbytes[x - 20] = sigbytes[x]; + } + } + BigInteger s = new NativeBigInteger(1, sbytes); + BigInteger r = new NativeBigInteger(1, rbytes); + BigInteger y = new NativeBigInteger(1, verifyingKey.getData()); + BigInteger w = s.modInverse(CryptoConstants.dsaq); + BigInteger u1 = ((new NativeBigInteger(1, calculateHash(signedData).getData())).multiply(w)) + .mod(CryptoConstants.dsaq); + BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq); + BigInteger v = ((CryptoConstants.dsag.modPow(u1, CryptoConstants.dsap)) + .multiply(y.modPow(u2, + CryptoConstants.dsap))) + .mod( + CryptoConstants.dsap) + .mod( + CryptoConstants.dsaq); + + boolean ok = v.compareTo(r) == 0; + + long diff = Clock.getInstance().now() - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to verify the signature (" + diff + "ms)"); + } + + return ok; } - + public Signature sign(byte data[], SigningPrivateKey signingKey) { - if ( (signingKey == null) || (data == null) || (data.length <= 0) ) return null; - long start = Clock.getInstance().now(); - - Signature sig = new Signature(); - BigInteger k; - - do { - k = new BigInteger(160, RandomSource.getInstance()); - } while (k.compareTo(CryptoConstants.dsaq) != 1); - - BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq); - BigInteger kinv = k.modInverse(CryptoConstants.dsaq); - Hash h = calculateHash(data); - - if (h == null) return null; - - BigInteger M = new NativeBigInteger(1, h.getData()); - BigInteger x = new NativeBigInteger(1, signingKey.getData()); - BigInteger s = (kinv.multiply(M.add(x.multiply(r)))).mod(CryptoConstants.dsaq); - - byte[] rbytes = r.toByteArray(); + if ((signingKey == null) || (data == null) || (data.length <= 0)) return null; + long start = Clock.getInstance().now(); + + Signature sig = new Signature(); + BigInteger k; + + do { + k = new BigInteger(160, RandomSource.getInstance()); + } while (k.compareTo(CryptoConstants.dsaq) != 1); + + BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq); + BigInteger kinv = k.modInverse(CryptoConstants.dsaq); + Hash h = calculateHash(data); + + if (h == null) return null; + + BigInteger M = new NativeBigInteger(1, h.getData()); + BigInteger x = new NativeBigInteger(1, signingKey.getData()); + BigInteger s = (kinv.multiply(M.add(x.multiply(r)))).mod(CryptoConstants.dsaq); + + byte[] rbytes = r.toByteArray(); byte[] sbytes = s.toByteArray(); byte[] out = new byte[40]; - - if (rbytes.length == 20) { + + if (rbytes.length == 20) { for (int i = 0; i < 20; i++) { out[i] = rbytes[i]; } } else if (rbytes.length == 21) { for (int i = 0; i < 20; i++) { - out[i] = rbytes[i+1]; + out[i] = rbytes[i + 1]; } } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short rbytes.length [" + rbytes.length + "]"); for (int i = 0; i < rbytes.length; i++) - out[i+20-rbytes.length] = rbytes[i]; + out[i + 20 - rbytes.length] = rbytes[i]; } if (sbytes.length == 20) { for (int i = 0; i < 20; i++) { - out[i+20] = sbytes[i]; + out[i + 20] = sbytes[i]; } } else if (sbytes.length == 21) { for (int i = 0; i < 20; i++) { - out[i+20] = sbytes[i+1]; + out[i + 20] = sbytes[i + 1]; } } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short sbytes.length [" + sbytes.length + "]"); - for (int i = 0; i< sbytes.length; i++) - out[i+20+20-sbytes.length] = sbytes[i]; + for (int i = 0; i < sbytes.length; i++) + out[i + 20 + 20 - sbytes.length] = sbytes[i]; } - sig.setData(out); + sig.setData(out); - long diff = Clock.getInstance().now() - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to sign (" + diff + "ms)"); - } + long diff = Clock.getInstance().now() - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to sign (" + diff + "ms)"); + } - return sig; + return sig; } - private int[] H0 = { - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - }; - - private Hash calculateHash(byte[]source) { - long length = source.length * 8; - int k = 448 - (int) ((length + 1) % 512); - if (k < 0) { - k += 512; - } - int padbytes = k / 8; - int wordlength = (int) (source.length / 4 + padbytes / 4 + 3); - int[] M0 = new int[wordlength]; - int wordcount = 0; - int x = 0; - for (x = 0; x < (source.length / 4) * 4; x += 4) { - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; - M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0; - wordcount++; - } - - switch (source.length - (wordcount + 1) * 4 + 4) { - case 0: - M0[wordcount] |= 0x80000000; - break; - case 1: - M0[wordcount] = source[x] << 24 >>> 24 << 24; - M0[wordcount] |= 0x00800000; - break; - case 2: - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= 0x00008000; - break; - case 3: - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; - M0[wordcount] |= 0x00000080; - break; - } - M0[wordlength - 2] = (int) (length >>> 32); - M0[wordlength - 1] = (int) (length); - int[] H = new int[5]; - for (x = 0; x < 5; x++) { - H[x] = H0[x]; - } - int blocks = M0.length / 16; - for (int bl = 0; bl < blocks; bl++) { - int a = H[0]; - int b = H[1]; - int c = H[2]; - int d = H[3]; - int e = H[4]; - - int[] W = new int[80]; - - for (x = 0; x < 80; x++) { - if (x < 16) { - W[x] = M0[bl * 16 + x]; - } else { - W[x] = ROTL(1, W[x - 3] ^ W[x - 8] ^ W[x - 14] ^ W[x - 16]); - } - } - - for (x = 0; x < 80; x++) { - int T = add(ROTL(5, a), add(f(x, b, c, d), add(e, add(k(x), W[x])))); - e = d; - d = c; - c = ROTL(30, b); - b = a; - a = T; - } - - H[0] = add(a, H[0]); - H[1] = add(b, H[1]); - H[2] = add(c, H[2]); - H[3] = add(d, H[3]); - H[4] = add(e, H[4]); - } - - byte[] hashbytes = new byte[20]; - for (x = 0; x < 5; x++) { - hashbytes[ x * 4 ] = (byte) (H[x] << 0 >>> 24); - hashbytes[x * 4 + 1] = (byte) (H[x] << 8 >>> 24); - hashbytes[x * 4 + 2] = (byte) (H[x] << 16 >>> 24); - hashbytes[x * 4 + 3] = (byte) (H[x] << 24 >>> 24); - } - Hash hash = new Hash(); - hash.setData(hashbytes); - return hash; + private int[] H0 = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0}; + + private Hash calculateHash(byte[] source) { + long length = source.length * 8; + int k = 448 - (int) ((length + 1) % 512); + if (k < 0) { + k += 512; + } + int padbytes = k / 8; + int wordlength = (int) (source.length / 4 + padbytes / 4 + 3); + int[] M0 = new int[wordlength]; + int wordcount = 0; + int x = 0; + for (x = 0; x < (source.length / 4) * 4; x += 4) { + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; + M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0; + wordcount++; + } + + switch (source.length - (wordcount + 1) * 4 + 4) { + case 0: + M0[wordcount] |= 0x80000000; + break; + case 1: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= 0x00800000; + break; + case 2: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= 0x00008000; + break; + case 3: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; + M0[wordcount] |= 0x00000080; + break; + } + M0[wordlength - 2] = (int) (length >>> 32); + M0[wordlength - 1] = (int) (length); + int[] H = new int[5]; + for (x = 0; x < 5; x++) { + H[x] = H0[x]; + } + int blocks = M0.length / 16; + for (int bl = 0; bl < blocks; bl++) { + int a = H[0]; + int b = H[1]; + int c = H[2]; + int d = H[3]; + int e = H[4]; + + int[] W = new int[80]; + + for (x = 0; x < 80; x++) { + if (x < 16) { + W[x] = M0[bl * 16 + x]; + } else { + W[x] = ROTL(1, W[x - 3] ^ W[x - 8] ^ W[x - 14] ^ W[x - 16]); + } + } + + for (x = 0; x < 80; x++) { + int T = add(ROTL(5, a), add(f(x, b, c, d), add(e, add(k(x), W[x])))); + e = d; + d = c; + c = ROTL(30, b); + b = a; + a = T; + } + + H[0] = add(a, H[0]); + H[1] = add(b, H[1]); + H[2] = add(c, H[2]); + H[3] = add(d, H[3]); + H[4] = add(e, H[4]); + } + + byte[] hashbytes = new byte[20]; + for (x = 0; x < 5; x++) { + hashbytes[x * 4] = (byte) (H[x] << 0 >>> 24); + hashbytes[x * 4 + 1] = (byte) (H[x] << 8 >>> 24); + hashbytes[x * 4 + 2] = (byte) (H[x] << 16 >>> 24); + hashbytes[x * 4 + 3] = (byte) (H[x] << 24 >>> 24); + } + Hash hash = new Hash(); + hash.setData(hashbytes); + return hash; } private int k(int t) { - if (t > -1 && t < 20) { - return 0x5a827999; - } else if (t > 19 && t < 40) { - return 0x6ed9eba1; - } else if (t > 39 && t < 60) { - return 0x8f1bbcdc; - } else if (t > 59 && t < 80) { - return 0xca62c1d6; - } - return 0x00000000; + if (t > -1 && t < 20) { + return 0x5a827999; + } else if (t > 19 && t < 40) { + return 0x6ed9eba1; + } else if (t > 39 && t < 60) { + return 0x8f1bbcdc; + } else if (t > 59 && t < 80) { return 0xca62c1d6; } + return 0x00000000; } private int f(int t, int x, int y, int z) { - if (t > -1 && t < 20) { - return Ch(x, y, z); - } else if (t > 19 && t < 40) { - return Parity(x, y, z); - } else if (t > 39 && t < 60) { - return Maj(x, y, z); - } else if (t > 59 && t < 80) { - return Parity(x, y, z); - } - return 0x00000000; + if (t > -1 && t < 20) { + return Ch(x, y, z); + } else if (t > 19 && t < 40) { + return Parity(x, y, z); + } else if (t > 39 && t < 60) { + return Maj(x, y, z); + } else if (t > 59 && t < 80) { return Parity(x, y, z); } + return 0x00000000; } private int Ch(int x, int y, int z) { - return (x & y) ^ (~x & z); + return (x & y) ^ (~x & z); } private int Parity(int x, int y, int z) { - return x ^ y ^ z; + return x ^ y ^ z; } private int Maj(int x, int y, int z) { - return (x & y) ^ (x & z) ^ (y & z); + return (x & y) ^ (x & z) ^ (y & z); } private int ROTL(int n, int x) { - return (x << n) | (x >>> 32 - n); + return (x << n) | (x >>> 32 - n); } private int add(int x, int y) { - return x + y; + return x + y; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/DummyElGamalEngine.java b/core/java/src/net/i2p/crypto/DummyElGamalEngine.java index fdaa2a1bf5331af919cfa18678005432c5d1298e..d86428ded458c6b6d6cb9c496f08142c7ad564f3 100644 --- a/core/java/src/net/i2p/crypto/DummyElGamalEngine.java +++ b/core/java/src/net/i2p/crypto/DummyElGamalEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -23,69 +24,72 @@ import net.i2p.util.Log; * @author jrandom */ public class DummyElGamalEngine extends ElGamalEngine { - private final static Log _log = new Log(DummyElGamalEngine.class); - + private final static Log _log = new Log(DummyElGamalEngine.class); + public DummyElGamalEngine() { - _log.log(Log.CRIT, "Dummy ElGamal engine in use! NO DATA SECURITY. Danger Will Robinson, Danger!", new Exception("I really hope you know what you're doing")); + _log.log(Log.CRIT, "Dummy ElGamal engine in use! NO DATA SECURITY. Danger Will Robinson, Danger!", + new Exception("I really hope you know what you're doing")); } - + /** encrypt the data to the public key * @return encrypted data * @param publicKey public key encrypt to * @param data data to encrypt - */ + */ public byte[] encrypt(byte data[], PublicKey publicKey) { - if ( (data == null) || (data.length >= 223) ) throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment"); - if (publicKey == null) throw new IllegalArgumentException("Null public key specified"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(256); - try { - baos.write(0xFF); - Hash hash = SHA256Generator.getInstance().calculateHash(data); - hash.writeBytes(baos); - baos.write(data); - baos.flush(); - } catch (Exception e) { - _log.error("Internal error writing to buffer", e); - return null; - } - byte d2[] = baos.toByteArray(); - byte[] out = new byte[514]; - System.arraycopy(d2, 0, out, (d2.length < 257 ? 257 - d2.length : 0), (d2.length > 257 ? 257 : d2.length)); - return out; + if ((data == null) || (data.length >= 223)) + throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment"); + if (publicKey == null) throw new IllegalArgumentException("Null public key specified"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(256); + try { + baos.write(0xFF); + Hash hash = SHA256Generator.getInstance().calculateHash(data); + hash.writeBytes(baos); + baos.write(data); + baos.flush(); + } catch (Exception e) { + _log.error("Internal error writing to buffer", e); + return null; + } + byte d2[] = baos.toByteArray(); + byte[] out = new byte[514]; + System.arraycopy(d2, 0, out, (d2.length < 257 ? 257 - d2.length : 0), (d2.length > 257 ? 257 : d2.length)); + return out; } - + /** Decrypt the data * @param encrypted encrypted data * @param privateKey private key to decrypt with * @return unencrypted data - */ + */ public byte[] decrypt(byte encrypted[], PrivateKey privateKey) { - if ( (encrypted == null) || (encrypted.length > 514) ) throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment"); - byte val[] = new byte[257]; - System.arraycopy(encrypted, 0, val, 0, val.length); - int i = 0; - for (i = 0; i < val.length; i++) - if (val[i] != (byte)0x00) - break; - ByteArrayInputStream bais = new ByteArrayInputStream(val, i, val.length - i); - Hash hash = new Hash(); - byte rv[] = null; - try { - bais.read(); // skip first byte - hash.readBytes(bais); - rv = new byte[val.length - i - 1 - 32]; - bais.read(rv); - } catch (Exception e) { - _log.error("Internal error reading value", e); - return null; - } - Hash calcHash = SHA256Generator.getInstance().calculateHash(rv); - if (calcHash.equals(hash)) { - _log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length)); - return rv; - } else { - _log.debug("Doesn't match hash [calc=" + calcHash + " sent hash=" + hash + "]\ndata = " + new String(rv), new Exception("Doesn't match")); - return null; - } + if ((encrypted == null) || (encrypted.length > 514)) + throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment"); + byte val[] = new byte[257]; + System.arraycopy(encrypted, 0, val, 0, val.length); + int i = 0; + for (i = 0; i < val.length; i++) + if (val[i] != (byte) 0x00) break; + ByteArrayInputStream bais = new ByteArrayInputStream(val, i, val.length - i); + Hash hash = new Hash(); + byte rv[] = null; + try { + bais.read(); // skip first byte + hash.readBytes(bais); + rv = new byte[val.length - i - 1 - 32]; + bais.read(rv); + } catch (Exception e) { + _log.error("Internal error reading value", e); + return null; + } + Hash calcHash = SHA256Generator.getInstance().calculateHash(rv); + if (calcHash.equals(hash)) { + _log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length)); + return rv; + } else { + _log.debug("Doesn't match hash [calc=" + calcHash + " sent hash=" + hash + "]\ndata = " + new String(rv), + new Exception("Doesn't match")); + return null; + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java index d2b7d717491080a93f36c2fa9bb948fec9b2e5e8..1e9e54fa0d72b65e41f5b303bf4213324e6bef79 100644 --- a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java +++ b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -24,10 +25,10 @@ import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; +import net.i2p.stat.StatManager; +import net.i2p.util.Clock; import net.i2p.util.Log; import net.i2p.util.RandomSource; -import net.i2p.util.Clock; -import net.i2p.stat.StatManager; /** * Handles the actual ElGamal+AES encryption and decryption scenarios using the @@ -36,76 +37,87 @@ import net.i2p.stat.StatManager; public class ElGamalAESEngine { private final static Log _log = new Log(ElGamalAESEngine.class); private final static int MIN_ENCRYPTED_SIZE = 80; // smallest possible resulting size - + static { - StatManager.getInstance().createFrequencyStat("crypto.elGamalAES.encryptNewSession", - "how frequently we encrypt to a new ElGamal/AES+SessionTag session?", "Encryption", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l } ); - StatManager.getInstance().createFrequencyStat("crypto.elGamalAES.encryptExistingSession", - "how frequently we encrypt to an existing ElGamal/AES+SessionTag session?", "Encryption", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l } ); - StatManager.getInstance().createFrequencyStat("crypto.elGamalAES.decryptNewSession", - "how frequently we decrypt with a new ElGamal/AES+SessionTag session?", "Encryption", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l } ); - StatManager.getInstance().createFrequencyStat("crypto.elGamalAES.decryptExistingSession", - "how frequently we decrypt with an existing ElGamal/AES+SessionTag session?", "Encryption", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l } ); - StatManager.getInstance().createFrequencyStat("crypto.elGamalAES.decryptFail", - "how frequently we fail to decrypt with ElGamal/AES+SessionTag?", "Encryption", new long[] { 60*60*1000l, 24*60*60*1000l } ); + StatManager.getInstance() + .createFrequencyStat("crypto.elGamalAES.encryptNewSession", + "how frequently we encrypt to a new ElGamal/AES+SessionTag session?", + "Encryption", new long[] { 60 * 1000l, 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); + StatManager.getInstance() + .createFrequencyStat("crypto.elGamalAES.encryptExistingSession", + "how frequently we encrypt to an existing ElGamal/AES+SessionTag session?", + "Encryption", new long[] { 60 * 1000l, 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); + StatManager.getInstance() + .createFrequencyStat("crypto.elGamalAES.decryptNewSession", + "how frequently we decrypt with a new ElGamal/AES+SessionTag session?", + "Encryption", new long[] { 60 * 1000l, 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); + StatManager.getInstance() + .createFrequencyStat("crypto.elGamalAES.decryptExistingSession", + "how frequently we decrypt with an existing ElGamal/AES+SessionTag session?", + "Encryption", new long[] { 60 * 1000l, 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); + StatManager.getInstance() + .createFrequencyStat("crypto.elGamalAES.decryptFail", + "how frequently we fail to decrypt with ElGamal/AES+SessionTag?", "Encryption", + new long[] { 60 * 60 * 1000l, 24 * 60 * 60 * 1000l}); } - - /** + + /** * Decrypt the message using the given private key. This works according to the * ElGamal+AES algorithm in the data structure spec. * */ public static byte[] decrypt(byte data[], PrivateKey targetPrivateKey) throws DataFormatException { - if (data == null) { - if (_log.shouldLog(Log.WARN)) _log.warn("Null data being decrypted?"); - return null; - } else if (data.length < MIN_ENCRYPTED_SIZE) { - if (_log.shouldLog(Log.WARN)) _log.warn("Data is less than the minimum size (" + data.length +" < " + MIN_ENCRYPTED_SIZE + ")"); - return null; - } - - byte tag[] = new byte[32]; - System.arraycopy(data, 0, tag, 0, tag.length); - SessionTag st = new SessionTag(tag); - SessionKey key = SessionKeyManager.getInstance().consumeTag(st); - SessionKey foundKey = new SessionKey(); - foundKey.setData(null); - SessionKey usedKey = new SessionKey(); - Set foundTags = new HashSet(); - byte decrypted[] = null; - if (key != null) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is known for tag " + st); - usedKey.setData(key.getData()); - decrypted = decryptExistingSession(data, key, targetPrivateKey, foundTags, usedKey, foundKey); - if (decrypted != null) - StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptExistingSession"); - else - StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptFailed"); - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is NOT known for tag " + st); - decrypted = decryptNewSession(data, targetPrivateKey, foundTags, usedKey, foundKey); - if (decrypted != null) - StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptNewSession"); - else - StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptFailed"); - } - - if ( (key == null) && (decrypted == null) ) { - //_log.debug("Unable to decrypt the data starting with tag [" + st + "] - did the tag expire recently?", new Exception("Decrypt failure")); - } - - if (foundTags.size() > 0) { - if (foundKey.getData() != null) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Found key: " + foundKey); - SessionKeyManager.getInstance().tagsReceived(foundKey, foundTags); - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Used key: " + usedKey); - SessionKeyManager.getInstance().tagsReceived(usedKey, foundTags); - } - } - return decrypted; + if (data == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Null data being decrypted?"); + return null; + } else if (data.length < MIN_ENCRYPTED_SIZE) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Data is less than the minimum size (" + data.length + " < " + MIN_ENCRYPTED_SIZE + ")"); + return null; + } + + byte tag[] = new byte[32]; + System.arraycopy(data, 0, tag, 0, tag.length); + SessionTag st = new SessionTag(tag); + SessionKey key = SessionKeyManager.getInstance().consumeTag(st); + SessionKey foundKey = new SessionKey(); + foundKey.setData(null); + SessionKey usedKey = new SessionKey(); + Set foundTags = new HashSet(); + byte decrypted[] = null; + if (key != null) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is known for tag " + st); + usedKey.setData(key.getData()); + decrypted = decryptExistingSession(data, key, targetPrivateKey, foundTags, usedKey, foundKey); + if (decrypted != null) + StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptExistingSession"); + else + StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptFailed"); + } else { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Key is NOT known for tag " + st); + decrypted = decryptNewSession(data, targetPrivateKey, foundTags, usedKey, foundKey); + if (decrypted != null) + StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptNewSession"); + else + StatManager.getInstance().updateFrequency("crypto.elGamalAES.decryptFailed"); + } + + if ((key == null) && (decrypted == null)) { + //_log.debug("Unable to decrypt the data starting with tag [" + st + "] - did the tag expire recently?", new Exception("Decrypt failure")); + } + + if (foundTags.size() > 0) { + if (foundKey.getData() != null) { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Found key: " + foundKey); + SessionKeyManager.getInstance().tagsReceived(foundKey, foundTags); + } else { + if (_log.shouldLog(Log.DEBUG)) _log.debug("Used key: " + usedKey); + SessionKeyManager.getInstance().tagsReceived(usedKey, foundTags); + } + } + return decrypted; } - + /** * scenario 1: * Begin with 222 bytes, ElG encrypted, containing: @@ -120,55 +132,56 @@ public class ElGamalAESEngine { * * @return null if decryption fails */ - static byte[] decryptNewSession(byte data[], PrivateKey targetPrivateKey, Set foundTags, SessionKey usedKey, SessionKey foundKey) throws DataFormatException { - if (data == null) { - if (_log.shouldLog(Log.WARN)) _log.warn("Data is null, unable to decrypt new session"); - return null; - } else if (data.length < 514) { - if (_log.shouldLog(Log.WARN)) _log.warn("Data length is too small ("+ data.length + ")"); - return null; - } - byte elgEncr[] = new byte[514]; - if (data.length > 514) { - System.arraycopy(data, 0, elgEncr, 0, 514); - } else { - System.arraycopy(data, 0, elgEncr, 514-data.length, data.length); - } - byte elgDecr[] = ElGamalEngine.getInstance().decrypt(elgEncr, targetPrivateKey); - if (elgDecr == null) - return null; - - ByteArrayInputStream bais = new ByteArrayInputStream(elgDecr); - byte preIV[] = null; - - try { - usedKey.readBytes(bais); - preIV = new byte[32]; - int read = bais.read(preIV); - if (read != preIV.length) { - // hmm, this can't really happen... - throw new DataFormatException("Somehow ElGamal broke and 256 bytes is less than 32 bytes..."); - } - } catch (IOException ioe) { - if (_log.shouldLog(Log.ERROR)) _log.error("Error decrypting the new session", ioe); - return null; - } - // ignore the next 192 bytes - byte aesEncr[] = new byte[data.length - 514]; - System.arraycopy(data, 514, aesEncr, 0, aesEncr.length); - - //_log.debug("Pre IV for decryptNewSession: " + DataHelper.toString(preIV, 32)); - //_log.debug("SessionKey for decryptNewSession: " + DataHelper.toString(key.getData(), 32)); - Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); - byte iv[] = new byte[16]; - System.arraycopy(ivHash.getData(), 0, iv, 0, 16); - - byte aesDecr[] = decryptAESBlock(aesEncr, usedKey, iv, null, foundTags, foundKey); - - if (_log.shouldLog(Log.DEBUG)) _log.debug("Decrypt with a NEW session successfull: # tags read = " + foundTags.size(), new Exception("Decrypted by")); - return aesDecr; + static byte[] decryptNewSession(byte data[], PrivateKey targetPrivateKey, Set foundTags, SessionKey usedKey, + SessionKey foundKey) throws DataFormatException { + if (data == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Data is null, unable to decrypt new session"); + return null; + } else if (data.length < 514) { + if (_log.shouldLog(Log.WARN)) _log.warn("Data length is too small (" + data.length + ")"); + return null; + } + byte elgEncr[] = new byte[514]; + if (data.length > 514) { + System.arraycopy(data, 0, elgEncr, 0, 514); + } else { + System.arraycopy(data, 0, elgEncr, 514 - data.length, data.length); + } + byte elgDecr[] = ElGamalEngine.getInstance().decrypt(elgEncr, targetPrivateKey); + if (elgDecr == null) return null; + + ByteArrayInputStream bais = new ByteArrayInputStream(elgDecr); + byte preIV[] = null; + + try { + usedKey.readBytes(bais); + preIV = new byte[32]; + int read = bais.read(preIV); + if (read != preIV.length) { + // hmm, this can't really happen... + throw new DataFormatException("Somehow ElGamal broke and 256 bytes is less than 32 bytes..."); } + } catch (IOException ioe) { + if (_log.shouldLog(Log.ERROR)) _log.error("Error decrypting the new session", ioe); + return null; + } + // ignore the next 192 bytes + byte aesEncr[] = new byte[data.length - 514]; + System.arraycopy(data, 514, aesEncr, 0, aesEncr.length); + + //_log.debug("Pre IV for decryptNewSession: " + DataHelper.toString(preIV, 32)); + //_log.debug("SessionKey for decryptNewSession: " + DataHelper.toString(key.getData(), 32)); + Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); + byte iv[] = new byte[16]; + System.arraycopy(ivHash.getData(), 0, iv, 0, 16); + + byte aesDecr[] = decryptAESBlock(aesEncr, usedKey, iv, null, foundTags, foundKey); + + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Decrypt with a NEW session successfull: # tags read = " + foundTags.size(), + new Exception("Decrypted by")); + return aesDecr; } - + /** * scenario 2: * The data begins with 32 byte session tag, which also serves as the preIV. @@ -187,31 +200,35 @@ public class ElGamalAESEngine { * @param foundKey session key which may be filled with a new sessionKey found during decryption * */ - static byte[] decryptExistingSession(byte data[], SessionKey key, PrivateKey targetPrivateKey, Set foundTags, SessionKey usedKey, SessionKey foundKey) throws DataFormatException { - byte preIV[] = new byte[32]; - System.arraycopy(data, 0, preIV, 0, preIV.length); - byte encr[] = new byte[data.length-32]; - System.arraycopy(data, 32, encr, 0, encr.length); - Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); - byte iv[] = new byte[16]; - System.arraycopy(ivHash.getData(), 0, iv, 0, 16); - - usedKey.setData(key.getData()); - - //_log.debug("Pre IV for decryptExistingSession: " + DataHelper.toString(preIV, 32)); - //_log.debug("SessionKey for decryptNewSession: " + DataHelper.toString(key.getData(), 32)); - byte decrypted[] = decryptAESBlock(encr, key, iv, preIV, foundTags, foundKey); - if (decrypted == null) { - // it begins with a valid session tag, but thats just a coincidence. - if (_log.shouldLog(Log.DEBUG)) _log.debug("Decrypt with a non session tag, but tags read: " + foundTags.size()); - return decryptNewSession(data, targetPrivateKey, foundTags, usedKey, foundKey); - } else { - // existing session decrypted successfully! - if (_log.shouldLog(Log.DEBUG)) _log.debug("Decrypt with an EXISTING session tag successfull, # tags read: " + foundTags.size(), new Exception("Decrypted by")); - return decrypted; - } + static byte[] decryptExistingSession(byte data[], SessionKey key, PrivateKey targetPrivateKey, Set foundTags, + SessionKey usedKey, SessionKey foundKey) throws DataFormatException { + byte preIV[] = new byte[32]; + System.arraycopy(data, 0, preIV, 0, preIV.length); + byte encr[] = new byte[data.length - 32]; + System.arraycopy(data, 32, encr, 0, encr.length); + Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); + byte iv[] = new byte[16]; + System.arraycopy(ivHash.getData(), 0, iv, 0, 16); + + usedKey.setData(key.getData()); + + //_log.debug("Pre IV for decryptExistingSession: " + DataHelper.toString(preIV, 32)); + //_log.debug("SessionKey for decryptNewSession: " + DataHelper.toString(key.getData(), 32)); + byte decrypted[] = decryptAESBlock(encr, key, iv, preIV, foundTags, foundKey); + if (decrypted == null) { + // it begins with a valid session tag, but thats just a coincidence. + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Decrypt with a non session tag, but tags read: " + foundTags.size()); + return decryptNewSession(data, targetPrivateKey, foundTags, usedKey, foundKey); + } else { + // existing session decrypted successfully! + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Decrypt with an EXISTING session tag successfull, # tags read: " + foundTags.size(), + new Exception("Decrypted by")); + return decrypted; + } } - + /** * Decrypt the AES data with the session key and IV. The result should be: * - 2 byte integer specifying the # of session tags @@ -229,68 +246,63 @@ public class ElGamalAESEngine { * @param foundTags set which is filled with any sessionTags found during decryption * @param foundKey session key which may be filled with a new sessionKey found during decryption */ - static byte[] decryptAESBlock(byte encrypted[], SessionKey key, byte iv[], byte sentTag[], Set foundTags, 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[] = AESEngine.getInstance().decrypt(encrypted, key, iv); - Hash h = SHA256Generator.getInstance().calculateHash(decrypted); - //_log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32)); - try { - SessionKey newKey = null; - Hash readHash = null; - List tags = new ArrayList(); - - ByteArrayInputStream bais = new ByteArrayInputStream(decrypted); - long numTags = DataHelper.readLong(bais, 2); - //_log.debug("# tags: " + numTags); - if ( (numTags < 0) || (numTags > 65535) ) - throw new Exception("Invalid number of session tags"); - for (int i = 0; i < numTags; i++) { - byte tag[] = new byte[32]; - int read = bais.read(tag); - if (read != 32) - throw new Exception("Invalid session tag - # tags: " + numTags + " curTag #: " + i + " read: " + read); - tags.add(new SessionTag(tag)); - } - long len = DataHelper.readLong(bais, 4); - //_log.debug("len: " + len); - if ( (len < 0) || (len > encrypted.length) ) - throw new Exception("Invalid size of payload"); - byte hashval[] = new byte[32]; - int read = bais.read(hashval); - if (read != hashval.length) - throw new Exception("Invalid size of hash"); - readHash = new Hash(); - readHash.setData(hashval); - byte flag = (byte)bais.read(); - if (flag == 0x01) { - byte rekeyVal[] = new byte[32]; - read = bais.read(rekeyVal); - if (read != rekeyVal.length) - throw new Exception("Invalid size of the rekeyed session key"); - newKey = new SessionKey(); - newKey.setData(rekeyVal); - } - byte unencrData[] = new byte[(int)len]; - read = bais.read(unencrData); - if (read != unencrData.length) - throw new Exception("Invalid size of the data read"); - Hash calcHash = SHA256Generator.getInstance().calculateHash(unencrData); - if (calcHash.equals(readHash)) { - // everything matches. w00t. - foundTags.addAll(tags); - if (newKey != null) - foundKey.setData(newKey.getData()); - return unencrData; - } else { - throw new Exception("Hash does not match"); - } - } catch (Exception e) { - if (_log.shouldLog(Log.WARN)) _log.warn("Unable to decrypt AES block", e); - return null; - } + static byte[] decryptAESBlock(byte encrypted[], SessionKey key, byte iv[], byte sentTag[], Set foundTags, + 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[] = AESEngine.getInstance().decrypt(encrypted, key, iv); + Hash h = SHA256Generator.getInstance().calculateHash(decrypted); + //_log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32)); + try { + SessionKey newKey = null; + Hash readHash = null; + List tags = new ArrayList(); + + ByteArrayInputStream bais = new ByteArrayInputStream(decrypted); + long numTags = DataHelper.readLong(bais, 2); + //_log.debug("# tags: " + numTags); + if ((numTags < 0) || (numTags > 65535)) throw new Exception("Invalid number of session tags"); + for (int i = 0; i < numTags; i++) { + byte tag[] = new byte[32]; + int read = bais.read(tag); + if (read != 32) + throw new Exception("Invalid session tag - # tags: " + numTags + " curTag #: " + i + " read: " + + read); + tags.add(new SessionTag(tag)); + } + long len = DataHelper.readLong(bais, 4); + //_log.debug("len: " + len); + if ((len < 0) || (len > encrypted.length)) throw new Exception("Invalid size of payload"); + byte hashval[] = new byte[32]; + int read = bais.read(hashval); + if (read != hashval.length) throw new Exception("Invalid size of hash"); + readHash = new Hash(); + readHash.setData(hashval); + byte flag = (byte) bais.read(); + if (flag == 0x01) { + byte rekeyVal[] = new byte[32]; + read = bais.read(rekeyVal); + if (read != rekeyVal.length) throw new Exception("Invalid size of the rekeyed session key"); + newKey = new SessionKey(); + newKey.setData(rekeyVal); + } + byte unencrData[] = new byte[(int) len]; + read = bais.read(unencrData); + if (read != unencrData.length) throw new Exception("Invalid size of the data read"); + Hash calcHash = SHA256Generator.getInstance().calculateHash(unencrData); + if (calcHash.equals(readHash)) { + // everything matches. w00t. + foundTags.addAll(tags); + if (newKey != null) foundKey.setData(newKey.getData()); + return unencrData; + } else { + throw new Exception("Hash does not match"); + } + } catch (Exception e) { + if (_log.shouldLog(Log.WARN)) _log.warn("Unable to decrypt AES block", e); + return null; + } } - /** * Encrypt the unencrypted data to the target. The total size returned will be @@ -305,39 +317,43 @@ public class ElGamalAESEngine { * @param paddedSize minimum size in bytes of the body after padding it (if less than the * body's real size, no bytes are appended but the body is not truncated) */ - public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, SessionTag currentTag, SessionKey newKey, long paddedSize) { - if (currentTag == null) { - if (_log.shouldLog(Log.INFO)) _log.info("Current tag is null, encrypting as new session", new Exception("encrypt new")); - StatManager.getInstance().updateFrequency("crypto.elGamalAES.encryptNewSession"); - return encryptNewSession(data, target, key, tagsForDelivery, newKey, paddedSize); - } else { - if (_log.shouldLog(Log.INFO)) _log.info("Current tag is NOT null, encrypting as existing session", new Exception("encrypt existing")); - StatManager.getInstance().updateFrequency("crypto.elGamalAES.encryptExistingSession"); - return encryptExistingSession(data, target, key, tagsForDelivery, currentTag, newKey, paddedSize); - } + public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, + SessionTag currentTag, SessionKey newKey, long paddedSize) { + if (currentTag == null) { + if (_log.shouldLog(Log.INFO)) + _log.info("Current tag is null, encrypting as new session", new Exception("encrypt new")); + StatManager.getInstance().updateFrequency("crypto.elGamalAES.encryptNewSession"); + return encryptNewSession(data, target, key, tagsForDelivery, newKey, paddedSize); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("Current tag is NOT null, encrypting as existing session", new Exception("encrypt existing")); + StatManager.getInstance().updateFrequency("crypto.elGamalAES.encryptExistingSession"); + return encryptExistingSession(data, target, key, tagsForDelivery, currentTag, newKey, paddedSize); + } } - + /** * Encrypt the data to the target using the given key and deliver the specified tags */ - public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, SessionTag currentTag, long paddedSize) { - return encrypt(data, target, key, tagsForDelivery, currentTag, null, paddedSize); + public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, + SessionTag currentTag, long paddedSize) { + return encrypt(data, target, key, tagsForDelivery, currentTag, null, paddedSize); } - + /** * Encrypt the data to the target using the given key and deliver the specified tags */ public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, long paddedSize) { - return encrypt(data, target, key, tagsForDelivery, null, null, paddedSize); + return encrypt(data, target, key, tagsForDelivery, null, null, paddedSize); } - + /** * Encrypt the data to the target using the given key delivering no tags */ public static byte[] encrypt(byte data[], PublicKey target, SessionKey key, long paddedSize) { - return encrypt(data, target, key, null, null, null, paddedSize); + return encrypt(data, target, key, null, null, null, paddedSize); } - + /** * scenario 1: * Begin with 222 bytes, ElG encrypted, containing: @@ -354,56 +370,59 @@ public class ElGamalAESEngine { * - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0 * */ - static byte[] encryptNewSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, SessionKey newKey, long paddedSize) { - //_log.debug("Encrypting to a NEW session"); - try { - ByteArrayOutputStream elgSrc = new ByteArrayOutputStream(64); - key.writeBytes(elgSrc); - byte preIV[] = new byte[32]; - RandomSource.getInstance().nextBytes(preIV); - elgSrc.write(preIV); - byte rnd[] = new byte[158]; - RandomSource.getInstance().nextBytes(rnd); - elgSrc.write(rnd); - elgSrc.flush(); - - //_log.debug("Pre IV for encryptNewSession: " + DataHelper.toString(preIV, 32)); - //_log.debug("SessionKey for encryptNewSession: " + DataHelper.toString(key.getData(), 32)); - long before = Clock.getInstance().now(); - byte elgEncr[] = ElGamalEngine.getInstance().encrypt(elgSrc.toByteArray(), target); - long after = Clock.getInstance().now(); - if (_log.shouldLog(Log.INFO)) _log.info("elgEngine.encrypt of the session key took " + (after-before) + "ms"); - if (elgEncr.length < 514) { - byte elg[] = new byte[514]; - int diff = elg.length - elgEncr.length; - if (_log.shouldLog(Log.DEBUG)) _log.debug("Difference in size: " + diff); - System.arraycopy(elgEncr, 0, elg, diff, elgEncr.length); - elgEncr = elg; - } - //_log.debug("ElGamal encrypted length: " + elgEncr.length + " elGamal source length: " + elgSrc.toByteArray().length); - - Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); - byte iv[] = new byte[16]; - System.arraycopy(ivHash.getData(), 0, iv, 0, 16); - byte aesEncr[] = encryptAESBlock(data, key, iv, tagsForDelivery, newKey, paddedSize); - //_log.debug("AES encrypted length: " + aesEncr.length); - - byte rv[] = new byte[elgEncr.length + aesEncr.length]; - System.arraycopy(elgEncr, 0, rv, 0, elgEncr.length); - System.arraycopy(aesEncr, 0, rv, elgEncr.length, aesEncr.length); - //_log.debug("Return length: " + rv.length); - long finish = Clock.getInstance().now(); - if (_log.shouldLog(Log.DEBUG)) _log.debug("after the elgEngine.encrypt took a total of " + (finish-after) +"ms"); - return rv; - } catch (IOException ioe) { - _log.error("Error encrypting the new session", ioe); - return null; - } catch (DataFormatException dfe) { - _log.error("Error writing out the bytes for the new session", dfe); - return null; - } + static byte[] encryptNewSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, + SessionKey newKey, long paddedSize) { + //_log.debug("Encrypting to a NEW session"); + try { + ByteArrayOutputStream elgSrc = new ByteArrayOutputStream(64); + key.writeBytes(elgSrc); + byte preIV[] = new byte[32]; + RandomSource.getInstance().nextBytes(preIV); + elgSrc.write(preIV); + byte rnd[] = new byte[158]; + RandomSource.getInstance().nextBytes(rnd); + elgSrc.write(rnd); + elgSrc.flush(); + + //_log.debug("Pre IV for encryptNewSession: " + DataHelper.toString(preIV, 32)); + //_log.debug("SessionKey for encryptNewSession: " + DataHelper.toString(key.getData(), 32)); + long before = Clock.getInstance().now(); + byte elgEncr[] = ElGamalEngine.getInstance().encrypt(elgSrc.toByteArray(), target); + long after = Clock.getInstance().now(); + if (_log.shouldLog(Log.INFO)) + _log.info("elgEngine.encrypt of the session key took " + (after - before) + "ms"); + if (elgEncr.length < 514) { + byte elg[] = new byte[514]; + int diff = elg.length - elgEncr.length; + if (_log.shouldLog(Log.DEBUG)) _log.debug("Difference in size: " + diff); + System.arraycopy(elgEncr, 0, elg, diff, elgEncr.length); + elgEncr = elg; + } + //_log.debug("ElGamal encrypted length: " + elgEncr.length + " elGamal source length: " + elgSrc.toByteArray().length); + + Hash ivHash = SHA256Generator.getInstance().calculateHash(preIV); + byte iv[] = new byte[16]; + System.arraycopy(ivHash.getData(), 0, iv, 0, 16); + byte aesEncr[] = encryptAESBlock(data, key, iv, tagsForDelivery, newKey, paddedSize); + //_log.debug("AES encrypted length: " + aesEncr.length); + + byte rv[] = new byte[elgEncr.length + aesEncr.length]; + System.arraycopy(elgEncr, 0, rv, 0, elgEncr.length); + System.arraycopy(aesEncr, 0, rv, elgEncr.length, aesEncr.length); + //_log.debug("Return length: " + rv.length); + long finish = Clock.getInstance().now(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("after the elgEngine.encrypt took a total of " + (finish - after) + "ms"); + return rv; + } catch (IOException ioe) { + _log.error("Error encrypting the new session", ioe); + return null; + } catch (DataFormatException dfe) { + _log.error("Error writing out the bytes for the new session", dfe); + return null; + } } - + /** * scenario 2: * Begin with 32 byte session tag, which also serves as the preIV. @@ -417,25 +436,26 @@ public class ElGamalAESEngine { * - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0 * */ - static byte[] encryptExistingSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, SessionTag currentTag, SessionKey newKey, long paddedSize) { - //_log.debug("Encrypting to an EXISTING session"); - byte rawTag[] = currentTag.getData(); - - //_log.debug("Pre IV for encryptExistingSession (aka tag): " + currentTag.toString()); - //_log.debug("SessionKey for encryptNewSession: " + DataHelper.toString(key.getData(), 32)); + static byte[] encryptExistingSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, + SessionTag currentTag, SessionKey newKey, long paddedSize) { + //_log.debug("Encrypting to an EXISTING session"); + byte rawTag[] = currentTag.getData(); + + //_log.debug("Pre IV for encryptExistingSession (aka tag): " + currentTag.toString()); + //_log.debug("SessionKey for encryptNewSession: " + DataHelper.toString(key.getData(), 32)); Hash ivHash = SHA256Generator.getInstance().calculateHash(rawTag); byte iv[] = new byte[16]; System.arraycopy(ivHash.getData(), 0, iv, 0, 16); - + byte aesEncr[] = encryptAESBlock(data, key, iv, tagsForDelivery, newKey, paddedSize); byte rv[] = new byte[rawTag.length + aesEncr.length]; System.arraycopy(rawTag, 0, rv, 0, rawTag.length); System.arraycopy(aesEncr, 0, rv, rawTag.length, aesEncr.length); return rv; } - + private final static Set EMPTY_SET = new HashSet(); - + /** * For both scenarios, this method encrypts the AES area using the given key, iv * and making sure the resulting data is at least as long as the paddedSize and @@ -449,72 +469,71 @@ public class ElGamalAESEngine { * - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0 * */ - final static byte[] encryptAESBlock(byte data[], SessionKey key, byte[] iv, Set tagsForDelivery, SessionKey newKey, long paddedSize) { - //_log.debug("iv for encryption: " + DataHelper.toString(iv, 16)); - //_log.debug("Encrypting AES"); - try { - ByteArrayOutputStream aesSrc = new ByteArrayOutputStream((int)paddedSize); - if (tagsForDelivery == null) tagsForDelivery = EMPTY_SET; - DataHelper.writeLong(aesSrc, 2, tagsForDelivery.size()); - for (Iterator iter = tagsForDelivery.iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); - aesSrc.write(tag.getData()); - } - //_log.debug("# tags created, registered, and written: " + tags.size()); - DataHelper.writeLong(aesSrc, 4, data.length); - //_log.debug("data length: " + data.length); - Hash hash = SHA256Generator.getInstance().calculateHash(data); - hash.writeBytes(aesSrc); - //_log.debug("hash of data: " + DataHelper.toString(hash.getData(), 32)); - if (newKey == null) { - byte flag = 0x00; // don't rekey - aesSrc.write(flag); - //_log.debug("flag written"); - } else { - byte flag = 0x01; // rekey - aesSrc.write(flag); - aesSrc.write(newKey.getData()); - } - aesSrc.write(data); - int len = aesSrc.toByteArray().length; - //_log.debug("raw data written: " + len); - byte padding[] = getPadding(len, paddedSize); - //_log.debug("padding length: " + padding.length); - aesSrc.write(padding); - - byte aesUnencr[] = aesSrc.toByteArray(); - Hash h = SHA256Generator.getInstance().calculateHash(aesUnencr); - //_log.debug("Hash of entire aes block before encryption: (len=" + aesUnencr.length + ")\n" + DataHelper.toString(h.getData(), 32)); - byte aesEncr[] = AESEngine.getInstance().encrypt(aesUnencr, key, iv); - //_log.debug("Encrypted length: " + aesEncr.length); - return aesEncr; - } catch (IOException ioe) { - if (_log.shouldLog(Log.ERROR)) _log.error("Error encrypting AES chunk", ioe); - return null; - } catch (DataFormatException dfe) { - if (_log.shouldLog(Log.ERROR)) _log.error("Error formatting the bytes to write the AES chunk", dfe); - return null; - } + final static byte[] encryptAESBlock(byte data[], SessionKey key, byte[] iv, Set tagsForDelivery, SessionKey newKey, + long paddedSize) { + //_log.debug("iv for encryption: " + DataHelper.toString(iv, 16)); + //_log.debug("Encrypting AES"); + try { + ByteArrayOutputStream aesSrc = new ByteArrayOutputStream((int) paddedSize); + if (tagsForDelivery == null) tagsForDelivery = EMPTY_SET; + DataHelper.writeLong(aesSrc, 2, tagsForDelivery.size()); + for (Iterator iter = tagsForDelivery.iterator(); iter.hasNext();) { + SessionTag tag = (SessionTag) iter.next(); + aesSrc.write(tag.getData()); + } + //_log.debug("# tags created, registered, and written: " + tags.size()); + DataHelper.writeLong(aesSrc, 4, data.length); + //_log.debug("data length: " + data.length); + Hash hash = SHA256Generator.getInstance().calculateHash(data); + hash.writeBytes(aesSrc); + //_log.debug("hash of data: " + DataHelper.toString(hash.getData(), 32)); + if (newKey == null) { + byte flag = 0x00; // don't rekey + aesSrc.write(flag); + //_log.debug("flag written"); + } else { + byte flag = 0x01; // rekey + aesSrc.write(flag); + aesSrc.write(newKey.getData()); + } + aesSrc.write(data); + int len = aesSrc.toByteArray().length; + //_log.debug("raw data written: " + len); + byte padding[] = getPadding(len, paddedSize); + //_log.debug("padding length: " + padding.length); + aesSrc.write(padding); + + byte aesUnencr[] = aesSrc.toByteArray(); + Hash h = SHA256Generator.getInstance().calculateHash(aesUnencr); + //_log.debug("Hash of entire aes block before encryption: (len=" + aesUnencr.length + ")\n" + DataHelper.toString(h.getData(), 32)); + byte aesEncr[] = AESEngine.getInstance().encrypt(aesUnencr, key, iv); + //_log.debug("Encrypted length: " + aesEncr.length); + return aesEncr; + } catch (IOException ioe) { + if (_log.shouldLog(Log.ERROR)) _log.error("Error encrypting AES chunk", ioe); + return null; + } catch (DataFormatException dfe) { + if (_log.shouldLog(Log.ERROR)) _log.error("Error formatting the bytes to write the AES chunk", dfe); + return null; + } } - - + /** * Return random bytes for padding the data to a mod 16 size so that it is * at least minPaddedSize * */ final static byte[] getPadding(int curSize, long minPaddedSize) { - int diff = 0; - if (curSize < minPaddedSize) { - diff = (int)minPaddedSize - curSize; - } - - int numPadding = diff; - if (((curSize + diff) % 16) != 0) - numPadding += (16-((curSize + diff) % 16)); - byte rv[] = new byte[numPadding]; - RandomSource.getInstance().nextBytes(rv); - return rv; + int diff = 0; + if (curSize < minPaddedSize) { + diff = (int) minPaddedSize - curSize; + } + + int numPadding = diff; + if (((curSize + diff) % 16) != 0) numPadding += (16 - ((curSize + diff) % 16)); + byte rv[] = new byte[numPadding]; + RandomSource.getInstance().nextBytes(rv); + return rv; } - + } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/ElGamalEngine.java b/core/java/src/net/i2p/crypto/ElGamalEngine.java index 5c7839fd0a034b1df6d62a9976c28233b56a034e..03923fa80c8dd92728c8345606beb4cfdc3b31fa 100644 --- a/core/java/src/net/i2p/crypto/ElGamalEngine.java +++ b/core/java/src/net/i2p/crypto/ElGamalEngine.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * Copyright (c) 2003, TheCrypto * All rights reserved. @@ -37,11 +38,11 @@ import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; +import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.Log; import net.i2p.util.NativeBigInteger; import net.i2p.util.RandomSource; -import net.i2p.stat.StatManager; /** * Wrapper for ElGamal encryption/signature schemes. @@ -55,204 +56,224 @@ import net.i2p.stat.StatManager; */ public class ElGamalEngine { - private final static Log _log = new Log(ElGamalEngine.class); + private final static Log _log = new Log(ElGamalEngine.class); private static ElGamalEngine _engine; static { - if ("off".equals(System.getProperty("i2p.encryption", "on"))) - _engine = new DummyElGamalEngine(); - else - _engine = new ElGamalEngine(); - - StatManager.getInstance().createRateStat("crypto.elGamal.encrypt", - "how long does it take to do a full ElGamal encryption", "Encryption", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 } ); - StatManager.getInstance().createRateStat("crypto.elGamal.decrypt", - "how long does it take to do a full ElGamal decryption", "Encryption", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 } ); + if ("off".equals(System.getProperty("i2p.encryption", "on"))) + _engine = new DummyElGamalEngine(); + else + _engine = new ElGamalEngine(); + + StatManager.getInstance().createRateStat("crypto.elGamal.encrypt", + "how long does it take to do a full ElGamal encryption", "Encryption", + new long[] { 60 * 1000, 60 * 60 * 1000, 24 * 60 * 60 * 1000}); + StatManager.getInstance().createRateStat("crypto.elGamal.decrypt", + "how long does it take to do a full ElGamal decryption", "Encryption", + new long[] { 60 * 1000, 60 * 60 * 1000, 24 * 60 * 60 * 1000}); + } + + public static ElGamalEngine getInstance() { + return _engine; } - public static ElGamalEngine getInstance() { return _engine; } - private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02 } ); - - private BigInteger[] getNextYK() { return YKGenerator.getNextYK(); } - + private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02}); + + private BigInteger[] getNextYK() { + return YKGenerator.getNextYK(); + } + /** encrypt the data to the public key * @return encrypted data * @param publicKey public key encrypt to * @param data data to encrypt - */ + */ public byte[] encrypt(byte data[], PublicKey publicKey) { - if ( (data == null) || (data.length >= 223) ) throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment"); - if (publicKey == null) throw new IllegalArgumentException("Null public key specified"); - - long start = Clock.getInstance().now(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(256); - try { - baos.write(0xFF); - Hash hash = SHA256Generator.getInstance().calculateHash(data); - hash.writeBytes(baos); - baos.write(data); - baos.flush(); - } catch (Exception e) { - if (_log.shouldLog(Log.ERROR)) _log.error("Internal error writing to buffer", e); - return null; - } - - byte d2[] = baos.toByteArray(); - long t0 = Clock.getInstance().now(); - BigInteger m = new NativeBigInteger(1, d2); - long t1 = Clock.getInstance().now(); - if (m.compareTo(CryptoConstants.elgp) >= 0) - throw new IllegalArgumentException("ARGH. Data cannot be larger than the ElGamal prime. FIXME"); - long t2 = Clock.getInstance().now(); - BigInteger aalpha = new NativeBigInteger(1, publicKey.getData()); - long t3 = Clock.getInstance().now(); - BigInteger yk[] = getNextYK(); - BigInteger k = yk[1]; - BigInteger y = yk[0]; + if ((data == null) || (data.length >= 223)) + throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment"); + if (publicKey == null) throw new IllegalArgumentException("Null public key specified"); + + long start = Clock.getInstance().now(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(256); + try { + baos.write(0xFF); + Hash hash = SHA256Generator.getInstance().calculateHash(data); + hash.writeBytes(baos); + baos.write(data); + baos.flush(); + } catch (Exception e) { + if (_log.shouldLog(Log.ERROR)) _log.error("Internal error writing to buffer", e); + return null; + } - long t7 = Clock.getInstance().now(); - BigInteger d = aalpha.modPow(k, CryptoConstants.elgp); - long t8 = Clock.getInstance().now(); - d = d.multiply(m); - long t9 = Clock.getInstance().now(); - d = d.mod(CryptoConstants.elgp); - long t10 = Clock.getInstance().now(); + byte d2[] = baos.toByteArray(); + long t0 = Clock.getInstance().now(); + BigInteger m = new NativeBigInteger(1, d2); + long t1 = Clock.getInstance().now(); + if (m.compareTo(CryptoConstants.elgp) >= 0) + throw new IllegalArgumentException("ARGH. Data cannot be larger than the ElGamal prime. FIXME"); + long t2 = Clock.getInstance().now(); + BigInteger aalpha = new NativeBigInteger(1, publicKey.getData()); + long t3 = Clock.getInstance().now(); + BigInteger yk[] = getNextYK(); + BigInteger k = yk[1]; + BigInteger y = yk[0]; - byte[] ybytes = y.toByteArray(); - byte[] dbytes = d.toByteArray(); - byte[] out = new byte[514]; - System.arraycopy(ybytes, 0, out, (ybytes.length < 257 ? 257 - ybytes.length : 0), (ybytes.length > 257 ? 257 : ybytes.length)); - System.arraycopy(dbytes, 0, out, (dbytes.length < 257 ? 514 - dbytes.length : 257), (dbytes.length > 257 ? 257 : dbytes.length)); - StringBuffer buf = new StringBuffer(1024); - buf.append("Timing\n"); - buf.append("0-1: ").append(t1-t0).append('\n'); - buf.append("1-2: ").append(t2-t1).append('\n'); - buf.append("2-3: ").append(t3-t2).append('\n'); - //buf.append("3-4: ").append(t4-t3).append('\n'); - //buf.append("4-5: ").append(t5-t4).append('\n'); - //buf.append("5-6: ").append(t6-t5).append('\n'); - //buf.append("6-7: ").append(t7-t6).append('\n'); - buf.append("7-8: ").append(t8-t7).append('\n'); - buf.append("8-9: ").append(t9-t8).append('\n'); - buf.append("9-10: ").append(t10-t9).append('\n'); - //_log.debug(buf.toString()); - long end = Clock.getInstance().now(); + long t7 = Clock.getInstance().now(); + BigInteger d = aalpha.modPow(k, CryptoConstants.elgp); + long t8 = Clock.getInstance().now(); + d = d.multiply(m); + long t9 = Clock.getInstance().now(); + d = d.mod(CryptoConstants.elgp); + long t10 = Clock.getInstance().now(); - long diff = end - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to encrypt ElGamal block (" + diff + "ms)"); - } - - StatManager.getInstance().addRateData("crypto.elGamal.encrypt", diff, diff); - return out; + byte[] ybytes = y.toByteArray(); + byte[] dbytes = d.toByteArray(); + byte[] out = new byte[514]; + System.arraycopy(ybytes, 0, out, (ybytes.length < 257 ? 257 - ybytes.length : 0), + (ybytes.length > 257 ? 257 : ybytes.length)); + System.arraycopy(dbytes, 0, out, (dbytes.length < 257 ? 514 - dbytes.length : 257), + (dbytes.length > 257 ? 257 : dbytes.length)); + StringBuffer buf = new StringBuffer(1024); + buf.append("Timing\n"); + buf.append("0-1: ").append(t1 - t0).append('\n'); + buf.append("1-2: ").append(t2 - t1).append('\n'); + buf.append("2-3: ").append(t3 - t2).append('\n'); + //buf.append("3-4: ").append(t4-t3).append('\n'); + //buf.append("4-5: ").append(t5-t4).append('\n'); + //buf.append("5-6: ").append(t6-t5).append('\n'); + //buf.append("6-7: ").append(t7-t6).append('\n'); + buf.append("7-8: ").append(t8 - t7).append('\n'); + buf.append("8-9: ").append(t9 - t8).append('\n'); + buf.append("9-10: ").append(t10 - t9).append('\n'); + //_log.debug(buf.toString()); + long end = Clock.getInstance().now(); + + long diff = end - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to encrypt ElGamal block (" + diff + "ms)"); + } + + StatManager.getInstance().addRateData("crypto.elGamal.encrypt", diff, diff); + return out; } - + /** Decrypt the data * @param encrypted encrypted data * @param privateKey private key to decrypt with * @return unencrypted data - */ + */ public byte[] decrypt(byte encrypted[], PrivateKey privateKey) { - if ( (encrypted == null) || (encrypted.length > 514) ) throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment"); - long start = Clock.getInstance().now(); - - byte[] ybytes = new byte[257]; - byte[] dbytes = new byte[257]; - System.arraycopy(encrypted, 0, ybytes, 0, 257); - System.arraycopy(encrypted, 257, dbytes, 0, 257); - BigInteger y = new NativeBigInteger(1, ybytes); - BigInteger d = new NativeBigInteger(1, dbytes); - BigInteger a = new NativeBigInteger(1, privateKey.getData()); - BigInteger y1p = CryptoConstants.elgp.subtract(BigInteger.ONE).subtract(a); - BigInteger ya = y.modPow(y1p, CryptoConstants.elgp); - BigInteger m = ya.multiply(d); m = m.mod(CryptoConstants.elgp); - byte val[] = m.toByteArray(); - int i = 0; - for (i = 0; i < val.length; i++) - if (val[i] != (byte)0x00) - break; + if ((encrypted == null) || (encrypted.length > 514)) + throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment"); + long start = Clock.getInstance().now(); - ByteArrayInputStream bais = new ByteArrayInputStream(val, i, val.length - i); - Hash hash = new Hash(); - byte rv[] = null; - try { - bais.read(); // skip first byte - hash.readBytes(bais); - rv = new byte[val.length - i - 1 - 32]; - bais.read(rv); - } catch (Exception e) { - if (_log.shouldLog(Log.ERROR)) _log.error("Internal error reading value", e); - return null; - } + byte[] ybytes = new byte[257]; + byte[] dbytes = new byte[257]; + System.arraycopy(encrypted, 0, ybytes, 0, 257); + System.arraycopy(encrypted, 257, dbytes, 0, 257); + BigInteger y = new NativeBigInteger(1, ybytes); + BigInteger d = new NativeBigInteger(1, dbytes); + BigInteger a = new NativeBigInteger(1, privateKey.getData()); + BigInteger y1p = CryptoConstants.elgp.subtract(BigInteger.ONE).subtract(a); + BigInteger ya = y.modPow(y1p, CryptoConstants.elgp); + BigInteger m = ya.multiply(d); + m = m.mod(CryptoConstants.elgp); + byte val[] = m.toByteArray(); + int i = 0; + for (i = 0; i < val.length; i++) + if (val[i] != (byte) 0x00) break; + ByteArrayInputStream bais = new ByteArrayInputStream(val, i, val.length - i); + Hash hash = new Hash(); + byte rv[] = null; + try { + bais.read(); // skip first byte + hash.readBytes(bais); + rv = new byte[val.length - i - 1 - 32]; + bais.read(rv); + } catch (Exception e) { + if (_log.shouldLog(Log.ERROR)) _log.error("Internal error reading value", e); + return null; + } - Hash calcHash = SHA256Generator.getInstance().calculateHash(rv); - boolean ok = calcHash.equals(hash); + Hash calcHash = SHA256Generator.getInstance().calculateHash(rv); + boolean ok = calcHash.equals(hash); - long end = Clock.getInstance().now(); + long end = Clock.getInstance().now(); - long diff = end - start; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to decrypt and verify ElGamal block (" + diff + "ms)"); - } + long diff = end - start; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Took too long to decrypt and verify ElGamal block (" + diff + "ms)"); + } - StatManager.getInstance().addRateData("crypto.elGamal.decrypt", diff, diff); - - if (ok) { - //_log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length)); - return rv; - } else { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Doesn't match hash [calc=" + calcHash + " sent hash=" + hash + "]\ndata = " + Base64.encode(rv), new Exception("Doesn't match")); - return null; - } + StatManager.getInstance().addRateData("crypto.elGamal.decrypt", diff, diff); + + if (ok) { + //_log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length)); + return rv; + } else { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Doesn't match hash [calc=" + calcHash + " sent hash=" + hash + "]\ndata = " + + Base64.encode(rv), new Exception("Doesn't match")); + return null; + } } - + public static void main(String args[]) { - long eTime = 0; - long dTime = 0; - long gTime = 0; - int numRuns = 100; - if (args.length > 0) - try { - numRuns = Integer.parseInt(args[0]); - } catch (NumberFormatException nfe) {} - - try { Thread.sleep(30*1000); } catch (InterruptedException ie) {} - - RandomSource.getInstance().nextBoolean(); - - System.out.println("Running " + numRuns + " times"); - - for (int i = 0; i < numRuns; i++) { - long startG = Clock.getInstance().now(); - Object pair[] = KeyGenerator.getInstance().generatePKIKeypair(); - long endG = Clock.getInstance().now(); - - PublicKey pubkey = (PublicKey)pair[0]; - PrivateKey privkey = (PrivateKey)pair[1]; - byte buf[] = new byte[128]; - RandomSource.getInstance().nextBytes(buf); - long startE = Clock.getInstance().now(); - byte encr[] = ElGamalEngine.getInstance().encrypt(buf, pubkey); - long endE = Clock.getInstance().now(); - byte decr[] = ElGamalEngine.getInstance().decrypt(encr, privkey); - long endD = Clock.getInstance().now(); - eTime += endE - startE; - dTime += endD - endE; - gTime += endG - startG; - - if (!DataHelper.eq(decr, buf)) { - System.out.println("PublicKey : " + DataHelper.toString(pubkey.getData(), pubkey.getData().length)); - System.out.println("PrivateKey : " + DataHelper.toString(privkey.getData(), privkey.getData().length)); - System.out.println("orig : " + DataHelper.toString(buf, buf.length)); - System.out.println("d(e(orig) : " + DataHelper.toString(decr, decr.length)); - System.out.println("orig.len : " + buf.length); - System.out.println("d(e(orig).len : " + decr.length); - System.out.println("Not equal!"); - System.exit(0); - } else { - System.out.println("*Run " +i+" is successful, with encr.length = " + encr.length + " [E: " + (endE-startE) + " D: " + (endD-endE) + " G: " + (endG - startG) + "]\n"); - } - } - System.out.println("\n\nAll "+numRuns+" tests successful, average encryption time: " + (eTime/numRuns) + " average decryption time: " + (dTime / numRuns) + " average key generation time: " + (gTime / numRuns)); + long eTime = 0; + long dTime = 0; + long gTime = 0; + int numRuns = 100; + if (args.length > 0) try { + numRuns = Integer.parseInt(args[0]); + } catch (NumberFormatException nfe) { + } + + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException ie) { + } + + RandomSource.getInstance().nextBoolean(); + + System.out.println("Running " + numRuns + " times"); + + for (int i = 0; i < numRuns; i++) { + long startG = Clock.getInstance().now(); + Object pair[] = KeyGenerator.getInstance().generatePKIKeypair(); + long endG = Clock.getInstance().now(); + + PublicKey pubkey = (PublicKey) pair[0]; + PrivateKey privkey = (PrivateKey) pair[1]; + byte buf[] = new byte[128]; + RandomSource.getInstance().nextBytes(buf); + long startE = Clock.getInstance().now(); + byte encr[] = ElGamalEngine.getInstance().encrypt(buf, pubkey); + long endE = Clock.getInstance().now(); + byte decr[] = ElGamalEngine.getInstance().decrypt(encr, privkey); + long endD = Clock.getInstance().now(); + eTime += endE - startE; + dTime += endD - endE; + gTime += endG - startG; + + if (!DataHelper.eq(decr, buf)) { + System.out.println("PublicKey : " + DataHelper.toString(pubkey.getData(), pubkey.getData().length)); + System.out.println("PrivateKey : " + + DataHelper.toString(privkey.getData(), privkey.getData().length)); + System.out.println("orig : " + DataHelper.toString(buf, buf.length)); + System.out.println("d(e(orig) : " + DataHelper.toString(decr, decr.length)); + System.out.println("orig.len : " + buf.length); + System.out.println("d(e(orig).len : " + decr.length); + System.out.println("Not equal!"); + System.exit(0); + } else { + System.out.println("*Run " + i + " is successful, with encr.length = " + encr.length + " [E: " + + (endE - startE) + " D: " + (endD - endE) + " G: " + (endG - startG) + "]\n"); + } + } + System.out.println("\n\nAll " + numRuns + " tests successful, average encryption time: " + (eTime / numRuns) + + " average decryption time: " + (dTime / numRuns) + " average key generation time: " + + (gTime / numRuns)); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/HMACSHA256Generator.java b/core/java/src/net/i2p/crypto/HMACSHA256Generator.java index 99d908febc3531e19340a9a2c91836e83a812c60..62bbc10605da88fb59095c0ba4723867df4e5f95 100644 --- a/core/java/src/net/i2p/crypto/HMACSHA256Generator.java +++ b/core/java/src/net/i2p/crypto/HMACSHA256Generator.java @@ -1,18 +1,21 @@ package net.i2p.crypto; +import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.SessionKey; -import net.i2p.data.DataHelper; /** * Calculate the HMAC-SHA256 of a key+message. Currently FAKE - returns a stupid * kludgy hash: H(H(key) XOR H(data)). Fix me! * */ -public abstract class HMACSHA256Generator { +public abstract class HMACSHA256Generator { private static HMACSHA256Generator _generator = new DummyHMACSHA256Generator(); - public static HMACSHA256Generator getInstance() { return _generator; } - + + public static HMACSHA256Generator getInstance() { + return _generator; + } + public abstract Hash calculate(SessionKey key, byte data[]); } @@ -20,14 +23,14 @@ public abstract class HMACSHA256Generator { * jrandom smells. * */ + class DummyHMACSHA256Generator extends HMACSHA256Generator { public Hash calculate(SessionKey key, byte data[]) { - if ( (key == null) || (key.getData() == null) || (data == null) ) - throw new NullPointerException("Null arguments for HMAC"); - - Hash hkey = SHA256Generator.getInstance().calculateHash(key.getData()); - Hash hdata = SHA256Generator.getInstance().calculateHash(data); - return SHA256Generator.getInstance().calculateHash(DataHelper.xor(hkey.getData(), hdata.getData())); + if ((key == null) || (key.getData() == null) || (data == null)) + throw new NullPointerException("Null arguments for HMAC"); + + Hash hkey = SHA256Generator.getInstance().calculateHash(key.getData()); + Hash hdata = SHA256Generator.getInstance().calculateHash(data); + return SHA256Generator.getInstance().calculateHash(DataHelper.xor(hkey.getData(), hdata.getData())); } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java index ea59b28b694a5f08efc39abdf930b6bf105a00c3..fecb4404854813a5b5abf8bd5508d59aae0fcd8a 100644 --- a/core/java/src/net/i2p/crypto/KeyGenerator.java +++ b/core/java/src/net/i2p/crypto/KeyGenerator.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -29,8 +30,11 @@ public class KeyGenerator { private final static Log _log = new Log(KeyGenerator.class); private static final RandomSource _random = RandomSource.getInstance(); private static KeyGenerator _generator = new KeyGenerator(); - public static KeyGenerator getInstance() { return _generator; } - + + public static KeyGenerator getInstance() { + return _generator; + } + /** Generate a private 256 bit session key * @return session key */ @@ -38,121 +42,124 @@ public class KeyGenerator { // 256bit random # as a session key SessionKey key = new SessionKey(); byte data[] = new byte[SessionKey.KEYSIZE_BYTES]; - _random.nextBytes(data); + _random.nextBytes(data); key.setData(data); return key; } - + /** Generate a pair of keys, where index 0 is a PublicKey, and * index 1 is a PrivateKey * @return pair of keys */ public Object[] generatePKIKeypair() { - BigInteger a = new NativeBigInteger(2048, _random); - BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp); - + BigInteger a = new NativeBigInteger(2048, _random); + BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp); + Object[] keys = new Object[2]; keys[0] = new PublicKey(); keys[1] = new PrivateKey(); byte[] k0 = aalpha.toByteArray(); byte[] k1 = a.toByteArray(); - - // bigInteger.toByteArray returns SIGNED integers, but since they'return positive, - // signed two's complement is the same as unsigned - - ((PublicKey)keys[0]).setData(padBuffer(k0, PublicKey.KEYSIZE_BYTES)); - ((PrivateKey)keys[1]).setData(padBuffer(k1, PrivateKey.KEYSIZE_BYTES)); - - return keys; + + // bigInteger.toByteArray returns SIGNED integers, but since they'return positive, + // signed two's complement is the same as unsigned + + ((PublicKey) keys[0]).setData(padBuffer(k0, PublicKey.KEYSIZE_BYTES)); + ((PrivateKey) keys[1]).setData(padBuffer(k1, PrivateKey.KEYSIZE_BYTES)); + + return keys; } - + /** Generate a pair of DSA keys, where index 0 is a SigningPublicKey, and * index 1 is a SigningPrivateKey * @return pair of keys */ public Object[] generateSigningKeypair() { - Object[] keys = new Object[2]; - BigInteger x = null; - - // make sure the random key is less than the DSA q - do { - x = new NativeBigInteger(160, _random); - } while (x.compareTo(CryptoConstants.dsaq) >= 0); - - BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap); - keys[0] = new SigningPublicKey(); - keys[1] = new SigningPrivateKey(); - byte k0[] = padBuffer(y.toByteArray(), SigningPublicKey.KEYSIZE_BYTES); - byte k1[] = padBuffer(x.toByteArray(), SigningPrivateKey.KEYSIZE_BYTES); - - ((SigningPublicKey)keys[0]).setData(k0); - ((SigningPrivateKey)keys[1]).setData(k1); - return keys; + Object[] keys = new Object[2]; + BigInteger x = null; + + // make sure the random key is less than the DSA q + do { + x = new NativeBigInteger(160, _random); + } while (x.compareTo(CryptoConstants.dsaq) >= 0); + + BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap); + keys[0] = new SigningPublicKey(); + keys[1] = new SigningPrivateKey(); + byte k0[] = padBuffer(y.toByteArray(), SigningPublicKey.KEYSIZE_BYTES); + byte k1[] = padBuffer(x.toByteArray(), SigningPrivateKey.KEYSIZE_BYTES); + + ((SigningPublicKey) keys[0]).setData(k0); + ((SigningPrivateKey) keys[1]).setData(k1); + return keys; } - - + /** * Pad the buffer w/ leading 0s or trim off leading bits so the result is the * given length. */ private final static byte[] padBuffer(byte src[], int length) { - byte buf[] = new byte[length]; - - if (src.length > buf.length) // extra bits, chop leading bits - System.arraycopy(src, src.length - buf.length, buf, 0, buf.length); - else if (src.length < buf.length) // short bits, padd w/ 0s - System.arraycopy(src, 0, buf, buf.length - src.length, src.length); - else // eq - System.arraycopy(src, 0, buf, 0, buf.length); - - return buf; + byte buf[] = new byte[length]; + + if (src.length > buf.length) // extra bits, chop leading bits + System.arraycopy(src, src.length - buf.length, buf, 0, buf.length); + else if (src.length < buf.length) // short bits, padd w/ 0s + System.arraycopy(src, 0, buf, buf.length - src.length, src.length); + else + // eq + System.arraycopy(src, 0, buf, 0, buf.length); + + return buf; } - + public static void main(String args[]) { - Log log = new Log("keygenTest"); - RandomSource.getInstance().nextBoolean(); - byte src[] = new byte[200]; - RandomSource.getInstance().nextBytes(src); - - long time = 0; - for (int i = 0; i < 10; i++) { - long start = Clock.getInstance().now(); - Object keys[] = KeyGenerator.getInstance().generatePKIKeypair(); - long end = Clock.getInstance().now(); - byte ctext[] = ElGamalEngine.getInstance().encrypt(src, (PublicKey)keys[0]); - byte ptext[] = ElGamalEngine.getInstance().decrypt(ctext, (PrivateKey)keys[1]); - time += end - start; - if (DataHelper.eq(ptext, src)) - log.debug("D(E(data)) == data"); - else - log.error("D(E(data)) != data!!!!!!"); - } - log.info("Keygen 10 times: " + time + "ms"); - - Object obj[] = KeyGenerator.getInstance().generateSigningKeypair(); - SigningPublicKey fake = (SigningPublicKey)obj[0]; - time = 0; - for (int i = 0; i < 10; i++) { - long start = Clock.getInstance().now(); - Object keys[] = KeyGenerator.getInstance().generateSigningKeypair(); - long end = Clock.getInstance().now(); - Signature sig = DSAEngine.getInstance().sign(src, (SigningPrivateKey)keys[1]); - boolean ok = DSAEngine.getInstance().verifySignature(sig, src, (SigningPublicKey)keys[0]); - boolean fakeOk = DSAEngine.getInstance().verifySignature(sig, src, fake); - time += end - start; - log.debug("V(S(data)) == " + ok + " fake verify correctly failed? " + (fakeOk == false)); - } - log.info("Signing Keygen 10 times: " + time + "ms"); - - time = 0; - for (int i = 0; i < 1000; i++) { - long start = Clock.getInstance().now(); - KeyGenerator.getInstance().generateSessionKey(); - long end = Clock.getInstance().now(); - time += end - start; - } - log.info("Session keygen 1000 times: " + time + "ms"); - - try { Thread.sleep(5000); } catch (InterruptedException ie) {} + Log log = new Log("keygenTest"); + RandomSource.getInstance().nextBoolean(); + byte src[] = new byte[200]; + RandomSource.getInstance().nextBytes(src); + + long time = 0; + for (int i = 0; i < 10; i++) { + long start = Clock.getInstance().now(); + Object keys[] = KeyGenerator.getInstance().generatePKIKeypair(); + long end = Clock.getInstance().now(); + byte ctext[] = ElGamalEngine.getInstance().encrypt(src, (PublicKey) keys[0]); + byte ptext[] = ElGamalEngine.getInstance().decrypt(ctext, (PrivateKey) keys[1]); + time += end - start; + if (DataHelper.eq(ptext, src)) + log.debug("D(E(data)) == data"); + else + log.error("D(E(data)) != data!!!!!!"); + } + log.info("Keygen 10 times: " + time + "ms"); + + Object obj[] = KeyGenerator.getInstance().generateSigningKeypair(); + SigningPublicKey fake = (SigningPublicKey) obj[0]; + time = 0; + for (int i = 0; i < 10; i++) { + long start = Clock.getInstance().now(); + Object keys[] = KeyGenerator.getInstance().generateSigningKeypair(); + long end = Clock.getInstance().now(); + Signature sig = DSAEngine.getInstance().sign(src, (SigningPrivateKey) keys[1]); + boolean ok = DSAEngine.getInstance().verifySignature(sig, src, (SigningPublicKey) keys[0]); + boolean fakeOk = DSAEngine.getInstance().verifySignature(sig, src, fake); + time += end - start; + log.debug("V(S(data)) == " + ok + " fake verify correctly failed? " + (fakeOk == false)); + } + log.info("Signing Keygen 10 times: " + time + "ms"); + + time = 0; + for (int i = 0; i < 1000; i++) { + long start = Clock.getInstance().now(); + KeyGenerator.getInstance().generateSessionKey(); + long end = Clock.getInstance().now(); + time += end - start; + } + log.info("Session keygen 1000 times: " + time + "ms"); + + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java b/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java index bdeba3e20b5383005b61629e2418352f41430d51..5c88e9eddf30849d15383b5768b0def9bdbdaa1d 100644 --- a/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/PersistentSessionKeyManager.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -35,130 +36,135 @@ import net.i2p.util.Log; */ public class PersistentSessionKeyManager extends TransientSessionKeyManager { private final static Log _log = new Log(PersistentSessionKeyManager.class); - + private Object _yk = YKGenerator.class; - + /** * Write the session key data to the given stream * */ public void saveState(OutputStream out) throws IOException, DataFormatException { - Set tagSets = getInboundTagSets(); - Set sessions = getOutboundSessions(); - _log.info("Saving state with " + tagSets.size() + " inbound tagSets and " + sessions.size() + " outbound sessions"); - - DataHelper.writeLong(out, 4, tagSets.size()); - for (Iterator iter = tagSets.iterator(); iter.hasNext(); ) { - TagSet ts = (TagSet)iter.next(); - writeTagSet(out, ts); - } - DataHelper.writeLong(out, 4, sessions.size()); - for (Iterator iter = sessions.iterator(); iter.hasNext(); ) { - OutboundSession sess = (OutboundSession)iter.next(); - writeOutboundSession(out, sess); - } + Set tagSets = getInboundTagSets(); + Set sessions = getOutboundSessions(); + _log.info("Saving state with " + tagSets.size() + " inbound tagSets and " + sessions.size() + + " outbound sessions"); + + DataHelper.writeLong(out, 4, tagSets.size()); + for (Iterator iter = tagSets.iterator(); iter.hasNext();) { + TagSet ts = (TagSet) iter.next(); + writeTagSet(out, ts); + } + DataHelper.writeLong(out, 4, sessions.size()); + for (Iterator iter = sessions.iterator(); iter.hasNext();) { + OutboundSession sess = (OutboundSession) iter.next(); + writeOutboundSession(out, sess); + } } - /** * Load the session key data from the given stream * */ public void loadState(InputStream in) throws IOException, DataFormatException { - int inboundSets = (int)DataHelper.readLong(in, 4); - Set tagSets = new HashSet(inboundSets); - for (int i = 0; i < inboundSets; i++) { - TagSet ts = readTagSet(in); - tagSets.add(ts); - } - int outboundSessions = (int)DataHelper.readLong(in, 4); - Set sessions = new HashSet(outboundSessions); - for (int i = 0; i < outboundSessions; i++) { - OutboundSession sess = readOutboundSession(in); - sessions.add(sess); - } - - _log.info("Loading state with " + tagSets.size() + " inbound tagSets and " + sessions.size() + " outbound sessions"); - setData(tagSets, sessions); + int inboundSets = (int) DataHelper.readLong(in, 4); + Set tagSets = new HashSet(inboundSets); + for (int i = 0; i < inboundSets; i++) { + TagSet ts = readTagSet(in); + tagSets.add(ts); + } + int outboundSessions = (int) DataHelper.readLong(in, 4); + Set sessions = new HashSet(outboundSessions); + for (int i = 0; i < outboundSessions; i++) { + OutboundSession sess = readOutboundSession(in); + sessions.add(sess); + } + + _log.info("Loading state with " + tagSets.size() + " inbound tagSets and " + sessions.size() + + " outbound sessions"); + setData(tagSets, sessions); } - + private void writeOutboundSession(OutputStream out, OutboundSession sess) throws IOException, DataFormatException { - sess.getTarget().writeBytes(out); - sess.getCurrentKey().writeBytes(out); - DataHelper.writeDate(out, new Date(sess.getEstablishedDate())); - DataHelper.writeDate(out, new Date(sess.getLastUsedDate())); - List sets = sess.getTagSets(); - DataHelper.writeLong(out, 2, sets.size()); - for (Iterator iter = sets.iterator(); iter.hasNext(); ) { - TagSet set = (TagSet)iter.next(); - writeTagSet(out, set); - } + sess.getTarget().writeBytes(out); + sess.getCurrentKey().writeBytes(out); + DataHelper.writeDate(out, new Date(sess.getEstablishedDate())); + DataHelper.writeDate(out, new Date(sess.getLastUsedDate())); + List sets = sess.getTagSets(); + DataHelper.writeLong(out, 2, sets.size()); + for (Iterator iter = sets.iterator(); iter.hasNext();) { + TagSet set = (TagSet) iter.next(); + writeTagSet(out, set); + } } - + private void writeTagSet(OutputStream out, TagSet ts) throws IOException, DataFormatException { - ts.getAssociatedKey().writeBytes(out); - DataHelper.writeDate(out, new Date(ts.getDate())); - DataHelper.writeLong(out, 2, ts.getTags().size()); - for (Iterator iter = ts.getTags().iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); - out.write(tag.getData()); - } + ts.getAssociatedKey().writeBytes(out); + DataHelper.writeDate(out, new Date(ts.getDate())); + DataHelper.writeLong(out, 2, ts.getTags().size()); + for (Iterator iter = ts.getTags().iterator(); iter.hasNext();) { + SessionTag tag = (SessionTag) iter.next(); + out.write(tag.getData()); + } } - + private OutboundSession readOutboundSession(InputStream in) throws IOException, DataFormatException { - PublicKey key = new PublicKey(); - key.readBytes(in); - SessionKey skey = new SessionKey(); - skey.readBytes(in); - Date established = DataHelper.readDate(in); - Date lastUsed = DataHelper.readDate(in); - int tagSets = (int)DataHelper.readLong(in, 2); - ArrayList sets = new ArrayList(tagSets); - for (int i = 0; i < tagSets; i++) { - TagSet ts = readTagSet(in); - sets.add(ts); - } - - return new OutboundSession(key, skey, established.getTime(), lastUsed.getTime(), sets); + PublicKey key = new PublicKey(); + key.readBytes(in); + SessionKey skey = new SessionKey(); + skey.readBytes(in); + Date established = DataHelper.readDate(in); + Date lastUsed = DataHelper.readDate(in); + int tagSets = (int) DataHelper.readLong(in, 2); + ArrayList sets = new ArrayList(tagSets); + for (int i = 0; i < tagSets; i++) { + TagSet ts = readTagSet(in); + sets.add(ts); + } + + return new OutboundSession(key, skey, established.getTime(), lastUsed.getTime(), sets); } - + private TagSet readTagSet(InputStream in) throws IOException, DataFormatException { - SessionKey key = new SessionKey(); - key.readBytes(in); - Date date = DataHelper.readDate(in); - int numTags = (int)DataHelper.readLong(in, 2); - Set tags = new HashSet(numTags); - for (int i = 0; i < numTags; i++) { - SessionTag tag = new SessionTag(); - byte val[] = new byte[SessionTag.BYTE_LENGTH]; - int read = DataHelper.read(in, val); - if (read != SessionTag.BYTE_LENGTH) - throw new IOException("Unable to fully read a session tag [" + read + " not " + SessionTag.BYTE_LENGTH + ")"); - tag.setData(val); - tags.add(tag); - } - TagSet ts = new TagSet(tags, key); - ts.setDate(date.getTime()); - return ts; + SessionKey key = new SessionKey(); + key.readBytes(in); + Date date = DataHelper.readDate(in); + int numTags = (int) DataHelper.readLong(in, 2); + Set tags = new HashSet(numTags); + for (int i = 0; i < numTags; i++) { + SessionTag tag = new SessionTag(); + byte val[] = new byte[SessionTag.BYTE_LENGTH]; + int read = DataHelper.read(in, val); + if (read != SessionTag.BYTE_LENGTH) + throw new IOException("Unable to fully read a session tag [" + read + " not " + SessionTag.BYTE_LENGTH + + ")"); + tag.setData(val); + tags.add(tag); + } + TagSet ts = new TagSet(tags, key); + ts.setDate(date.getTime()); + return ts; } - + public static void main(String args[]) { - PersistentSessionKeyManager mgr = new PersistentSessionKeyManager(); - try { - mgr.loadState(new FileInputStream("sessionKeys.dat")); - String state = mgr.renderStatusHTML(); - FileOutputStream fos = new FileOutputStream("sessionKeysBeforeExpire.html"); - fos.write(state.getBytes()); - fos.close(); - int expired = mgr.aggressiveExpire(); - _log.error("Expired: " + expired); - String stateAfter = mgr.renderStatusHTML(); - FileOutputStream fos2 = new FileOutputStream("sessionKeysAfterExpire.html"); - fos2.write(stateAfter.getBytes()); - fos2.close(); - } catch (Throwable t) { - _log.error("Error loading/storing sessionKeys", t); - } - try { Thread.sleep(3000); } catch (Throwable t) {} + PersistentSessionKeyManager mgr = new PersistentSessionKeyManager(); + try { + mgr.loadState(new FileInputStream("sessionKeys.dat")); + String state = mgr.renderStatusHTML(); + FileOutputStream fos = new FileOutputStream("sessionKeysBeforeExpire.html"); + fos.write(state.getBytes()); + fos.close(); + int expired = mgr.aggressiveExpire(); + _log.error("Expired: " + expired); + String stateAfter = mgr.renderStatusHTML(); + FileOutputStream fos2 = new FileOutputStream("sessionKeysAfterExpire.html"); + fos2.write(stateAfter.getBytes()); + fos2.close(); + } catch (Throwable t) { + _log.error("Error loading/storing sessionKeys", t); + } + try { + Thread.sleep(3000); + } catch (Throwable t) { + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/SHA256Generator.java b/core/java/src/net/i2p/crypto/SHA256Generator.java index e4966f9b7819dba945de96fd672f504986f38c17..2ed42a12d6821758e5e8b7cfb9b03c724a07a0fa 100644 --- a/core/java/src/net/i2p/crypto/SHA256Generator.java +++ b/core/java/src/net/i2p/crypto/SHA256Generator.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * Copyright (c) 2003, TheCrypto * All rights reserved. @@ -36,138 +37,156 @@ import net.i2p.data.Hash; * * @author thecrypto,jrandom */ -public class SHA256Generator { +public class SHA256Generator { private static SHA256Generator _generator = new SHA256Generator(); - public static SHA256Generator getInstance() { return _generator; } - - static int[] K = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - }; - - static int[] H0 = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 - }; - + + public static SHA256Generator getInstance() { + return _generator; + } + + static int[] K = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; + + static int[] H0 = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + /** Calculate the SHA-256 has of the source * @param source what to hash * @return hash of the source - */ + */ public Hash calculateHash(byte[] source) { - long length = source.length * 8; - int k = 448 - (int)((length+1) % 512); - if (k < 0) { - k += 512; - } - int padbytes = k/8; - int wordlength = (int)(source.length/4 + padbytes/4 + 3); - int[] M0 = new int[wordlength]; - int wordcount = 0; - int x = 0; - for (x = 0; x < (source.length / 4) * 4; x += 4) { - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; - M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0; - wordcount++; - } - switch (source.length - (wordcount + 1) * 4 + 4) { - case 0: - M0[wordcount] |= 0x80000000; - break; - case 1: - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= 0x00800000; - break; - case 2: - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= 0x00008000; - break; - case 3: - M0[wordcount] = source[ x ] << 24 >>> 24 << 24; - M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; - M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; - M0[wordcount] |= 0x00000080; - break; - } - M0[wordlength - 2] = (int)(length >>> 32); - M0[wordlength - 1] = (int)(length); - int[] H = new int[8]; - for (x = 0; x < 8; x++) { - H[x] = H0[x]; - } - int blocks = M0.length/16; - for (int bl = 0; bl < blocks; bl++) { - int a = H[0]; int b = H[1]; int c = H[2]; int d = H[3]; - int e = H[4]; int f = H[5]; int g = H[6]; int h = H[7]; - int[] W = new int[64]; - for (x = 0; x < 64; x++) { - if (x < 16) { - W[x] = M0[bl*16 + x]; - } else { - W[x] = add(o1(W[x-2]), add(W[x-7], add(o0(W[x-15]), W[x-16]))); - } - } - for (x = 0; x < 64; x++) { - int T1 = add(h, add(e1(e), add(Ch(e, f, g), add(K[x], W[x])))); - int T2 = add(e0(a), Maj(a, b, c)); - h = g; g = f; f = e; e = add(d, T1); d = c; c = b; b = a; a = add(T1, T2); - } - H[0] = add(a, H[0]); H[1] = add(b, H[1]); H[2] = add(c, H[2]); H[3] = add(d, H[3]); - H[4] = add(e, H[4]); H[5] = add(f, H[5]); H[6] = add(g, H[6]); H[7] = add(h, H[7]); - } - byte[] hashbytes = new byte[32]; - for (x = 0; x < 8; x++) { - hashbytes[ x * 4 ] = (byte)(H[x] << 0 >>> 24); - hashbytes[x * 4 + 1] = (byte)(H[x] << 8 >>> 24); - hashbytes[x * 4 + 2] = (byte)(H[x] << 16 >>> 24); - hashbytes[x * 4 + 3] = (byte)(H[x] << 24 >>> 24); - } + long length = source.length * 8; + int k = 448 - (int) ((length + 1) % 512); + if (k < 0) { + k += 512; + } + int padbytes = k / 8; + int wordlength = (int) (source.length / 4 + padbytes / 4 + 3); + int[] M0 = new int[wordlength]; + int wordcount = 0; + int x = 0; + for (x = 0; x < (source.length / 4) * 4; x += 4) { + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; + M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0; + wordcount++; + } + switch (source.length - (wordcount + 1) * 4 + 4) { + case 0: + M0[wordcount] |= 0x80000000; + break; + case 1: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= 0x00800000; + break; + case 2: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= 0x00008000; + break; + case 3: + M0[wordcount] = source[x] << 24 >>> 24 << 24; + M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16; + M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8; + M0[wordcount] |= 0x00000080; + break; + } + M0[wordlength - 2] = (int) (length >>> 32); + M0[wordlength - 1] = (int) (length); + int[] H = new int[8]; + for (x = 0; x < 8; x++) { + H[x] = H0[x]; + } + int blocks = M0.length / 16; + for (int bl = 0; bl < blocks; bl++) { + int a = H[0]; + int b = H[1]; + int c = H[2]; + int d = H[3]; + int e = H[4]; + int f = H[5]; + int g = H[6]; + int h = H[7]; + int[] W = new int[64]; + for (x = 0; x < 64; x++) { + if (x < 16) { + W[x] = M0[bl * 16 + x]; + } else { + W[x] = add(o1(W[x - 2]), add(W[x - 7], add(o0(W[x - 15]), W[x - 16]))); + } + } + for (x = 0; x < 64; x++) { + int T1 = add(h, add(e1(e), add(Ch(e, f, g), add(K[x], W[x])))); + int T2 = add(e0(a), Maj(a, b, c)); + h = g; + g = f; + f = e; + e = add(d, T1); + d = c; + c = b; + b = a; + a = add(T1, T2); + } + H[0] = add(a, H[0]); + H[1] = add(b, H[1]); + H[2] = add(c, H[2]); + H[3] = add(d, H[3]); + H[4] = add(e, H[4]); + H[5] = add(f, H[5]); + H[6] = add(g, H[6]); + H[7] = add(h, H[7]); + } + byte[] hashbytes = new byte[32]; + for (x = 0; x < 8; x++) { + hashbytes[x * 4] = (byte) (H[x] << 0 >>> 24); + hashbytes[x * 4 + 1] = (byte) (H[x] << 8 >>> 24); + hashbytes[x * 4 + 2] = (byte) (H[x] << 16 >>> 24); + hashbytes[x * 4 + 3] = (byte) (H[x] << 24 >>> 24); + } Hash hash = new Hash(); - hash.setData(hashbytes); + hash.setData(hashbytes); return hash; } - private static int Ch(int x, int y, int z) { - return (x & y) ^ (~x & z); - } - - private static int Maj(int x, int y, int z) { - return (x & y) ^ (x & z) ^ (y & z); - } - - private static int ROTR (int x, int n) { - return (x >>> n) | (x << 32 - n); - } - - private static int e0(int x) { - return ROTR(x, 2) ^ ROTR (x, 13) ^ ROTR(x, 22); - } - - private static int e1(int x) { - return ROTR(x, 6) ^ ROTR (x, 11) ^ ROTR(x, 25); - } - - private static int SHR(int x, int n) { - return x >>> n; - } - - private static int o0(int x) { - return ROTR(x, 7) ^ ROTR (x, 18) ^ SHR(x, 3); - } - - private static int o1(int x) { - return ROTR(x, 17) ^ ROTR (x, 19) ^ SHR(x, 10); - } - - private static int add (int x, int y) { - return x+y; - } -} + private static int Ch(int x, int y, int z) { + return (x & y) ^ (~x & z); + } + + private static int Maj(int x, int y, int z) { + return (x & y) ^ (x & z) ^ (y & z); + } + + private static int ROTR(int x, int n) { + return (x >>> n) | (x << 32 - n); + } + + private static int e0(int x) { + return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22); + } + + private static int e1(int x) { + return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25); + } + + private static int SHR(int x, int n) { + return x >>> n; + } + + private static int o0(int x) { + return ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3); + } + + private static int o1(int x) { + return ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10); + } + + private static int add(int x, int y) { + return x + y; + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/SessionKeyManager.java b/core/java/src/net/i2p/crypto/SessionKeyManager.java index ac2aaf75696a405539fe21341d1a1101451ca101..cdbd91152c7429ee89057b9190079f753751bab7 100644 --- a/core/java/src/net/i2p/crypto/SessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/SessionKeyManager.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,12 +9,12 @@ package net.i2p.crypto; * */ +import java.util.Set; + import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; -import java.util.Set; - /** * Manage the session keys and session tags used for encryption and decryption. * This base implementation simply ignores sessions and acts as if everything is @@ -23,32 +24,38 @@ import java.util.Set; */ public class SessionKeyManager { private final static SessionKeyManager _instance = new PersistentSessionKeyManager(); // new TransientSessionKeyManager(); // SessionKeyManager(); - public final static SessionKeyManager getInstance() { return _instance; } - + + public final static SessionKeyManager getInstance() { + return _instance; + } + /** * Retrieve the session key currently associated with encryption to the target, * or null if a new session key should be generated. * */ - public SessionKey getCurrentKey(PublicKey target) { return null; } - + public SessionKey getCurrentKey(PublicKey target) { + return null; + } + /** * Associate a new session key with the specified target. Metrics to determine * when to expire that key begin with this call. * */ - public void createSession(PublicKey target, SessionKey key) { } - + public void createSession(PublicKey target, SessionKey key) { + } + /** * Generate a new session key and associate it with the specified target. * */ - public SessionKey createSession(PublicKey target) { - SessionKey key = KeyGenerator.getInstance().generateSessionKey(); - createSession(target, key); - return key; + public SessionKey createSession(PublicKey target) { + SessionKey key = KeyGenerator.getInstance().generateSessionKey(); + createSession(target, key); + return key; } - + /** * Retrieve the next available session tag for identifying the use of the given * key when communicating with the target. If this returns null, no tags are @@ -56,43 +63,52 @@ public class SessionKeyManager { * NOT be used) * */ - public SessionTag consumeNextAvailableTag(PublicKey target, SessionKey key) { return null; } - + public SessionTag consumeNextAvailableTag(PublicKey target, SessionKey key) { + return null; + } + /** * Determine (approximately) how many available session tags for the current target * have been confirmed and are available * */ - public int getAvailableTags(PublicKey target, SessionKey key) { return 0; } - + public int getAvailableTags(PublicKey target, SessionKey key) { + return 0; + } + /** * Determine how long the available tags will be available for before expiring, in * milliseconds */ - public long getAvailableTimeLeft(PublicKey target, SessionKey key) { return 0; } - + public long getAvailableTimeLeft(PublicKey target, SessionKey key) { + return 0; + } + /** * Take note of the fact that the given sessionTags associated with the key for * encryption to the target have definitely been received at the target (aka call this * method after receiving an ack to a message delivering them) * */ - public void tagsDelivered(PublicKey target, SessionKey key, Set sessionTags) { } - + public void tagsDelivered(PublicKey target, SessionKey key, Set sessionTags) { + } + /** * Mark all of the tags delivered to the target up to this point as invalid, since the peer * has failed to respond when they should have. This call essentially lets the system recover * from corrupted tag sets and crashes * */ - public void failTags(PublicKey target) {} - + public void failTags(PublicKey target) { + } + /** * Accept the given tags and associate them with the given key for decryption * */ - public void tagsReceived(SessionKey key, Set sessionTags) { } - + public void tagsReceived(SessionKey key, Set sessionTags) { + } + /** * Determine if we have received a session key associated with the given session tag, * and if so, discard it (but keep track for frequent dups) and return the decryption @@ -100,12 +116,15 @@ public class SessionKeyManager { * matches * */ - public SessionKey consumeTag(SessionTag tag) { return null; } - + public SessionKey consumeTag(SessionTag tag) { + return null; + } + /** * Called when the system is closing down, instructing the session key manager to take * whatever precautions are necessary (saving state, etc) * */ - public void shutdown() {} + public void shutdown() { + } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java index a37aef81989af42e0c9d0f42a3aedce67fa8606f..33109e6d00149ecd9bb9b62b9f9a34846abf94cb 100644 --- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java +++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,22 +9,21 @@ package net.i2p.crypto; * */ +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.i2p.data.DataHelper; import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; -import net.i2p.data.DataHelper; - -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Set; -import java.util.HashSet; -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Date; +import net.i2p.util.Log; /** * Implement the session key management, but keep everything in memory (don't write @@ -35,94 +35,98 @@ class TransientSessionKeyManager extends SessionKeyManager { private final static Log _log = new Log(TransientSessionKeyManager.class); private Map _outboundSessions; // PublicKey --> OutboundSession private Map _inboundTagSets; // SessionTag --> TagSet - + /** * Let session tags sit around for 10 minutes before expiring them. We can now have such a large * value since there is the persistent session key manager. This value is for outbound tags - * inbound tags are managed by SESSION_LIFETIME_MAX_MS * */ - public final static long SESSION_TAG_DURATION_MS = 10*60*1000; + public final static long SESSION_TAG_DURATION_MS = 10 * 60 * 1000; /** * Keep unused inbound session tags around for up to 15 minutes (5 minutes longer than * session tags are used on the outbound side so that no reasonable network lag * can cause failed decrypts) * */ - public final static long SESSION_LIFETIME_MAX_MS = SESSION_TAG_DURATION_MS + 5*60*1000; - public final static int MAX_INBOUND_SESSION_TAGS = 100*1000; // this will consume at most 3.2M - + public final static long SESSION_LIFETIME_MAX_MS = SESSION_TAG_DURATION_MS + 5 * 60 * 1000; + public final static int MAX_INBOUND_SESSION_TAGS = 100 * 1000; // this will consume at most 3.2M + public TransientSessionKeyManager() { - super(); - _outboundSessions = new HashMap(64); - _inboundTagSets = new HashMap(1024); + super(); + _outboundSessions = new HashMap(64); + _inboundTagSets = new HashMap(1024); } - + /** TagSet */ - protected Set getInboundTagSets() { - synchronized (_inboundTagSets) { - return new HashSet(_inboundTagSets.values()); - } + protected Set getInboundTagSets() { + synchronized (_inboundTagSets) { + return new HashSet(_inboundTagSets.values()); + } } + /** OutboundSession */ - protected Set getOutboundSessions() { - synchronized (_outboundSessions) { - return new HashSet(_outboundSessions.values()); - } + protected Set getOutboundSessions() { + synchronized (_outboundSessions) { + return new HashSet(_outboundSessions.values()); + } } - protected void setData(Set inboundTagSets, Set outboundSessions) { - _log.info("Loading " + inboundTagSets.size() + " inbound tag sets, and " + outboundSessions.size() + " outbound sessions"); - Map tagSets = new HashMap(inboundTagSets.size()); - for (Iterator iter = inboundTagSets.iterator(); iter.hasNext(); ) { - TagSet ts = (TagSet)iter.next(); - for (Iterator tsIter = ts.getTags().iterator(); tsIter.hasNext(); ) { - SessionTag tag = (SessionTag)tsIter.next(); - tagSets.put(tag, ts); - } - } - synchronized (_inboundTagSets) { - _inboundTagSets.clear(); - _inboundTagSets.putAll(tagSets); - } - Map sessions = new HashMap(outboundSessions.size()); - for (Iterator iter = outboundSessions.iterator(); iter.hasNext(); ) { - OutboundSession sess = (OutboundSession)iter.next(); - sessions.put(sess.getTarget(), sess); - } - synchronized (_outboundSessions) { - _outboundSessions.clear(); - _outboundSessions.putAll(sessions); - } + + protected void setData(Set inboundTagSets, Set outboundSessions) { + _log.info("Loading " + inboundTagSets.size() + " inbound tag sets, and " + outboundSessions.size() + + " outbound sessions"); + Map tagSets = new HashMap(inboundTagSets.size()); + for (Iterator iter = inboundTagSets.iterator(); iter.hasNext();) { + TagSet ts = (TagSet) iter.next(); + for (Iterator tsIter = ts.getTags().iterator(); tsIter.hasNext();) { + SessionTag tag = (SessionTag) tsIter.next(); + tagSets.put(tag, ts); + } + } + synchronized (_inboundTagSets) { + _inboundTagSets.clear(); + _inboundTagSets.putAll(tagSets); + } + Map sessions = new HashMap(outboundSessions.size()); + for (Iterator iter = outboundSessions.iterator(); iter.hasNext();) { + OutboundSession sess = (OutboundSession) iter.next(); + sessions.put(sess.getTarget(), sess); + } + synchronized (_outboundSessions) { + _outboundSessions.clear(); + _outboundSessions.putAll(sessions); + } } - + /** * Retrieve the session key currently associated with encryption to the target, * or null if a new session key should be generated. * */ - public SessionKey getCurrentKey(PublicKey target) { - OutboundSession sess = getSession(target); - if (sess == null) return null; - long now = Clock.getInstance().now(); - if (sess.getEstablishedDate() < now - SESSION_LIFETIME_MAX_MS) { - _log.info("Expiring old session key established on " + new Date(sess.getEstablishedDate()) + " with target " + target); - return null; - } else { - return sess.getCurrentKey(); - } + public SessionKey getCurrentKey(PublicKey target) { + OutboundSession sess = getSession(target); + if (sess == null) return null; + long now = Clock.getInstance().now(); + if (sess.getEstablishedDate() < now - SESSION_LIFETIME_MAX_MS) { + _log.info("Expiring old session key established on " + new Date(sess.getEstablishedDate()) + + " with target " + target); + return null; + } else { + return sess.getCurrentKey(); + } } - + /** * Associate a new session key with the specified target. Metrics to determine * when to expire that key begin with this call. * */ - public void createSession(PublicKey target, SessionKey key) { - OutboundSession sess = new OutboundSession(target); - sess.setCurrentKey(key); - addSession(sess); + public void createSession(PublicKey target, SessionKey key) { + OutboundSession sess = new OutboundSession(target); + sess.setCurrentKey(key); + addSession(sess); } - + /** * Retrieve the next available session tag for identifying the use of the given * key when communicating with the target. If this returns null, no tags are @@ -130,110 +134,103 @@ class TransientSessionKeyManager extends SessionKeyManager { * NOT be used) * */ - public SessionTag consumeNextAvailableTag(PublicKey target, SessionKey key) { - OutboundSession sess = getSession(target); - if (sess == null) { - _log.debug("No session for " + target); - return null; - } - if (sess.getCurrentKey().equals(key)) { - SessionTag nxt = sess.consumeNext(); - _log.debug("Tag consumed: " + nxt); - return nxt; - } else { - _log.debug("Key does not match existing key, no tag"); - return null; - } + public SessionTag consumeNextAvailableTag(PublicKey target, SessionKey key) { + OutboundSession sess = getSession(target); + if (sess == null) { + _log.debug("No session for " + target); + return null; + } + if (sess.getCurrentKey().equals(key)) { + SessionTag nxt = sess.consumeNext(); + _log.debug("Tag consumed: " + nxt); + return nxt; + } else { + _log.debug("Key does not match existing key, no tag"); + return null; + } } - + /** * Determine (approximately) how many available session tags for the current target * have been confirmed and are available * */ - public int getAvailableTags(PublicKey target, SessionKey key) { - OutboundSession sess = getSession(target); - if (sess == null) { - return 0; - } - if (sess.getCurrentKey().equals(key)) { - return sess.availableTags(); - } else { - return 0; - } + public int getAvailableTags(PublicKey target, SessionKey key) { + OutboundSession sess = getSession(target); + if (sess == null) { return 0; } + if (sess.getCurrentKey().equals(key)) { + return sess.availableTags(); + } else { + return 0; + } } - - + /** * Determine how long the available tags will be available for before expiring, in * milliseconds */ - public long getAvailableTimeLeft(PublicKey target, SessionKey key) { - OutboundSession sess = getSession(target); - if (sess == null) { - return 0; - } - if (sess.getCurrentKey().equals(key)) { - return (sess.getLastExpirationDate() + SESSION_TAG_DURATION_MS) - Clock.getInstance().now(); - } else { - return 0; - } + public long getAvailableTimeLeft(PublicKey target, SessionKey key) { + OutboundSession sess = getSession(target); + if (sess == null) { return 0; } + if (sess.getCurrentKey().equals(key)) { + return (sess.getLastExpirationDate() + SESSION_TAG_DURATION_MS) - Clock.getInstance().now(); + } else { + return 0; + } } - + /** * Take note of the fact that the given sessionTags associated with the key for * encryption to the target have definitely been received at the target (aka call this * method after receiving an ack to a message delivering them) * */ - public void tagsDelivered(PublicKey target, SessionKey key, Set sessionTags) { - OutboundSession sess = getSession(target); - if (sess == null) { - createSession(target, key); - sess = getSession(target); - } - sess.setCurrentKey(key); - TagSet set = new TagSet(sessionTags, key); - sess.addTags(set); - _log.debug("Tags delivered to set " + set + " on session " + sess); + public void tagsDelivered(PublicKey target, SessionKey key, Set sessionTags) { + OutboundSession sess = getSession(target); + if (sess == null) { + createSession(target, key); + sess = getSession(target); + } + sess.setCurrentKey(key); + TagSet set = new TagSet(sessionTags, key); + sess.addTags(set); + _log.debug("Tags delivered to set " + set + " on session " + sess); } - + /** * Mark all of the tags delivered to the target up to this point as invalid, since the peer * has failed to respond when they should have. This call essentially lets the system recover * from corrupted tag sets and crashes * */ - public void failTags(PublicKey target) { - removeSession(target); + public void failTags(PublicKey target) { + removeSession(target); } - - + /** * Accept the given tags and associate them with the given key for decryption * */ - public void tagsReceived(SessionKey key, Set sessionTags) { - TagSet tagSet = new TagSet(sessionTags, key); - for (Iterator iter = sessionTags.iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); - _log.debug("Receiving tag " + tag + " for key " + key); - synchronized (_inboundTagSets) { - _inboundTagSets.put(tag, tagSet); - } - } - synchronized (_inboundTagSets) { - // todo: make this limit the tags by sessionKey and actually enforce the limit! - int overage = _inboundTagSets.size() - MAX_INBOUND_SESSION_TAGS; - if (overage > 0) { - _log.error("TOO MANY SESSION TAGS! " + (_inboundTagSets.size())); - } - } - - if (sessionTags.size() <= 0) - _log.debug("Received 0 tags for key " + key); + public void tagsReceived(SessionKey key, Set sessionTags) { + TagSet tagSet = new TagSet(sessionTags, key); + for (Iterator iter = sessionTags.iterator(); iter.hasNext();) { + SessionTag tag = (SessionTag) iter.next(); + _log.debug("Receiving tag " + tag + " for key " + key); + synchronized (_inboundTagSets) { + _inboundTagSets.put(tag, tagSet); + } + } + synchronized (_inboundTagSets) { + // todo: make this limit the tags by sessionKey and actually enforce the limit! + int overage = _inboundTagSets.size() - MAX_INBOUND_SESSION_TAGS; + if (overage > 0) { + _log.error("TOO MANY SESSION TAGS! " + (_inboundTagSets.size())); + } + } + + if (sessionTags.size() <= 0) _log.debug("Received 0 tags for key " + key); } - + /** * Determine if we have received a session key associated with the given session tag, * and if so, discard it (but keep track for frequent dups) and return the decryption @@ -241,287 +238,320 @@ class TransientSessionKeyManager extends SessionKeyManager { * matches * */ - public SessionKey consumeTag(SessionTag tag) { - synchronized (_inboundTagSets) { - TagSet tagSet = (TagSet)_inboundTagSets.remove(tag); - if (tagSet == null) { - _log.debug("Cannot consume tag " + tag + " as it is not known"); - return null; - } else { - tagSet.consume(tag); - } - SessionKey key = tagSet.getAssociatedKey(); - _log.debug("Consuming tag " + tag + " for sessionKey " + key); - return key; - } - } - + public SessionKey consumeTag(SessionTag tag) { + synchronized (_inboundTagSets) { + TagSet tagSet = (TagSet) _inboundTagSets.remove(tag); + if (tagSet == null) { + _log.debug("Cannot consume tag " + tag + " as it is not known"); + return null; + } else { + tagSet.consume(tag); + } + SessionKey key = tagSet.getAssociatedKey(); + _log.debug("Consuming tag " + tag + " for sessionKey " + key); + return key; + } + } + private OutboundSession getSession(PublicKey target) { - synchronized (_outboundSessions) { - return (OutboundSession)_outboundSessions.get(target); - } + synchronized (_outboundSessions) { + return (OutboundSession) _outboundSessions.get(target); + } } - + private void addSession(OutboundSession sess) { - synchronized (_outboundSessions) { - _outboundSessions.put(sess.getTarget(), sess); - } + synchronized (_outboundSessions) { + _outboundSessions.put(sess.getTarget(), sess); + } } - + private void removeSession(PublicKey target) { - if (target == null) return; - synchronized (_outboundSessions) { - _outboundSessions.remove(target); - } + if (target == null) return; + synchronized (_outboundSessions) { + _outboundSessions.remove(target); + } } - + /** * Aggressively expire inbound tag sets and outbound sessions * * @return number of tag sets expired */ public int aggressiveExpire() { - int removed = 0; - long now = Clock.getInstance().now(); - Set tagsToDrop = new HashSet(64); - synchronized (_inboundTagSets) { - for (Iterator iter = _inboundTagSets.keySet().iterator(); iter.hasNext(); ) { - SessionTag tag = (SessionTag)iter.next(); - TagSet ts = (TagSet)_inboundTagSets.get(tag); - if (ts.getDate() < now - SESSION_LIFETIME_MAX_MS) { - tagsToDrop.add(tag); - } - } - removed += tagsToDrop.size(); - for (Iterator iter = tagsToDrop.iterator(); iter.hasNext(); ) - _inboundTagSets.remove(iter.next()); - } - //_log.warn("Expiring tags: [" + tagsToDrop + "]"); - - synchronized (_outboundSessions) { - Set sessionsToDrop = new HashSet(64); - for (Iterator iter = _outboundSessions.keySet().iterator(); iter.hasNext(); ) { - PublicKey key = (PublicKey)iter.next(); - OutboundSession sess = (OutboundSession)_outboundSessions.get(key); - removed += sess.expireTags(); - if (sess.getTagSets().size() <= 0) - sessionsToDrop.add(key); - } - for (Iterator iter = sessionsToDrop.iterator(); iter.hasNext(); ) - _outboundSessions.remove(iter.next()); - } - return removed; + int removed = 0; + long now = Clock.getInstance().now(); + Set tagsToDrop = new HashSet(64); + synchronized (_inboundTagSets) { + for (Iterator iter = _inboundTagSets.keySet().iterator(); iter.hasNext();) { + SessionTag tag = (SessionTag) iter.next(); + TagSet ts = (TagSet) _inboundTagSets.get(tag); + if (ts.getDate() < now - SESSION_LIFETIME_MAX_MS) { + tagsToDrop.add(tag); + } + } + removed += tagsToDrop.size(); + for (Iterator iter = tagsToDrop.iterator(); iter.hasNext();) + _inboundTagSets.remove(iter.next()); + } + //_log.warn("Expiring tags: [" + tagsToDrop + "]"); + + synchronized (_outboundSessions) { + Set sessionsToDrop = new HashSet(64); + for (Iterator iter = _outboundSessions.keySet().iterator(); iter.hasNext();) { + PublicKey key = (PublicKey) iter.next(); + OutboundSession sess = (OutboundSession) _outboundSessions.get(key); + removed += sess.expireTags(); + if (sess.getTagSets().size() <= 0) sessionsToDrop.add(key); + } + for (Iterator iter = sessionsToDrop.iterator(); iter.hasNext();) + _outboundSessions.remove(iter.next()); + } + return removed; } - + public String renderStatusHTML() { - StringBuffer buf = new StringBuffer(1024); - buf.append("<h2>Inbound sessions</h2>"); - buf.append("<table border=\"1\">"); - Set inbound = getInboundTagSets(); - Map inboundSets = new HashMap(inbound.size()); - for (Iterator iter = inbound.iterator(); iter.hasNext(); ) { - TagSet ts = (TagSet)iter.next(); - if (!inboundSets.containsKey(ts.getAssociatedKey())) - inboundSets.put(ts.getAssociatedKey(), new HashSet()); - Set sets = (Set)inboundSets.get(ts.getAssociatedKey()); - sets.add(ts); - } - for (Iterator iter = inboundSets.keySet().iterator(); iter.hasNext(); ) { - SessionKey skey = (SessionKey)iter.next(); - Set sets = (Set)inboundSets.get(skey); - buf.append("<tr><td><b>Session key</b>: ").append(skey.toBase64()).append("</td>"); - buf.append("<td><b># Sets:</b> ").append(sets.size()).append("</td></tr>"); - buf.append("<tr><td colspan=\"2\"><ul>"); - for (Iterator siter = sets.iterator(); siter.hasNext(); ) { - TagSet ts = (TagSet)siter.next(); - buf.append("<li><b>Received on:</b> ").append(new Date(ts.getDate())).append(" with ").append(ts.getTags().size()).append(" tags remaining</li>"); - } - buf.append("</ul></td></tr>"); - } - buf.append("</table>"); - - buf.append("<h2><b>Outbound sessions</b></h2>"); - - buf.append("<table border=\"1\">"); - Set outbound = getOutboundSessions(); - for (Iterator iter = outbound.iterator(); iter.hasNext(); ) { - OutboundSession sess = (OutboundSession)iter.next(); - buf.append("<tr><td><b>Target key:</b> ").append(sess.getTarget().toString()).append("<br />"); - buf.append("<b>Established:</b> ").append(new Date(sess.getEstablishedDate())).append("<br />"); - buf.append("<b>Last Used:</b> ").append(new Date(sess.getLastUsedDate())).append("<br />"); - buf.append("<b># Sets:</b> ").append(sess.getTagSets().size()).append("</td></tr>"); - buf.append("<tr><td><b>Session key:</b> ").append(sess.getCurrentKey().toBase64()).append("</td></tr>"); - buf.append("<tr><td><ul>"); - for (Iterator siter = sess.getTagSets().iterator(); siter.hasNext(); ) { - TagSet ts = (TagSet)siter.next(); - buf.append("<li><b>Sent on:</b> ").append(new Date(ts.getDate())).append(" with ").append(ts.getTags().size()).append(" tags remaining</li>"); - } - buf.append("</ul></td></tr>"); - } - buf.append("</table>"); - - return buf.toString(); + StringBuffer buf = new StringBuffer(1024); + buf.append("<h2>Inbound sessions</h2>"); + buf.append("<table border=\"1\">"); + Set inbound = getInboundTagSets(); + Map inboundSets = new HashMap(inbound.size()); + for (Iterator iter = inbound.iterator(); iter.hasNext();) { + TagSet ts = (TagSet) iter.next(); + if (!inboundSets.containsKey(ts.getAssociatedKey())) inboundSets.put(ts.getAssociatedKey(), new HashSet()); + Set sets = (Set) inboundSets.get(ts.getAssociatedKey()); + sets.add(ts); + } + for (Iterator iter = inboundSets.keySet().iterator(); iter.hasNext();) { + SessionKey skey = (SessionKey) iter.next(); + Set sets = (Set) inboundSets.get(skey); + buf.append("<tr><td><b>Session key</b>: ").append(skey.toBase64()).append("</td>"); + buf.append("<td><b># Sets:</b> ").append(sets.size()).append("</td></tr>"); + buf.append("<tr><td colspan=\"2\"><ul>"); + for (Iterator siter = sets.iterator(); siter.hasNext();) { + TagSet ts = (TagSet) siter.next(); + buf.append("<li><b>Received on:</b> ").append(new Date(ts.getDate())).append(" with ") + .append(ts.getTags().size()).append(" tags remaining</li>"); + } + buf.append("</ul></td></tr>"); + } + buf.append("</table>"); + + buf.append("<h2><b>Outbound sessions</b></h2>"); + + buf.append("<table border=\"1\">"); + Set outbound = getOutboundSessions(); + for (Iterator iter = outbound.iterator(); iter.hasNext();) { + OutboundSession sess = (OutboundSession) iter.next(); + buf.append("<tr><td><b>Target key:</b> ").append(sess.getTarget().toString()).append("<br />"); + buf.append("<b>Established:</b> ").append(new Date(sess.getEstablishedDate())).append("<br />"); + buf.append("<b>Last Used:</b> ").append(new Date(sess.getLastUsedDate())).append("<br />"); + buf.append("<b># Sets:</b> ").append(sess.getTagSets().size()).append("</td></tr>"); + buf.append("<tr><td><b>Session key:</b> ").append(sess.getCurrentKey().toBase64()).append("</td></tr>"); + buf.append("<tr><td><ul>"); + for (Iterator siter = sess.getTagSets().iterator(); siter.hasNext();) { + TagSet ts = (TagSet) siter.next(); + buf.append("<li><b>Sent on:</b> ").append(new Date(ts.getDate())).append(" with ").append( + ts.getTags() + .size()) + .append(" tags remaining</li>"); + } + buf.append("</ul></td></tr>"); + } + buf.append("</table>"); + + return buf.toString(); } - + static class OutboundSession { - private PublicKey _target; - private SessionKey _currentKey; - private long _established; - private long _lastUsed; - private List _tagSets; - - public OutboundSession(PublicKey target) { - this(target, null, Clock.getInstance().now(), Clock.getInstance().now(), new ArrayList()); - } - - OutboundSession(PublicKey target, SessionKey curKey, long established, long lastUsed, List tagSets) { - _target = target; - _currentKey = curKey; - _established = established; - _lastUsed = lastUsed; - _tagSets = tagSets; - } - - /** list of TagSet objects */ - List getTagSets() { - synchronized (_tagSets) { - return new ArrayList(_tagSets); - } - } - - public PublicKey getTarget() { return _target; } - public SessionKey getCurrentKey() { return _currentKey; } - public void setCurrentKey(SessionKey key) { - if (_currentKey != null) { - if (!_currentKey.equals(key)) { - int dropped = 0; - List sets = _tagSets; - _tagSets = new ArrayList(); - for (int i = 0; i < sets.size(); i++) { - TagSet set = (TagSet)sets.get(i); - dropped += set.getTags().size(); - } - _log.info("Rekeyed from " + _currentKey + " to " + key + ": dropping " + dropped + " session tags"); - } - } - _currentKey = key; - - } - public long getEstablishedDate() { return _established; } - public long getLastUsedDate() { return _lastUsed; } - /** - * Expire old tags, returning the number of tag sets removed - */ - public int expireTags() { - long now = Clock.getInstance().now(); - Set toRemove = new HashSet(64); - synchronized (_tagSets) { - for (int i = 0; i < _tagSets.size(); i++) { - TagSet set = (TagSet)_tagSets.get(i); - if (set.getDate() + SESSION_TAG_DURATION_MS <= now) { - toRemove.add(set); - } - } - _tagSets.removeAll(toRemove); - } - return toRemove.size(); - } - public SessionTag consumeNext() { - long now = Clock.getInstance().now(); - synchronized (_tagSets) { - while (_tagSets.size() > 0) { - TagSet set = (TagSet)_tagSets.get(0); - if (set.getDate() + SESSION_TAG_DURATION_MS > now) { - SessionTag tag = set.consumeNext(); - if (tag != null) return tag; - } else { - _log.info("TagSet from " + new Date(set.getDate()) + " expired"); - } - _tagSets.remove(0); - } - } - return null; - } - public int availableTags() { - int tags = 0; - synchronized (_tagSets) { - for (int i = 0; i < _tagSets.size(); i++) { - TagSet set = (TagSet)_tagSets.get(i); - tags += set.getTags().size(); - } - } - return tags; - } - /** - * Get the furthest away tag set expiration date - after which all of the - * tags will have expired - * - */ - public long getLastExpirationDate() { - long last = 0; - synchronized (_tagSets) { - for (Iterator iter = _tagSets.iterator(); iter.hasNext(); ) { - TagSet set = (TagSet)iter.next(); - if (set.getDate() > last) - last = set.getDate(); - } - } - return last + SESSION_TAG_DURATION_MS; - } - public void addTags(TagSet set) { - synchronized (_tagSets) { - _tagSets.add(set); - } - } + private PublicKey _target; + private SessionKey _currentKey; + private long _established; + private long _lastUsed; + private List _tagSets; + + public OutboundSession(PublicKey target) { + this(target, null, Clock.getInstance().now(), Clock.getInstance().now(), new ArrayList()); + } + + OutboundSession(PublicKey target, SessionKey curKey, long established, long lastUsed, List tagSets) { + _target = target; + _currentKey = curKey; + _established = established; + _lastUsed = lastUsed; + _tagSets = tagSets; + } + + /** list of TagSet objects */ + List getTagSets() { + synchronized (_tagSets) { + return new ArrayList(_tagSets); + } + } + + public PublicKey getTarget() { + return _target; + } + + public SessionKey getCurrentKey() { + return _currentKey; + } + + public void setCurrentKey(SessionKey key) { + if (_currentKey != null) { + if (!_currentKey.equals(key)) { + int dropped = 0; + List sets = _tagSets; + _tagSets = new ArrayList(); + for (int i = 0; i < sets.size(); i++) { + TagSet set = (TagSet) sets.get(i); + dropped += set.getTags().size(); + } + _log.info("Rekeyed from " + _currentKey + " to " + key + ": dropping " + dropped + " session tags"); + } + } + _currentKey = key; + + } + + public long getEstablishedDate() { + return _established; + } + + public long getLastUsedDate() { + return _lastUsed; + } + + /** + * Expire old tags, returning the number of tag sets removed + */ + public int expireTags() { + long now = Clock.getInstance().now(); + Set toRemove = new HashSet(64); + synchronized (_tagSets) { + for (int i = 0; i < _tagSets.size(); i++) { + TagSet set = (TagSet) _tagSets.get(i); + if (set.getDate() + SESSION_TAG_DURATION_MS <= now) { + toRemove.add(set); + } + } + _tagSets.removeAll(toRemove); + } + return toRemove.size(); + } + + public SessionTag consumeNext() { + long now = Clock.getInstance().now(); + synchronized (_tagSets) { + while (_tagSets.size() > 0) { + TagSet set = (TagSet) _tagSets.get(0); + if (set.getDate() + SESSION_TAG_DURATION_MS > now) { + SessionTag tag = set.consumeNext(); + if (tag != null) return tag; + } else { + _log.info("TagSet from " + new Date(set.getDate()) + " expired"); + } + _tagSets.remove(0); + } + } + return null; + } + + public int availableTags() { + int tags = 0; + synchronized (_tagSets) { + for (int i = 0; i < _tagSets.size(); i++) { + TagSet set = (TagSet) _tagSets.get(i); + tags += set.getTags().size(); + } + } + return tags; + } + + /** + * Get the furthest away tag set expiration date - after which all of the + * tags will have expired + * + */ + public long getLastExpirationDate() { + long last = 0; + synchronized (_tagSets) { + for (Iterator iter = _tagSets.iterator(); iter.hasNext();) { + TagSet set = (TagSet) iter.next(); + if (set.getDate() > last) last = set.getDate(); + } + } + return last + SESSION_TAG_DURATION_MS; + } + + public void addTags(TagSet set) { + synchronized (_tagSets) { + _tagSets.add(set); + } + } } - + static class TagSet { - private Set _sessionTags; - private SessionKey _key; - private long _date; - public TagSet(Set tags, SessionKey key) { - if (key == null) - throw new IllegalArgumentException("Missing key"); - if (tags == null) - throw new IllegalArgumentException("Missing tags"); - _sessionTags = tags; - _key = key; - _date = Clock.getInstance().now(); - } - public long getDate() { return _date; } - void setDate(long when) { _date = when; } - public Set getTags() { return _sessionTags; } - public SessionKey getAssociatedKey() { return _key; } - public boolean contains(SessionTag tag) { return _sessionTags.contains(tag); } - public void consume(SessionTag tag) { - if (contains(tag)) { - _sessionTags.remove(tag); - } - } - public SessionTag consumeNext() { - if (_sessionTags.size() <= 0) { - return null; - } else { - SessionTag first = (SessionTag)_sessionTags.iterator().next(); - _sessionTags.remove(first); - return first; - } - } - public int hashCode() { - long rv = 0; - if (_key != null) - rv = rv*7 + _key.hashCode(); - rv = rv*7 + _date; - if (_sessionTags != null) - rv = rv*7 + DataHelper.hashCode(_sessionTags); - return (int)rv; - } - public boolean equals(Object o) { - if ( (o == null) || !(o instanceof TagSet) ) return false; - TagSet ts = (TagSet)o; - return DataHelper.eq(ts.getAssociatedKey(), getAssociatedKey()) && - DataHelper.eq(ts.getTags(), getTags()) && - ts.getDate() == getDate(); - } + private Set _sessionTags; + private SessionKey _key; + private long _date; + + public TagSet(Set tags, SessionKey key) { + if (key == null) throw new IllegalArgumentException("Missing key"); + if (tags == null) throw new IllegalArgumentException("Missing tags"); + _sessionTags = tags; + _key = key; + _date = Clock.getInstance().now(); + } + + public long getDate() { + return _date; + } + + void setDate(long when) { + _date = when; + } + + public Set getTags() { + return _sessionTags; + } + + public SessionKey getAssociatedKey() { + return _key; + } + + public boolean contains(SessionTag tag) { + return _sessionTags.contains(tag); + } + + public void consume(SessionTag tag) { + if (contains(tag)) { + _sessionTags.remove(tag); + } + } + + public SessionTag consumeNext() { + if (_sessionTags.size() <= 0) { + return null; + } else { + SessionTag first = (SessionTag) _sessionTags.iterator().next(); + _sessionTags.remove(first); + return first; + } + } + + public int hashCode() { + long rv = 0; + if (_key != null) rv = rv * 7 + _key.hashCode(); + rv = rv * 7 + _date; + if (_sessionTags != null) rv = rv * 7 + DataHelper.hashCode(_sessionTags); + return (int) rv; + } + + public boolean equals(Object o) { + if ((o == null) || !(o instanceof TagSet)) return false; + TagSet ts = (TagSet) o; + return DataHelper.eq(ts.getAssociatedKey(), getAssociatedKey()) && DataHelper.eq(ts.getTags(), getTags()) + && ts.getDate() == getDate(); + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/crypto/YKGenerator.java b/core/java/src/net/i2p/crypto/YKGenerator.java index 39bc4be9c8acae85f40a3e2073f3f8ab0897af9c..c97a76e485d616e7de3822cd4e256fce0e5168ba 100644 --- a/core/java/src/net/i2p/crypto/YKGenerator.java +++ b/core/java/src/net/i2p/crypto/YKGenerator.java @@ -1,4 +1,5 @@ package net.i2p.crypto; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -13,8 +14,8 @@ import java.util.ArrayList; import java.util.List; import net.i2p.util.Clock; -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; import net.i2p.util.NativeBigInteger; import net.i2p.util.RandomSource; @@ -43,152 +44,174 @@ class YKGenerator { private static int CALC_DELAY = -1; private static volatile List _values = new ArrayList(50); // list of BigInteger[] values (y and k) private static Thread _precalcThread = null; - + public final static String PROP_YK_PRECALC_MIN = "crypto.yk.precalc.min"; public final static String PROP_YK_PRECALC_MAX = "crypto.yk.precalc.max"; public final static String PROP_YK_PRECALC_DELAY = "crypto.yk.precalc.delay"; public final static String DEFAULT_YK_PRECALC_MIN = "10"; public final static String DEFAULT_YK_PRECALC_MAX = "30"; public final static String DEFAULT_YK_PRECALC_DELAY = "10000"; - + /** check every 30 seconds whether we have less than the minimum */ - private final static long CHECK_DELAY = 30*1000; - - static { - try { - int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_MIN, DEFAULT_YK_PRECALC_MIN)); - MIN_NUM_BUILDERS = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_YK_PRECALC_MIN); - MIN_NUM_BUILDERS = val; - } - try { - int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_MAX, DEFAULT_YK_PRECALC_MAX)); - MAX_NUM_BUILDERS = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_YK_PRECALC_MAX); - MAX_NUM_BUILDERS = val; - } - try { - int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_DELAY, DEFAULT_YK_PRECALC_DELAY)); - CALC_DELAY = val; - } catch (Throwable t) { - int val = Integer.parseInt(DEFAULT_YK_PRECALC_DELAY); - CALC_DELAY = val; - } - - if (_log.shouldLog(Log.DEBUG)) _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: " + CALC_DELAY + ")"); - - _precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS)); - _precalcThread.setName("YK Precalc"); - _precalcThread.setDaemon(true); - _precalcThread.setPriority(Thread.MIN_PRIORITY); - _precalcThread.start(); + private final static long CHECK_DELAY = 30 * 1000; + + static { + try { + int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_MIN, DEFAULT_YK_PRECALC_MIN)); + MIN_NUM_BUILDERS = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_YK_PRECALC_MIN); + MIN_NUM_BUILDERS = val; + } + try { + int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_MAX, DEFAULT_YK_PRECALC_MAX)); + MAX_NUM_BUILDERS = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_YK_PRECALC_MAX); + MAX_NUM_BUILDERS = val; + } + try { + int val = Integer.parseInt(System.getProperty(PROP_YK_PRECALC_DELAY, DEFAULT_YK_PRECALC_DELAY)); + CALC_DELAY = val; + } catch (Throwable t) { + int val = Integer.parseInt(DEFAULT_YK_PRECALC_DELAY); + CALC_DELAY = val; + } + + if (_log.shouldLog(Log.DEBUG)) + _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: " + + CALC_DELAY + ")"); + + _precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS)); + _precalcThread.setName("YK Precalc"); + _precalcThread.setDaemon(true); + _precalcThread.setPriority(Thread.MIN_PRIORITY); + _precalcThread.start(); } - - private static final int getSize() { synchronized (_values) { return _values.size(); } } + + private static final int getSize() { + synchronized (_values) { + return _values.size(); + } + } + private static final int addValues(BigInteger yk[]) { - int sz = 0; - synchronized (_values) { - _values.add(yk); - sz = _values.size(); - } - return sz; + int sz = 0; + synchronized (_values) { + _values.add(yk); + sz = _values.size(); + } + return sz; } - + public static BigInteger[] getNextYK() { - if (true) { - synchronized (_values) { - if (_values.size() > 0) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Sufficient precalculated YK values - fetch the existing"); - return (BigInteger[])_values.remove(0); - } - } - } - if (_log.shouldLog(Log.INFO)) _log.info("Insufficient precalculated YK values - create a new one"); - return generateYK(); + if (true) { + synchronized (_values) { + if (_values.size() > 0) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Sufficient precalculated YK values - fetch the existing"); + return (BigInteger[]) _values.remove(0); + } + } + } + if (_log.shouldLog(Log.INFO)) _log.info("Insufficient precalculated YK values - create a new one"); + return generateYK(); } - - private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02 } ); - + + private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02}); + private static final BigInteger[] generateYK() { - NativeBigInteger k = null; - BigInteger y = null; - long t0 = 0; - long t1 = 0; - while (k == null) { - t0 = Clock.getInstance().now(); - k = new NativeBigInteger(2048, RandomSource.getInstance()); - t1 = Clock.getInstance().now(); - if (BigInteger.ZERO.compareTo(k) == 0) { - k = null; - continue; - } - BigInteger kPlus2 = k.add(_two); - if (kPlus2.compareTo(CryptoConstants.elgp) > 0) - k = null; - } - long t2 = Clock.getInstance().now(); - y = CryptoConstants.elgg.modPow(k, CryptoConstants.elgp); - - BigInteger yk[] = new BigInteger[2]; - yk[0] = y; - yk[1] = k; - - long diff = t2 - t0; - if (diff > 1000) { - if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to generate YK value for ElGamal (" + diff + "ms)"); - } - - return yk; + NativeBigInteger k = null; + BigInteger y = null; + long t0 = 0; + long t1 = 0; + while (k == null) { + t0 = Clock.getInstance().now(); + k = new NativeBigInteger(2048, RandomSource.getInstance()); + t1 = Clock.getInstance().now(); + if (BigInteger.ZERO.compareTo(k) == 0) { + k = null; + continue; + } + BigInteger kPlus2 = k.add(_two); + if (kPlus2.compareTo(CryptoConstants.elgp) > 0) k = null; + } + long t2 = Clock.getInstance().now(); + y = CryptoConstants.elgg.modPow(k, CryptoConstants.elgp); + + BigInteger yk[] = new BigInteger[2]; + yk[0] = y; + yk[1] = k; + + long diff = t2 - t0; + if (diff > 1000) { + if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to generate YK value for ElGamal (" + diff + "ms)"); + } + + return yk; } - - + public static void main(String args[]) { - RandomSource.getInstance().nextBoolean(); // warm it up - try { Thread.sleep(20*1000); } catch (InterruptedException ie) {} - _log.debug("\n\n\n\nBegin test\n"); - long negTime = 0; - for (int i = 0; i < 5; i++) { - long startNeg = Clock.getInstance().now(); - getNextYK(); - long endNeg = Clock.getInstance().now(); - } - _log.debug("YK fetch time for 5 runs: " + negTime + " @ " + negTime/5l + "ms each"); - try { Thread.sleep(30*1000); } catch (InterruptedException ie) {} + RandomSource.getInstance().nextBoolean(); // warm it up + try { + Thread.sleep(20 * 1000); + } catch (InterruptedException ie) { + } + _log.debug("\n\n\n\nBegin test\n"); + long negTime = 0; + for (int i = 0; i < 5; i++) { + long startNeg = Clock.getInstance().now(); + getNextYK(); + long endNeg = Clock.getInstance().now(); + } + _log.debug("YK fetch time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each"); + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException ie) { + } } - - + private static class YKPrecalcRunner implements Runnable { - private int _minSize; - private int _maxSize; - private YKPrecalcRunner(int minSize, int maxSize) { - _minSize = minSize; - _maxSize = maxSize; - } - public void run() { - while (true) { - int curSize = 0; - long start = Clock.getInstance().now(); - int startSize = getSize(); - curSize = startSize; - while (curSize < _minSize) { - while (curSize < _maxSize) { - long begin = Clock.getInstance().now(); - curSize = addValues(generateYK()); - long end = Clock.getInstance().now(); - if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalculated YK value in " + (end-begin) + "ms"); - // for some relief... - try { Thread.sleep(CALC_DELAY); } catch (InterruptedException ie) {} - } - } - long end = Clock.getInstance().now(); - int numCalc = curSize - startSize; - if (numCalc > 0) { - if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalced " + numCalc + " to " + curSize + " in " + (end-start-CALC_DELAY*numCalc) + "ms (not counting " + (CALC_DELAY*numCalc) + "ms relief). now sleeping"); - } - try { Thread.sleep(CHECK_DELAY); } catch (InterruptedException ie) {} - } - } + private int _minSize; + private int _maxSize; + + private YKPrecalcRunner(int minSize, int maxSize) { + _minSize = minSize; + _maxSize = maxSize; + } + + public void run() { + while (true) { + int curSize = 0; + long start = Clock.getInstance().now(); + int startSize = getSize(); + curSize = startSize; + while (curSize < _minSize) { + while (curSize < _maxSize) { + long begin = Clock.getInstance().now(); + curSize = addValues(generateYK()); + long end = Clock.getInstance().now(); + if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalculated YK value in " + (end - begin) + "ms"); + // for some relief... + try { + Thread.sleep(CALC_DELAY); + } catch (InterruptedException ie) { + } + } + } + long end = Clock.getInstance().now(); + int numCalc = curSize - startSize; + if (numCalc > 0) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Precalced " + numCalc + " to " + curSize + " in " + + (end - start - CALC_DELAY * numCalc) + "ms (not counting " + + (CALC_DELAY * numCalc) + "ms relief). now sleeping"); + } + try { + Thread.sleep(CHECK_DELAY); + } catch (InterruptedException ie) { + } + } + } } } \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Base64.java b/core/java/src/net/i2p/data/Base64.java index f9d4e2358361b84b8507cf865b8aca0a26069b8e..078d57e741cf352c975597dc34cd95371d28305a 100644 --- a/core/java/src/net/i2p/data/Base64.java +++ b/core/java/src/net/i2p/data/Base64.java @@ -36,177 +36,168 @@ import java.io.OutputStream; * @author rob@iharder.net * @version 1.3.4 */ -public class Base64 -{ - public static String encode(byte[] source) { return safeEncode(source); } - public static byte[] decode(String s) { return safeDecode(s); } - +public class Base64 { + public static String encode(byte[] source) { + return safeEncode(source); + } + + public static byte[] decode(String s) { + return safeDecode(s); + } + /** Maximum line length (76) of Base64 output. */ private final static int MAX_LINE_LENGTH = 76; - - + /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte)'='; - - + private final static byte EQUALS_SIGN = (byte) '='; + /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte)'\n'; - - + private final static byte NEW_LINE = (byte) '\n'; + /** The 64 valid Base64 values. */ - private final static byte[] ALPHABET = - { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' - }; - + private final static byte[] ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', + (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', + (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', + (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', + (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', + (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', + (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', + (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', + (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', + (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) '+', (byte) '/'}; + /** * Translates a Base64 value to either its 6-bit reconstruction value * or a negative number indicating some other meaning. **/ - private final static byte[] DECODABET = - { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9,-9,-9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ + private final static byte[] DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9 // Decimal 123 - 126 + /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 + -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ }; - - private final static byte BAD_ENCODING = -9; // Indicates error in encoding + + private final static byte BAD_ENCODING = -9; // Indicates error in encoding private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - /** Defeats instantiation. */ - private Base64(){} - - public static void main(String[] args) - { - if (args.length == 0) { - help(); - return; + private Base64() { } - runApp(args); + + public static void main(String[] args) { + if (args.length == 0) { + help(); + return; + } + runApp(args); } private static void runApp(String args[]) { - try { - InputStream in = System.in; - OutputStream out = System.out; - if (args.length >= 3) { - out = new FileOutputStream(args[2]); - } - if (args.length >= 2) { - in = new FileInputStream(args[1]); - } - if ("encode".equalsIgnoreCase(args[0])) { - encode(in, out); - return; - } - if ("decode".equalsIgnoreCase(args[0])) { - decode(in, out); - return; - } - } catch (IOException ioe) { - ioe.printStackTrace(System.err); - } + try { + InputStream in = System.in; + OutputStream out = System.out; + if (args.length >= 3) { + out = new FileOutputStream(args[2]); + } + if (args.length >= 2) { + in = new FileInputStream(args[1]); + } + if ("encode".equalsIgnoreCase(args[0])) { + encode(in, out); + return; + } + if ("decode".equalsIgnoreCase(args[0])) { + decode(in, out); + return; + } + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } } - private static byte[] read(InputStream in) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); - byte buf[] = new byte[4096]; - while (true) { - int read = in.read(buf); - if (read < 0) - break; - baos.write(buf, 0, read); - } - return baos.toByteArray(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); + byte buf[] = new byte[4096]; + while (true) { + int read = in.read(buf); + if (read < 0) break; + baos.write(buf, 0, read); + } + return baos.toByteArray(); } private static void encode(InputStream in, OutputStream out) throws IOException { - String encoded = encode(read(in)); - out.write(encoded.getBytes()); + String encoded = encode(read(in)); + out.write(encoded.getBytes()); } - + private static void decode(InputStream in, OutputStream out) throws IOException { - byte decoded[] = decode(new String(read(in))); - out.write(decoded); + byte decoded[] = decode(new String(read(in))); + out.write(decoded); } private static void help() { - System.out.println("Syntax: Base64 encode <inFile> <outFile>"); - System.out.println("or : Base64 encode <inFile>"); - System.out.println("or : Base64 encode"); - System.out.println("or : Base64 decode <inFile> <outFile>"); - System.out.println("or : Base64 decode <inFile>"); - System.out.println("or : Base64 decode"); - System.out.println("or : Base64 test"); + System.out.println("Syntax: Base64 encode <inFile> <outFile>"); + System.out.println("or : Base64 encode <inFile>"); + System.out.println("or : Base64 encode"); + System.out.println("or : Base64 decode <inFile> <outFile>"); + System.out.println("or : Base64 decode <inFile>"); + System.out.println("or : Base64 decode"); + System.out.println("or : Base64 test"); } - private static void test() { - String orig = "you smell"; - String encoded = Base64.encode(orig.getBytes()); - System.out.println("Encoded: [" + encoded + "]"); - byte decoded[] = Base64.decode(encoded); - String transformed = new String(decoded); - if (orig.equals(transformed)) - System.out.println("D(E('you smell')) == 'you smell'"); - else - throw new RuntimeException("D(E('you smell')) != 'you smell'!!! transformed = [" + transformed + "]"); - byte all[] = new byte[256]; - for (int i = 0; i < all.length; i++) - all[i] = (byte)(0xFF & i); - encoded = Base64.encode(all); - System.out.println("Encoded: [" + encoded + "]"); - decoded = Base64.decode(encoded); - if (DataHelper.eq(decoded, all)) - System.out.println("D(E([all bytes])) == [all bytes]"); - else - throw new RuntimeException("D(E([all bytes])) != [all bytes]!!!"); + String orig = "you smell"; + String encoded = Base64.encode(orig.getBytes()); + System.out.println("Encoded: [" + encoded + "]"); + byte decoded[] = Base64.decode(encoded); + String transformed = new String(decoded); + if (orig.equals(transformed)) + System.out.println("D(E('you smell')) == 'you smell'"); + else + throw new RuntimeException("D(E('you smell')) != 'you smell'!!! transformed = [" + transformed + "]"); + byte all[] = new byte[256]; + for (int i = 0; i < all.length; i++) + all[i] = (byte) (0xFF & i); + encoded = Base64.encode(all); + System.out.println("Encoded: [" + encoded + "]"); + decoded = Base64.decode(encoded); + if (DataHelper.eq(decoded, all)) + System.out.println("D(E([all bytes])) == [all bytes]"); + else + throw new RuntimeException("D(E([all bytes])) != [all bytes]!!!"); } - - -/* ******** E N C O D I N G M E T H O D S ******** */ - - + + /* ******** E N C O D I N G M E T H O D S ******** */ + /** * Encodes the first three bytes of array <var>threeBytes</var> * and returns a four-byte array in Base64 notation. @@ -215,12 +206,10 @@ public class Base64 * @return four byte array in Base64 notation. * @since 1.3 */ - private static byte[] encode3to4( byte[] threeBytes ) - { return encode3to4( threeBytes, 3 ); - } // end encodeToBytes - - - + private static byte[] encode3to4(byte[] threeBytes) { + return encode3to4(threeBytes, 3); + } // end encodeToBytes + /** * Encodes up to the first three bytes of array <var>threeBytes</var> * and returns a four-byte array in Base64 notation. @@ -234,14 +223,12 @@ public class Base64 * @return four byte array in Base64 notation. * @since 1.3 */ - private static byte[] encode3to4( byte[] threeBytes, int numSigBytes ) - { byte[] dest = new byte[4]; - encode3to4( threeBytes, 0, numSigBytes, dest, 0 ); + private static byte[] encode3to4(byte[] threeBytes, int numSigBytes) { + byte[] dest = new byte[4]; + encode3to4(threeBytes, 0, numSigBytes, dest, 0); return dest; } - - - + /** * Encodes up to three bytes of the array <var>source</var> * and writes the resulting four Base64 bytes to <var>destination</var>. @@ -263,53 +250,49 @@ public class Base64 * @return the <var>destination</var> array * @since 1.3 */ - private static byte[] encode3to4( - byte[] source, int srcOffset, int numSigBytes, - byte[] destination, int destOffset ) - { + private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset) { // 1 2 3 // 01234567890123456789012345678901 Bit position // --------000000001111111122222222 Array position from threeBytes // --------| || || || | Six bit groups to index ALPHABET // >>18 >>12 >> 6 >> 0 Right shift necessary // 0x3f 0x3f 0x3f Additional AND - + // Create buffer with zero-padding if there are only one or two // significant bytes passed in the array. // We have to shift left 24 in order to flush out the 1's that appear // when Java treats a value as negative that is cast from a byte to an int. - int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) - | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) - | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); - - switch( numSigBytes ) - { - case 3: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; - return destination; - - case 2: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - case 1: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = EQUALS_SIGN; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - default: - return destination; - } // end switch - } // end encode3to4 - + int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) + | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) + | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); + + switch (numSigBytes) { + case 3: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f]; + return destination; + + case 2: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + case 1: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = EQUALS_SIGN; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + default: + return destination; + } // end switch + } // end encode3to4 + /** * Encodes a byte array into Base64 notation. * Equivalen to calling @@ -318,33 +301,31 @@ public class Base64 * @param source The data to convert * @since 1.4 */ - private static String encodeBytes( byte[] source ) - { - return encodeBytes( source, false ); // don't add newlines - } // end encodeBytes - + private static String encodeBytes(byte[] source) { + return encodeBytes(source, false); // don't add newlines + } // end encodeBytes + /** * Same as encodeBytes, except uses a filesystem / URL friendly set of characters, * replacing / with ~, and + with - */ private static String safeEncode(byte[] source) { - String encoded = encodeBytes(source); - encoded = encoded.replace('/', '~'); - encoded = encoded.replace('+', '-'); - return encoded; + String encoded = encodeBytes(source); + encoded = encoded.replace('/', '~'); + encoded = encoded.replace('+', '-'); + return encoded; } - - + /** * Same as decode, except from a filesystem / URL friendly set of characters, * replacing / with ~, and + with - */ - private static byte[] safeDecode(String source) { - String toDecode = source.replace('~', '/'); - toDecode = toDecode.replace('-', '+'); - return standardDecode(toDecode); + private static byte[] safeDecode(String source) { + String toDecode = source.replace('~', '/'); + toDecode = toDecode.replace('-', '+'); + return standardDecode(toDecode); } - + /** * Encodes a byte array into Base64 notation. * Equivalen to calling @@ -354,12 +335,10 @@ public class Base64 * @param breakLines Break lines at 80 characters or less. * @since 1.4 */ - private static String encodeBytes( byte[] source, boolean breakLines ) - { - return encodeBytes( source, 0, source.length, breakLines ); - } // end encodeBytes - - + private static String encodeBytes(byte[] source, boolean breakLines) { + return encodeBytes(source, 0, source.length, breakLines); + } // end encodeBytes + /** * Encodes a byte array into Base64 notation. * @@ -368,12 +347,10 @@ public class Base64 * @param len Length of data to convert * @since 1.4 */ - private static String encodeBytes( byte[] source, int off, int len ) - { - return encodeBytes( source, off, len, true ); - } // end encodeBytes - - + private static String encodeBytes(byte[] source, int off, int len) { + return encodeBytes(source, off, len, true); + } // end encodeBytes + /** * Encodes a byte array into Base64 notation. * @@ -383,39 +360,34 @@ public class Base64 * @param breakLines Break lines at 80 characters or less. * @since 1.4 */ - private static String encodeBytes( byte[] source, int off, int len, boolean breakLines ) - { - int len43 = len * 4 / 3; - byte[] outBuff = new byte[ ( len43 ) // Main 4:3 - + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding - + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines + private static String encodeBytes(byte[] source, int off, int len, boolean breakLines) { + int len43 = len * 4 / 3; + byte[] outBuff = new byte[(len43) // Main 4:3 + + ((len % 3) > 0 ? 4 : 0) // Account for padding + + (breakLines ? (len43 / MAX_LINE_LENGTH) : 0)]; // New lines int d = 0; int e = 0; int len2 = len - 2; int lineLength = 0; - for( ; d < len2; d+=3, e+=4 ) - { - encode3to4( source, d+off, 3, outBuff, e ); - + for (; d < len2; d += 3, e += 4) { + encode3to4(source, d + off, 3, outBuff, e); + lineLength += 4; - if( breakLines && lineLength == MAX_LINE_LENGTH ) - { - outBuff[e+4] = NEW_LINE; + if (breakLines && lineLength == MAX_LINE_LENGTH) { + outBuff[e + 4] = NEW_LINE; e++; lineLength = 0; - } // end if: end of line - } // en dfor: each piece of array - - if( d < len ) - { - encode3to4( source, d+off, len - d, outBuff, e ); + } // end if: end of line + } // en dfor: each piece of array + + if (d < len) { + encode3to4(source, d + off, len - d, outBuff, e); e += 4; - } // end if: some padding needed - - return new String( outBuff, 0, e ); - } // end encodeBytes - - + } // end if: some padding needed + + return new String(outBuff, 0, e); + } // end encodeBytes + /** * Encodes a string in Base64 notation with line breaks * after every 75 Base64 characters. @@ -424,11 +396,10 @@ public class Base64 * @return the encoded string * @since 1.3 */ - private static String encodeString( String s ) - { - return encodeString( s, true ); - } // end encodeString - + private static String encodeString(String s) { + return encodeString(s, true); + } // end encodeString + /** * Encodes a string in Base64 notation with line breaks * after every 75 Base64 characters. @@ -438,17 +409,12 @@ public class Base64 * @return the encoded string * @since 1.3 */ - private static String encodeString( String s, boolean breakLines ) - { - return encodeBytes( s.getBytes(), breakLines ); - } // end encodeString - - - - -/* ******** D E C O D I N G M E T H O D S ******** */ - - + private static String encodeString(String s, boolean breakLines) { + return encodeBytes(s.getBytes(), breakLines); + } // end encodeString + + /* ******** D E C O D I N G M E T H O D S ******** */ + /** * Decodes the first four bytes of array <var>fourBytes</var> * and returns an array up to three bytes long with the @@ -458,21 +424,17 @@ public class Base64 * @return array with decoded values * @since 1.3 */ - private static byte[] decode4to3( byte[] fourBytes ) - { + private static byte[] decode4to3(byte[] fourBytes) { byte[] outBuff1 = new byte[3]; - int count = decode4to3( fourBytes, 0, outBuff1, 0 ); - byte[] outBuff2 = new byte[ count ]; - - for( int i = 0; i < count; i++ ) + int count = decode4to3(fourBytes, 0, outBuff1, 0); + byte[] outBuff2 = new byte[count]; + + for (int i = 0; i < count; i++) outBuff2[i] = outBuff1[i]; - + return outBuff2; } - - - - + /** * Decodes four bytes from array <var>source</var> * and writes the resulting bytes (up to three of them) @@ -495,67 +457,62 @@ public class Base64 * @return the number of decoded bytes converted * @since 1.3 */ - private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset ) - { + private static int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset) { // Example: Dk== - if( source[ srcOffset + 2] == EQUALS_SIGN ) - { + if (source[srcOffset + 2] == EQUALS_SIGN) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); + + destination[destOffset] = (byte) (outBuff >>> 16); return 1; } - + // Example: DkL= - else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) - { + else if (source[srcOffset + 3] == EQUALS_SIGN) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); return 2; } - + // Example: DkLE - else - { - try{ - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) - | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); - - - destination[ destOffset ] = (byte)( outBuff >> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); - destination[ destOffset + 2 ] = (byte)( outBuff ); - - return 3; - }catch( Exception e){ - System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); - System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); - System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); - System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); + else { + try { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) + | ((DECODABET[source[srcOffset + 3]] & 0xFF)); + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + + return 3; + } catch (Exception e) { + System.out.println("" + source[srcOffset] + ": " + (DECODABET[source[srcOffset]])); + System.out.println("" + source[srcOffset + 1] + ": " + (DECODABET[source[srcOffset + 1]])); + System.out.println("" + source[srcOffset + 2] + ": " + (DECODABET[source[srcOffset + 2]])); + System.out.println("" + source[srcOffset + 3] + ": " + (DECODABET[source[srcOffset + 3]])); return -1; - } //e nd catch + } //e nd catch } - } // end decodeToBytes - + } // end decodeToBytes + /** * Decodes data from Base64 notation. * @@ -563,13 +520,11 @@ public class Base64 * @return the decoded data * @since 1.4 */ - private static byte[] standardDecode( String s ) - { + private static byte[] standardDecode(String s) { byte[] bytes = s.getBytes(); - return decode( bytes, 0, bytes.length ); - } // end decode - - + return decode(bytes, 0, bytes.length); + } // end decode + /** * Decodes data from Base64 notation and * returns it as a string. @@ -580,10 +535,10 @@ public class Base64 * @return The data as a string * @since 1.4 */ - private static String decodeToString( String s ) - { return new String( decode( s ) ); - } // end decodeToString - + private static String decodeToString(String s) { + return new String(decode(s)); + } // end decodeToString + /** * Decodes Base64 content in byte array format and returns * the decoded byte array. @@ -594,49 +549,43 @@ public class Base64 * @return decoded data * @since 1.3 */ - private static byte[] decode( byte[] source, int off, int len ) - { - int len34 = len * 3 / 4; - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; - - byte[] b4 = new byte[4]; - int b4Posn = 0; - int i = 0; - byte sbiCrop = 0; - byte sbiDecode = 0; - for( i = 0; i < len; i++ ) - { - sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits - sbiDecode = DECODABET[ sbiCrop ]; - - if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better + private static byte[] decode(byte[] source, int off, int len) { + int len34 = len * 3 / 4; + byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; + + byte[] b4 = new byte[4]; + int b4Posn = 0; + int i = 0; + byte sbiCrop = 0; + byte sbiDecode = 0; + for (i = 0; i < len; i++) { + sbiCrop = (byte) (source[i] & 0x7f); // Only the low seven bits + sbiDecode = DECODABET[sbiCrop]; + + if (sbiDecode >= WHITE_SPACE_ENC) // White space, Equals sign or better { - if( sbiDecode >= EQUALS_SIGN_ENC ) - { - b4[ b4Posn++ ] = sbiCrop; - if( b4Posn > 3 ) - { - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn ); + if (sbiDecode >= EQUALS_SIGN_ENC) { + b4[b4Posn++] = sbiCrop; + if (b4Posn > 3) { + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn); b4Posn = 0; - + // If that was the equals sign, break out of 'for' loop - if( sbiCrop == EQUALS_SIGN ) - break; - } // end if: quartet built - - } // end if: equals sign or better - - } // end if: white space, equals sign or better - else - { - System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); + if (sbiCrop == EQUALS_SIGN) break; + } // end if: quartet built + + } // end if: equals sign or better + + } // end if: white space, equals sign or better + else { + System.err.println("Bad Base64 input character at " + i + ": " + source[i] + "(decimal)"); return null; - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); + } // end else: + } // each input character + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); return out; - } // end decode -} // end class Base64 + } // end decode +} // end class Base64 diff --git a/core/java/src/net/i2p/data/ByteArray.java b/core/java/src/net/i2p/data/ByteArray.java index 296cbf915517ec1af18cb880d88aa604e82dde69..243cc73abbfdd46b2de07af0e22431f74dc98e33 100644 --- a/core/java/src/net/i2p/data/ByteArray.java +++ b/core/java/src/net/i2p/data/ByteArray.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -18,29 +19,46 @@ import java.io.Serializable; */ public class ByteArray implements Serializable { private byte[] _data; - public ByteArray() { this(null); } - public ByteArray(byte[] data) { _data = data; } - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public ByteArray() { + this(null); + } + + public ByteArray(byte[] data) { + _data = data; + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public boolean equals(Object o) { - if (o == null) return false; - if (o instanceof ByteArray) { - return compare(getData(), ((ByteArray)o).getData()); - } else { - try { - byte val[] = (byte[])o; - return compare(getData(), val); - } catch (Throwable t) { - return false; - } - } - } - + if (o == null) return false; + if (o instanceof ByteArray) { + return compare(getData(), ((ByteArray) o).getData()); + } else { + try { + byte val[] = (byte[]) o; + return compare(getData(), val); + } catch (Throwable t) { + return false; + } + } + } + private boolean compare(byte[] lhs, byte[] rhs) { - return DataHelper.eq(lhs, rhs); + return DataHelper.eq(lhs, rhs); + } + + public int hashCode() { + return DataHelper.hashCode(getData()); + } + + public String toString() { + return DataHelper.toString(getData(), 32); } - - public int hashCode() { return DataHelper.hashCode(getData()); } - public String toString() { return DataHelper.toString(getData(), 32); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Certificate.java b/core/java/src/net/i2p/data/Certificate.java index 6013f8b3143cc6f13b86039567e4ad5b01b52fbd..7d82464644f6e483a619a2d786c6ec2e042bf536 100644 --- a/core/java/src/net/i2p/data/Certificate.java +++ b/core/java/src/net/i2p/data/Certificate.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -28,68 +29,75 @@ public class Certificate extends DataStructureImpl { private final static Log _log = new Log(Certificate.class); private int _type; private byte[] _payload; - - /** Specifies a null certificate type with no payload */ + + /** Specifies a null certificate type with no payload */ public final static int CERTIFICATE_TYPE_NULL = 0; - /** specifies a Hashcash style certificate */ + /** specifies a Hashcash style certificate */ public final static int CERTIFICATE_TYPE_HASHCASH = 1; - + public Certificate() { _type = 0; _payload = null; } - + public Certificate(int type, byte[] payload) { _type = type; _payload = payload; } - - /** */ - public int getCertificateType() { return _type; } - public void setCertificateType(int type) { _type = type; } - - public byte[] getPayload() { return _payload; } - public void setPayload(byte[] payload) { _payload = payload; } - + + /** */ + public int getCertificateType() { + return _type; + } + + public void setCertificateType(int type) { + _type = type; + } + + public byte[] getPayload() { + return _payload; + } + + public void setPayload(byte[] payload) { + _payload = payload; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - _type = (int)DataHelper.readLong(in, 1); - int length = (int)DataHelper.readLong(in, 2); + _type = (int) DataHelper.readLong(in, 1); + int length = (int) DataHelper.readLong(in, 2); if (length > 0) { _payload = new byte[length]; int read = read(in, _payload); if (read != length) - throw new DataFormatException("Not enough bytes for the payload (read: " + read + " length: " + length + ")"); + throw new DataFormatException("Not enough bytes for the payload (read: " + read + " length: " + length + + ")"); } } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_type < 0) - throw new DataFormatException("Invalid certificate type: " + _type); - if ( (_type != 0) && (_payload == null) ) - throw new DataFormatException("Payload is required for non null type"); - - DataHelper.writeLong(out, 1, (long)_type); + if (_type < 0) throw new DataFormatException("Invalid certificate type: " + _type); + if ((_type != 0) && (_payload == null)) throw new DataFormatException("Payload is required for non null type"); + + DataHelper.writeLong(out, 1, (long) _type); if (_payload != null) { - DataHelper.writeLong(out, 2, (long)_payload.length); + DataHelper.writeLong(out, 2, (long) _payload.length); out.write(_payload); - } else { + } else { DataHelper.writeLong(out, 2, 0L); } } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof Certificate) ) - return false; - Certificate cert = (Certificate)object; - return getCertificateType() == cert.getCertificateType() && - DataHelper.eq(getPayload(), cert.getPayload()); + if ((object == null) || !(object instanceof Certificate)) return false; + Certificate cert = (Certificate) object; + return getCertificateType() == cert.getCertificateType() && DataHelper.eq(getPayload(), cert.getPayload()); } - - public int hashCode() { + + public int hashCode() { return getCertificateType() + DataHelper.hashCode(getPayload()); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[Certificate: type: "); if (getCertificateType() == CERTIFICATE_TYPE_NULL) @@ -98,18 +106,17 @@ public class Certificate extends DataStructureImpl { buf.append("Hashcash certificate"); else buf.append("Unknown certificiate type (").append(getCertificateType()).append(")"); - + if (_payload == null) { buf.append(" null payload"); } else { buf.append(" payload size: ").append(_payload.length); int len = 32; - if (len > _payload.length) - len = _payload.length; + if (len > _payload.length) len = _payload.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_payload, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/DataFormatException.java b/core/java/src/net/i2p/data/DataFormatException.java index 23f2c1c760b42dd8128dfe3f93282464f47a55da..95e0d26c828e1f6d2b986673a6dd40339ff11569 100644 --- a/core/java/src/net/i2p/data/DataFormatException.java +++ b/core/java/src/net/i2p/data/DataFormatException.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,8 +9,8 @@ package net.i2p.data; * */ -import net.i2p.util.Log; import net.i2p.I2PException; +import net.i2p.util.Log; /** * Thrown when the data was not available to read or write a DataStructure @@ -18,11 +19,12 @@ import net.i2p.I2PException; */ public class DataFormatException extends I2PException { private final static Log _log = new Log(DataFormatException.class); - + public DataFormatException(String msg, Throwable t) { super(msg, t); } + public DataFormatException(String msg) { super(msg); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 03f035d33b3e1e704f895e2553b74df35d8256fe..78dfe048578334d794af3992a1464a639f962032 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -37,7 +38,7 @@ public class DataHelper { private final static Log _log = new Log(DataHelper.class); private final static String _equal = "="; // in UTF-8 private final static String _semicolon = ";"; // in UTF-8 - + /** Read a mapping from the stream, as defined by the I2P data structure spec, * and store it into a Properties object. * @@ -58,35 +59,34 @@ public class DataHelper { public static Properties readProperties(InputStream rawStream) throws DataFormatException, IOException { Properties props = new OrderedProperties(); long size = readLong(rawStream, 2); - byte data[] = new byte[(int)size]; + byte data[] = new byte[(int) size]; int read = read(rawStream, data); - if (read != size) - throw new DataFormatException("Not enough data to read the properties"); - ByteArrayInputStream in = new ByteArrayInputStream(data); - byte eqBuf[] = _equal.getBytes(); - byte semiBuf[] = _semicolon.getBytes(); - try { - while (in.available() > 0) { - String key = readString(in); - read = read(in, eqBuf); - if ((read != eqBuf.length) || (!eq(new String(eqBuf), _equal))) { - _log.debug("Failed eqtest [" + new String(eqBuf) + "]"); - break; - } - String val = readString(in); - read = read(in, semiBuf); - if ((read != semiBuf.length) || (!eq(new String(semiBuf), _semicolon))) { - _log.debug("Failed semitest [" + new String(semiBuf) + "]"); - break; - } - props.put(key, val); - } - } catch (IOException ioe) { - _log.warn("Error reading properties", ioe); - } + if (read != size) throw new DataFormatException("Not enough data to read the properties"); + ByteArrayInputStream in = new ByteArrayInputStream(data); + byte eqBuf[] = _equal.getBytes(); + byte semiBuf[] = _semicolon.getBytes(); + try { + while (in.available() > 0) { + String key = readString(in); + read = read(in, eqBuf); + if ((read != eqBuf.length) || (!eq(new String(eqBuf), _equal))) { + _log.debug("Failed eqtest [" + new String(eqBuf) + "]"); + break; + } + String val = readString(in); + read = read(in, semiBuf); + if ((read != semiBuf.length) || (!eq(new String(semiBuf), _semicolon))) { + _log.debug("Failed semitest [" + new String(semiBuf) + "]"); + break; + } + props.put(key, val); + } + } catch (IOException ioe) { + _log.warn("Error reading properties", ioe); + } return props; } - + /** * Write a mapping to the stream, as defined by the I2P data structure spec, * and store it into a Properties object. See readProperties for the format. @@ -96,43 +96,43 @@ public class DataHelper { * @throws DataFormatException if there is not enough valid data to write out * @throws IOException if there is an IO error writing out the data */ - 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(); + 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(_equal.getBytes()); - writeString(baos, val); - baos.write(_semicolon.getBytes()); + writeString(baos, key); + baos.write(_equal.getBytes()); + writeString(baos, val); + baos.write(_semicolon.getBytes()); } - baos.close(); + baos.close(); byte propBytes[] = baos.toByteArray(); writeLong(rawStream, 2, propBytes.length); rawStream.write(propBytes); } - + /** * Pretty print the mapping * */ public static String toString(Properties options) { StringBuffer buf = new StringBuffer(); - if (options != null) { - for (Iterator iter = options.keySet().iterator(); iter.hasNext(); ) { - String key = (String)iter.next(); - String val = options.getProperty(key); - buf.append("[").append(key).append("] = [").append(val).append("]"); - } - } else { - buf.append("(null properties map)"); - } + if (options != null) { + for (Iterator iter = options.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = options.getProperty(key); + buf.append("[").append(key).append("] = [").append(val).append("]"); + } + } else { + buf.append("(null properties map)"); + } return buf.toString(); } @@ -143,58 +143,59 @@ public class DataHelper { public static String toString(Collection col) { StringBuffer buf = new StringBuffer(); if (col != null) { - for (Iterator iter = col.iterator(); iter.hasNext(); ) { + for (Iterator iter = col.iterator(); iter.hasNext();) { Object o = iter.next(); buf.append("[").append(o).append("]"); - if (iter.hasNext()) - buf.append(", "); + if (iter.hasNext()) buf.append(", "); } } else { buf.append("null"); } return buf.toString(); } - - + public static String toString(byte buf[]) { - if (buf == null) return ""; - else return toString(buf, buf.length); + if (buf == null) + return ""; + else + return toString(buf, buf.length); } - + public static String toString(byte buf[], int len) { - if (buf == null) buf = "".getBytes(); - StringBuffer out = new StringBuffer(); - if (len > buf.length) { - for (int i = 0; i < len - buf.length; i++) - out.append("00"); - } - for (int i = 0; i < buf.length && i < len; i++) { - StringBuffer temp = new StringBuffer(Integer.toHexString((int)buf[i])); - while (temp.length() < 2) { - temp.insert(0, '0'); - } - temp = new StringBuffer(temp.substring(temp.length()-2)); - out.append(temp.toString()); - } - return out.toString(); + if (buf == null) buf = "".getBytes(); + StringBuffer out = new StringBuffer(); + if (len > buf.length) { + for (int i = 0; i < len - buf.length; i++) + out.append("00"); + } + for (int i = 0; i < buf.length && i < len; i++) { + StringBuffer temp = new StringBuffer(Integer.toHexString((int) buf[i])); + while (temp.length() < 2) { + temp.insert(0, '0'); + } + temp = new StringBuffer(temp.substring(temp.length() - 2)); + out.append(temp.toString()); + } + return out.toString(); } + public static String toDecimalString(byte buf[], int len) { - if (buf == null) buf = "".getBytes(); - BigInteger val = new BigInteger(1, buf); - return val.toString(10); + if (buf == null) buf = "".getBytes(); + BigInteger val = new BigInteger(1, buf); + return val.toString(10); } - + public final static String toHexString(byte data[]) { - if ( (data == null) || (data.length <= 0) ) return "00"; - BigInteger bi = new BigInteger(1, data); - return bi.toString(16); + if ((data == null) || (data.length <= 0)) return "00"; + BigInteger bi = new BigInteger(1, data); + return bi.toString(16); } - + public final static byte[] fromHexString(String val) { - BigInteger bv = new BigInteger(val, 16); - return bv.toByteArray(); + BigInteger bv = new BigInteger(val, 16); + return bv.toByteArray(); } - + /** Read the stream for an integer as defined by the I2P data structure specification. * Integers are a fixed number of bytes (numBytes), stored as unsigned integers in network byte order. * @param rawStream stream to read from @@ -205,16 +206,17 @@ public class DataHelper { */ public static long readLong(InputStream rawStream, int numBytes) throws DataFormatException, IOException { if (numBytes > 8) - throw new DataFormatException("readLong doesn't currently support reading numbers > 8 bytes [as thats bigger than java's long]"); + throw new DataFormatException( + "readLong doesn't currently support reading numbers > 8 bytes [as thats bigger than java's long]"); byte data[] = new byte[numBytes]; int num = read(rawStream, data); if (num != numBytes) throw new DataFormatException("Not enough bytes [" + num + "] as required for the field [" + numBytes + "]"); - + UnsignedInteger val = new UnsignedInteger(data); return val.getLong(); } - + /** Write an integer as defined by the I2P data structure specification to the stream. * Integers are a fixed number of bytes (numBytes), stored as unsigned integers in network byte order. * @param value value to write out @@ -223,11 +225,12 @@ public class DataHelper { * @throws DataFormatException if the stream doesn't contain a validly formatted number of that many bytes * @throws IOException if there is an IO error writing to the stream */ - public static void writeLong(OutputStream rawStream, int numBytes, long value) throws DataFormatException, IOException { + public static void writeLong(OutputStream rawStream, int numBytes, long value) throws DataFormatException, + IOException { UnsignedInteger i = new UnsignedInteger(value); rawStream.write(i.getBytes(numBytes)); } - + /** Read in a date from the stream as specified by the I2P data structure spec. * A date is an 8 byte unsigned integer in network byte order specifying the number of * milliseconds since midnight on January 1, 1970 in the GMT timezone. If the number is @@ -244,7 +247,7 @@ public class DataHelper { else return new Date(date); } - + /** Write out a date to the stream as specified by the I2P data structure spec. * @param out stream to write to * @param date date to write (can be null) @@ -267,13 +270,13 @@ public class DataHelper { * @return UTF-8 string */ public static String readString(InputStream in) throws DataFormatException, IOException { - int size = (int)readLong(in, 1); + int size = (int) readLong(in, 1); byte raw[] = new byte[size]; int read = read(in, raw); - if (read != size) - throw new DataFormatException("Not enough bytes to read the string"); + if (read != size) throw new DataFormatException("Not enough bytes to read the string"); return new String(raw); } + /** Write out a string to the stream as specified by the I2P data structure spec. Note that the max * size for a string allowed by the spec is 255 bytes. * @@ -284,15 +287,16 @@ public class DataHelper { * @throws IOException if there is an IO error writing the string */ public static void writeString(OutputStream out, String string) throws DataFormatException, IOException { - if (string == null) { - writeLong(out, 1, 0); - } else { - if (string.length() > 255) - throw new DataFormatException("The I2P data spec limits strings to 255 bytes or less, but this is " + string.length() + " [" + string + "]"); - byte raw[] = string.getBytes(); - writeLong(out, 1, raw.length); - out.write(raw); - } + if (string == null) { + writeLong(out, 1, 0); + } else { + if (string.length() > 255) + throw new DataFormatException("The I2P data spec limits strings to 255 bytes or less, but this is " + + string.length() + " [" + string + "]"); + byte raw[] = string.getBytes(); + writeLong(out, 1, raw.length); + out.write(raw); + } } /** Read in a boolean as specified by the I2P data structure spec. @@ -303,18 +307,20 @@ public class DataHelper { * @return boolean value, or null */ public static Boolean readBoolean(InputStream in) throws DataFormatException, IOException { - int val = (int)readLong(in, 1); + int val = (int) readLong(in, 1); switch (val) { - case 0: - return Boolean.FALSE; - case 1: - return Boolean.TRUE; - case 2: - return null; - default: - throw new DataFormatException("Uhhh.. readBoolean read a value that isn't a known ternary val (0,1,2): " + val); + case 0: + return Boolean.FALSE; + case 1: + return Boolean.TRUE; + case 2: + return null; + default: + throw new DataFormatException("Uhhh.. readBoolean read a value that isn't a known ternary val (0,1,2): " + + val); } } + /** Write out a boolean as specified by the I2P data structure spec. * A boolean is 1 byte that is either 0 (false), 1 (true), or 2 (null) * @param out stream to write to @@ -330,13 +336,12 @@ public class DataHelper { else writeLong(out, 1, 0); } - + // // The following comparator helpers make it simpler to write consistently comparing // functions for objects based on their value, not JVM memory address // - /** * Helper util to compare two objects, including null handling. * <p /> @@ -344,15 +349,15 @@ public class DataHelper { * This treats (null == null) as true, and (null == (!null)) as false. */ public final static boolean eq(Object lhs, Object rhs) { - try { - boolean eq = ( ( (lhs == null) && (rhs == null) ) || - ( (lhs != null) && (lhs.equals(rhs))) ); - return eq; - } catch (ClassCastException cce) { - _log.warn("Error comparing [" + lhs + "] with [" + rhs + "]", cce); - return false; - } + try { + boolean eq = (((lhs == null) && (rhs == null)) || ((lhs != null) && (lhs.equals(rhs)))); + return eq; + } catch (ClassCastException cce) { + _log.warn("Error comparing [" + lhs + "] with [" + rhs + "]", cce); + return false; + } } + /** * Run a deep comparison across the two collections. * <p /> @@ -366,17 +371,16 @@ public class DataHelper { * */ public final static boolean eq(Collection lhs, Collection rhs) { - if ( (lhs == null) && (rhs == null) ) return true; - if ( (lhs == null) || (rhs == null) ) return false; + if ((lhs == null) && (rhs == null)) return true; + if ((lhs == null) || (rhs == null)) return false; if (lhs.size() != rhs.size()) return false; Iterator liter = lhs.iterator(); Iterator riter = rhs.iterator(); - while ( (liter.hasNext()) && (riter.hasNext()) ) - if (!(eq(liter.next(), riter.next()))) - return false; + while ((liter.hasNext()) && (riter.hasNext())) + if (!(eq(liter.next(), riter.next()))) return false; return true; } - + /** * Run a comparison on the byte arrays, byte by byte. <p /> * @@ -385,79 +389,93 @@ public class DataHelper { * */ public final static boolean eq(byte lhs[], byte rhs[]) { - boolean eq = ( ( (lhs == null) && (rhs == null) ) || - ( (lhs != null) && (rhs != null) && (Arrays.equals(lhs, rhs)) ) ); + boolean eq = (((lhs == null) && (rhs == null)) || ((lhs != null) && (rhs != null) && (Arrays.equals(lhs, rhs)))); return eq; } + /** * Compare two integers, really just for consistency. */ - public final static boolean eq(int lhs, int rhs) { return lhs == rhs; } + public final static boolean eq(int lhs, int rhs) { + return lhs == rhs; + } + /** * Compare two longs, really just for consistency. */ - public final static boolean eq(long lhs, long rhs) { return lhs == rhs; } + public final static boolean eq(long lhs, long rhs) { + return lhs == rhs; + } + /** * Compare two bytes, really just for consistency. */ - public final static boolean eq(byte lhs, byte rhs) { return lhs == rhs; } - + public final static boolean eq(byte lhs, byte rhs) { + return lhs == rhs; + } + public final static int compareTo(byte lhs[], byte rhs[]) { - if ( (rhs == null) && (lhs == null) ) return 0; - if (lhs == null) return -1; - if (rhs == null) return 1; - if (rhs.length < lhs.length) return 1; - if (rhs.length > lhs.length) return -1; - for (int i = 0; i < rhs.length; i++) { - if (rhs[i] > lhs[i]) return -1; - else if (rhs[i] < lhs[i]) return 1; - } - return 0; - } - + if ((rhs == null) && (lhs == null)) return 0; + if (lhs == null) return -1; + if (rhs == null) return 1; + if (rhs.length < lhs.length) return 1; + if (rhs.length > lhs.length) return -1; + for (int i = 0; i < rhs.length; i++) { + if (rhs[i] > lhs[i]) + return -1; + else if (rhs[i] < lhs[i]) return 1; + } + return 0; + } + public final static byte[] xor(byte lhs[], byte rhs[]) { - if ( (lhs == null) || (rhs == null) || (lhs.length != rhs.length) ) return null; - byte diff[] = new byte[lhs.length]; - for (int i = 0; i < lhs.length; i++) - diff[i] = (byte)(lhs[i] ^ rhs[i]); - return diff; - } - - + if ((lhs == null) || (rhs == null) || (lhs.length != rhs.length)) return null; + byte diff[] = new byte[lhs.length]; + for (int i = 0; i < lhs.length; i++) + diff[i] = (byte) (lhs[i] ^ rhs[i]); + return diff; + } + // // The following hashcode helpers make it simpler to write consistently hashing // functions for objects based on their value, not JVM memory address // - + /** * Calculate the hashcode of the object, using 0 for null * */ public static int hashCode(Object obj) { - if (obj == null) return 0; - else return obj.hashCode(); + if (obj == null) + return 0; + else + return obj.hashCode(); } + /** * Calculate the hashcode of the date, using 0 for null * */ public static int hashCode(Date obj) { - if (obj == null) return 0; - else return (int)obj.getTime(); + if (obj == null) + return 0; + else + return (int) obj.getTime(); } + /** * Calculate the hashcode of the byte array, using 0 for null * */ public static int hashCode(byte b[]) { - int rv = 0; - if (b != null) { - for (int i = 0; i < b.length && i < 8; i++) - rv += b[i]; - } - return rv; - } - + int rv = 0; + if (b != null) { + for (int i = 0; i < b.length && i < 8; i++) + rv += b[i]; + } + return rv; + } + /** * Calculate the hashcode of the collection, using 0 for null * @@ -465,95 +483,95 @@ public class DataHelper { public static int hashCode(Collection col) { if (col == null) return 0; int c = 0; - for (Iterator iter = col.iterator(); iter.hasNext(); ) - c = 7*c + hashCode(iter.next()); + for (Iterator iter = col.iterator(); iter.hasNext();) + c = 7 * c + hashCode(iter.next()); return c; } public static int read(InputStream in, byte target[]) throws IOException { - int cur = 0; - while (cur < target.length) { - int numRead = in.read(target, cur, target.length - cur); - if (numRead == -1) { - if (cur == 0) - return -1; // throw new EOFException("EOF Encountered during reading"); - else - return cur; - } - cur += numRead; - } - return cur; - } - + int cur = 0; + while (cur < target.length) { + int numRead = in.read(target, cur, target.length - cur); + if (numRead == -1) { + if (cur == 0) + return -1; // throw new EOFException("EOF Encountered during reading"); + else + return cur; + } + cur += numRead; + } + return cur; + } public static List sortStructures(Collection dataStructures) { - if (dataStructures == null) return new ArrayList(); - ArrayList rv = new ArrayList(dataStructures.size()); - TreeMap tm = new TreeMap(); - for (Iterator iter = dataStructures.iterator(); iter.hasNext(); ) { - DataStructure struct = (DataStructure)iter.next(); - tm.put(struct.calculateHash().toString(), struct); - } - for (Iterator iter = tm.keySet().iterator(); iter.hasNext();) { - Object k = iter.next(); - rv.add(tm.get(k)); - } - return rv; + if (dataStructures == null) return new ArrayList(); + ArrayList rv = new ArrayList(dataStructures.size()); + TreeMap tm = new TreeMap(); + for (Iterator iter = dataStructures.iterator(); iter.hasNext();) { + DataStructure struct = (DataStructure) iter.next(); + tm.put(struct.calculateHash().toString(), struct); + } + for (Iterator iter = tm.keySet().iterator(); iter.hasNext();) { + Object k = iter.next(); + rv.add(tm.get(k)); + } + return rv; } public static String formatDuration(long ms) { - if (ms < 30*1000) { - return ms + "ms"; - } else if (ms < 5*60*1000) { - return (ms/1000) + "s"; - } else if (ms < 90*60*1000) { - return (ms / (60*1000)) + "m"; - } else if (ms < 3*24*60*60*1000) { - return (ms / (60*60*1000)) + "h"; - } else { - return (ms / (24*60*60*1000)) + "d"; - } - } - + if (ms < 30 * 1000) { + return ms + "ms"; + } else if (ms < 5 * 60 * 1000) { + return (ms / 1000) + "s"; + } else if (ms < 90 * 60 * 1000) { + return (ms / (60 * 1000)) + "m"; + } else if (ms < 3 * 24 * 60 * 60 * 1000) { + return (ms / (60 * 60 * 1000)) + "h"; + } else { + return (ms / (24 * 60 * 60 * 1000)) + "d"; + } + } + /** compress the data and return a new GZIP compressed array */ public static byte[] compress(byte orig[]) { - if ( (orig == null) || (orig.length <= 0) ) return orig; - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(orig.length); - GZIPOutputStream out = new GZIPOutputStream(baos, orig.length); - out.write(orig); - out.finish(); - out.flush(); - byte rv[] = baos.toByteArray(); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Compression of " + orig.length + " into " + rv.length + " (or " + 100.0d*(((double)orig.length) / ((double)rv.length)) + "% savings)"); - return rv; - } catch (IOException ioe) { - _log.error("Error compressing?!", ioe); - return null; - } - } - + if ((orig == null) || (orig.length <= 0)) return orig; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(orig.length); + GZIPOutputStream out = new GZIPOutputStream(baos, orig.length); + out.write(orig); + out.finish(); + out.flush(); + byte rv[] = baos.toByteArray(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Compression of " + orig.length + " into " + rv.length + " (or " + 100.0d + * (((double) orig.length) / ((double) rv.length)) + "% savings)"); + return rv; + } catch (IOException ioe) { + _log.error("Error compressing?!", ioe); + return null; + } + } + /** decompress the GZIP compressed data (returning null on error) */ public static byte[] decompress(byte orig[]) { - if ( (orig == null) || (orig.length <= 0) ) return orig; - try { - GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(orig), orig.length); - ByteArrayOutputStream baos = new ByteArrayOutputStream(orig.length * 2); - byte buf[] = new byte[4*1024]; - while (true) { - int read = in.read(buf); - if (read == -1) - break; - baos.write(buf, 0, read); - } - byte rv[] = baos.toByteArray(); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Decompression of " + orig.length + " into " + rv.length + " (or " + 100.0d*(((double)rv.length) / ((double)orig.length)) + "% savings)"); - return rv; - } catch (IOException ioe) { - _log.error("Error decompressing?", ioe); - return null; - } - } -} + if ((orig == null) || (orig.length <= 0)) return orig; + try { + GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(orig), orig.length); + ByteArrayOutputStream baos = new ByteArrayOutputStream(orig.length * 2); + byte buf[] = new byte[4 * 1024]; + while (true) { + int read = in.read(buf); + if (read == -1) break; + baos.write(buf, 0, read); + } + byte rv[] = baos.toByteArray(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Decompression of " + orig.length + " into " + rv.length + " (or " + 100.0d + * (((double) rv.length) / ((double) orig.length)) + "% savings)"); + return rv; + } catch (IOException ioe) { + _log.error("Error decompressing?", ioe); + return null; + } + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/DataStructure.java b/core/java/src/net/i2p/data/DataStructure.java index 8044ded8c0c7287c88e1d918747a8a25e0725da9..9c7d8e818543967512b52b75e6e5b22b021a7bcd 100644 --- a/core/java/src/net/i2p/data/DataStructure.java +++ b/core/java/src/net/i2p/data/DataStructure.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import java.io.Serializable; /** @@ -29,7 +30,7 @@ public interface DataStructure extends Serializable { * @throws IOException if there was a problem reading the stream */ public void readBytes(InputStream in) throws DataFormatException, IOException; - + /** * Write out the data structure to the stream, using the format defined in the * I2P data structure specification. @@ -39,26 +40,27 @@ public interface DataStructure extends Serializable { * @throws IOException if there was a problem writing to the stream */ public void writeBytes(OutputStream out) throws DataFormatException, IOException; - + /** * render the structure into modified base 64 notation * @return null on error */ public String toBase64(); - + /** * Load the structure from the base 64 encoded data provided * */ public void fromBase64(String data) throws DataFormatException; - + public byte[] toByteArray(); + public void fromByteArray(byte data[]) throws DataFormatException; - + /** * Calculate the SHA256 value of this object (useful for a few scenarios) * * @return SHA256 hash, or null if there were problems (data format or io errors) */ public Hash calculateHash(); -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/DataStructureImpl.java b/core/java/src/net/i2p/data/DataStructureImpl.java index cbe9bcfb07fe12b672837daeaca83ba0138a8857..8307bd139e216491356ea2f3e47b36ac1c19a1b6 100644 --- a/core/java/src/net/i2p/data/DataStructureImpl.java +++ b/core/java/src/net/i2p/data/DataStructureImpl.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -23,58 +24,57 @@ import net.i2p.util.Log; */ public abstract class DataStructureImpl implements DataStructure { private final static Log _log = new Log(DataStructureImpl.class); - + public String toBase64() { - byte data[] = toByteArray(); - if (data == null) return null; - else return Base64.encode(data); + byte data[] = toByteArray(); + if (data == null) + return null; + else + return Base64.encode(data); } - + public void fromBase64(String data) throws DataFormatException { - if (data == null) - throw new DataFormatException("Null data passed in"); - byte bytes[] = Base64.decode(data); - fromByteArray(bytes); + if (data == null) throw new DataFormatException("Null data passed in"); + byte bytes[] = Base64.decode(data); + fromByteArray(bytes); } - + public Hash calculateHash() { - byte data[] = toByteArray(); - if (data != null) - return SHA256Generator.getInstance().calculateHash(data); - return null; + byte data[] = toByteArray(); + if (data != null) return SHA256Generator.getInstance().calculateHash(data); + return null; } - + public byte[] toByteArray() { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(512); - writeBytes(baos); - return baos.toByteArray(); - } catch (IOException ioe) { - _log.error("Error writing out the byte array", ioe); - return null; - } catch (DataFormatException dfe) { - _log.error("Error writing out the byte array", dfe); - return null; - } + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(512); + writeBytes(baos); + return baos.toByteArray(); + } catch (IOException ioe) { + _log.error("Error writing out the byte array", ioe); + return null; + } catch (DataFormatException dfe) { + _log.error("Error writing out the byte array", dfe); + return null; + } } - + public void fromByteArray(byte data[]) throws DataFormatException { - if (data == null) - throw new DataFormatException("Null data passed in"); - try { - ByteArrayInputStream bais = new ByteArrayInputStream(data); - readBytes(bais); - } catch (IOException ioe) { - throw new DataFormatException("Error reading the byte array", ioe); - } + if (data == null) throw new DataFormatException("Null data passed in"); + try { + ByteArrayInputStream bais = new ByteArrayInputStream(data); + readBytes(bais); + } catch (IOException ioe) { + throw new DataFormatException("Error reading the byte array", ioe); + } } - + /** * Repeated reads until the buffer is full or IOException is thrown * * @return number of bytes read (should always equal target.length) */ protected int read(InputStream in, byte target[]) throws IOException { - return DataHelper.read(in, target); + return DataHelper.read(in, target); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Destination.java b/core/java/src/net/i2p/data/Destination.java index dfc08986b85a4ddea1f7300532e61c26f9b0443b..dac90bb378e9b09b8e98f9591ba7b9b9789536a4 100644 --- a/core/java/src/net/i2p/data/Destination.java +++ b/core/java/src/net/i2p/data/Destination.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -26,30 +27,41 @@ public class Destination extends DataStructureImpl { private SigningPublicKey _signingKey; private PublicKey _publicKey; private Hash __calculatedHash; - - public Destination() { + + public Destination() { setCertificate(null); setSigningPublicKey(null); setPublicKey(null); - __calculatedHash = null; + __calculatedHash = null; } - - public Certificate getCertificate() { return _certificate; } - public void setCertificate(Certificate cert) { - _certificate = cert; - __calculatedHash = null; + + public Certificate getCertificate() { + return _certificate; } - public PublicKey getPublicKey() { return _publicKey; } - public void setPublicKey(PublicKey key) { - _publicKey = key; - __calculatedHash = null; + + public void setCertificate(Certificate cert) { + _certificate = cert; + __calculatedHash = null; } - public SigningPublicKey getSigningPublicKey() { return _signingKey; } - public void setSigningPublicKey(SigningPublicKey key) { - _signingKey = key; - __calculatedHash = null; + + public PublicKey getPublicKey() { + return _publicKey; + } + + public void setPublicKey(PublicKey key) { + _publicKey = key; + __calculatedHash = null; + } + + public SigningPublicKey getSigningPublicKey() { + return _signingKey; } - + + public void setSigningPublicKey(SigningPublicKey key) { + _signingKey = key; + __calculatedHash = null; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _publicKey = new PublicKey(); _publicKey.readBytes(in); @@ -57,32 +69,30 @@ public class Destination extends DataStructureImpl { _signingKey.readBytes(in); _certificate = new Certificate(); _certificate.readBytes(in); - __calculatedHash = null; + __calculatedHash = null; } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_certificate == null) || (_publicKey == null) || (_signingKey == null) ) + if ((_certificate == null) || (_publicKey == null) || (_signingKey == null)) throw new DataFormatException("Not enough data to format the destination"); _publicKey.writeBytes(out); _signingKey.writeBytes(out); _certificate.writeBytes(out); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof Destination)) - return false; - Destination dst = (Destination)object; - return DataHelper.eq(getCertificate(), dst.getCertificate()) && - DataHelper.eq(getSigningPublicKey(), dst.getSigningPublicKey()) && - DataHelper.eq(getPublicKey(), dst.getPublicKey()); + if ((object == null) || !(object instanceof Destination)) return false; + Destination dst = (Destination) object; + return DataHelper.eq(getCertificate(), dst.getCertificate()) + && DataHelper.eq(getSigningPublicKey(), dst.getSigningPublicKey()) + && DataHelper.eq(getPublicKey(), dst.getPublicKey()); } - + public int hashCode() { - return DataHelper.hashCode(getCertificate()) + - DataHelper.hashCode(getSigningPublicKey()) + - DataHelper.hashCode(getPublicKey()); + return DataHelper.hashCode(getCertificate()) + DataHelper.hashCode(getSigningPublicKey()) + + DataHelper.hashCode(getPublicKey()); } - + public String toString() { StringBuffer buf = new StringBuffer(128); buf.append("[Destination: "); @@ -93,10 +103,9 @@ public class Destination extends DataStructureImpl { buf.append("]"); return buf.toString(); } - + public Hash calculateHash() { - if (__calculatedHash == null) - __calculatedHash = super.calculateHash(); - return __calculatedHash; + if (__calculatedHash == null) __calculatedHash = super.calculateHash(); + return __calculatedHash; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Hash.java b/core/java/src/net/i2p/data/Hash.java index 4f9e71ec794d75394c96fa0e60f8a69075993e40..30588551892398e2f5910d6f294b0b1bdb6145d6 100644 --- a/core/java/src/net/i2p/data/Hash.java +++ b/core/java/src/net/i2p/data/Hash.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -24,56 +25,61 @@ public class Hash extends DataStructureImpl { private final static Log _log = new Log(Hash.class); private byte[] _data; private volatile String _stringified; - + public final static int HASH_LENGTH = 32; public final static Hash FAKE_HASH = new Hash(new byte[HASH_LENGTH]); - - public Hash() { setData(null); } - public Hash(byte data[]) { setData(data); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { - _data = data; - _stringified = null; + + public Hash() { + setData(null); + } + + public Hash(byte data[]) { + setData(data); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + _stringified = null; } - + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[HASH_LENGTH]; - _stringified = null; + _stringified = null; int read = read(in, _data); - if (read != HASH_LENGTH) - throw new DataFormatException("Not enough bytes to read the hash"); + if (read != HASH_LENGTH) throw new DataFormatException("Not enough bytes to read the hash"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the hash to write out"); - if (_data.length != HASH_LENGTH) - throw new DataFormatException("Invalid size of data in the private key"); + if (_data == null) throw new DataFormatException("No data in the hash to write out"); + if (_data.length != HASH_LENGTH) throw new DataFormatException("Invalid size of data in the private key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof Hash)) - return false; - return DataHelper.eq(_data, ((Hash)obj)._data); + if ((obj == null) || !(obj instanceof Hash)) return false; + return DataHelper.eq(_data, ((Hash) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - public String toString() { - if (_stringified == null) { - StringBuffer buf = new StringBuffer(64); - buf.append("[Hash: "); - if (_data == null) { - buf.append("null hash"); - } else { - buf.append(toBase64()); - } - buf.append("]"); - _stringified = buf.toString(); - } - return _stringified; + + public String toString() { + if (_stringified == null) { + StringBuffer buf = new StringBuffer(64); + buf.append("[Hash: "); + if (_data == null) { + buf.append("null hash"); + } else { + buf.append(toBase64()); + } + buf.append("]"); + _stringified = buf.toString(); + } + return _stringified; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Lease.java b/core/java/src/net/i2p/data/Lease.java index 3b38265b3dbc3dde234df501326eab87d84e725c..7f9e442846d908067a0496de39129748a3a0394f 100644 --- a/core/java/src/net/i2p/data/Lease.java +++ b/core/java/src/net/i2p/data/Lease.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -13,8 +14,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Date; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Defines the proof that a particular router / tunnel is allowed to receive @@ -29,58 +30,88 @@ public class Lease extends DataStructureImpl { private Date _end; private int _numSuccess; private int _numFailure; - - public Lease() { + + public Lease() { setRouterIdentity(null); setTunnelId(null); setEndDate(null); - setNumSuccess(0); - setNumFailure(0); + setNumSuccess(0); + setNumFailure(0); } - + /** Retrieve the router at which the destination can be contacted * @return identity of the router acting as a gateway - */ - public RouterIdentity getRouterIdentity() { return _routerIdentity; } + */ + public RouterIdentity getRouterIdentity() { + return _routerIdentity; + } + /** Configure the router at which the destination can be contacted * @param ident router acting as the gateway - */ - public void setRouterIdentity(RouterIdentity ident) { _routerIdentity = ident; } + */ + public void setRouterIdentity(RouterIdentity ident) { + _routerIdentity = ident; + } + /** Tunnel on the gateway to communicate with * @return tunnel ID - */ - public TunnelId getTunnelId() { return _tunnelId; } + */ + public TunnelId getTunnelId() { + return _tunnelId; + } + /** Configure the tunnel on the gateway to communicate with * @param id tunnel ID - */ - public void setTunnelId(TunnelId id) { _tunnelId = id; } - public Date getEndDate() { return _end; } - public void setEndDate(Date date) { _end = date; } - + */ + public void setTunnelId(TunnelId id) { + _tunnelId = id; + } + + public Date getEndDate() { + return _end; + } + + public void setEndDate(Date date) { + _end = date; + } + /** * Transient attribute of the lease, used to note how many times messages sent * to the destination through the current lease were successful. * */ - public int getNumSuccess() { return _numSuccess; } - public void setNumSuccess(int num) { _numSuccess = num; } - + public int getNumSuccess() { + return _numSuccess; + } + + public void setNumSuccess(int num) { + _numSuccess = num; + } + /** * Transient attribute of the lease, used to note how many times messages sent * to the destination through the current lease failed. * */ - public int getNumFailure() { return _numFailure; } - public void setNumFailure(int num) { _numFailure = num; } - + public int getNumFailure() { + return _numFailure; + } + + public void setNumFailure(int num) { + _numFailure = num; + } + /** has this lease already expired? */ - public boolean isExpired() { return isExpired(0); } + public boolean isExpired() { + return isExpired(0); + } + /** has this lease already expired (giving allowing up the fudgeFactor milliseconds for clock skew)? */ public boolean isExpired(long fudgeFactor) { - if (_end == null) return true; - return _end.getTime() < Clock.getInstance().now() - fudgeFactor; + if (_end == null) return true; + return _end.getTime() < Clock.getInstance().now() - fudgeFactor; } - + public void readBytes(InputStream in) throws DataFormatException, IOException { _routerIdentity = new RouterIdentity(); _routerIdentity.readBytes(in); @@ -88,31 +119,29 @@ public class Lease extends DataStructureImpl { _tunnelId.readBytes(in); _end = DataHelper.readDate(in); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_routerIdentity == null) || (_tunnelId == null) ) + if ((_routerIdentity == null) || (_tunnelId == null)) throw new DataFormatException("Not enough data to write out a Lease"); - + _routerIdentity.writeBytes(out); _tunnelId.writeBytes(out); DataHelper.writeDate(out, _end); } public boolean equals(Object object) { - if ( (object == null) || !(object instanceof Lease) ) - return false; - Lease lse = (Lease)object; - return DataHelper.eq(getEndDate(), lse.getEndDate()) && - DataHelper.eq(getRouterIdentity(), lse.getRouterIdentity()); - - } - + if ((object == null) || !(object instanceof Lease)) return false; + Lease lse = (Lease) object; + return DataHelper.eq(getEndDate(), lse.getEndDate()) + && DataHelper.eq(getRouterIdentity(), lse.getRouterIdentity()); + + } + public int hashCode() { - return DataHelper.hashCode(getEndDate()) + - DataHelper.hashCode(getRouterIdentity()) + - DataHelper.hashCode(getTunnelId()); + return DataHelper.hashCode(getEndDate()) + DataHelper.hashCode(getRouterIdentity()) + + DataHelper.hashCode(getTunnelId()); } - + public String toString() { StringBuffer buf = new StringBuffer(128); buf.append("[Lease: "); @@ -122,4 +151,4 @@ public class Lease extends DataStructureImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/LeaseSet.java b/core/java/src/net/i2p/data/LeaseSet.java index e50f9911bc4fc86a5ffca3c1ebc5d99a52dd19d2..cea706043d1558c5461b9d22d86ad81459122dbf 100644 --- a/core/java/src/net/i2p/data/LeaseSet.java +++ b/core/java/src/net/i2p/data/LeaseSet.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -17,8 +18,8 @@ import java.util.Iterator; import java.util.List; import net.i2p.crypto.DSAEngine; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Defines the set of leases a destination currently has. @@ -34,57 +35,96 @@ public class LeaseSet extends DataStructureImpl { private Signature _signature; private volatile Hash _currentRoutingKey; private volatile byte[] _routingKeyGenMod; - + /** um, no lease can last more than a year. */ - private final static long MAX_FUTURE_EXPIRATION = 365*24*60*60*1000L; - - public LeaseSet() { + private final static long MAX_FUTURE_EXPIRATION = 365 * 24 * 60 * 60 * 1000L; + + public LeaseSet() { setDestination(null); - setEncryptionKey(null); - setSigningKey(null); - setSignature(null); - setRoutingKey(null); - _leases = new ArrayList(); - _routingKeyGenMod = null; + setEncryptionKey(null); + setSigningKey(null); + setSignature(null); + setRoutingKey(null); + _leases = new ArrayList(); + _routingKeyGenMod = null; + } + + public Destination getDestination() { + return _destination; + } + + public void setDestination(Destination dest) { + _destination = dest; + } + + public PublicKey getEncryptionKey() { + return _encryptionKey; + } + + public void setEncryptionKey(PublicKey encryptionKey) { + _encryptionKey = encryptionKey; + } + + public SigningPublicKey getSigningKey() { + return _signingKey; + } + + public void setSigningKey(SigningPublicKey key) { + _signingKey = key; + } + + public void addLease(Lease lease) { + _leases.add(lease); + } + + public void removeLease(Lease lease) { + _leases.remove(lease); + } + + public int getLeaseCount() { + return _leases.size(); + } + + public Lease getLease(int index) { + return (Lease) _leases.get(index); } - - public Destination getDestination() { return _destination; } - public void setDestination(Destination dest) { _destination = dest; } - public PublicKey getEncryptionKey() { return _encryptionKey; } - public void setEncryptionKey(PublicKey encryptionKey) { _encryptionKey = encryptionKey; } - public SigningPublicKey getSigningKey() { return _signingKey; } - public void setSigningKey(SigningPublicKey key) { _signingKey = key; } - public void addLease(Lease lease) { _leases.add(lease); } - public void removeLease(Lease lease) { _leases.remove(lease); } - public int getLeaseCount() { return _leases.size(); } - public Lease getLease(int index) { return (Lease)_leases.get(index); } - public Signature getSignature() { return _signature; } - public void setSignature(Signature sig) { _signature = sig; } - + + public Signature getSignature() { + return _signature; + } + + public void setSignature(Signature sig) { + _signature = sig; + } + /** * Get the routing key for the structure using the current modifier in the RoutingKeyGenerator. * This only calculates a new one when necessary though (if the generator's key modifier changes) * */ - public Hash getRoutingKey() { - RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance(); - if ( (gen.getModData() == null) || (_routingKeyGenMod == null) || (!DataHelper.eq(gen.getModData(), _routingKeyGenMod)) ) { - setRoutingKey(gen.getRoutingKey(getDestination().calculateHash())); - _routingKeyGenMod = gen.getModData(); - } - return _currentRoutingKey; + public Hash getRoutingKey() { + RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance(); + if ((gen.getModData() == null) || (_routingKeyGenMod == null) + || (!DataHelper.eq(gen.getModData(), _routingKeyGenMod))) { + setRoutingKey(gen.getRoutingKey(getDestination().calculateHash())); + _routingKeyGenMod = gen.getModData(); + } + return _currentRoutingKey; + } + + public void setRoutingKey(Hash key) { + _currentRoutingKey = key; } - public void setRoutingKey(Hash key) { _currentRoutingKey = key; } - + public boolean validateRoutingKey() { - Hash destKey = getDestination().calculateHash(); - Hash rk = RoutingKeyGenerator.getInstance().getRoutingKey(destKey); - if (rk.equals(getRoutingKey())) - return true; - else - return false; + Hash destKey = getDestination().calculateHash(); + Hash rk = RoutingKeyGenerator.getInstance().getRoutingKey(destKey); + if (rk.equals(getRoutingKey())) + return true; + else + return false; } - + /** * Retrieve the end date of the earliest lease include in this leaseSet. * This is the date that should be used in comparisons for leaseSet age - to @@ -94,64 +134,66 @@ public class LeaseSet extends DataStructureImpl { * @return earliest end date of any lease in the set, or -1 if there are no leases */ public long getEarliestLeaseDate() { - long when = -1; - for (int i = 0; i < getLeaseCount(); i++) { - Lease lse = (Lease)getLease(i); - if ( (lse != null) && (lse.getEndDate() != null) ) { - if ( (when <= 0) || (lse.getEndDate().getTime() < when) ) - when = lse.getEndDate().getTime(); - } - } - return when; + long when = -1; + for (int i = 0; i < getLeaseCount(); i++) { + Lease lse = (Lease) getLease(i); + if ((lse != null) && (lse.getEndDate() != null)) { + if ((when <= 0) || (lse.getEndDate().getTime() < when)) when = lse.getEndDate().getTime(); + } + } + return when; } - + /** * Sign the structure using the supplied signing key * */ public void sign(SigningPrivateKey key) throws DataFormatException { - byte[] bytes = getBytes(); - if (bytes == null) throw new DataFormatException("Not enough data to sign"); + byte[] bytes = getBytes(); + if (bytes == null) throw new DataFormatException("Not enough data to sign"); // now sign with the key - Signature sig = DSAEngine.getInstance().sign(bytes, key); + Signature sig = DSAEngine.getInstance().sign(bytes, key); setSignature(sig); } - + /** * Verify that the signature matches the lease set's destination's signing public key. * * @return true only if the signature matches */ public boolean verifySignature() { - if (getSignature() == null) return false; - if (getDestination() == null) return false; - byte data[] = getBytes(); - if (data == null) return false; - boolean signedByDest = DSAEngine.getInstance().verifySignature(getSignature(), data, getDestination().getSigningPublicKey()); - boolean signedByRevoker = false; - if (!signedByDest) { - signedByRevoker = DSAEngine.getInstance().verifySignature(getSignature(), data, _signingKey); - } - return signedByDest || signedByRevoker; + if (getSignature() == null) return false; + if (getDestination() == null) return false; + byte data[] = getBytes(); + if (data == null) return false; + boolean signedByDest = DSAEngine.getInstance().verifySignature(getSignature(), data, + getDestination().getSigningPublicKey()); + boolean signedByRevoker = false; + if (!signedByDest) { + signedByRevoker = DSAEngine.getInstance().verifySignature(getSignature(), data, _signingKey); + } + return signedByDest || signedByRevoker; } + /** * Verify that the signature matches the lease set's destination's signing public key. * * @return true only if the signature matches */ public boolean verifySignature(SigningPublicKey signingKey) { - if (getSignature() == null) return false; - if (getDestination() == null) return false; - byte data[] = getBytes(); - if (data == null) return false; - boolean signedByDest = DSAEngine.getInstance().verifySignature(getSignature(), data, getDestination().getSigningPublicKey()); - boolean signedByRevoker = false; - if (!signedByDest) { - signedByRevoker = DSAEngine.getInstance().verifySignature(getSignature(), data, signingKey); - } - return signedByDest || signedByRevoker; + if (getSignature() == null) return false; + if (getDestination() == null) return false; + byte data[] = getBytes(); + if (data == null) return false; + boolean signedByDest = DSAEngine.getInstance().verifySignature(getSignature(), data, + getDestination().getSigningPublicKey()); + boolean signedByRevoker = false; + if (!signedByDest) { + signedByRevoker = DSAEngine.getInstance().verifySignature(getSignature(), data, signingKey); + } + return signedByDest || signedByRevoker; } - + /** * Determine whether there are currently valid leases, at least within a given * fudge factor @@ -160,109 +202,104 @@ public class LeaseSet extends DataStructureImpl { * @return true if there are current leases, false otherwise */ public boolean isCurrent(long fudge) { - long now = Clock.getInstance().now(); - long insane = now + MAX_FUTURE_EXPIRATION; - int cnt = getLeaseCount(); - for (int i = 0; i < cnt; i++) { - Lease l = getLease(i); - if (l.getEndDate().getTime() > insane) { - _log.warn("LeaseSet" + calculateHash() + " expires an insane amount in the future - skip it: " + l); - return false; - } - // if it hasn't finished, we're current - if (l.getEndDate().getTime() > now) { - _log.debug("LeaseSet " + calculateHash() + " isn't exired: " + l); - return true; - } else if (l.getEndDate().getTime() > now - fudge) { - _log.debug("LeaseSet " + calculateHash() + " isn't quite expired, but its within the fudge factor so we'll let it slide: " + l); - return true; - } - } - return false; + long now = Clock.getInstance().now(); + long insane = now + MAX_FUTURE_EXPIRATION; + int cnt = getLeaseCount(); + for (int i = 0; i < cnt; i++) { + Lease l = getLease(i); + if (l.getEndDate().getTime() > insane) { + _log.warn("LeaseSet" + calculateHash() + " expires an insane amount in the future - skip it: " + l); + return false; + } + // if it hasn't finished, we're current + if (l.getEndDate().getTime() > now) { + _log.debug("LeaseSet " + calculateHash() + " isn't exired: " + l); + return true; + } else if (l.getEndDate().getTime() > now - fudge) { + _log.debug("LeaseSet " + calculateHash() + + " isn't quite expired, but its within the fudge factor so we'll let it slide: " + l); + return true; + } + } + return false; } - + private byte[] getBytes() { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { - if ( (_destination == null) || (_encryptionKey == null) || (_signingKey == null) || - (_leases == null) ) - return null; - - _destination.writeBytes(out); - _encryptionKey.writeBytes(out); - _signingKey.writeBytes(out); - DataHelper.writeLong(out, 1, _leases.size()); - //DataHelper.writeLong(out, 4, _version); - for (Iterator iter = _leases.iterator(); iter.hasNext();) { - Lease lease = (Lease)iter.next(); - lease.writeBytes(out); - } + if ((_destination == null) || (_encryptionKey == null) || (_signingKey == null) || (_leases == null)) + return null; + + _destination.writeBytes(out); + _encryptionKey.writeBytes(out); + _signingKey.writeBytes(out); + DataHelper.writeLong(out, 1, _leases.size()); + //DataHelper.writeLong(out, 4, _version); + for (Iterator iter = _leases.iterator(); iter.hasNext();) { + Lease lease = (Lease) iter.next(); + lease.writeBytes(out); + } } catch (IOException ioe) { return null; } catch (DataFormatException dfe) { - return null; - } - return out.toByteArray(); + return null; + } + return out.toByteArray(); } - + public void readBytes(InputStream in) throws DataFormatException, IOException { - _destination = new Destination(); - _destination.readBytes(in); - _encryptionKey = new PublicKey(); - _encryptionKey.readBytes(in); - _signingKey = new SigningPublicKey(); - _signingKey.readBytes(in); - int numLeases = (int)DataHelper.readLong(in, 1); - //_version = DataHelper.readLong(in, 4); - _leases.clear(); - for (int i = 0; i < numLeases; i++) { - Lease lease = new Lease(); - lease.readBytes(in); - _leases.add(lease); - } - _signature = new Signature(); - _signature.readBytes(in); + _destination = new Destination(); + _destination.readBytes(in); + _encryptionKey = new PublicKey(); + _encryptionKey.readBytes(in); + _signingKey = new SigningPublicKey(); + _signingKey.readBytes(in); + int numLeases = (int) DataHelper.readLong(in, 1); + //_version = DataHelper.readLong(in, 4); + _leases.clear(); + for (int i = 0; i < numLeases; i++) { + Lease lease = new Lease(); + lease.readBytes(in); + _leases.add(lease); + } + _signature = new Signature(); + _signature.readBytes(in); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_destination == null) || (_encryptionKey == null) || (_signingKey == null) || - (_leases == null) || (_signature == null) ) - throw new DataFormatException("Not enough data to write out a LeaseSet"); - - _destination.writeBytes(out); - _encryptionKey.writeBytes(out); - _signingKey.writeBytes(out); - DataHelper.writeLong(out, 1, _leases.size()); - //DataHelper.writeLong(out, 4, _version); - for (Iterator iter = _leases.iterator(); iter.hasNext();) { - Lease lease = (Lease)iter.next(); - lease.writeBytes(out); - } - _signature.writeBytes(out); + if ((_destination == null) || (_encryptionKey == null) || (_signingKey == null) || (_leases == null) + || (_signature == null)) throw new DataFormatException("Not enough data to write out a LeaseSet"); + + _destination.writeBytes(out); + _encryptionKey.writeBytes(out); + _signingKey.writeBytes(out); + DataHelper.writeLong(out, 1, _leases.size()); + //DataHelper.writeLong(out, 4, _version); + for (Iterator iter = _leases.iterator(); iter.hasNext();) { + Lease lease = (Lease) iter.next(); + lease.writeBytes(out); + } + _signature.writeBytes(out); } public boolean equals(Object object) { - if ( (object == null) || !(object instanceof LeaseSet) ) - return false; - LeaseSet ls = (LeaseSet)object; + if ((object == null) || !(object instanceof LeaseSet)) return false; + LeaseSet ls = (LeaseSet) object; return DataHelper.eq(getEncryptionKey(), ls.getEncryptionKey()) && - //DataHelper.eq(getVersion(), ls.getVersion()) && - DataHelper.eq(_leases, ls._leases) && - DataHelper.eq(getSignature(), ls.getSignature()) && - DataHelper.eq(getSigningKey(), ls.getSigningKey()) && - DataHelper.eq(getDestination(), ls.getDestination()); - + //DataHelper.eq(getVersion(), ls.getVersion()) && + DataHelper.eq(_leases, ls._leases) && DataHelper.eq(getSignature(), ls.getSignature()) + && DataHelper.eq(getSigningKey(), ls.getSigningKey()) + && DataHelper.eq(getDestination(), ls.getDestination()); + } - + public int hashCode() { return DataHelper.hashCode(getEncryptionKey()) + - //(int)_version + - DataHelper.hashCode(_leases) + - DataHelper.hashCode(getSignature()) + - DataHelper.hashCode(getSigningKey()) + - DataHelper.hashCode(getDestination()); + //(int)_version + + DataHelper.hashCode(_leases) + DataHelper.hashCode(getSignature()) + + DataHelper.hashCode(getSigningKey()) + DataHelper.hashCode(getDestination()); } - + public String toString() { StringBuffer buf = new StringBuffer(128); buf.append("[LeaseSet: "); @@ -272,9 +309,9 @@ public class LeaseSet extends DataStructureImpl { //buf.append("\n\tVersion: ").append(getVersion()); buf.append("\n\tSignature: ").append(getSignature()); buf.append("\n\tLeases: #").append(getLeaseCount()); - for (int i = 0; i < getLeaseCount(); i++) - buf.append("\n\t\tLease (").append(i).append("): ").append(getLease(i)); + for (int i = 0; i < getLeaseCount(); i++) + buf.append("\n\t\tLease (").append(i).append("): ").append(getLease(i)); buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Payload.java b/core/java/src/net/i2p/data/Payload.java index 9b778fc2ce3649d8d5664ecac4aa6bf00690ac9a..4c4bbf58572f7cafb8b4bdce35594260ff3bf02c 100644 --- a/core/java/src/net/i2p/data/Payload.java +++ b/core/java/src/net/i2p/data/Payload.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -24,69 +25,74 @@ public class Payload extends DataStructureImpl { private final static Log _log = new Log(Payload.class); private byte[] _encryptedData; private byte[] _unencryptedData; - + public Payload() { setUnencryptedData(null); - setEncryptedData(null); + setEncryptedData(null); } - + /** * Retrieve the unencrypted body of the message. * * @return body of the message, or null if the message has either not been * decrypted yet or if the hash is not correct */ - public byte[] getUnencryptedData() { - return _unencryptedData; + public byte[] getUnencryptedData() { + return _unencryptedData; } + /** * Populate the message body with data. This does not automatically encrypt * yet. * */ - public void setUnencryptedData(byte[] data) { _unencryptedData = data; } - public byte[] getEncryptedData() { return _encryptedData; } - public void setEncryptedData(byte[] data) { _encryptedData = data; } - - public int getSize() { - if (_unencryptedData != null) - return _unencryptedData.length; - else if (_encryptedData != null) - return _encryptedData.length; - else - return 0; + public void setUnencryptedData(byte[] data) { + _unencryptedData = data; + } + + public byte[] getEncryptedData() { + return _encryptedData; + } + + public void setEncryptedData(byte[] data) { + _encryptedData = data; } - + + public int getSize() { + if (_unencryptedData != null) + return _unencryptedData.length; + else if (_encryptedData != null) + return _encryptedData.length; + else + return 0; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - int size = (int)DataHelper.readLong(in, 4); + int size = (int) DataHelper.readLong(in, 4); _encryptedData = new byte[size]; int read = read(in, _encryptedData); - if (read != size) - throw new DataFormatException("Incorrect number of bytes read in the payload structure"); + if (read != size) throw new DataFormatException("Incorrect number of bytes read in the payload structure"); _log.debug("read payload: " + read + " bytes"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_encryptedData == null) - throw new DataFormatException("Not yet encrypted. Please set the encrypted data"); + if (_encryptedData == null) throw new DataFormatException("Not yet encrypted. Please set the encrypted data"); DataHelper.writeLong(out, 4, _encryptedData.length); out.write(_encryptedData); _log.debug("wrote payload: " + _encryptedData.length); } - - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof Payload) ) - return false; - Payload p = (Payload)object; - return DataHelper.eq(getUnencryptedData(), p.getUnencryptedData()) && - DataHelper.eq(getEncryptedData(), p.getEncryptedData()); + if ((object == null) || !(object instanceof Payload)) return false; + Payload p = (Payload) object; + return DataHelper.eq(getUnencryptedData(), p.getUnencryptedData()) + && DataHelper.eq(getEncryptedData(), p.getEncryptedData()); } - + public int hashCode() { return DataHelper.hashCode(getUnencryptedData()); } - + public String toString() { StringBuffer buf = new StringBuffer(128); buf.append("[Payload: "); @@ -97,4 +103,4 @@ public class Payload extends DataStructureImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/PrivateKey.java b/core/java/src/net/i2p/data/PrivateKey.java index f908fe49f45599badb21bf164f9634473f7254e5..5bbebc2b54bda2879dfafe6540003864f0203b29 100644 --- a/core/java/src/net/i2p/data/PrivateKey.java +++ b/core/java/src/net/i2p/data/PrivateKey.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -24,40 +25,44 @@ import net.i2p.util.Log; public class PrivateKey extends DataStructureImpl { private final static Log _log = new Log(PrivateKey.class); private byte[] _data; - + public final static int KEYSIZE_BYTES = 256; - - public PrivateKey() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public PrivateKey() { + setData(null); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[KEYSIZE_BYTES]; int read = read(in, _data); - if (read != KEYSIZE_BYTES) - throw new DataFormatException("Not enough bytes to read the private key"); + if (read != KEYSIZE_BYTES) throw new DataFormatException("Not enough bytes to read the private key"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the private key to write out"); + if (_data == null) throw new DataFormatException("No data in the private key to write out"); if (_data.length != KEYSIZE_BYTES) throw new DataFormatException("Invalid size of data in the private key [" + _data.length + "]"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof PrivateKey)) - return false; - return DataHelper.eq(_data, ((PrivateKey)obj)._data); + if ((obj == null) || !(obj instanceof PrivateKey)) return false; + return DataHelper.eq(_data, ((PrivateKey) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[PrivateKey: "); if (_data == null) { @@ -65,12 +70,11 @@ public class PrivateKey extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/PublicKey.java b/core/java/src/net/i2p/data/PublicKey.java index bde5f7922a977027ea47ccb22bfa5919c63a9316..6713febe5026526f72dd3db661b70c5d04daec3f 100644 --- a/core/java/src/net/i2p/data/PublicKey.java +++ b/core/java/src/net/i2p/data/PublicKey.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -24,39 +25,43 @@ import net.i2p.util.Log; public class PublicKey extends DataStructureImpl { private final static Log _log = new Log(PublicKey.class); private byte[] _data; - + public final static int KEYSIZE_BYTES = 256; - - public PublicKey() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public PublicKey() { + setData(null); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[KEYSIZE_BYTES]; int read = read(in, _data); - if (read != KEYSIZE_BYTES) - throw new DataFormatException("Not enough bytes to read the public key"); + if (read != KEYSIZE_BYTES) throw new DataFormatException("Not enough bytes to read the public key"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the public key to write out"); - if (_data.length != KEYSIZE_BYTES) - throw new DataFormatException("Invalid size of data in the public key"); + if (_data == null) throw new DataFormatException("No data in the public key to write out"); + if (_data.length != KEYSIZE_BYTES) throw new DataFormatException("Invalid size of data in the public key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof PublicKey)) - return false; - return DataHelper.eq(_data, ((PublicKey)obj)._data); + if ((obj == null) || !(obj instanceof PublicKey)) return false; + return DataHelper.eq(_data, ((PublicKey) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[PublicKey: "); if (_data == null) { @@ -64,12 +69,11 @@ public class PublicKey extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/RouterAddress.java b/core/java/src/net/i2p/data/RouterAddress.java index 2de2c42456c5b9bc3b61d5794a225448dab0f739..a0a69f98b1fd16a803701cea84d4e5ca6c1b5cdd 100644 --- a/core/java/src/net/i2p/data/RouterAddress.java +++ b/core/java/src/net/i2p/data/RouterAddress.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,13 +9,12 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import java.util.Properties; -import java.util.Iterator; import java.util.Date; +import java.util.Iterator; +import java.util.Properties; import net.i2p.util.Log; @@ -29,93 +29,112 @@ public class RouterAddress extends DataStructureImpl { private Date _expiration; private String _transportStyle; private Properties _options; - + public RouterAddress() { setCost(-1); setExpiration(null); setTransportStyle(null); setOptions(null); } - + /** * Retrieve the weighted cost of this address, relative to other methods of * contacting this router. The value 0 means free and 255 means really expensive. * No value above 255 is allowed. * */ - public int getCost() { return _cost; } + public int getCost() { + return _cost; + } + /** * Configure the weighted cost of using the address. * No value above 255 is allowed. * */ - public void setCost(int cost) { _cost = cost; } + public void setCost(int cost) { + _cost = cost; + } + /** * Retrieve the date after which the address should not be used. If this * is null, then the address never expires. * - */ - public Date getExpiration() { return _expiration; } + */ + public Date getExpiration() { + return _expiration; + } + /** * Configure the expiration date of the address (null for no expiration) * */ - public void setExpiration(Date expiration) { _expiration = expiration; } + public void setExpiration(Date expiration) { + _expiration = expiration; + } + /** * Retrieve the type of transport that must be used to communicate on this address. * */ - public String getTransportStyle() { return _transportStyle; } + public String getTransportStyle() { + return _transportStyle; + } + /** * Configure the type of transport that must be used to communicate on this address * */ - public void setTransportStyle(String transportStyle) { _transportStyle = transportStyle; } + public void setTransportStyle(String transportStyle) { + _transportStyle = transportStyle; + } + /** * Retrieve the transport specific options necessary for communication * */ - public Properties getOptions() { return _options; } + public Properties getOptions() { + return _options; + } + /** * Specify the transport specific options necessary for communication * */ - public void setOptions(Properties options) { _options = options; } - + public void setOptions(Properties options) { + _options = options; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - _cost = (int)DataHelper.readLong(in, 1); + _cost = (int) DataHelper.readLong(in, 1); _expiration = DataHelper.readDate(in); _transportStyle = DataHelper.readString(in); _options = DataHelper.readProperties(in); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_cost < 0) || (_transportStyle == null) || (_options == null) ) + if ((_cost < 0) || (_transportStyle == null) || (_options == null)) throw new DataFormatException("Not enough data to write a router address"); DataHelper.writeLong(out, 1, _cost); DataHelper.writeDate(out, _expiration); DataHelper.writeString(out, _transportStyle); DataHelper.writeProperties(out, _options); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof RouterAddress) ) - return false; - RouterAddress addr = (RouterAddress)object; - return DataHelper.eq(getCost(), addr.getCost()) && - DataHelper.eq(getExpiration(), addr.getExpiration()) && - DataHelper.eq(getOptions(), addr.getOptions()) && - DataHelper.eq(getTransportStyle(), addr.getTransportStyle()); + if ((object == null) || !(object instanceof RouterAddress)) return false; + RouterAddress addr = (RouterAddress) object; + return DataHelper.eq(getCost(), addr.getCost()) && DataHelper.eq(getExpiration(), addr.getExpiration()) + && DataHelper.eq(getOptions(), addr.getOptions()) + && DataHelper.eq(getTransportStyle(), addr.getTransportStyle()); } - + public int hashCode() { - return getCost() + - DataHelper.hashCode(getTransportStyle()) + - DataHelper.hashCode(getExpiration()) + - DataHelper.hashCode(getOptions()); + return getCost() + DataHelper.hashCode(getTransportStyle()) + DataHelper.hashCode(getExpiration()) + + DataHelper.hashCode(getOptions()); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[RouterAddress: "); buf.append("\n\tTransportStyle: ").append(getTransportStyle()); @@ -123,11 +142,11 @@ public class RouterAddress extends DataStructureImpl { buf.append("\n\tExpiration: ").append(getExpiration()); buf.append("\n\tOptions: #: ").append(getOptions().size()); for (Iterator iter = getOptions().keySet().iterator(); iter.hasNext();) { - String key = (String)iter.next(); + String key = (String) iter.next(); String val = getOptions().getProperty(key); buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]"); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/RouterIdentity.java b/core/java/src/net/i2p/data/RouterIdentity.java index ed113aa8a3fd871d3b85694b5cb21a51fc4e87e1..573fb9d083e883ef907522c1610d41b74fbe870d 100644 --- a/core/java/src/net/i2p/data/RouterIdentity.java +++ b/core/java/src/net/i2p/data/RouterIdentity.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,10 +9,10 @@ package net.i2p.data; * */ -import java.io.InputStream; -import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import net.i2p.crypto.SHA256Generator; import net.i2p.util.Log; @@ -28,30 +29,41 @@ public class RouterIdentity extends DataStructureImpl { private SigningPublicKey _signingKey; private PublicKey _publicKey; private Hash __calculatedHash; - + public RouterIdentity() { setCertificate(null); setSigningPublicKey(null); setPublicKey(null); - __calculatedHash = null; + __calculatedHash = null; } - - public Certificate getCertificate() { return _certificate; } - public void setCertificate(Certificate cert) { - _certificate = cert; - __calculatedHash = null; + + public Certificate getCertificate() { + return _certificate; + } + + public void setCertificate(Certificate cert) { + _certificate = cert; + __calculatedHash = null; } - public PublicKey getPublicKey() { return _publicKey; } - public void setPublicKey(PublicKey key) { - _publicKey = key; - __calculatedHash = null; + + public PublicKey getPublicKey() { + return _publicKey; } - public SigningPublicKey getSigningPublicKey() { return _signingKey; } - public void setSigningPublicKey(SigningPublicKey key) { - _signingKey = key; - __calculatedHash = null; + + public void setPublicKey(PublicKey key) { + _publicKey = key; + __calculatedHash = null; } - + + public SigningPublicKey getSigningPublicKey() { + return _signingKey; + } + + public void setSigningPublicKey(SigningPublicKey key) { + _signingKey = key; + __calculatedHash = null; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _publicKey = new PublicKey(); _publicKey.readBytes(in); @@ -59,32 +71,31 @@ public class RouterIdentity extends DataStructureImpl { _signingKey.readBytes(in); _certificate = new Certificate(); _certificate.readBytes(in); - __calculatedHash = null; + __calculatedHash = null; } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_certificate == null) || (_publicKey == null) || (_signingKey == null) ) + if ((_certificate == null) || (_publicKey == null) || (_signingKey == null)) throw new DataFormatException("Not enough data to format the destination"); _publicKey.writeBytes(out); _signingKey.writeBytes(out); _certificate.writeBytes(out); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof RouterIdentity) ) - return false; - RouterIdentity ident = (RouterIdentity)object; - return DataHelper.eq(getCertificate(), ident.getCertificate()) && - DataHelper.eq(getSigningPublicKey(), ident.getSigningPublicKey()) && - DataHelper.eq(getPublicKey(), ident.getPublicKey()); + if ((object == null) || !(object instanceof RouterIdentity)) return false; + RouterIdentity ident = (RouterIdentity) object; + return DataHelper.eq(getCertificate(), ident.getCertificate()) + && DataHelper.eq(getSigningPublicKey(), ident.getSigningPublicKey()) + && DataHelper.eq(getPublicKey(), ident.getPublicKey()); } - + public int hashCode() { - return DataHelper.hashCode(getCertificate()) + - DataHelper.hashCode(getSigningPublicKey()) + - DataHelper.hashCode(getPublicKey()); + return DataHelper.hashCode(getCertificate()) + DataHelper.hashCode(getSigningPublicKey()) + + DataHelper.hashCode(getPublicKey()); } - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[RouterIdentity: "); buf.append("\n\tHash: ").append(getHash().toBase64()); @@ -94,24 +105,25 @@ public class RouterIdentity extends DataStructureImpl { buf.append("]"); return buf.toString(); } - - public Hash calculateHash() { return getHash(); } - + + public Hash calculateHash() { + return getHash(); + } + public Hash getHash() { - if (__calculatedHash != null) { - //_log.info("Returning cached ident hash"); - return __calculatedHash; - } - byte identBytes[] = null; - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeBytes(baos); - identBytes = baos.toByteArray(); - } catch (Throwable t) { - _log.error("Error writing out hash"); - return null; - } - __calculatedHash = SHA256Generator.getInstance().calculateHash(identBytes); - return __calculatedHash; + if (__calculatedHash != null) { + //_log.info("Returning cached ident hash"); + return __calculatedHash; } + byte identBytes[] = null; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeBytes(baos); + identBytes = baos.toByteArray(); + } catch (Throwable t) { + _log.error("Error writing out hash"); + return null; + } + __calculatedHash = SHA256Generator.getInstance().calculateHash(identBytes); + return __calculatedHash; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/RouterInfo.java b/core/java/src/net/i2p/data/RouterInfo.java index 49e990a2e1e211e6b49a7f98a0619c616ba67ab2..bccb067696454bfe9cb671ac2a065f03746311b6 100644 --- a/core/java/src/net/i2p/data/RouterInfo.java +++ b/core/java/src/net/i2p/data/RouterInfo.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,23 +9,22 @@ package net.i2p.data; * */ -import java.io.InputStream; -import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; - -import java.util.Set; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; import java.util.HashSet; import java.util.Iterator; -import java.util.Properties; import java.util.List; -import java.util.Date; +import java.util.Properties; +import java.util.Set; -import net.i2p.util.Log; -import net.i2p.util.OrderedProperties; -import net.i2p.util.Clock; import net.i2p.crypto.DSAEngine; import net.i2p.crypto.SHA256Generator; +import net.i2p.util.Clock; +import net.i2p.util.Log; +import net.i2p.util.OrderedProperties; /** * Defines the data that a router either publishes to the global routing table or @@ -46,49 +46,53 @@ public class RouterInfo extends DataStructureImpl { private volatile boolean _isValid; private volatile String _stringified; private volatile byte _byteified[]; - + public RouterInfo() { setIdentity(null); - setPublished(0); + setPublished(0); _addresses = new HashSet(); _peers = new HashSet(); _options = new OrderedProperties(); setSignature(null); _validated = false; _isValid = false; - _currentRoutingKey = null; - _stringified = null; - _byteified = null; + _currentRoutingKey = null; + _stringified = null; + _byteified = null; } - + public RouterInfo(RouterInfo old) { - this(); - setIdentity(old.getIdentity()); - setPublished(old.getPublished()); - setAddresses(old.getAddresses()); - setPeers(old.getPeers()); - setOptions(old.getOptions()); - setSignature(old.getSignature()); - } - + this(); + setIdentity(old.getIdentity()); + setPublished(old.getPublished()); + setAddresses(old.getAddresses()); + setPeers(old.getPeers()); + setOptions(old.getOptions()); + setSignature(old.getSignature()); + } + private void resetCache() { - _stringified = null; - _byteified = null; + _stringified = null; + _byteified = null; } - + /** * Retrieve the identity of the router represented * */ - public RouterIdentity getIdentity() { return _identity; } + public RouterIdentity getIdentity() { + return _identity; + } + /** * Configure the identity of the router represented * */ - public void setIdentity(RouterIdentity ident) { - _identity = ident; - resetCache(); + public void setIdentity(RouterIdentity ident) { + _identity = ident; + resetCache(); } + /** * Retrieve the approximate date on which the info was published * (essentially a version number for the routerInfo structure, except that @@ -97,185 +101,202 @@ public class RouterInfo extends DataStructureImpl { * old routerInfo structures * */ - public long getPublished() { return _published; } + public long getPublished() { + return _published; + } + /** * Date on which it was published, in milliseconds since Midnight GMT on Jan 01, 1970 * */ - public void setPublished(long published) { _published = published; } + public void setPublished(long published) { + _published = published; + } + /** * Retrieve the set of RouterAddress structures at which this * router can be contacted. * */ - public Set getAddresses() { - synchronized (_addresses) { - return new HashSet(_addresses); - } + public Set getAddresses() { + synchronized (_addresses) { + return new HashSet(_addresses); + } } + /** * Specify a set of RouterAddress structures at which this router * can be contacted. * */ - public void setAddresses(Set addresses) { - synchronized (_addresses) { - _addresses.clear(); - if (addresses != null) - _addresses.addAll(addresses); - } - resetCache(); + public void setAddresses(Set addresses) { + synchronized (_addresses) { + _addresses.clear(); + if (addresses != null) _addresses.addAll(addresses); + } + resetCache(); } + /** * Retrieve a set of SHA-256 hashes of RouterIdentities from rotuers * this router can be reached through. * */ - public Set getPeers() { return _peers; } + public Set getPeers() { + return _peers; + } + /** * Specify a set of SHA-256 hashes of RouterIdentities from rotuers * this router can be reached through. * */ - public void setPeers(Set peers) { - synchronized (_peers) { - _peers.clear(); - if (peers != null) - _peers.addAll(peers); - } - resetCache(); + public void setPeers(Set peers) { + synchronized (_peers) { + _peers.clear(); + if (peers != null) _peers.addAll(peers); + } + resetCache(); } + /** * Retrieve a set of options or statistics that the router can expose * */ public Properties getOptions() { - if (_options == null) return new Properties(); - synchronized (_options) { - return (Properties)_options.clone(); - } + if (_options == null) return new Properties(); + synchronized (_options) { + return (Properties) _options.clone(); + } } + /** * Configure a set of options or statistics that the router can expose * */ - public void setOptions(Properties options) { - synchronized (_options) { - _options.clear(); - if (options != null) { - for (Iterator iter = options.keySet().iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); - if (name == null) continue; - String val = options.getProperty(name); - if (val == null) continue; - _options.setProperty(name, val); - } - } - } - resetCache(); + public void setOptions(Properties options) { + synchronized (_options) { + _options.clear(); + if (options != null) { + for (Iterator iter = options.keySet().iterator(); iter.hasNext();) { + String name = (String) iter.next(); + if (name == null) continue; + String val = options.getProperty(name); + if (val == null) continue; + _options.setProperty(name, val); + } + } + } + resetCache(); } + /** * Retrieve the proof that the identity stands behind the info here * */ - public Signature getSignature() { return _signature; } + public Signature getSignature() { + return _signature; + } + /** * Configure the proof that the entity stands behind the info here * */ - public void setSignature(Signature signature) { - _signature = signature; - resetCache(); + public void setSignature(Signature signature) { + _signature = signature; + resetCache(); } - + /** * Sign the structure using the supplied signing key * */ public synchronized void sign(SigningPrivateKey key) throws DataFormatException { - byte[] bytes = getBytes(); - if (bytes == null) throw new DataFormatException("Not enough data to sign"); + byte[] bytes = getBytes(); + if (bytes == null) throw new DataFormatException("Not enough data to sign"); // now sign with the key - Signature sig = DSAEngine.getInstance().sign(bytes, key); + Signature sig = DSAEngine.getInstance().sign(bytes, key); setSignature(sig); - //_log.debug("Signed " + SHA256Generator.getInstance().calculateHash(bytes).toBase64() + " with " + key); - //_log.debug("verify ok? " + DSAEngine.getInstance().verifySignature(sig, bytes, getIdentity().getSigningPublicKey())); - //_log.debug("Signed data: \n" + Base64.encode(bytes)); - //_log.debug("Signature: " + getSignature()); - - resetCache(); + //_log.debug("Signed " + SHA256Generator.getInstance().calculateHash(bytes).toBase64() + " with " + key); + //_log.debug("verify ok? " + DSAEngine.getInstance().verifySignature(sig, bytes, getIdentity().getSigningPublicKey())); + //_log.debug("Signed data: \n" + Base64.encode(bytes)); + //_log.debug("Signature: " + getSignature()); + + resetCache(); } - + private byte[] getBytes() throws DataFormatException { - if (_byteified != null) return _byteified; - if (_identity == null) throw new IllegalStateException("Router identity isn't set? wtf!"); - if (_addresses == null) throw new IllegalStateException("Router addressess isn't set? wtf!"); - if (_peers == null) throw new IllegalStateException("Router peers isn't set? wtf!"); - if (_options == null) throw new IllegalStateException("Router options isn't set? wtf!"); - - long before = Clock.getInstance().now(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); + if (_byteified != null) return _byteified; + if (_identity == null) throw new IllegalStateException("Router identity isn't set? wtf!"); + if (_addresses == null) throw new IllegalStateException("Router addressess isn't set? wtf!"); + if (_peers == null) throw new IllegalStateException("Router peers isn't set? wtf!"); + if (_options == null) throw new IllegalStateException("Router options isn't set? wtf!"); + + long before = Clock.getInstance().now(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); try { _identity.writeBytes(out); DataHelper.writeDate(out, new Date(_published)); DataHelper.writeLong(out, 1, _addresses.size()); - List addresses = DataHelper.sortStructures(_addresses); - for (Iterator iter = addresses.iterator(); iter.hasNext(); ) { - RouterAddress addr = (RouterAddress)iter.next(); + List addresses = DataHelper.sortStructures(_addresses); + for (Iterator iter = addresses.iterator(); iter.hasNext();) { + RouterAddress addr = (RouterAddress) iter.next(); addr.writeBytes(out); } DataHelper.writeLong(out, 1, _peers.size()); - List peers = DataHelper.sortStructures(_peers); - for (Iterator iter = peers.iterator(); iter.hasNext(); ) { - Hash peerHash = (Hash)iter.next(); + List peers = DataHelper.sortStructures(_peers); + for (Iterator iter = peers.iterator(); iter.hasNext();) { + Hash peerHash = (Hash) iter.next(); peerHash.writeBytes(out); } DataHelper.writeProperties(out, _options); } catch (IOException ioe) { throw new DataFormatException("IO Error getting bytes", ioe); - } - byte data[] = out.toByteArray(); - long after = Clock.getInstance().now(); - _log.debug("getBytes() took " + (after-before) + "ms"); - _byteified = data; + } + byte data[] = out.toByteArray(); + long after = Clock.getInstance().now(); + _log.debug("getBytes() took " + (after - before) + "ms"); + _byteified = data; return data; } - + /** * Determine whether this router info is authorized with a valid signature * */ public synchronized boolean isValid() { - if (!_validated) - doValidate(); + if (!_validated) doValidate(); return _isValid; } - + /** * Get the routing key for the structure using the current modifier in the RoutingKeyGenerator. * This only calculates a new one when necessary though (if the generator's key modifier changes) * */ - public synchronized Hash getRoutingKey() { - RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance(); - if ( (gen.getModData() == null) || (_routingKeyGenMod == null) || (!DataHelper.eq(gen.getModData(), _routingKeyGenMod)) ) { - setRoutingKey(gen.getRoutingKey(getIdentity().getHash())); - _routingKeyGenMod = gen.getModData(); - } - return _currentRoutingKey; + public synchronized Hash getRoutingKey() { + RoutingKeyGenerator gen = RoutingKeyGenerator.getInstance(); + if ((gen.getModData() == null) || (_routingKeyGenMod == null) + || (!DataHelper.eq(gen.getModData(), _routingKeyGenMod))) { + setRoutingKey(gen.getRoutingKey(getIdentity().getHash())); + _routingKeyGenMod = gen.getModData(); + } + return _currentRoutingKey; } - public void setRoutingKey(Hash key) { _currentRoutingKey = key; } - + + public void setRoutingKey(Hash key) { + _currentRoutingKey = key; + } + public boolean validateRoutingKey() { - Hash identKey = getIdentity().getHash(); - Hash rk = RoutingKeyGenerator.getInstance().getRoutingKey(identKey); - if (rk.equals(getRoutingKey())) - return true; - else - return false; + Hash identKey = getIdentity().getHash(); + Hash rk = RoutingKeyGenerator.getInstance().getRoutingKey(identKey); + if (rk.equals(getRoutingKey())) + return true; + else + return false; } - - + /** * Determine whether the router was published recently (within the given age milliseconds). * The age should be large enough to take into consideration any clock fudge factor, so @@ -285,56 +306,57 @@ public class RouterInfo extends DataStructureImpl { * @return true if it was published recently, false otherwise */ public boolean isCurrent(long maxAgeMs) { - long earliestExpire = Clock.getInstance().now() - maxAgeMs; - if (getPublished() < earliestExpire) { - return false; - } else { - return true; - } + long earliestExpire = Clock.getInstance().now() - maxAgeMs; + if (getPublished() < earliestExpire) { + return false; + } else { + return true; + } } - + /** * Actually validate the signature */ private synchronized void doValidate() { _validated = true; - if (getSignature() == null) { - _log.error("Signature is null"); - _isValid = false; - return; - } - byte data[] = null; - try { - data = getBytes(); - } catch (DataFormatException dfe) { - _log.error("Error validating", dfe); - _isValid = false; - return; - } - if (data == null) { - _log.error("Data could not be loaded"); - _isValid = false; - return; - } - _isValid = DSAEngine.getInstance().verifySignature(_signature, data, _identity.getSigningPublicKey()); - if (!_isValid) { - _log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64() + "] w/ signing key: " + _identity.getSigningPublicKey(), new Exception("Signature failed")); - _log.debug("Failed data: \n" + Base64.encode(data)); - _log.debug("Signature: " + getSignature()); - } + if (getSignature() == null) { + _log.error("Signature is null"); + _isValid = false; + return; + } + byte data[] = null; + try { + data = getBytes(); + } catch (DataFormatException dfe) { + _log.error("Error validating", dfe); + _isValid = false; + return; + } + if (data == null) { + _log.error("Data could not be loaded"); + _isValid = false; + return; + } + _isValid = DSAEngine.getInstance().verifySignature(_signature, data, _identity.getSigningPublicKey()); + if (!_isValid) { + _log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64() + + "] w/ signing key: " + _identity.getSigningPublicKey(), new Exception("Signature failed")); + _log.debug("Failed data: \n" + Base64.encode(data)); + _log.debug("Signature: " + getSignature()); + } } - + public synchronized void readBytes(InputStream in) throws DataFormatException, IOException { _identity = new RouterIdentity(); _identity.readBytes(in); _published = DataHelper.readDate(in).getTime(); - int numAddresses = (int)DataHelper.readLong(in, 1); + int numAddresses = (int) DataHelper.readLong(in, 1); for (int i = 0; i < numAddresses; i++) { RouterAddress address = new RouterAddress(); address.readBytes(in); _addresses.add(address); } - int numPeers = (int)DataHelper.readLong(in, 1); + int numPeers = (int) DataHelper.readLong(in, 1); for (int i = 0; i < numPeers; i++) { Hash peerIdentityHash = new Hash(); peerIdentityHash.readBytes(in); @@ -343,66 +365,56 @@ public class RouterInfo extends DataStructureImpl { _options = DataHelper.readProperties(in); _signature = new Signature(); _signature.readBytes(in); - - resetCache(); - - //_log.debug("Read routerInfo: " + toString()); + + resetCache(); + + //_log.debug("Read routerInfo: " + toString()); } - + public synchronized void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_identity == null) - throw new DataFormatException("Missing identity"); - if (_published <= 0) - throw new DataFormatException("Invalid published date: " + _published); - if (_signature == null) - throw new DataFormatException("Signature is null"); - //if (!isValid()) - // throw new DataFormatException("Data is not valid"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(512); + if (_identity == null) throw new DataFormatException("Missing identity"); + if (_published <= 0) throw new DataFormatException("Invalid published date: " + _published); + if (_signature == null) throw new DataFormatException("Signature is null"); + //if (!isValid()) + // throw new DataFormatException("Data is not valid"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(512); _identity.writeBytes(baos); DataHelper.writeDate(baos, new Date(_published)); DataHelper.writeLong(baos, 1, _addresses.size()); - for (Iterator iter = _addresses.iterator(); iter.hasNext(); ) { - RouterAddress addr = (RouterAddress)iter.next(); + for (Iterator iter = _addresses.iterator(); iter.hasNext();) { + RouterAddress addr = (RouterAddress) iter.next(); addr.writeBytes(baos); } DataHelper.writeLong(baos, 1, _peers.size()); - for (Iterator iter = _peers.iterator(); iter.hasNext(); ) { - Hash peerHash = (Hash)iter.next(); + for (Iterator iter = _peers.iterator(); iter.hasNext();) { + Hash peerHash = (Hash) iter.next(); peerHash.writeBytes(baos); } DataHelper.writeProperties(baos, _options); _signature.writeBytes(baos); - - byte data[] = baos.toByteArray(); - //_log.debug("Writing routerInfo [len=" + data.length + "]: " + toString()); - out.write(data); + + byte data[] = baos.toByteArray(); + //_log.debug("Writing routerInfo [len=" + data.length + "]: " + toString()); + out.write(data); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof RouterInfo) ) - return false; - RouterInfo info = (RouterInfo)object; - return DataHelper.eq(getAddresses(), info.getAddresses()) && - DataHelper.eq(getIdentity(), info.getIdentity()) && - DataHelper.eq(getOptions(), info.getOptions()) && - DataHelper.eq(getPeers(), info.getPeers()) && - DataHelper.eq(getSignature(), info.getSignature()) && - DataHelper.eq(getPublished(), info.getPublished()); + if ((object == null) || !(object instanceof RouterInfo)) return false; + RouterInfo info = (RouterInfo) object; + return DataHelper.eq(getAddresses(), info.getAddresses()) && DataHelper.eq(getIdentity(), info.getIdentity()) + && DataHelper.eq(getOptions(), info.getOptions()) && DataHelper.eq(getPeers(), info.getPeers()) + && DataHelper.eq(getSignature(), info.getSignature()) + && DataHelper.eq(getPublished(), info.getPublished()); } - + public int hashCode() { - return DataHelper.hashCode(getAddresses()) + - DataHelper.hashCode(getIdentity()) + - DataHelper.hashCode(getOptions()) + - DataHelper.hashCode(getPeers()) + - DataHelper.hashCode(getSignature()) + - (int)getPublished(); + return DataHelper.hashCode(getAddresses()) + DataHelper.hashCode(getIdentity()) + + DataHelper.hashCode(getOptions()) + DataHelper.hashCode(getPeers()) + + DataHelper.hashCode(getSignature()) + (int) getPublished(); } - - public String toString() { - if (_stringified != null) - return _stringified; + + public String toString() { + if (_stringified != null) return _stringified; StringBuffer buf = new StringBuffer(128); buf.append("[RouterInfo: "); buf.append("\n\tIdentity: ").append(getIdentity()); @@ -410,23 +422,23 @@ public class RouterInfo extends DataStructureImpl { buf.append("\n\tPublished on: ").append(new Date(getPublished())); buf.append("\n\tAddresses: #: ").append(getAddresses().size()); for (Iterator iter = getAddresses().iterator(); iter.hasNext();) { - RouterAddress addr = (RouterAddress)iter.next(); + RouterAddress addr = (RouterAddress) iter.next(); buf.append("\n\t\tAddress: ").append(addr); } buf.append("\n\tPeers: #: ").append(getPeers().size()); for (Iterator iter = getPeers().iterator(); iter.hasNext();) { - Hash hash = (Hash)iter.next(); + Hash hash = (Hash) iter.next(); buf.append("\n\t\tPeer hash: ").append(hash); } - Properties options = getOptions(); + Properties options = getOptions(); buf.append("\n\tOptions: #: ").append(options.size()); for (Iterator iter = options.keySet().iterator(); iter.hasNext();) { - String key = (String)iter.next(); + String key = (String) iter.next(); String val = options.getProperty(key); buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]"); } buf.append("]"); - _stringified = buf.toString(); - return _stringified; + _stringified = buf.toString(); + return _stringified; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/RoutingKeyGenerator.java b/core/java/src/net/i2p/data/RoutingKeyGenerator.java index c4ed8e457495ba4f9c49d786494f503e5120ff68..5b549e2b8b5393095fb6ad463d03c66ee81f4729 100644 --- a/core/java/src/net/i2p/data/RoutingKeyGenerator.java +++ b/core/java/src/net/i2p/data/RoutingKeyGenerator.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,17 +9,16 @@ package net.i2p.data; * */ -import net.i2p.crypto.SHA256Generator; - -import net.i2p.util.Log; -import net.i2p.util.RandomSource; -import net.i2p.util.Clock; - +import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; -import java.util.Date; -import java.text.SimpleDateFormat; + +import net.i2p.crypto.SHA256Generator; +import net.i2p.util.Clock; +import net.i2p.util.Log; +import net.i2p.util.RandomSource; /** * Component to manage the munging of hashes into routing keys - given a hash, @@ -41,41 +41,47 @@ import java.text.SimpleDateFormat; */ public class RoutingKeyGenerator { private final static RoutingKeyGenerator _instance = new RoutingKeyGenerator(); - public static RoutingKeyGenerator getInstance() { return _instance; } + + public static RoutingKeyGenerator getInstance() { + return _instance; + } private final static Log _log = new Log(RoutingKeyGenerator.class); private byte _currentModData[]; - + private final static Calendar _cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); private final static SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd"); - - public byte[] getModData() { return _currentModData; } + + public byte[] getModData() { + return _currentModData; + } + public void setModData(byte modData[]) { - _currentModData = modData; + _currentModData = modData; } - + /** * Update the current modifier data with some bytes derived from the current * date (yyyyMMdd in GMT) * */ public void generateDateBasedModData() { - Date today = null; - synchronized (_cal) { - _cal.setTime(new Date(Clock.getInstance().now())); - _cal.set(Calendar.HOUR_OF_DAY, 0); - _cal.set(Calendar.MINUTE, 0); - _cal.set(Calendar.SECOND, 0); - _cal.set(Calendar.MILLISECOND, 0); - today = _cal.getTime(); - } - byte mod[] = null; - synchronized (_fmt) { - mod = _fmt.format(today).getBytes(); - } - _log.info("Routing modifier generated: " + new String(mod)); - setModData(mod); + Date today = null; + synchronized (_cal) { + _cal.setTime(new Date(Clock.getInstance().now())); + _cal.set(Calendar.HOUR_OF_DAY, 0); + _cal.set(Calendar.MINUTE, 0); + _cal.set(Calendar.SECOND, 0); + _cal.set(Calendar.MILLISECOND, 0); + today = _cal.getTime(); + } + byte mod[] = null; + synchronized (_fmt) { + mod = _fmt.format(today).getBytes(); + } + _log.info("Routing modifier generated: " + new String(mod)); + setModData(mod); } - + /** * Generate a modified (yet consistent) hash from the origKey by generating the * SHA256 of the targetKey with the current modData appended to it, *then* @@ -86,27 +92,29 @@ public class RoutingKeyGenerator { * @throws IllegalArgumentException if origKey is null */ public Hash getRoutingKey(Hash origKey) { - if (origKey == null) - throw new IllegalArgumentException("Original key is null"); - if (_currentModData == null) generateDateBasedModData(); - byte modVal[] = new byte[Hash.HASH_LENGTH+_currentModData.length]; - System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH); - System.arraycopy(_currentModData, 0, modVal, Hash.HASH_LENGTH, _currentModData.length); - return SHA256Generator.getInstance().calculateHash(modVal); + if (origKey == null) throw new IllegalArgumentException("Original key is null"); + if (_currentModData == null) generateDateBasedModData(); + byte modVal[] = new byte[Hash.HASH_LENGTH + _currentModData.length]; + System.arraycopy(origKey.getData(), 0, modVal, 0, Hash.HASH_LENGTH); + System.arraycopy(_currentModData, 0, modVal, Hash.HASH_LENGTH, _currentModData.length); + return SHA256Generator.getInstance().calculateHash(modVal); } - + public static void main(String args[]) { - Hash k1 = new Hash(); - byte k1d[] = new byte[Hash.HASH_LENGTH]; - RandomSource.getInstance().nextBytes(k1d); - k1.setData(k1d); + Hash k1 = new Hash(); + byte k1d[] = new byte[Hash.HASH_LENGTH]; + RandomSource.getInstance().nextBytes(k1d); + k1.setData(k1d); - for (int i = 0; i < 10; i++) { - System.out.println("K1: " + k1); - Hash k1m = RoutingKeyGenerator.getInstance().getRoutingKey(k1); - System.out.println("MOD: " + new String(RoutingKeyGenerator.getInstance().getModData())); - System.out.println("K1M: " + k1m); - } - try { Thread.sleep(2000); } catch (Throwable t) {} + for (int i = 0; i < 10; i++) { + System.out.println("K1: " + k1); + Hash k1m = RoutingKeyGenerator.getInstance().getRoutingKey(k1); + System.out.println("MOD: " + new String(RoutingKeyGenerator.getInstance().getModData())); + System.out.println("K1M: " + k1m); + } + try { + Thread.sleep(2000); + } catch (Throwable t) { + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/SessionKey.java b/core/java/src/net/i2p/data/SessionKey.java index 3928b5661f2ce773a388eef6f22048e7401b02f0..c8e6ca56dd51e11ddd3548706a62d40420dd7c12 100644 --- a/core/java/src/net/i2p/data/SessionKey.java +++ b/core/java/src/net/i2p/data/SessionKey.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -23,40 +24,43 @@ import net.i2p.util.Log; public class SessionKey extends DataStructureImpl { private final static Log _log = new Log(SessionKey.class); private byte[] _data; - + public final static int KEYSIZE_BYTES = 32; - - public SessionKey() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public SessionKey() { + setData(null); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[KEYSIZE_BYTES]; int read = read(in, _data); - if (read != KEYSIZE_BYTES) - throw new DataFormatException("Not enough bytes to read the session key"); + if (read != KEYSIZE_BYTES) throw new DataFormatException("Not enough bytes to read the session key"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the session key to write out"); - if (_data.length != KEYSIZE_BYTES) - throw new DataFormatException("Invalid size of data in the private key"); + if (_data == null) throw new DataFormatException("No data in the session key to write out"); + if (_data.length != KEYSIZE_BYTES) throw new DataFormatException("Invalid size of data in the private key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof SessionKey)) - return false; - return DataHelper.eq(_data, ((SessionKey)obj)._data); + if ((obj == null) || !(obj instanceof SessionKey)) return false; + return DataHelper.eq(_data, ((SessionKey) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[SessionKey: "); if (_data == null) { @@ -64,12 +68,11 @@ public class SessionKey extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/SessionTag.java b/core/java/src/net/i2p/data/SessionTag.java index 3e61c8afab5dd21a2f5527fcbea9e83f74a9728f..49f93d5bcd18d2340b9aae56953df4cf7dde34de 100644 --- a/core/java/src/net/i2p/data/SessionTag.java +++ b/core/java/src/net/i2p/data/SessionTag.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -12,23 +13,29 @@ import net.i2p.util.RandomSource; public class SessionTag extends ByteArray { public final static int BYTE_LENGTH = 32; - public SessionTag() { super(); } + + public SessionTag() { + super(); + } + public SessionTag(boolean create) { - super(); - if (create) { - byte buf[] = new byte[BYTE_LENGTH]; - RandomSource.getInstance().nextBytes(buf); - setData(buf); - } + super(); + if (create) { + byte buf[] = new byte[BYTE_LENGTH]; + RandomSource.getInstance().nextBytes(buf); + setData(buf); + } } + public SessionTag(byte val[]) { - super(); - setData(val); + super(); + setData(val); } - + public void setData(byte val[]) throws IllegalArgumentException { - if (val == null) super.setData(null); - if (val.length != BYTE_LENGTH) throw new IllegalArgumentException("SessionTags must be " + BYTE_LENGTH + " bytes"); - super.setData(val); + if (val == null) super.setData(null); + if (val.length != BYTE_LENGTH) + throw new IllegalArgumentException("SessionTags must be " + BYTE_LENGTH + " bytes"); + super.setData(val); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/Signature.java b/core/java/src/net/i2p/data/Signature.java index 1a8aeee7bdb9899b436b7b7c011a27c4dd22efa6..b389b2d59f4dfde213ddf7562e2b4e8730ceb396 100644 --- a/core/java/src/net/i2p/data/Signature.java +++ b/core/java/src/net/i2p/data/Signature.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -24,45 +25,48 @@ import net.i2p.util.Log; public class Signature extends DataStructureImpl { private final static Log _log = new Log(Signature.class); private byte[] _data; - + public final static int SIGNATURE_BYTES = 40; public final static byte[] FAKE_SIGNATURE = new byte[SIGNATURE_BYTES]; static { - for (int i = 0; i < SIGNATURE_BYTES; i++) - FAKE_SIGNATURE[i] = 0x00; + for (int i = 0; i < SIGNATURE_BYTES; i++) + FAKE_SIGNATURE[i] = 0x00; + } + + public Signature() { + setData(null); + } + + public byte[] getData() { + return _data; } - - public Signature() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[SIGNATURE_BYTES]; int read = read(in, _data); - if (read != SIGNATURE_BYTES) - throw new DataFormatException("Not enough bytes to read the signature"); + if (read != SIGNATURE_BYTES) throw new DataFormatException("Not enough bytes to read the signature"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the signature to write out"); - if (_data.length != SIGNATURE_BYTES) - throw new DataFormatException("Invalid size of data in the private key"); + if (_data == null) throw new DataFormatException("No data in the signature to write out"); + if (_data.length != SIGNATURE_BYTES) throw new DataFormatException("Invalid size of data in the private key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof Signature)) - return false; - return DataHelper.eq(_data, ((Signature)obj)._data); + if ((obj == null) || !(obj instanceof Signature)) return false; + return DataHelper.eq(_data, ((Signature) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[Signature: "); if (_data == null) { @@ -70,12 +74,11 @@ public class Signature extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/SigningPrivateKey.java b/core/java/src/net/i2p/data/SigningPrivateKey.java index b0ab6326f370a4c80b1e03d3c204f49342be8812..fe0a2a0f934ce895e684217e3519d8dcde29cc9a 100644 --- a/core/java/src/net/i2p/data/SigningPrivateKey.java +++ b/core/java/src/net/i2p/data/SigningPrivateKey.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -25,40 +26,43 @@ import net.i2p.util.Log; public class SigningPrivateKey extends DataStructureImpl { private final static Log _log = new Log(SigningPrivateKey.class); private byte[] _data; - + public final static int KEYSIZE_BYTES = 20; - - public SigningPrivateKey() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public SigningPrivateKey() { + setData(null); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[KEYSIZE_BYTES]; int read = read(in, _data); - if (read != KEYSIZE_BYTES) - throw new DataFormatException("Not enough bytes to read the private key"); + if (read != KEYSIZE_BYTES) throw new DataFormatException("Not enough bytes to read the private key"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the private key to write out"); - if (_data.length != KEYSIZE_BYTES) - throw new DataFormatException("Invalid size of data in the private key"); + if (_data == null) throw new DataFormatException("No data in the private key to write out"); + if (_data.length != KEYSIZE_BYTES) throw new DataFormatException("Invalid size of data in the private key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof SigningPrivateKey)) - return false; - return DataHelper.eq(_data, ((SigningPrivateKey)obj)._data); + if ((obj == null) || !(obj instanceof SigningPrivateKey)) return false; + return DataHelper.eq(_data, ((SigningPrivateKey) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[SigningPrivateKey: "); if (_data == null) { @@ -66,12 +70,11 @@ public class SigningPrivateKey extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/SigningPublicKey.java b/core/java/src/net/i2p/data/SigningPublicKey.java index 59f182097c89d4b123b87dd51dee719fc5ce9fe2..d320589e3db329249906eff00b5474088b17770e 100644 --- a/core/java/src/net/i2p/data/SigningPublicKey.java +++ b/core/java/src/net/i2p/data/SigningPublicKey.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; @@ -25,39 +26,43 @@ import net.i2p.util.Log; public class SigningPublicKey extends DataStructureImpl { private final static Log _log = new Log(SigningPublicKey.class); private byte[] _data; - + public final static int KEYSIZE_BYTES = 128; - - public SigningPublicKey() { setData(null); } - - public byte[] getData() { return _data; } - public void setData(byte[] data) { _data = data; } - + + public SigningPublicKey() { + setData(null); + } + + public byte[] getData() { + return _data; + } + + public void setData(byte[] data) { + _data = data; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _data = new byte[KEYSIZE_BYTES]; int read = read(in, _data); - if (read != KEYSIZE_BYTES) - throw new DataFormatException("Not enough bytes to read the public key"); + if (read != KEYSIZE_BYTES) throw new DataFormatException("Not enough bytes to read the public key"); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if (_data == null) - throw new DataFormatException("No data in the public key to write out"); - if (_data.length != KEYSIZE_BYTES) - throw new DataFormatException("Invalid size of data in the public key"); + if (_data == null) throw new DataFormatException("No data in the public key to write out"); + if (_data.length != KEYSIZE_BYTES) throw new DataFormatException("Invalid size of data in the public key"); out.write(_data); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof SigningPublicKey)) - return false; - return DataHelper.eq(_data, ((SigningPublicKey)obj)._data); + if ((obj == null) || !(obj instanceof SigningPublicKey)) return false; + return DataHelper.eq(_data, ((SigningPublicKey) obj)._data); } - + public int hashCode() { - return DataHelper.hashCode(_data); + return DataHelper.hashCode(_data); } - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(64); buf.append("[SigningPublicKey: "); if (_data == null) { @@ -65,12 +70,11 @@ public class SigningPublicKey extends DataStructureImpl { } else { buf.append("size: ").append(_data.length); int len = 32; - if (len > _data.length) - len = _data.length; + if (len > _data.length) len = _data.length; buf.append(" first ").append(len).append(" bytes: "); buf.append(DataHelper.toString(_data, len)); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/TunnelId.java b/core/java/src/net/i2p/data/TunnelId.java index 745eb948973c4187232cdae45fa62d4fdef7f725..c8c8f558b7e8bc062f23140c3cbcb614e52c31ed 100644 --- a/core/java/src/net/i2p/data/TunnelId.java +++ b/core/java/src/net/i2p/data/TunnelId.java @@ -8,9 +8,9 @@ package net.i2p.data; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; import net.i2p.util.Log; diff --git a/core/java/src/net/i2p/data/UnsignedInteger.java b/core/java/src/net/i2p/data/UnsignedInteger.java index ab75e2055a559676f27e829b58294bf6c6ec3f76..6d32739e26ef5814767b5b44b5f4e202f57b8d79 100644 --- a/core/java/src/net/i2p/data/UnsignedInteger.java +++ b/core/java/src/net/i2p/data/UnsignedInteger.java @@ -1,4 +1,5 @@ package net.i2p.data; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,10 +9,10 @@ package net.i2p.data; * */ -import net.i2p.util.Log; - import java.math.BigInteger; +import net.i2p.util.Log; + /** * Manage an arbitrarily large unsigned integer, using the first bit and first byte * as the most significant one. Also allows the exporting to byte arrays with whatever @@ -26,7 +27,7 @@ public class UnsignedInteger { private final static Log _log = new Log(UnsignedInteger.class); private byte[] _data; private long _value; - + /** * Construct the integer from the bytes given, making the value accessible * immediately. @@ -46,11 +47,11 @@ public class UnsignedInteger { } _data = new byte[data.length - start]; for (int i = 0; i < _data.length; i++) - _data[i] = data[i+start]; + _data[i] = data[i + start]; // done stripping excess bytes, now calc _value = calculateValue(_data); } - + /** * Construct the integer with the java number given, making the bytes * available immediately. @@ -61,114 +62,132 @@ public class UnsignedInteger { _value = value; _data = calculateBytes(value); } - + /** * Calculate the value of the array of bytes, treating it as an unsigned integer * with the most significant bit and byte first * */ private static long calculateValue(byte[] data) { - if (data == null) { - _log.error("Null data to be calculating for", new Exception("Argh")); - return 0; - } else if (data.length == 0) { - return 0; - } + if (data == null) { + _log.error("Null data to be calculating for", new Exception("Argh")); + return 0; + } else if (data.length == 0) { return 0; } BigInteger bi = new BigInteger(1, data); return bi.longValue(); } - + /** * hexify the byte array * */ private final static String toString(byte[] val) { - return "0x" + DataHelper.toString(val, val.length); + return "0x" + DataHelper.toString(val, val.length); } - + /** * Calculate the bytes as an unsigned integer with the most significant bit and byte in the first position */ private static byte[] calculateBytes(long value) { - BigInteger bi = new BigInteger(""+value); - byte buf[] = bi.toByteArray(); - if ( (buf == null) || (buf.length <= 0) ) - throw new IllegalArgumentException("Value [" + value + "] cannot be transformed"); - int trim = 0; - while ( (trim < buf.length) && (buf[trim] == 0x00) ) - trim++; - byte rv[] = new byte[buf.length - trim]; - System.arraycopy(buf, trim, rv, 0, rv.length); - return rv; - } - + BigInteger bi = new BigInteger("" + value); + byte buf[] = bi.toByteArray(); + if ((buf == null) || (buf.length <= 0)) + throw new IllegalArgumentException("Value [" + value + "] cannot be transformed"); + int trim = 0; + while ((trim < buf.length) && (buf[trim] == 0x00)) + trim++; + byte rv[] = new byte[buf.length - trim]; + System.arraycopy(buf, trim, rv, 0, rv.length); + return rv; + } + /** * Get the unsigned bytes, most significant bit and bytes first, without any padding * */ - public byte[] getBytes() { return _data; } + public byte[] getBytes() { + return _data; + } + /** * Get the unsigned bytes, most significant bit and bytes first, zero padded to the * specified number of bytes * * @throws IllegalArgumentException if numBytes < necessary number of bytes */ - public byte[] getBytes(int numBytes) throws IllegalArgumentException { - if ( (_data == null) || (numBytes < _data.length) ) - throw new IllegalArgumentException("Value (" +_value+") is greater than the requested number of bytes ("+numBytes+")"); - + public byte[] getBytes(int numBytes) throws IllegalArgumentException { + if ((_data == null) || (numBytes < _data.length)) + throw new IllegalArgumentException("Value (" + _value + ") is greater than the requested number of bytes (" + + numBytes + ")"); + byte[] data = new byte[numBytes]; - System.arraycopy(_data, 0, data, numBytes - _data.length, _data.length); - return data; - } - - public BigInteger getBigInteger() { return new BigInteger(1, _data); } - public long getLong() { return _value; } - public int getInt() { return (int)_value; } - public short getShort() { return (short)_value; } - + System.arraycopy(_data, 0, data, numBytes - _data.length, _data.length); + return data; + } + + public BigInteger getBigInteger() { + return new BigInteger(1, _data); + } + + public long getLong() { + return _value; + } + + public int getInt() { + return (int) _value; + } + + public short getShort() { + return (short) _value; + } + public boolean equals(Object obj) { - if ( (obj != null) && (obj instanceof UnsignedInteger) ) { - return DataHelper.eq(_data, ((UnsignedInteger)obj)._data) && - DataHelper.eq(_value, ((UnsignedInteger)obj)._value); + if ((obj != null) && (obj instanceof UnsignedInteger)) { + return DataHelper.eq(_data, ((UnsignedInteger) obj)._data) + && DataHelper.eq(_value, ((UnsignedInteger) obj)._value); } else { return false; } } - - public int hashCode() { - return DataHelper.hashCode(_data) + (int)_value; + + public int hashCode() { + return DataHelper.hashCode(_data) + (int) _value; } - + public String toString() { return "UnsignedInteger: " + getLong() + "/" + toString(getBytes()); } - + public static void main(String args[]) { _log.debug("Testing 1024"); testNum(1024L); _log.debug("Testing 1025"); testNum(1025L); _log.debug("Testing 2Gb-1"); - testNum(1024*1024*1024*2L-1L); + testNum(1024 * 1024 * 1024 * 2L - 1L); _log.debug("Testing 4Gb-1"); - testNum(1024*1024*1024*4L-1L); + testNum(1024 * 1024 * 1024 * 4L - 1L); _log.debug("Testing 4Gb"); - testNum(1024*1024*1024*4L); + testNum(1024 * 1024 * 1024 * 4L); _log.debug("Testing 4Gb+1"); - testNum(1024*1024*1024*4L+1L); + testNum(1024 * 1024 * 1024 * 4L + 1L); _log.debug("Testing MaxLong"); testNum(Long.MAX_VALUE); - try { Thread.sleep(1000); } catch (Throwable t) {} + try { + Thread.sleep(1000); + } catch (Throwable t) { + } } - + private static void testNum(long num) { UnsignedInteger i = new UnsignedInteger(num); - _log.debug(num + " turned into an unsigned integer: " + i + " (" + i.getLong() + "/" + toString(i.getBytes()) + ")"); + _log.debug(num + " turned into an unsigned integer: " + i + " (" + i.getLong() + "/" + toString(i.getBytes()) + + ")"); _log.debug(num + " turned into an BigInteger: " + i.getBigInteger()); byte[] val = i.getBytes(); UnsignedInteger val2 = new UnsignedInteger(val); - _log.debug(num + " turned into a byte array and back again: " + val2 + " (" + val2.getLong() + "/" + toString(val2.getBytes()) + ")"); + _log.debug(num + " turned into a byte array and back again: " + val2 + " (" + val2.getLong() + "/" + + toString(val2.getBytes()) + ")"); _log.debug(num + " As an 8 byte array: " + toString(val2.getBytes(8))); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/AbuseReason.java b/core/java/src/net/i2p/data/i2cp/AbuseReason.java index 82966fd60ea19759193136edce6d54759b4d0a69..019e916b1b7c99deecb0a59389858c122bb84549 100644 --- a/core/java/src/net/i2p/data/i2cp/AbuseReason.java +++ b/core/java/src/net/i2p/data/i2cp/AbuseReason.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,15 +9,14 @@ package net.i2p.data.i2cp; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; +import net.i2p.util.Log; /** * Defines the structure for why abuse was reported either by the client to @@ -27,29 +27,37 @@ import net.i2p.data.DataFormatException; public class AbuseReason extends DataStructureImpl { private final static Log _log = new Log(AbuseReason.class); private String _reason; - - public AbuseReason() { setReason(null); } - - public String getReason() { return _reason; } - public void setReason(String reason) { _reason = reason; } - + + public AbuseReason() { + setReason(null); + } + + public String getReason() { + return _reason; + } + + public void setReason(String reason) { + _reason = reason; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { _reason = DataHelper.readString(in); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { if (_reason == null) throw new DataFormatException("Invalid abuse reason"); DataHelper.writeString(out, _reason); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof AbuseReason) ) - return false; - return DataHelper.eq(getReason(), ((AbuseReason)object).getReason()); + if ((object == null) || !(object instanceof AbuseReason)) return false; + return DataHelper.eq(getReason(), ((AbuseReason) object).getReason()); } - - public int hashCode() { return DataHelper.hashCode(getReason()); } - + + public int hashCode() { + return DataHelper.hashCode(getReason()); + } + public String toString() { return "[AbuseReason: " + getReason() + "]"; } diff --git a/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java b/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java index 8d9220fac3658912e9f7c5217c3bab22f3eee4e6..218ade0706b17bb2a0a0df0e6e237d51c8b6a736 100644 --- a/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java +++ b/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,15 +9,14 @@ package net.i2p.data.i2cp; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; +import net.i2p.util.Log; /** * Provides a severity level (larger numbers are more severe) in association with @@ -28,29 +28,37 @@ import net.i2p.data.DataFormatException; public class AbuseSeverity extends DataStructureImpl { private final static Log _log = new Log(AbuseSeverity.class); private int _severityId; - - public AbuseSeverity() { setSeverity(-1); } - - public int getSeverity() { return _severityId; } - public void setSeverity(int id) { _severityId = id; } - + + public AbuseSeverity() { + setSeverity(-1); + } + + public int getSeverity() { + return _severityId; + } + + public void setSeverity(int id) { + _severityId = id; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - _severityId = (int)DataHelper.readLong(in, 1); + _severityId = (int) DataHelper.readLong(in, 1); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { if (_severityId < 0) throw new DataFormatException("Invalid abuse severity: " + _severityId); DataHelper.writeLong(out, 1, _severityId); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof AbuseSeverity) ) - return false; - return DataHelper.eq(getSeverity(), ((AbuseSeverity)object).getSeverity()); + if ((object == null) || !(object instanceof AbuseSeverity)) return false; + return DataHelper.eq(getSeverity(), ((AbuseSeverity) object).getSeverity()); } - - public int hashCode() { return getSeverity(); } - + + public int hashCode() { + return getSeverity(); + } + public String toString() { return "[AbuseSeverity: " + getSeverity() + "]"; } diff --git a/core/java/src/net/i2p/data/i2cp/CreateLeaseSetMessage.java b/core/java/src/net/i2p/data/i2cp/CreateLeaseSetMessage.java index 569974a2c54bc928b4c90f854424c30d996377ab..9135f4ac01ea057ace5ea0c8625be475a824bf60 100644 --- a/core/java/src/net/i2p/data/i2cp/CreateLeaseSetMessage.java +++ b/core/java/src/net/i2p/data/i2cp/CreateLeaseSetMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -32,68 +33,93 @@ public class CreateLeaseSetMessage extends I2CPMessageImpl { private LeaseSet _leaseSet; private SigningPrivateKey _signingPrivateKey; private PrivateKey _privateKey; - - public CreateLeaseSetMessage() { + + public CreateLeaseSetMessage() { setSessionId(null); setLeaseSet(null); - setSigningPrivateKey(null); - setPrivateKey(null); + setSigningPrivateKey(null); + setPrivateKey(null); + } + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public SigningPrivateKey getSigningPrivateKey() { + return _signingPrivateKey; + } + + public void setSigningPrivateKey(SigningPrivateKey key) { + _signingPrivateKey = key; + } + + public PrivateKey getPrivateKey() { + return _privateKey; + } + + public void setPrivateKey(PrivateKey privateKey) { + _privateKey = privateKey; } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public SigningPrivateKey getSigningPrivateKey() { return _signingPrivateKey; } - public void setSigningPrivateKey(SigningPrivateKey key) { _signingPrivateKey = key; } - public PrivateKey getPrivateKey() { return _privateKey; } - public void setPrivateKey(PrivateKey privateKey) { _privateKey = privateKey; } - public LeaseSet getLeaseSet() { return _leaseSet; } - public void setLeaseSet(LeaseSet leaseSet) { _leaseSet = leaseSet; } - + + public LeaseSet getLeaseSet() { + return _leaseSet; + } + + public void setLeaseSet(LeaseSet leaseSet) { + _leaseSet = leaseSet; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { - try { - _sessionId = new SessionId(); - _sessionId.readBytes(in); - _signingPrivateKey = new SigningPrivateKey(); - _signingPrivateKey.readBytes(in); - _privateKey = new PrivateKey(); - _privateKey.readBytes(in); - _leaseSet = new LeaseSet(); - _leaseSet.readBytes(in); - } catch (DataFormatException dfe) { - throw new I2CPMessageException("Error reading the CreateLeaseSetMessage", dfe); - } + try { + _sessionId = new SessionId(); + _sessionId.readBytes(in); + _signingPrivateKey = new SigningPrivateKey(); + _signingPrivateKey.readBytes(in); + _privateKey = new PrivateKey(); + _privateKey.readBytes(in); + _leaseSet = new LeaseSet(); + _leaseSet.readBytes(in); + } catch (DataFormatException dfe) { + throw new I2CPMessageException("Error reading the CreateLeaseSetMessage", dfe); + } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_signingPrivateKey == null) || (_privateKey == null) || (_leaseSet == null) ) + if ((_sessionId == null) || (_signingPrivateKey == null) || (_privateKey == null) || (_leaseSet == null)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(512); try { _sessionId.writeBytes(os); - _signingPrivateKey.writeBytes(os); - _privateKey.writeBytes(os); - _leaseSet.writeBytes(os); + _signingPrivateKey.writeBytes(os); + _privateKey.writeBytes(os); + _leaseSet.writeBytes(os); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error writing out the message data", dfe); } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof CreateLeaseSetMessage) ) { - CreateLeaseSetMessage msg = (CreateLeaseSetMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getSigningPrivateKey(),msg.getSigningPrivateKey()) && - DataHelper.eq(getPrivateKey(), msg.getPrivateKey()) && - DataHelper.eq(getLeaseSet(),msg.getLeaseSet()); + if ((object != null) && (object instanceof CreateLeaseSetMessage)) { + CreateLeaseSetMessage msg = (CreateLeaseSetMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getSigningPrivateKey(), msg.getSigningPrivateKey()) + && DataHelper.eq(getPrivateKey(), msg.getPrivateKey()) + && DataHelper.eq(getLeaseSet(), msg.getLeaseSet()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[CreateLeaseSetMessage: "); buf.append("\n\tLeaseSet: ").append(getLeaseSet()); diff --git a/core/java/src/net/i2p/data/i2cp/CreateSessionMessage.java b/core/java/src/net/i2p/data/i2cp/CreateSessionMessage.java index 126eef6f9f841e39eb1fa8cb319e624600ac1995..fbe18f91c315a19a46cd7fc8cebd86f057bc3592 100644 --- a/core/java/src/net/i2p/data/i2cp/CreateSessionMessage.java +++ b/core/java/src/net/i2p/data/i2cp/CreateSessionMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -26,13 +27,23 @@ public class CreateSessionMessage extends I2CPMessageImpl { private final static Log _log = new Log(CreateSessionMessage.class); public final static int MESSAGE_TYPE = 1; private SessionConfig _sessionConfig; - - public CreateSessionMessage(SessionConfig config) { setSessionConfig(config); } - public CreateSessionMessage() { setSessionConfig(new SessionConfig()); } - - public SessionConfig getSessionConfig() { return _sessionConfig; } - public void setSessionConfig(SessionConfig config) { _sessionConfig = config; } - + + public CreateSessionMessage(SessionConfig config) { + setSessionConfig(config); + } + + public CreateSessionMessage() { + setSessionConfig(new SessionConfig()); + } + + public SessionConfig getSessionConfig() { + return _sessionConfig; + } + + public void setSessionConfig(SessionConfig config) { + _sessionConfig = config; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { SessionConfig config = new SessionConfig(); try { @@ -42,7 +53,7 @@ public class CreateSessionMessage extends I2CPMessageImpl { } setSessionConfig(config); } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { if (_sessionConfig == null) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); @@ -54,23 +65,25 @@ public class CreateSessionMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof CreateSessionMessage) ) { - CreateSessionMessage msg = (CreateSessionMessage)object; + if ((object != null) && (object instanceof CreateSessionMessage)) { + CreateSessionMessage msg = (CreateSessionMessage) object; return DataHelper.eq(getSessionConfig(), msg.getSessionConfig()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[CreateSessionMessage: "); buf.append("\n\tConfig: ").append(getSessionConfig()); buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/DestroySessionMessage.java b/core/java/src/net/i2p/data/i2cp/DestroySessionMessage.java index 1c27225d442c27feb3ce8f6a4f72cb2a0c389f1b..3aeb984f9f440dd8d54157ef200c209c15cd6bf5 100644 --- a/core/java/src/net/i2p/data/i2cp/DestroySessionMessage.java +++ b/core/java/src/net/i2p/data/i2cp/DestroySessionMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -26,14 +27,19 @@ public class DestroySessionMessage extends I2CPMessageImpl { private final static Log _log = new Log(DestroySessionMessage.class); public final static int MESSAGE_TYPE = 3; private SessionId _sessionId; - - public DestroySessionMessage() { + + public DestroySessionMessage() { setSessionId(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { SessionId id = new SessionId(); try { @@ -43,7 +49,7 @@ public class DestroySessionMessage extends I2CPMessageImpl { } setSessionId(id); } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { if (_sessionId == null) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); @@ -55,23 +61,25 @@ public class DestroySessionMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof DestroySessionMessage) ) { - DestroySessionMessage msg = (DestroySessionMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()); + if ((object != null) && (object instanceof DestroySessionMessage)) { + DestroySessionMessage msg = (DestroySessionMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[DestroySessionMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/DisconnectMessage.java b/core/java/src/net/i2p/data/i2cp/DisconnectMessage.java index 2d4ecb564bf0e98a61929a578404440498f61711..c4c294d604ec58e3fc8867db5c0dd2b6493829dd 100644 --- a/core/java/src/net/i2p/data/i2cp/DisconnectMessage.java +++ b/core/java/src/net/i2p/data/i2cp/DisconnectMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -26,14 +27,19 @@ public class DisconnectMessage extends I2CPMessageImpl { private final static Log _log = new Log(DisconnectMessage.class); public final static int MESSAGE_TYPE = 30; private String _reason; - - public DisconnectMessage() { + + public DisconnectMessage() { setReason(null); } - - public String getReason() { return _reason; } - public void setReason(String reason) { _reason = reason; } - + + public String getReason() { + return _reason; + } + + public void setReason(String reason) { + _reason = reason; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _reason = DataHelper.readString(in); @@ -41,7 +47,7 @@ public class DisconnectMessage extends I2CPMessageImpl { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(64); try { @@ -51,23 +57,25 @@ public class DisconnectMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof DisconnectMessage) ) { - DisconnectMessage msg = (DisconnectMessage)object; - return DataHelper.eq(getReason(),msg.getReason()); + if ((object != null) && (object instanceof DisconnectMessage)) { + DisconnectMessage msg = (DisconnectMessage) object; + return DataHelper.eq(getReason(), msg.getReason()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[DisconnectMessage: "); buf.append("\n\tReason: ").append(getReason()); buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/GetDateMessage.java b/core/java/src/net/i2p/data/i2cp/GetDateMessage.java index ecc73959a4d78da25b3cbc5ed41b0dd39bef1738..329de60ae4ddc41f11fd7a3785352333e86aac58 100644 --- a/core/java/src/net/i2p/data/i2cp/GetDateMessage.java +++ b/core/java/src/net/i2p/data/i2cp/GetDateMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -20,33 +21,35 @@ import net.i2p.util.Log; public class GetDateMessage extends I2CPMessageImpl { private final static Log _log = new Log(GetDateMessage.class); public final static int MESSAGE_TYPE = 32; - + public GetDateMessage() { - super(); + super(); } - + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { - // noop + // noop } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - byte rv[] = new byte[0]; - return rv; + byte rv[] = new byte[0]; + return rv; } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof GetDateMessage) ) { + if ((object != null) && (object instanceof GetDateMessage)) { return true; } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[GetDateMessage]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessage.java b/core/java/src/net/i2p/data/i2cp/I2CPMessage.java index 2ef4cd9e3b0f04f3238f00f4acf509f205def13e..412a3ffbc3a6ac9949ef14089eb387080c4f36b3 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessage.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -34,6 +35,7 @@ public interface I2CPMessage extends DataStructure { * @throws IOException if there is a problem reading from the stream */ public void readMessage(InputStream in, int size, int type) throws I2CPMessageException, IOException; + /** * Read the contents from the input stream into the current class's format. * The stream should be the message header and body as defined by the I2CP @@ -45,7 +47,7 @@ public interface I2CPMessage extends DataStructure { * @throws IOException if there is a problem reading from the stream */ public void readMessage(InputStream in) throws I2CPMessageException, IOException; - + /** * Write the current message to the output stream as a full message following * the specification from the I2CP definition. @@ -55,10 +57,10 @@ public interface I2CPMessage extends DataStructure { * @throws IOException if there is a problem writing to the stream */ public void writeMessage(OutputStream out) throws I2CPMessageException, IOException; - + /** * Return the unique identifier for this type of APIMessage, as specified in the * network specification document under #ClientAccessLayerMessages */ public int getType(); -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageException.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageException.java index 3132f170dd6853da4bb8b91a31d7252551e813da..b4902873136e3fc5dcd1971ff8677d6f136b3a87 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageException.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageException.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -18,11 +19,12 @@ import net.i2p.util.Log; */ public class I2CPMessageException extends I2PException { private final static Log _log = new Log(I2CPMessageException.class); - + public I2CPMessageException(String message, Throwable parent) { super(message, parent); } + public I2CPMessageException(String message) { super(message); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java index 77813fb38957916c55d4ea734f1f619bf7182100..608efebc370bb198591b00f72ae0c70e8108ee85 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,13 +9,12 @@ package net.i2p.data.i2cp; * */ -import java.io.InputStream; -import java.io.IOException; import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; -import net.i2p.data.DataHelper; import net.i2p.data.DataFormatException; - +import net.i2p.data.DataHelper; import net.i2p.util.Log; /** @@ -23,7 +23,7 @@ import net.i2p.util.Log; */ public class I2CPMessageHandler { private final static Log _log = new Log(I2CPMessageHandler.class); - + /** * Read an I2CPMessage from the stream and return the fully populated object. * @@ -33,9 +33,9 @@ public class I2CPMessageHandler { */ public static I2CPMessage readMessage(InputStream in) throws IOException, I2CPMessageException { try { - int length = (int)DataHelper.readLong(in, 4); + int length = (int) DataHelper.readLong(in, 4); if (length < 0) throw new I2CPMessageException("Invalid message length specified"); - int type = (int)DataHelper.readLong(in, 1); + int type = (int) DataHelper.readLong(in, 1); I2CPMessage msg = createMessage(in, length, type); msg.readMessage(in, length, type); return msg; @@ -43,46 +43,47 @@ public class I2CPMessageHandler { throw new I2CPMessageException("Error reading the message", dfe); } } - + /** * Yes, this is fairly ugly, but its the only place it ever happens. * */ - private static I2CPMessage createMessage(InputStream in, int length, int type) throws IOException, I2CPMessageException { + private static I2CPMessage createMessage(InputStream in, int length, int type) throws IOException, + I2CPMessageException { switch (type) { - case CreateLeaseSetMessage.MESSAGE_TYPE: - return new CreateLeaseSetMessage(); - case CreateSessionMessage.MESSAGE_TYPE: - return new CreateSessionMessage(); - case DestroySessionMessage.MESSAGE_TYPE: - return new DestroySessionMessage(); - case DisconnectMessage.MESSAGE_TYPE: - return new DisconnectMessage(); - case MessageStatusMessage.MESSAGE_TYPE: - return new MessageStatusMessage(); - case MessagePayloadMessage.MESSAGE_TYPE: - return new MessagePayloadMessage(); - case ReceiveMessageBeginMessage.MESSAGE_TYPE: - return new ReceiveMessageBeginMessage(); - case ReceiveMessageEndMessage.MESSAGE_TYPE: - return new ReceiveMessageEndMessage(); - case ReportAbuseMessage.MESSAGE_TYPE: - return new ReportAbuseMessage(); - case RequestLeaseSetMessage.MESSAGE_TYPE: - return new RequestLeaseSetMessage(); - case SendMessageMessage.MESSAGE_TYPE: - return new SendMessageMessage(); - case SessionStatusMessage.MESSAGE_TYPE: - return new SessionStatusMessage(); - case GetDateMessage.MESSAGE_TYPE: - return new GetDateMessage(); - case SetDateMessage.MESSAGE_TYPE: - return new SetDateMessage(); - default: - throw new I2CPMessageException("The type "+ type + " is an unknown I2CP message"); + case CreateLeaseSetMessage.MESSAGE_TYPE: + return new CreateLeaseSetMessage(); + case CreateSessionMessage.MESSAGE_TYPE: + return new CreateSessionMessage(); + case DestroySessionMessage.MESSAGE_TYPE: + return new DestroySessionMessage(); + case DisconnectMessage.MESSAGE_TYPE: + return new DisconnectMessage(); + case MessageStatusMessage.MESSAGE_TYPE: + return new MessageStatusMessage(); + case MessagePayloadMessage.MESSAGE_TYPE: + return new MessagePayloadMessage(); + case ReceiveMessageBeginMessage.MESSAGE_TYPE: + return new ReceiveMessageBeginMessage(); + case ReceiveMessageEndMessage.MESSAGE_TYPE: + return new ReceiveMessageEndMessage(); + case ReportAbuseMessage.MESSAGE_TYPE: + return new ReportAbuseMessage(); + case RequestLeaseSetMessage.MESSAGE_TYPE: + return new RequestLeaseSetMessage(); + case SendMessageMessage.MESSAGE_TYPE: + return new SendMessageMessage(); + case SessionStatusMessage.MESSAGE_TYPE: + return new SessionStatusMessage(); + case GetDateMessage.MESSAGE_TYPE: + return new GetDateMessage(); + case SetDateMessage.MESSAGE_TYPE: + return new SetDateMessage(); + default: + throw new I2CPMessageException("The type " + type + " is an unknown I2CP message"); } } - + public static void main(String args[]) { try { I2CPMessage msg = readMessage(new FileInputStream(args[0])); @@ -91,4 +92,4 @@ public class I2CPMessageHandler { e.printStackTrace(); } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java index dfcdffa28c4f72c196c85eaea0ec5eed6e7e3dd3..ca068c4cc7eac507143d2c1513937051360c6b4d 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -25,8 +26,10 @@ import net.i2p.util.Log; */ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPMessage { private final static Log _log = new Log(I2CPMessageImpl.class); - public I2CPMessageImpl() {} - + + public I2CPMessageImpl() { + } + /** * Validate the type and size of the message, and then read the message into the data structures. <p /> * @@ -34,51 +37,54 @@ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPM public void readMessage(InputStream in) throws I2CPMessageException, IOException { int length = 0; try { - length = (int)DataHelper.readLong(in, 4); + length = (int) DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error reading the length bytes", dfe); } if (length < 0) throw new I2CPMessageException("Invalid message length specified"); int type = -1; try { - type = (int)DataHelper.readLong(in, 1); + type = (int) DataHelper.readLong(in, 1); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error reading the type byte", dfe); } - readMessage(in, length, type); + readMessage(in, length, type); } - + /** * Read the body into the data structures * */ public void readMessage(InputStream in, int length, int type) throws I2CPMessageException, IOException { - if (type != getType()) throw new I2CPMessageException("Invalid message type (found: " + type + " supported: " + getType() + " class: " + getClass().getName()+ ")"); + if (type != getType()) + throw new I2CPMessageException("Invalid message type (found: " + type + " supported: " + getType() + + " class: " + getClass().getName() + ")"); if (length < 0) throw new IOException("Negative payload size"); - - byte buf[] = new byte[length]; - int read = DataHelper.read(in, buf); - if (read != length) - throw new IOException("Not able to read enough bytes [" + read + "] read, expected [ " + length + "]"); - ByteArrayInputStream bis = new ByteArrayInputStream(buf); - + byte buf[] = new byte[length]; + int read = DataHelper.read(in, buf); + if (read != length) + throw new IOException("Not able to read enough bytes [" + read + "] read, expected [ " + length + "]"); + + ByteArrayInputStream bis = new ByteArrayInputStream(buf); + doReadMessage(bis, length); } - + /** * Read in the payload part of the message (after the initial 4 byte size and 1 * byte type) * */ protected abstract void doReadMessage(InputStream buf, int size) throws I2CPMessageException, IOException; + /** * Write out the payload part of the message (not including the 4 byte size and * 1 byte type) * */ protected abstract byte[] doWriteMessage() throws I2CPMessageException, IOException; - + /** * Write out the full message to the stream, including the 4 byte size and 1 * byte type header. @@ -94,7 +100,7 @@ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPM } out.write(data); } - + public void readBytes(InputStream in) throws DataFormatException, IOException { try { readMessage(in); @@ -102,6 +108,7 @@ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPM throw new DataFormatException("Error reading the message", ime); } } + public void writeBytes(OutputStream out) throws DataFormatException, IOException { try { writeMessage(out); @@ -109,4 +116,4 @@ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPM throw new DataFormatException("Error writing the message", ime); } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java index d526b055a670ab5553a9f445bc5ac7e6b8e4ee2d..ea434fb8791f737fb852b3d7ca68f20160c16ca9 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -29,40 +30,56 @@ public class I2CPMessageReader { private I2CPMessageEventListener _listener; private I2CPMessageReaderRunner _reader; private Thread _readerThread; - + public I2CPMessageReader(InputStream stream, I2CPMessageEventListener lsnr) { _stream = stream; setListener(lsnr); _reader = new I2CPMessageReaderRunner(); _readerThread = new I2PThread(_reader); - _readerThread.setDaemon(true); - _readerThread.setName("I2CP Reader"); + _readerThread.setDaemon(true); + _readerThread.setName("I2CP Reader"); } - - public void setListener(I2CPMessageEventListener lsnr) { _listener = lsnr; } - public I2CPMessageEventListener getListener() { return _listener; } - + + public void setListener(I2CPMessageEventListener lsnr) { + _listener = lsnr; + } + + public I2CPMessageEventListener getListener() { + return _listener; + } + /** * Instruct the reader to begin reading messages off the stream * */ - public void startReading() { _readerThread.start(); } + public void startReading() { + _readerThread.start(); + } + /** * Have the already started reader pause its reading indefinitely * */ - public void pauseReading() { _reader.pauseRunner(); } + public void pauseReading() { + _reader.pauseRunner(); + } + /** * Resume reading after a pause * */ - public void resumeReading() { _reader.resumeRunner(); } + public void resumeReading() { + _reader.resumeRunner(); + } + /** * Cancel reading. * */ - public void stopReading() { _reader.cancelRunner(); } - + public void stopReading() { + _reader.cancelRunner(); + } + /** * Defines the different events the reader produces while reading the stream * @@ -74,41 +91,52 @@ public class I2CPMessageReader { * */ public void messageReceived(I2CPMessageReader reader, I2CPMessage message); + /** * Notify the listener that an exception was thrown while reading from the given * reader * */ public void readError(I2CPMessageReader reader, Exception error); + /** * Notify the listener that the stream the given reader was running off * closed * */ public void disconnected(I2CPMessageReader reader); - } - + } + private class I2CPMessageReaderRunner implements Runnable { - private boolean _doRun; + private boolean _doRun; private boolean _stayAlive; + public I2CPMessageReaderRunner() { _doRun = true; _stayAlive = true; } - public void pauseRunner() { _doRun = false; } - public void resumeRunner() { _doRun = true; } - public void cancelRunner() { + + public void pauseRunner() { _doRun = false; - _stayAlive = false; - if (_stream != null) { - try { - _stream.close(); - } catch (IOException ioe) { - _log.error("Error closing the stream", ioe); - } - } - _stream = null; } + + public void resumeRunner() { + _doRun = true; + } + + public void cancelRunner() { + _doRun = false; + _stayAlive = false; + if (_stream != null) { + try { + _stream.close(); + } catch (IOException ioe) { + _log.error("Error closing the stream", ioe); + } + } + _stream = null; + } + public void run() { while (_stayAlive) { while (_doRun) { @@ -116,30 +144,33 @@ public class I2CPMessageReader { try { I2CPMessage msg = I2CPMessageHandler.readMessage(_stream); if (msg != null) { - _log.debug("Before handling the newly received message"); + _log.debug("Before handling the newly received message"); _listener.messageReceived(I2CPMessageReader.this, msg); - _log.debug("After handling the newly received message"); - } + _log.debug("After handling the newly received message"); + } } catch (I2CPMessageException ime) { - _log.error("Error handling message", ime); + _log.error("Error handling message", ime); _listener.readError(I2CPMessageReader.this, ime); - cancelRunner(); + cancelRunner(); } catch (IOException ioe) { - _log.error("IO Error handling message", ioe); + _log.error("IO Error handling message", ioe); _listener.disconnected(I2CPMessageReader.this); cancelRunner(); } catch (Throwable t) { - _log.log(Log.CRIT, "Unhandled error reading I2CP stream", t); - _listener.disconnected(I2CPMessageReader.this); - cancelRunner(); - } + _log.log(Log.CRIT, "Unhandled error reading I2CP stream", t); + _listener.disconnected(I2CPMessageReader.this); + cancelRunner(); + } } if (!_doRun) { // pause .5 secs when we're paused - try { Thread.sleep(500); } catch (InterruptedException ie) {} + try { + Thread.sleep(500); + } catch (InterruptedException ie) { + } } } // boom bye bye bad bwoy } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/MessageId.java b/core/java/src/net/i2p/data/i2cp/MessageId.java index f4023aa126e843daaef9a89a78ec38c0027e3794..4d91e814824ac8fef8e69bdf8a323bc4900100b2 100644 --- a/core/java/src/net/i2p/data/i2cp/MessageId.java +++ b/core/java/src/net/i2p/data/i2cp/MessageId.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,15 +9,14 @@ package net.i2p.data.i2cp; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; +import net.i2p.util.Log; /** * Defines the message ID of a message delivered between a router and a client @@ -27,30 +27,38 @@ import net.i2p.data.DataFormatException; public class MessageId extends DataStructureImpl { private final static Log _log = new Log(MessageId.class); private int _messageId; - - public MessageId() { setMessageId(-1); } - - public int getMessageId() { return _messageId; } - public void setMessageId(int id) { _messageId = id; } - + + public MessageId() { + setMessageId(-1); + } + + public int getMessageId() { + return _messageId; + } + + public void setMessageId(int id) { + _messageId = id; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - _messageId = (int)DataHelper.readLong(in, 4); + _messageId = (int) DataHelper.readLong(in, 4); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { if (_messageId < 0) throw new DataFormatException("Invalid message ID: " + _messageId); DataHelper.writeLong(out, 4, _messageId); } - + public boolean equals(Object object) { - if ( (object == null) || !(object instanceof MessageId) ) - return false; - return DataHelper.eq(getMessageId(), ((MessageId)object).getMessageId()); + if ((object == null) || !(object instanceof MessageId)) return false; + return DataHelper.eq(getMessageId(), ((MessageId) object).getMessageId()); } - - public int hashCode() { return getMessageId(); } - + + public int hashCode() { + return getMessageId(); + } + public String toString() { return "[MessageId: " + getMessageId() + "]"; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java b/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java index 17f3526432271c44f11c2fa5faeb7ac239e188e0..7f425b6d7f7757bd779d805c03ba4a04bfcf0031 100644 --- a/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -29,20 +30,37 @@ public class MessagePayloadMessage extends I2CPMessageImpl { private SessionId _sessionId; private MessageId _messageId; private Payload _payload; - - public MessagePayloadMessage() { + + public MessagePayloadMessage() { setSessionId(null); setMessageId(null); setPayload(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public MessageId getMessageId() { return _messageId; } - public void setMessageId(MessageId id) { _messageId = id; } - public Payload getPayload() { return _payload; } - public void setPayload(Payload payload) { _payload = payload; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public MessageId getMessageId() { + return _messageId; + } + + public void setMessageId(MessageId id) { + _messageId = id; + } + + public Payload getPayload() { + return _payload; + } + + public void setPayload(Payload payload) { + _payload = payload; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); @@ -55,15 +73,15 @@ public class MessagePayloadMessage extends I2CPMessageImpl { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if (_sessionId == null) - throw new I2CPMessageException("Unable to write out the message, as the session ID has not been defined"); - if (_messageId == null) - throw new I2CPMessageException("Unable to write out the message, as the message ID has not been defined"); - if (_payload == null) - throw new I2CPMessageException("Unable to write out the message, as the payload has not been defined"); - + if (_sessionId == null) + throw new I2CPMessageException("Unable to write out the message, as the session ID has not been defined"); + if (_messageId == null) + throw new I2CPMessageException("Unable to write out the message, as the message ID has not been defined"); + if (_payload == null) + throw new I2CPMessageException("Unable to write out the message, as the payload has not been defined"); + ByteArrayOutputStream os = new ByteArrayOutputStream(512); try { _sessionId.writeBytes(os); @@ -74,21 +92,23 @@ public class MessagePayloadMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof MessagePayloadMessage) ) { - MessagePayloadMessage msg = (MessagePayloadMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getMessageId(),msg.getMessageId()) && - DataHelper.eq(getPayload(),msg.getPayload()); + if ((object != null) && (object instanceof MessagePayloadMessage)) { + MessagePayloadMessage msg = (MessagePayloadMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getMessageId(), msg.getMessageId()) + && DataHelper.eq(getPayload(), msg.getPayload()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[MessagePayloadMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -97,4 +117,4 @@ public class MessagePayloadMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java index 2b172a6a91814908fd66437586b2adda494383c8..1f85f13e669598dedada176835b8c5c5408e2464 100644 --- a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -30,61 +31,97 @@ public class MessageStatusMessage extends I2CPMessageImpl { private long _nonce; private long _size; private int _status; - + public final static int STATUS_AVAILABLE = 0; public final static int STATUS_SEND_ACCEPTED = 1; public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2; public final static int STATUS_SEND_BEST_EFFORT_FAILURE = 3; public final static int STATUS_SEND_GUARANTEED_SUCCESS = 4; public final static int STATUS_SEND_GUARANTEED_FAILURE = 5; - - public MessageStatusMessage() { + + public MessageStatusMessage() { setSessionId(null); setStatus(-1); setMessageId(null); setSize(-1); - setNonce(-1); - } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public int getStatus() { return _status; } - public void setStatus(int status) { _status = status; } - public MessageId getMessageId() { return _messageId; } - public void setMessageId(MessageId id) { _messageId = id; } - public long getSize() { return _size; } - public void setSize(long size) { _size = size; } - public long getNonce() { return _nonce; } - public void setNonce(long nonce) { _nonce = nonce; } - - public static final String getStatusString(int status) { - switch (status) { - case STATUS_AVAILABLE: return "AVAILABLE "; - case STATUS_SEND_ACCEPTED: return "SEND ACCEPTED "; - case STATUS_SEND_BEST_EFFORT_SUCCESS: return "BEST EFFORT SUCCESS"; - case STATUS_SEND_BEST_EFFORT_FAILURE: return "BEST EFFORT FAILURE"; - case STATUS_SEND_GUARANTEED_SUCCESS: return "GUARANTEED SUCCESS "; - case STATUS_SEND_GUARANTEED_FAILURE: return "GUARANTEED FAILURE "; - default: return "***INVALID STATUS: " + status; - } - } - + setNonce(-1); + } + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public int getStatus() { + return _status; + } + + public void setStatus(int status) { + _status = status; + } + + public MessageId getMessageId() { + return _messageId; + } + + public void setMessageId(MessageId id) { + _messageId = id; + } + + public long getSize() { + return _size; + } + + public void setSize(long size) { + _size = size; + } + + public long getNonce() { + return _nonce; + } + + public void setNonce(long nonce) { + _nonce = nonce; + } + + public static final String getStatusString(int status) { + switch (status) { + case STATUS_AVAILABLE: + return "AVAILABLE "; + case STATUS_SEND_ACCEPTED: + return "SEND ACCEPTED "; + case STATUS_SEND_BEST_EFFORT_SUCCESS: + return "BEST EFFORT SUCCESS"; + case STATUS_SEND_BEST_EFFORT_FAILURE: + return "BEST EFFORT FAILURE"; + case STATUS_SEND_GUARANTEED_SUCCESS: + return "GUARANTEED SUCCESS "; + case STATUS_SEND_GUARANTEED_FAILURE: + return "GUARANTEED FAILURE "; + default: + return "***INVALID STATUS: " + status; + } + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); _sessionId.readBytes(in); _messageId = new MessageId(); _messageId.readBytes(in); - _status = (int)DataHelper.readLong(in, 1); + _status = (int) DataHelper.readLong(in, 1); _size = DataHelper.readLong(in, 4); _nonce = DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_messageId == null) || (_status < 0) || (_nonce <= 0) ) + if ((_sessionId == null) || (_messageId == null) || (_status < 0) || (_nonce <= 0)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try { @@ -98,23 +135,23 @@ public class MessageStatusMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof MessageStatusMessage) ) { - MessageStatusMessage msg = (MessageStatusMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getMessageId(),msg.getMessageId()) && - (getNonce() == msg.getNonce()) && - DataHelper.eq(getSize(),msg.getSize()) && - DataHelper.eq(getStatus(),msg.getStatus()); + if ((object != null) && (object instanceof MessageStatusMessage)) { + MessageStatusMessage msg = (MessageStatusMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getMessageId(), msg.getMessageId()) && (getNonce() == msg.getNonce()) + && DataHelper.eq(getSize(), msg.getSize()) && DataHelper.eq(getStatus(), msg.getStatus()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[MessageStatusMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -125,4 +162,4 @@ public class MessageStatusMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java b/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java index ce55d17d87c0e006321d159f3c691f4f0c784227..30834aa0d6cacd1a187aedee936db7117ff258ae 100644 --- a/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java +++ b/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -27,17 +28,28 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 6; private SessionId _sessionId; private MessageId _messageId; - - public ReceiveMessageBeginMessage() { + + public ReceiveMessageBeginMessage() { setSessionId(null); setMessageId(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public MessageId getMessageId() { return _messageId; } - public void setMessageId(MessageId id) { _messageId = id; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public MessageId getMessageId() { + return _messageId; + } + + public void setMessageId(MessageId id) { + _messageId = id; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); @@ -48,9 +60,9 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_messageId == null) ) + if ((_sessionId == null) || (_messageId == null)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try { @@ -61,20 +73,22 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof ReceiveMessageBeginMessage) ) { - ReceiveMessageBeginMessage msg = (ReceiveMessageBeginMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getMessageId(),msg.getMessageId()); + if ((object != null) && (object instanceof ReceiveMessageBeginMessage)) { + ReceiveMessageBeginMessage msg = (ReceiveMessageBeginMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getMessageId(), msg.getMessageId()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[ReceiveMessageBeginMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -82,4 +96,4 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java b/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java index 6721e3b094ffd1409a3c23605dbbb004f61bbf3a..ee3f55f508f9d4a8afee8ac2031396486823e001 100644 --- a/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java +++ b/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -27,17 +28,28 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 7; private SessionId _sessionId; private MessageId _messageId; - - public ReceiveMessageEndMessage() { + + public ReceiveMessageEndMessage() { setSessionId(null); setMessageId(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public MessageId getMessageId() { return _messageId; } - public void setMessageId(MessageId id) { _messageId = id; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public MessageId getMessageId() { + return _messageId; + } + + public void setMessageId(MessageId id) { + _messageId = id; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); @@ -48,9 +60,9 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_messageId == null) ) + if ((_sessionId == null) || (_messageId == null)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try { @@ -61,20 +73,22 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof ReceiveMessageEndMessage) ) { - ReceiveMessageEndMessage msg = (ReceiveMessageEndMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getMessageId(),msg.getMessageId()); + if ((object != null) && (object instanceof ReceiveMessageEndMessage)) { + ReceiveMessageEndMessage msg = (ReceiveMessageEndMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getMessageId(), msg.getMessageId()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[ReceiveMessageEndMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -82,4 +96,4 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/ReportAbuseMessage.java b/core/java/src/net/i2p/data/i2cp/ReportAbuseMessage.java index fe67d19c35e45c0575328a7680b822bad4909483..072ab34fef9aa1da2c04d88459030b36cd9647a4 100644 --- a/core/java/src/net/i2p/data/i2cp/ReportAbuseMessage.java +++ b/core/java/src/net/i2p/data/i2cp/ReportAbuseMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -29,23 +30,46 @@ public class ReportAbuseMessage extends I2CPMessageImpl { private AbuseSeverity _severity; private AbuseReason _reason; private MessageId _messageId; - + public ReportAbuseMessage() { setSessionId(null); setSeverity(null); setReason(null); setMessageId(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public AbuseSeverity getSeverity() { return _severity; } - public void setSeverity(AbuseSeverity severity) { _severity = severity; } - public AbuseReason getReason() { return _reason; } - public void setReason(AbuseReason reason) { _reason = reason; } - public MessageId getMessageId() { return _messageId; } - public void setMessageId(MessageId id) { _messageId = id; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public AbuseSeverity getSeverity() { + return _severity; + } + + public void setSeverity(AbuseSeverity severity) { + _severity = severity; + } + + public AbuseReason getReason() { + return _reason; + } + + public void setReason(AbuseReason reason) { + _reason = reason; + } + + public MessageId getMessageId() { + return _messageId; + } + + public void setMessageId(MessageId id) { + _messageId = id; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); @@ -60,9 +84,9 @@ public class ReportAbuseMessage extends I2CPMessageImpl { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_severity == null) || (_reason == null) ) + if ((_sessionId == null) || (_severity == null) || (_reason == null)) throw new I2CPMessageException("Not enough information to construct the message"); ByteArrayOutputStream os = new ByteArrayOutputStream(32); try { @@ -70,7 +94,7 @@ public class ReportAbuseMessage extends I2CPMessageImpl { _severity.writeBytes(os); _reason.writeBytes(os); if (_messageId == null) { - _messageId = new MessageId(); + _messageId = new MessageId(); _messageId.setMessageId(0); } _messageId.writeBytes(os); @@ -79,22 +103,22 @@ public class ReportAbuseMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof ReportAbuseMessage) ) { - ReportAbuseMessage msg = (ReportAbuseMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getSeverity(),msg.getSeverity()) && - DataHelper.eq(getReason(),msg.getReason()) && - DataHelper.eq(getMessageId(),msg.getMessageId()); + if ((object != null) && (object instanceof ReportAbuseMessage)) { + ReportAbuseMessage msg = (ReportAbuseMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) && DataHelper.eq(getSeverity(), msg.getSeverity()) + && DataHelper.eq(getReason(), msg.getReason()) && DataHelper.eq(getMessageId(), msg.getMessageId()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[ReportAbuseMessage: "); buf.append("\n\tSessionID: ").append(getSessionId()); @@ -104,4 +128,4 @@ public class ReportAbuseMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java index 238e14b24cd801c46ecb338161b4c9476e1c8a74..986da520dea15abfaf8880a4148af1266d58a96d 100644 --- a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java +++ b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -33,121 +34,150 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl { private SessionId _sessionId; private List _endpoints; private Date _end; - - public RequestLeaseSetMessage() { + + public RequestLeaseSetMessage() { setSessionId(null); - _endpoints = new ArrayList(); + _endpoints = new ArrayList(); setEndDate(null); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public int getEndpoints() { return _endpoints.size(); } + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public int getEndpoints() { + return _endpoints.size(); + } + public RouterIdentity getRouter(int endpoint) { - if ( (endpoint < 0) || (_endpoints.size() < endpoint) ) return null; - return ((TunnelEndpoint)_endpoints.get(endpoint)).getRouter(); + if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null; + return ((TunnelEndpoint) _endpoints.get(endpoint)).getRouter(); } + public TunnelId getTunnelId(int endpoint) { - if ( (endpoint < 0) || (_endpoints.size() < endpoint) ) return null; - return ((TunnelEndpoint)_endpoints.get(endpoint)).getTunnelId(); + if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null; + return ((TunnelEndpoint) _endpoints.get(endpoint)).getTunnelId(); } + public void remoteEndpoint(int endpoint) { - if ( (endpoint >= 0) && (endpoint < _endpoints.size()) ) - _endpoints.remove(endpoint); + if ((endpoint >= 0) && (endpoint < _endpoints.size())) _endpoints.remove(endpoint); } + public void addEndpoint(RouterIdentity router, TunnelId tunnel) { - _endpoints.add(new TunnelEndpoint(router,tunnel)); + _endpoints.add(new TunnelEndpoint(router, tunnel)); } - public Date getEndDate() { return _end; } - public void setEndDate(Date end) { _end = end; } - + + public Date getEndDate() { + return _end; + } + + public void setEndDate(Date end) { + _end = end; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); _sessionId.readBytes(in); - int numTunnels = (int)DataHelper.readLong(in, 1); - _endpoints.clear(); - for (int i = 0; i < numTunnels; i++) { - RouterIdentity router = new RouterIdentity(); - router.readBytes(in); - TunnelId tunnel = new TunnelId(); - tunnel.readBytes(in); - _endpoints.add(new TunnelEndpoint(router, tunnel)); - } + int numTunnels = (int) DataHelper.readLong(in, 1); + _endpoints.clear(); + for (int i = 0; i < numTunnels; i++) { + RouterIdentity router = new RouterIdentity(); + router.readBytes(in); + TunnelId tunnel = new TunnelId(); + tunnel.readBytes(in); + _endpoints.add(new TunnelEndpoint(router, tunnel)); + } _end = DataHelper.readDate(in); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_endpoints == null) ) + if ((_sessionId == null) || (_endpoints == null)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try { _sessionId.writeBytes(os); - DataHelper.writeLong(os, 1, _endpoints.size()); - for (int i = 0; i < _endpoints.size(); i++) { - RouterIdentity router = getRouter(i); - router.writeBytes(os); - TunnelId tunnel = getTunnelId(i); - tunnel.writeBytes(os); - } + DataHelper.writeLong(os, 1, _endpoints.size()); + for (int i = 0; i < _endpoints.size(); i++) { + RouterIdentity router = getRouter(i); + router.writeBytes(os); + TunnelId tunnel = getTunnelId(i); + tunnel.writeBytes(os); + } DataHelper.writeDate(os, _end); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error writing out the message data", dfe); } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof RequestLeaseSetMessage) ) { - RequestLeaseSetMessage msg = (RequestLeaseSetMessage)object; - if (getEndpoints() != msg.getEndpoints()) return false; - for (int i = 0; i < getEndpoints(); i++) { - if (!DataHelper.eq(getRouter(i), msg.getRouter(i)) || - DataHelper.eq(getTunnelId(i), msg.getTunnelId(i))) - return false; - } - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getEndDate(),msg.getEndDate()); + if ((object != null) && (object instanceof RequestLeaseSetMessage)) { + RequestLeaseSetMessage msg = (RequestLeaseSetMessage) object; + if (getEndpoints() != msg.getEndpoints()) return false; + for (int i = 0; i < getEndpoints(); i++) { + if (!DataHelper.eq(getRouter(i), msg.getRouter(i)) || DataHelper.eq(getTunnelId(i), msg.getTunnelId(i))) + return false; + } + return DataHelper.eq(getSessionId(), msg.getSessionId()) && DataHelper.eq(getEndDate(), msg.getEndDate()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[RequestLeaseMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); - buf.append("\n\tTunnels:"); - for (int i = 0; i < getEndpoints(); i++) { - buf.append("\n\t\tRouterIdentity: ").append(getRouter(i)); - buf.append("\n\t\tTunnelId: ").append(getTunnelId(i)); - } + buf.append("\n\tTunnels:"); + for (int i = 0; i < getEndpoints(); i++) { + buf.append("\n\t\tRouterIdentity: ").append(getRouter(i)); + buf.append("\n\t\tTunnelId: ").append(getTunnelId(i)); + } buf.append("\n\tEndDate: ").append(getEndDate()); buf.append("]"); return buf.toString(); } - + private class TunnelEndpoint { - private RouterIdentity _router; - private TunnelId _tunnelId; - - public TunnelEndpoint() { - _router = null; - _tunnelId = null; - } - public TunnelEndpoint(RouterIdentity router, TunnelId id) { - _router = router; - _tunnelId = id; - } - - public RouterIdentity getRouter() { return _router; } - public void setRouter(RouterIdentity router) { _router = router; } - public TunnelId getTunnelId() { return _tunnelId; } - public void setTunnelId(TunnelId tunnelId) { _tunnelId = tunnelId; } - } -} + private RouterIdentity _router; + private TunnelId _tunnelId; + + public TunnelEndpoint() { + _router = null; + _tunnelId = null; + } + + public TunnelEndpoint(RouterIdentity router, TunnelId id) { + _router = router; + _tunnelId = id; + } + + public RouterIdentity getRouter() { + return _router; + } + + public void setRouter(RouterIdentity router) { + _router = router; + } + + public TunnelId getTunnelId() { + return _tunnelId; + } + + public void setTunnelId(TunnelId tunnelId) { + _tunnelId = tunnelId; + } + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java b/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java index 4f94b5e2b361e4556a6cb619208e95c326effd71..809b1334758ecb673e97765432d323b5d379167d 100644 --- a/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -31,23 +32,46 @@ public class SendMessageMessage extends I2CPMessageImpl { private Destination _destination; private Payload _payload; private long _nonce; - - public SendMessageMessage() { + + public SendMessageMessage() { setSessionId(null); setDestination(null); setPayload(null); - setNonce(0); + setNonce(0); + } + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public Destination getDestination() { + return _destination; + } + + public void setDestination(Destination destination) { + _destination = destination; + } + + public Payload getPayload() { + return _payload; } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public Destination getDestination() { return _destination; } - public void setDestination(Destination destination) { _destination = destination; } - public Payload getPayload() { return _payload; } - public void setPayload(Payload payload) { _payload = payload; } - public long getNonce() { return _nonce; } - public void setNonce(long nonce) { _nonce = nonce; } - + + public void setPayload(Payload payload) { + _payload = payload; + } + + public long getNonce() { + return _nonce; + } + + public void setNonce(long nonce) { + _nonce = nonce; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); @@ -56,42 +80,43 @@ public class SendMessageMessage extends I2CPMessageImpl { _destination.readBytes(in); _payload = new Payload(); _payload.readBytes(in); - _nonce = DataHelper.readLong(in, 4); + _nonce = DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { - if ( (_sessionId == null) || (_destination == null) || (_payload == null) || (_nonce <= 0) ) + if ((_sessionId == null) || (_destination == null) || (_payload == null) || (_nonce <= 0)) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); ByteArrayOutputStream os = new ByteArrayOutputStream(512); try { _sessionId.writeBytes(os); _destination.writeBytes(os); _payload.writeBytes(os); - DataHelper.writeLong(os, 4, _nonce); + DataHelper.writeLong(os, 4, _nonce); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error writing out the message data", dfe); } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof SendMessageMessage) ) { - SendMessageMessage msg = (SendMessageMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getDestination(),msg.getDestination()) && - (getNonce() == msg.getNonce()) && - DataHelper.eq(getPayload(),msg.getPayload()); + if ((object != null) && (object instanceof SendMessageMessage)) { + SendMessageMessage msg = (SendMessageMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) + && DataHelper.eq(getDestination(), msg.getDestination()) && (getNonce() == msg.getNonce()) + && DataHelper.eq(getPayload(), msg.getPayload()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[SendMessageMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -101,4 +126,4 @@ public class SendMessageMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/SessionConfig.java b/core/java/src/net/i2p/data/i2cp/SessionConfig.java index 96f4ab6c58472d2563a0d790fa26ced753ec8107..092cec0f27adad1ad21656495e82c494e493c084 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionConfig.java +++ b/core/java/src/net/i2p/data/i2cp/SessionConfig.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -12,6 +13,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Date; import java.util.Iterator; import java.util.Properties; @@ -22,10 +24,8 @@ import net.i2p.data.DataStructureImpl; import net.i2p.data.Destination; import net.i2p.data.Signature; import net.i2p.data.SigningPrivateKey; -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Date; +import net.i2p.util.Log; /** * Defines the information a client must provide to create a session @@ -38,180 +38,194 @@ public class SessionConfig extends DataStructureImpl { private Signature _signature; private Date _creationDate; private Properties _options; - + /** * if the client authorized this session more than the specified period ago, * refuse it, since it may be a replay attack * */ - private final static long OFFSET_VALIDITY = 30*1000; - + private final static long OFFSET_VALIDITY = 30 * 1000; + public SessionConfig() { _destination = null; _signature = null; - _creationDate = new Date(Clock.getInstance().now()); + _creationDate = new Date(Clock.getInstance().now()); _options = null; } - + /** * Retrieve the destination for which this session is supposed to connect * */ - public Destination getDestination() { return _destination; } + public Destination getDestination() { + return _destination; + } + /** * Specify the destination for which this session is supposed to connect * */ - public void setDestination(Destination dest) { _destination = dest; } + public void setDestination(Destination dest) { + _destination = dest; + } /** * Determine when this session was authorized by the destination (so we can * prevent replay attacks) * */ - public Date getCreationDate() { return _creationDate; } - public void setCreationDate(Date date) { _creationDate = date; } - + public Date getCreationDate() { + return _creationDate; + } + + public void setCreationDate(Date date) { + _creationDate = date; + } + /** * Retrieve any configuration options for the session * */ - public Properties getOptions() { return _options; } + public Properties getOptions() { + return _options; + } + /** * Configure the session with the given options * */ - public void setOptions(Properties options) { _options = options; } - - public Signature getSignature() { return _signature; } - public void setSignature(Signature sig) { _signature = sig; } - + public void setOptions(Properties options) { + _options = options; + } + + public Signature getSignature() { + return _signature; + } + + public void setSignature(Signature sig) { + _signature = sig; + } + /** * Sign the structure using the supplied private key * */ public void signSessionConfig(SigningPrivateKey signingKey) throws DataFormatException { - byte data[] = getBytes(); - if (data == null) throw new DataFormatException("Unable to retrieve bytes for signing"); + byte data[] = getBytes(); + if (data == null) throw new DataFormatException("Unable to retrieve bytes for signing"); _signature = DSAEngine.getInstance().sign(data, signingKey); } - + /** * Verify that the signature matches the destination's signing public key. * * @return true only if the signature matches */ public boolean verifySignature() { - if (getSignature() == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Signature is null!"); - return false; - } - if (getDestination() == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Destination is null!"); - return false; - } - if (getCreationDate() == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Date is null!"); - return false; - } - if (tooOld()) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Too old!"); - return false; - } - byte data[] = getBytes(); - if (data == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Bytes could not be found - wtf?"); - return false; - } - - boolean ok = DSAEngine.getInstance().verifySignature(getSignature(), data, getDestination().getSigningPublicKey()); - if (!ok) { - if (_log.shouldLog(Log.WARN)) - _log.warn("DSA signature failed!"); - } - return ok; - } - + if (getSignature() == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Signature is null!"); + return false; + } + if (getDestination() == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Destination is null!"); + return false; + } + if (getCreationDate() == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Date is null!"); + return false; + } + if (tooOld()) { + if (_log.shouldLog(Log.WARN)) _log.warn("Too old!"); + return false; + } + byte data[] = getBytes(); + if (data == null) { + if (_log.shouldLog(Log.WARN)) _log.warn("Bytes could not be found - wtf?"); + return false; + } + + boolean ok = DSAEngine.getInstance().verifySignature(getSignature(), data, + getDestination().getSigningPublicKey()); + if (!ok) { + if (_log.shouldLog(Log.WARN)) _log.warn("DSA signature failed!"); + } + return ok; + } + public boolean tooOld() { - long now = Clock.getInstance().now(); - long earliestValid = now - OFFSET_VALIDITY; - long latestValid = now + OFFSET_VALIDITY; - if (_creationDate == null) return true; - if (_creationDate.getTime() < earliestValid) return true; - if (_creationDate.getTime() > latestValid) return true; - return false; - } - + long now = Clock.getInstance().now(); + long earliestValid = now - OFFSET_VALIDITY; + long latestValid = now + OFFSET_VALIDITY; + if (_creationDate == null) return true; + if (_creationDate.getTime() < earliestValid) return true; + if (_creationDate.getTime() > latestValid) return true; + return false; + } + private byte[] getBytes() { - if (_destination == null) return null; - if (_options == null) return null; - if (_creationDate == null) return null; - + if (_destination == null) return null; + if (_options == null) return null; + if (_creationDate == null) return null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); try { - _log.debug("PubKey size for destination: " + _destination.getPublicKey().getData().length); - _log.debug("SigningKey size for destination: " + _destination.getSigningPublicKey().getData().length); + _log.debug("PubKey size for destination: " + _destination.getPublicKey().getData().length); + _log.debug("SigningKey size for destination: " + _destination.getSigningPublicKey().getData().length); _destination.writeBytes(out); - DataHelper.writeProperties(out, _options); - DataHelper.writeDate(out, _creationDate); + DataHelper.writeProperties(out, _options); + DataHelper.writeDate(out, _creationDate); } catch (IOException ioe) { - _log.error("IOError signing", ioe); - return null; + _log.error("IOError signing", ioe); + return null; } catch (DataFormatException dfe) { - _log.error("Error writing out the bytes for signing/verification", dfe); - return null; - } - return out.toByteArray(); + _log.error("Error writing out the bytes for signing/verification", dfe); + return null; + } + return out.toByteArray(); } - + public void readBytes(InputStream rawConfig) throws DataFormatException, IOException { _destination = new Destination(); _destination.readBytes(rawConfig); _options = DataHelper.readProperties(rawConfig); - _creationDate = DataHelper.readDate(rawConfig); + _creationDate = DataHelper.readDate(rawConfig); _signature = new Signature(); _signature.readBytes(rawConfig); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { - if ( (_destination == null) || (_options == null) || (_signature == null) || (_creationDate == null) ) + if ((_destination == null) || (_options == null) || (_signature == null) || (_creationDate == null)) throw new DataFormatException("Not enough data to create the session config"); _destination.writeBytes(out); DataHelper.writeProperties(out, _options); - DataHelper.writeDate(out, _creationDate); + DataHelper.writeDate(out, _creationDate); _signature.writeBytes(out); } - - + public boolean equals(Object object) { - if ( (object != null) && (object instanceof SessionConfig) ) { - SessionConfig cfg = (SessionConfig)object; - return DataHelper.eq(getSignature(), cfg.getSignature()) && - DataHelper.eq(getDestination(), cfg.getDestination()) && - DataHelper.eq(getCreationDate(), cfg.getCreationDate()) && - DataHelper.eq(getOptions(), cfg.getOptions()); + if ((object != null) && (object instanceof SessionConfig)) { + SessionConfig cfg = (SessionConfig) object; + return DataHelper.eq(getSignature(), cfg.getSignature()) + && DataHelper.eq(getDestination(), cfg.getDestination()) + && DataHelper.eq(getCreationDate(), cfg.getCreationDate()) + && DataHelper.eq(getOptions(), cfg.getOptions()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer("[SessionConfig: "); buf.append("\n\tDestination: ").append(getDestination()); buf.append("\n\tSignature: ").append(getSignature()); buf.append("\n\tCreation Date: ").append(getCreationDate()); buf.append("\n\tOptions: #: ").append(getOptions().size()); for (Iterator iter = getOptions().keySet().iterator(); iter.hasNext();) { - String key = (String)iter.next(); + String key = (String) iter.next(); String val = getOptions().getProperty(key); buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]"); } buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/SessionId.java b/core/java/src/net/i2p/data/i2cp/SessionId.java index 01b9cad02999822aa6619b079ca11a4d97d79c27..bd022494fe8183acb0430472de0bf755857ea172 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionId.java +++ b/core/java/src/net/i2p/data/i2cp/SessionId.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,15 +9,14 @@ package net.i2p.data.i2cp; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; +import net.i2p.util.Log; /** * Defines the token passed between the router and client to associate messages @@ -27,32 +27,38 @@ import net.i2p.data.DataFormatException; public class SessionId extends DataStructureImpl { private final static Log _log = new Log(SessionId.class); private int _sessionId; - - public SessionId() { setSessionId(-1); } - - public int getSessionId() { return _sessionId; } - public void setSessionId(int id) { _sessionId = id; } - + + public SessionId() { + setSessionId(-1); + } + + public int getSessionId() { + return _sessionId; + } + + public void setSessionId(int id) { + _sessionId = id; + } + public void readBytes(InputStream in) throws DataFormatException, IOException { - _sessionId = (int)DataHelper.readLong(in, 2); + _sessionId = (int) DataHelper.readLong(in, 2); } - + public void writeBytes(OutputStream out) throws DataFormatException, IOException { if (_sessionId < 0) throw new DataFormatException("Invalid session ID: " + _sessionId); DataHelper.writeLong(out, 2, _sessionId); } - + public boolean equals(Object obj) { - if ( (obj == null) || !(obj instanceof SessionId)) - return false; - return getSessionId() == ((SessionId)obj).getSessionId(); + if ((obj == null) || !(obj instanceof SessionId)) return false; + return getSessionId() == ((SessionId) obj).getSessionId(); } - + public int hashCode() { - return getSessionId(); + return getSessionId(); } - + public String toString() { return "[SessionId: " + getSessionId() + "]"; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java b/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java index 6c6094c1fd285ae199b083925a993123545ec87b..e694a8ad755a3173bebdece1dced9aae05fa73ac 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -27,32 +28,43 @@ public class SessionStatusMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 20; private SessionId _sessionId; private int _status; - + public final static int STATUS_DESTROYED = 0; public final static int STATUS_CREATED = 1; public final static int STATUS_UPDATED = 2; public final static int STATUS_INVALID = 3; - - public SessionStatusMessage() { + + public SessionStatusMessage() { setSessionId(null); setStatus(STATUS_INVALID); } - - public SessionId getSessionId() { return _sessionId; } - public void setSessionId(SessionId id) { _sessionId = id; } - public int getStatus() { return _status; } - public void setStatus(int status) { _status = status; } - + + public SessionId getSessionId() { + return _sessionId; + } + + public void setSessionId(SessionId id) { + _sessionId = id; + } + + public int getStatus() { + return _status; + } + + public void setStatus(int status) { + _status = status; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { _sessionId = new SessionId(); _sessionId.readBytes(in); - _status = (int)DataHelper.readLong(in, 1); + _status = (int) DataHelper.readLong(in, 1); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { if (_sessionId == null) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); @@ -65,20 +77,21 @@ public class SessionStatusMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof SessionStatusMessage) ) { - SessionStatusMessage msg = (SessionStatusMessage)object; - return DataHelper.eq(getSessionId(),msg.getSessionId()) && - DataHelper.eq(getStatus(),msg.getStatus()); + if ((object != null) && (object instanceof SessionStatusMessage)) { + SessionStatusMessage msg = (SessionStatusMessage) object; + return DataHelper.eq(getSessionId(), msg.getSessionId()) && DataHelper.eq(getStatus(), msg.getStatus()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[SessionStatusMessage: "); buf.append("\n\tSessionId: ").append(getSessionId()); @@ -86,4 +99,4 @@ public class SessionStatusMessage extends I2CPMessageImpl { buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/data/i2cp/SetDateMessage.java b/core/java/src/net/i2p/data/i2cp/SetDateMessage.java index b0e47be265f6241a6ef5b924f07690cc7315ad4e..b91c2e92a842599b30a9f6b2c25f88d179f09fac 100644 --- a/core/java/src/net/i2p/data/i2cp/SetDateMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SetDateMessage.java @@ -1,4 +1,5 @@ package net.i2p.data.i2cp; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -11,13 +12,12 @@ package net.i2p.data.i2cp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Date; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Date; +import net.i2p.util.Log; /** * Tell the other side what time it is @@ -27,23 +27,28 @@ public class SetDateMessage extends I2CPMessageImpl { private final static Log _log = new Log(SetDateMessage.class); public final static int MESSAGE_TYPE = 33; private Date _date; - + public SetDateMessage() { - super(); - setDate(new Date(Clock.getInstance().now())); + super(); + setDate(new Date(Clock.getInstance().now())); + } + + public Date getDate() { + return _date; } - - public Date getDate() { return _date; } - public void setDate(Date date) { _date = date; } - + + public void setDate(Date date) { + _date = date; + } + protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { - try { + try { _date = DataHelper.readDate(in); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } - + protected byte[] doWriteMessage() throws I2CPMessageException, IOException { if (_date == null) throw new I2CPMessageException("Unable to write out the message as there is not enough data"); @@ -55,23 +60,25 @@ public class SetDateMessage extends I2CPMessageImpl { } return os.toByteArray(); } - - public int getType() { return MESSAGE_TYPE; } - + + public int getType() { + return MESSAGE_TYPE; + } + public boolean equals(Object object) { - if ( (object != null) && (object instanceof SetDateMessage) ) { - SetDateMessage msg = (SetDateMessage)object; - return DataHelper.eq(getDate(), msg.getDate()); + if ((object != null) && (object instanceof SetDateMessage)) { + SetDateMessage msg = (SetDateMessage) object; + return DataHelper.eq(getDate(), msg.getDate()); } else { return false; } } - - public String toString() { + + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("[SetDateMessage"); buf.append("\n\tDate: ").append(getDate()); buf.append("]"); return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/Frequency.java b/core/java/src/net/i2p/stat/Frequency.java index 8155b7bf4d5ec6f89631e7d5d5f6b8bc5cdd81bf..82ffb64e4de3737cceba4ec68ec2f6944c696d2f 100644 --- a/core/java/src/net/i2p/stat/Frequency.java +++ b/core/java/src/net/i2p/stat/Frequency.java @@ -12,114 +12,163 @@ public class Frequency { private long _start = now(); private long _count = 0; private Object _lock = this; // new Object(); // in case we want to do fancy sync later - + public Frequency(long period) { - setPeriod(period); - setLastEvent(0); - setAverageInterval(0); - setMinAverageInterval(0); + setPeriod(period); + setLastEvent(0); + setAverageInterval(0); + setMinAverageInterval(0); } - + /** how long is this frequency averaged over? */ - public long getPeriod() { synchronized (_lock) { return _period; } } + public long getPeriod() { + synchronized (_lock) { + return _period; + } + } + /** when did the last event occur? */ - public long getLastEvent() { synchronized (_lock) { return _lastEvent; } } + public long getLastEvent() { + synchronized (_lock) { + return _lastEvent; + } + } + /** * on average over the last $period, after how many milliseconds are events coming in, * as calculated during the last event occurrence? * */ - public double getAverageInterval() { synchronized (_lock) { return _avgInterval; } } + public double getAverageInterval() { + synchronized (_lock) { + return _avgInterval; + } + } + /** what is the lowest average interval (aka most frequent) we have seen? */ - public double getMinAverageInterval() { synchronized (_lock) { return _minAverageInterval; } } - + public double getMinAverageInterval() { + synchronized (_lock) { + return _minAverageInterval; + } + } + /** calculate how many events would occur in a period given the current average */ - public double getAverageEventsPerPeriod() { - synchronized (_lock) { - if (_avgInterval > 0) - return _period / _avgInterval; - else - return 0; - } + public double getAverageEventsPerPeriod() { + synchronized (_lock) { + if (_avgInterval > 0) + return _period / _avgInterval; + else + return 0; + } } + /** calculate how many events would occur in a period given the maximum average */ - public double getMaxAverageEventsPerPeriod() { - synchronized (_lock) { - if (_minAverageInterval > 0) - return _period / _minAverageInterval; - else - return 0; - } - } - + public double getMaxAverageEventsPerPeriod() { + synchronized (_lock) { + if (_minAverageInterval > 0) + return _period / _minAverageInterval; + else + return 0; + } + } + /** over the lifetime of this stat, without any decay or weighting, what was the average interval between events? */ public double getStrictAverageInterval() { - synchronized (_lock) { - long duration = now() - _start; - if ( (duration <= 0) || (_count <= 0) ) - return 0; - else - return duration / _count; - } - } - + synchronized (_lock) { + long duration = now() - _start; + if ((duration <= 0) || (_count <= 0)) + return 0; + else + return duration / _count; + } + } + /** using the strict average interval, how many events occur within an average period? */ public double getStrictAverageEventsPerPeriod() { - double avgInterval = getStrictAverageInterval(); - synchronized (_lock) { - if (avgInterval > 0) - return _period / avgInterval; - else - return 0; - } - } - + double avgInterval = getStrictAverageInterval(); + synchronized (_lock) { + if (avgInterval > 0) + return _period / avgInterval; + else + return 0; + } + } + /** how many events have occurred within the lifetime of this stat? */ - public long getEventCount() { synchronized (_lock) { return _count; } } - + public long getEventCount() { + synchronized (_lock) { + return _count; + } + } + /** * Take note that a new event occurred, recalculating all the averages and frequencies * */ - public void eventOccurred() { recalculate(true); } + public void eventOccurred() { + recalculate(true); + } + /** * Recalculate the averages * */ - public void recalculate() { recalculate(false); } - + public void recalculate() { + recalculate(false); + } + /** * Recalculate, but only update the lastEvent if eventOccurred */ private void recalculate(boolean eventOccurred) { - synchronized (_lock) { - long now = now(); - long interval = now - _lastEvent; - if (interval >= _period) - interval = _period-1; - else if (interval <= 0) - interval = 1; - - double oldWeight = 1-(interval/(float)_period); - double newWeight = (interval/(float)_period); - - double oldInterval = _avgInterval * oldWeight; - double newInterval = interval * newWeight; - _avgInterval = oldInterval + newInterval; - - if ( (_avgInterval < _minAverageInterval) || (_minAverageInterval <= 0) ) - _minAverageInterval = _avgInterval; - - if (eventOccurred) { - _lastEvent = now; - _count++; - } - } - } - - private void setPeriod(long milliseconds) { synchronized (_lock) { _period = milliseconds; } } - private void setLastEvent(long when) { synchronized (_lock) { _lastEvent = when; } } - private void setAverageInterval(double msInterval) { synchronized (_lock) { _avgInterval = msInterval; } } - private void setMinAverageInterval(double minAverageInterval) { synchronized (_lock) { _minAverageInterval = minAverageInterval; } } - private final static long now() { return System.currentTimeMillis(); } -} + synchronized (_lock) { + long now = now(); + long interval = now - _lastEvent; + if (interval >= _period) + interval = _period - 1; + else if (interval <= 0) interval = 1; + + double oldWeight = 1 - (interval / (float) _period); + double newWeight = (interval / (float) _period); + + double oldInterval = _avgInterval * oldWeight; + double newInterval = interval * newWeight; + _avgInterval = oldInterval + newInterval; + + if ((_avgInterval < _minAverageInterval) || (_minAverageInterval <= 0)) _minAverageInterval = _avgInterval; + + if (eventOccurred) { + _lastEvent = now; + _count++; + } + } + } + + private void setPeriod(long milliseconds) { + synchronized (_lock) { + _period = milliseconds; + } + } + + private void setLastEvent(long when) { + synchronized (_lock) { + _lastEvent = when; + } + } + + private void setAverageInterval(double msInterval) { + synchronized (_lock) { + _avgInterval = msInterval; + } + } + + private void setMinAverageInterval(double minAverageInterval) { + synchronized (_lock) { + _minAverageInterval = minAverageInterval; + } + } + + private final static long now() { + return System.currentTimeMillis(); + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/FrequencyStat.java b/core/java/src/net/i2p/stat/FrequencyStat.java index 221a474d814938c3e17ba5891e8a473c19a4dc12..7aae3d296e1199b9abb044c82bcbcb578cccc8ee 100644 --- a/core/java/src/net/i2p/stat/FrequencyStat.java +++ b/core/java/src/net/i2p/stat/FrequencyStat.java @@ -12,41 +12,53 @@ public class FrequencyStat { private Frequency _frequencies[]; public FrequencyStat(String name, String description, String group, long periods[]) { - _statName = name; - _description = description; - _groupName = group; - _frequencies = new Frequency[periods.length]; - for (int i = 0; i < periods.length; i++) - _frequencies[i] = new Frequency(periods[i]); + _statName = name; + _description = description; + _groupName = group; + _frequencies = new Frequency[periods.length]; + for (int i = 0; i < periods.length; i++) + _frequencies[i] = new Frequency(periods[i]); } /** update all of the frequencies for the various periods */ public void eventOccurred() { - for (int i = 0; i < _frequencies.length; i++) - _frequencies[i].eventOccurred(); + for (int i = 0; i < _frequencies.length; i++) + _frequencies[i].eventOccurred(); } /** coallesce all the stats */ public void coallesceStats() { - //for (int i = 0; i < _frequencies.length; i++) - // _frequencies[i].coallesceStats(); + //for (int i = 0; i < _frequencies.length; i++) + // _frequencies[i].coallesceStats(); } - public String getName() { return _statName; } - public String getGroupName() { return _groupName; } - public String getDescription() { return _description; } - public long[] getPeriods() { - long rv[] = new long[_frequencies.length]; - for (int i = 0; i < _frequencies.length; i++) - rv[i] = _frequencies[i].getPeriod(); - return rv; + public String getName() { + return _statName; } + + public String getGroupName() { + return _groupName; + } + + public String getDescription() { + return _description; + } + + public long[] getPeriods() { + long rv[] = new long[_frequencies.length]; + for (int i = 0; i < _frequencies.length; i++) + rv[i] = _frequencies[i].getPeriod(); + return rv; + } + public Frequency getFrequency(long period) { - for (int i = 0; i < _frequencies.length; i++) { - if (_frequencies[i].getPeriod() == period) - return _frequencies[i]; - } - return null; - } - public int hashCode() { return _statName.hashCode(); } -} + for (int i = 0; i < _frequencies.length; i++) { + if (_frequencies[i].getPeriod() == period) return _frequencies[i]; + } + return null; + } + + public int hashCode() { + return _statName.hashCode(); + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/PersistenceHelper.java b/core/java/src/net/i2p/stat/PersistenceHelper.java index 73e3925837918ea9c5000d83f4a4e9272402ce2a..764b0c8aa4bf812d509063a196c0b51eb57e90a0 100644 --- a/core/java/src/net/i2p/stat/PersistenceHelper.java +++ b/core/java/src/net/i2p/stat/PersistenceHelper.java @@ -1,6 +1,7 @@ package net.i2p.stat; import java.util.Properties; + import net.i2p.util.Log; /** object orientation gives you hairy palms. */ @@ -9,42 +10,42 @@ class PersistenceHelper { private final static String NL = System.getProperty("line.separator"); public final static void add(StringBuffer buf, String prefix, String name, String description, double value) { - buf.append("# ").append(prefix.toUpperCase()).append(name.toUpperCase()).append(NL); - buf.append("# ").append(description).append(NL); - buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL); + buf.append("# ").append(prefix.toUpperCase()).append(name.toUpperCase()).append(NL); + buf.append("# ").append(description).append(NL); + buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL); } - + public final static void add(StringBuffer buf, String prefix, String name, String description, long value) { - buf.append("# ").append(prefix.toUpperCase()).append(name.toUpperCase()).append(NL); - buf.append("# ").append(description).append(NL); - buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL); + buf.append("# ").append(prefix.toUpperCase()).append(name.toUpperCase()).append(NL); + buf.append("# ").append(description).append(NL); + buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL); } - + public final static long getLong(Properties props, String prefix, String name) { - String val = props.getProperty(prefix + name); - if (val != null) { - try { - return Long.parseLong(val); - } catch (NumberFormatException nfe) { - _log.error("Error formatting " + val + " into a long", nfe); - } - } else { - _log.error("Key " + prefix + name + " does not exist"); - } - return 0; + String val = props.getProperty(prefix + name); + if (val != null) { + try { + return Long.parseLong(val); + } catch (NumberFormatException nfe) { + _log.error("Error formatting " + val + " into a long", nfe); + } + } else { + _log.error("Key " + prefix + name + " does not exist"); + } + return 0; } - + public final static double getDouble(Properties props, String prefix, String name) { - String val = props.getProperty(prefix + name); - if (val != null) { - try { - return Double.parseDouble(val); - } catch (NumberFormatException nfe) { - _log.error("Error formatting " + val + " into a double", nfe); - } - } else { - _log.error("Key " + prefix + name + " does not exist"); - } - return 0; + String val = props.getProperty(prefix + name); + if (val != null) { + try { + return Double.parseDouble(val); + } catch (NumberFormatException nfe) { + _log.error("Error formatting " + val + " into a double", nfe); + } + } else { + _log.error("Key " + prefix + name + " does not exist"); + } + return 0; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/Rate.java b/core/java/src/net/i2p/stat/Rate.java index 1101d2fb485ea7977379713105dfa65337508e8d..fb2dae576740437f9c8ab738bf2213069d1d1898 100644 --- a/core/java/src/net/i2p/stat/Rate.java +++ b/core/java/src/net/i2p/stat/Rate.java @@ -27,70 +27,114 @@ public class Rate { private volatile double _lifetimeTotalValue; private volatile long _lifetimeEventCount; private volatile long _lifetimeTotalEventTime; - + private volatile long _lastCoallesceDate; private long _creationDate; private long _period; - + /** locked during coallesce and addData */ private Object _lock = new Object(); - + /** in the current (partial) period, what is the total value acrued through all events? */ - public double getCurrentTotalValue() { return _currentTotalValue; } + public double getCurrentTotalValue() { + return _currentTotalValue; + } + /** in the current (partial) period, how many events have occurred? */ - public long getCurrentEventCount() { return _currentEventCount; } + public long getCurrentEventCount() { + return _currentEventCount; + } + /** in the current (partial) period, how much of the time has been spent doing the events? */ - public long getCurrentTotalEventTime() { return _currentTotalEventTime; } + public long getCurrentTotalEventTime() { + return _currentTotalEventTime; + } + /** in the last full period, what was the total value acrued through all events? */ - public double getLastTotalValue() { return _lastTotalValue; } + public double getLastTotalValue() { + return _lastTotalValue; + } + /** in the last full period, how many events occurred? */ - public long getLastEventCount() { return _lastEventCount; } + public long getLastEventCount() { + return _lastEventCount; + } + /** in the last full period, how much of the time was spent doing the events? */ - public long getLastTotalEventTime() { return _lastTotalEventTime; } + public long getLastTotalEventTime() { + return _lastTotalEventTime; + } + /** what was the max total value acrued in any period? */ - public double getExtremeTotalValue() { return _extremeTotalValue; } + public double getExtremeTotalValue() { + return _extremeTotalValue; + } + /** when the max(totalValue) was achieved, how many events occurred in that period? */ - public long getExtremeEventCount() { return _extremeEventCount; } + public long getExtremeEventCount() { + return _extremeEventCount; + } + /** when the max(totalValue) was achieved, how much of the time was spent doing the events? */ - public long getExtremeTotalEventTime() { return _extremeTotalEventTime; } + public long getExtremeTotalEventTime() { + return _extremeTotalEventTime; + } + /** since rate creation, what was the total value acrued through all events? */ - public double getLifetimeTotalValue() { return _lifetimeTotalValue; } + public double getLifetimeTotalValue() { + return _lifetimeTotalValue; + } + /** since rate creation, how many events have occurred? */ - public long getLifetimeEventCount() { return _lifetimeEventCount; } + public long getLifetimeEventCount() { + return _lifetimeEventCount; + } + /** since rate creation, how much of the time was spent doing the events? */ - public long getLifetimeTotalEventTime() { return _lifetimeTotalEventTime; } + public long getLifetimeTotalEventTime() { + return _lifetimeTotalEventTime; + } + /** when was the rate last coallesced? */ - public long getLastCoallesceDate() { return _lastCoallesceDate; } + public long getLastCoallesceDate() { + return _lastCoallesceDate; + } + /** when was this rate created? */ - public long getCreationDate() { return _creationDate; } + public long getCreationDate() { + return _creationDate; + } + /** how large should this rate's cycle be? */ - public long getPeriod() { return _period; } - + public long getPeriod() { + return _period; + } + /** * * @param period number of milliseconds in the period this rate deals with * @throws IllegalArgumentException if the period is not greater than 0 */ public Rate(long period) throws IllegalArgumentException { - if (period <= 0) throw new IllegalArgumentException("The period must be strictly positive"); - _currentTotalValue = 0.0d; - _currentEventCount = 0; - _currentTotalEventTime = 0; - _lastTotalValue = 0.0d; - _lastEventCount = 0; - _lastTotalEventTime = 0; - _extremeTotalValue = 0.0d; - _extremeEventCount = 0; - _extremeTotalEventTime = 0; - _lifetimeTotalValue = 0.0d; - _lifetimeEventCount = 0; - _lifetimeTotalEventTime = 0; - - _creationDate = now(); - _lastCoallesceDate = _creationDate; - _period = period; - } - + if (period <= 0) throw new IllegalArgumentException("The period must be strictly positive"); + _currentTotalValue = 0.0d; + _currentEventCount = 0; + _currentTotalEventTime = 0; + _lastTotalValue = 0.0d; + _lastEventCount = 0; + _lastTotalEventTime = 0; + _extremeTotalValue = 0.0d; + _extremeEventCount = 0; + _extremeTotalEventTime = 0; + _lifetimeTotalValue = 0.0d; + _lifetimeEventCount = 0; + _lifetimeTotalEventTime = 0; + + _creationDate = now(); + _lastCoallesceDate = _creationDate; + _period = period; + } + /** * Create a new rate and load its state from the properties, taking data * from the data points underneath the given prefix. <p /> @@ -105,13 +149,15 @@ public class Rate { * @throws IllegalArgumentException if the data was formatted incorrectly */ public Rate(Properties props, String prefix, boolean treatAsCurrent) throws IllegalArgumentException { - this(1); - load(props, prefix, treatAsCurrent); + this(1); + load(props, prefix, treatAsCurrent); } - - + /** accrue the data in the current period as an instantaneous event */ - public void addData(long value) { addData(value, 0); } + public void addData(long value) { + addData(value, 0); + } + /** * Accrue the data in the current period as if the event took the specified amount of time * @@ -119,72 +165,72 @@ public class Rate { * @param eventDuration how long it took to accrue this data (set to 0 if it was instantaneous) */ public void addData(long value, long eventDuration) { - synchronized (_lock) { - _currentTotalValue += value; - _currentEventCount++; - _currentTotalEventTime += eventDuration; - - _lifetimeTotalValue += value; - _lifetimeEventCount++; - _lifetimeTotalEventTime += eventDuration; - } - } - + synchronized (_lock) { + _currentTotalValue += value; + _currentEventCount++; + _currentTotalEventTime += eventDuration; + + _lifetimeTotalValue += value; + _lifetimeEventCount++; + _lifetimeTotalEventTime += eventDuration; + } + } + public void coallesce() { - synchronized (_lock) { - long now = now(); - long measuredPeriod = now - _lastCoallesceDate; - if (measuredPeriod < _period) { - // no need to coallesce - return; - } else { - // ok ok, lets coallesce - - // how much were we off by? (so that we can sample down the measured values) - double periodFactor = measuredPeriod / _period; - _lastTotalValue = (_currentTotalValue == 0 ? 0.0d : _currentTotalValue / periodFactor); - _lastEventCount = (_currentEventCount == 0 ? 0l : (long)(_currentEventCount / periodFactor)); - _lastTotalEventTime = (_currentTotalEventTime == 0 ? 0l : (long)(_currentTotalEventTime / periodFactor)); - _lastCoallesceDate = now; - - if (_lastTotalValue > _extremeTotalValue) { - _extremeTotalValue = _lastTotalValue; - _extremeEventCount = _lastEventCount; - _extremeTotalEventTime = _lastTotalEventTime; - } - - _currentTotalValue = 0.0d; - _currentEventCount = 0; - _currentTotalEventTime = 0; - } - } + synchronized (_lock) { + long now = now(); + long measuredPeriod = now - _lastCoallesceDate; + if (measuredPeriod < _period) { + // no need to coallesce + return; + } else { + // ok ok, lets coallesce + + // how much were we off by? (so that we can sample down the measured values) + double periodFactor = measuredPeriod / _period; + _lastTotalValue = (_currentTotalValue == 0 ? 0.0d : _currentTotalValue / periodFactor); + _lastEventCount = (_currentEventCount == 0 ? 0l : (long) (_currentEventCount / periodFactor)); + _lastTotalEventTime = (_currentTotalEventTime == 0 ? 0l + : (long) (_currentTotalEventTime / periodFactor)); + _lastCoallesceDate = now; + + if (_lastTotalValue > _extremeTotalValue) { + _extremeTotalValue = _lastTotalValue; + _extremeEventCount = _lastEventCount; + _extremeTotalEventTime = _lastTotalEventTime; + } + + _currentTotalValue = 0.0d; + _currentEventCount = 0; + _currentTotalEventTime = 0; + } + } } /** what was the average value across the events in the last period? */ - public double getAverageValue() { - if ( (_lastTotalValue != 0) && (_lastEventCount > 0) ) - return _lastTotalValue / _lastEventCount; - else - return 0.0d; + public double getAverageValue() { + if ((_lastTotalValue != 0) && (_lastEventCount > 0)) + return _lastTotalValue / _lastEventCount; + else + return 0.0d; } /** what was the average value across the events in the most active period? */ - public double getExtremeAverageValue() { - if ( (_extremeTotalValue != 0) && (_extremeEventCount > 0) ) - return _extremeTotalValue / _extremeEventCount; - else - return 0.0d; + public double getExtremeAverageValue() { + if ((_extremeTotalValue != 0) && (_extremeEventCount > 0)) + return _extremeTotalValue / _extremeEventCount; + else + return 0.0d; } - + /** what was the average value across the events since the stat was created? */ - public double getLifetimeAverageValue() { - if ( (_lifetimeTotalValue != 0) && (_lifetimeEventCount > 0) ) - return _lifetimeTotalValue / _lifetimeEventCount; - else - return 0.0d; - } - - + public double getLifetimeAverageValue() { + if ((_lifetimeTotalValue != 0) && (_lifetimeEventCount > 0)) + return _lifetimeTotalValue / _lifetimeEventCount; + else + return 0.0d; + } + /** * During the last period, how much of the time was spent actually processing events in proportion * to how many events could have occurred if there were no intervals? @@ -192,16 +238,16 @@ public class Rate { * @return percentage, or 0 if event times aren't used */ public double getLastEventSaturation() { - if ( (_lastEventCount > 0) && (_lastTotalEventTime > 0) ) { - double eventTime = (double)_lastTotalEventTime / (double)_lastEventCount; - double maxEvents = (double)_period / eventTime; - double saturation = _lastEventCount / maxEvents; - return saturation; - } else { - return 0.0d; - } - } - + if ((_lastEventCount > 0) && (_lastTotalEventTime > 0)) { + double eventTime = (double) _lastTotalEventTime / (double) _lastEventCount; + double maxEvents = (double) _period / eventTime; + double saturation = _lastEventCount / maxEvents; + return saturation; + } else { + return 0.0d; + } + } + /** * During the extreme period, how much of the time was spent actually processing events * in proportion to how many events could have occurred if there were no intervals? @@ -209,15 +255,15 @@ public class Rate { * @return percentage, or 0 if the statistic doesn't use event times */ public double getExtremeEventSaturation() { - if ( (_extremeEventCount > 0) && (_extremeTotalEventTime > 0) ) { - double eventTime = (double)_extremeTotalEventTime / (double)_extremeEventCount; - double maxEvents = (double)_period / eventTime; - return _extremeEventCount / maxEvents; - } else { - return 0.0d; - } - } - + if ((_extremeEventCount > 0) && (_extremeTotalEventTime > 0)) { + double eventTime = (double) _extremeTotalEventTime / (double) _extremeEventCount; + double maxEvents = (double) _period / eventTime; + return _extremeEventCount / maxEvents; + } else { + return 0.0d; + } + } + /** * During the lifetime of this stat, how much of the time was spent actually processing events in proportion * to how many events could have occurred if there were no intervals? @@ -225,24 +271,24 @@ public class Rate { * @return percentage, or 0 if event times aren't used */ public double getLifetimeEventSaturation() { - if ( (_lastEventCount > 0) && (_lifetimeTotalEventTime > 0) ) { - double eventTime = (double)_lifetimeTotalEventTime / (double)_lifetimeEventCount; - double maxEvents = (double)_period / eventTime; - double numPeriods = getLifetimePeriods(); - double avgEventsPerPeriod = _lifetimeEventCount / numPeriods; - return avgEventsPerPeriod / maxEvents; - } else { - return 0.0d; - } - } - + if ((_lastEventCount > 0) && (_lifetimeTotalEventTime > 0)) { + double eventTime = (double) _lifetimeTotalEventTime / (double) _lifetimeEventCount; + double maxEvents = (double) _period / eventTime; + double numPeriods = getLifetimePeriods(); + double avgEventsPerPeriod = _lifetimeEventCount / numPeriods; + return avgEventsPerPeriod / maxEvents; + } else { + return 0.0d; + } + } + /** how many periods have we already completed? */ public long getLifetimePeriods() { - long lifetime = now() - _creationDate; - double periods = lifetime / (double)_period; - return (long)Math.floor(periods); + long lifetime = now() - _creationDate; + double periods = lifetime / (double) _period; + return (long) Math.floor(periods); } - + /** * using the last period's rate, what is the total value that could have been sent * if events were constant? @@ -250,17 +296,17 @@ public class Rate { * @return max total value, or 0 if event times aren't used */ public double getLastSaturationLimit() { - if ( (_lastTotalValue != 0) && (_lastEventCount > 0) && (_lastTotalEventTime > 0) ) { - double saturation = getLastEventSaturation(); - if (saturation != 0.0d) - return _lastTotalValue / saturation; - else - return 0.0d; - } else { - return 0.0d; - } - } - + if ((_lastTotalValue != 0) && (_lastEventCount > 0) && (_lastTotalEventTime > 0)) { + double saturation = getLastEventSaturation(); + if (saturation != 0.0d) + return _lastTotalValue / saturation; + else + return 0.0d; + } else { + return 0.0d; + } + } + /** * using the extreme period's rate, what is the total value that could have been * sent if events were constant? @@ -268,62 +314,83 @@ public class Rate { * @return event total at saturation, or 0 if no event times are measured */ public double getExtremeSaturationLimit() { - if ( (_extremeTotalValue != 0) && (_extremeEventCount > 0) && (_extremeTotalEventTime > 0) ) { - double saturation = getExtremeEventSaturation(); - if (saturation != 0.0d) - return _extremeTotalValue / saturation; - else - return 0.0d; - } else { - return 0.0d; - } - } - + if ((_extremeTotalValue != 0) && (_extremeEventCount > 0) && (_extremeTotalEventTime > 0)) { + double saturation = getExtremeEventSaturation(); + if (saturation != 0.0d) + return _extremeTotalValue / saturation; + else + return 0.0d; + } else { + return 0.0d; + } + } + /** * How large was the last period's value as compared to the largest period ever? * */ public double getPercentageOfExtremeValue() { - if ( (_lastTotalValue != 0) && (_extremeTotalValue != 0) ) - return _lastTotalValue / _extremeTotalValue; - else - return 0.0d; + if ((_lastTotalValue != 0) && (_extremeTotalValue != 0)) + return _lastTotalValue / _extremeTotalValue; + else + return 0.0d; } - + /** * How large was the last period's value as compared to the lifetime average value? * */ public double getPercentageOfLifetimeValue() { - if ( (_lastTotalValue != 0) && (_lifetimeTotalValue != 0) ) { - double lifetimePeriodValue = _period * (_lifetimeTotalValue / (now() - _creationDate)); - return _lastTotalValue / lifetimePeriodValue; - } else { - return 0.0d; - } - } - + if ((_lastTotalValue != 0) && (_lifetimeTotalValue != 0)) { + double lifetimePeriodValue = _period * (_lifetimeTotalValue / (now() - _creationDate)); + return _lastTotalValue / lifetimePeriodValue; + } else { + return 0.0d; + } + } + public void store(OutputStream out, String prefix) throws IOException { - StringBuffer buf = new StringBuffer(2048); - PersistenceHelper.add(buf, prefix, ".period", "Number of milliseconds in the period", _period); - PersistenceHelper.add(buf, prefix, ".creationDate", "When was this rate created? (milliseconds since the epoch, GMT)", _creationDate); - PersistenceHelper.add(buf, prefix, ".lastCoallesceDate", "When did we last coallesce this rate? (milliseconds since the epoch, GMT)", _lastCoallesceDate); - PersistenceHelper.add(buf, prefix, ".currentDate", "When did this data get written? (milliseconds since the epoch, GMT)", now()); - PersistenceHelper.add(buf, prefix, ".currentTotalValue", "Total value of data points in the current (uncoallesced) period", _currentTotalValue); - PersistenceHelper.add(buf, prefix, ".currentEventCount", "How many events have occurred in the current (uncoallesced) period?", _currentEventCount); - PersistenceHelper.add(buf, prefix, ".currentTotalEventTime", "How many milliseconds have the events in the current (uncoallesced) period consumed?", _currentTotalEventTime); - PersistenceHelper.add(buf, prefix, ".lastTotalValue", "Total value of data points in the most recent (coallesced) period", _lastTotalValue); - PersistenceHelper.add(buf, prefix, ".lastEventCount", "How many events have occurred in the most recent (coallesced) period?", _lastEventCount); - PersistenceHelper.add(buf, prefix, ".lastTotalEventTime", "How many milliseconds have the events in the most recent (coallesced) period consumed?", _lastTotalEventTime); - PersistenceHelper.add(buf, prefix, ".extremeTotalValue", "Total value of data points in the most extreme period", _extremeTotalValue); - PersistenceHelper.add(buf, prefix, ".extremeEventCount", "How many events have occurred in the most extreme period?", _extremeEventCount); - PersistenceHelper.add(buf, prefix, ".extremeTotalEventTime", "How many milliseconds have the events in the most extreme period consumed?", _extremeTotalEventTime); - PersistenceHelper.add(buf, prefix, ".lifetimeTotalValue", "Total value of data points since this stat was created", _lifetimeTotalValue); - PersistenceHelper.add(buf, prefix, ".lifetimeEventCount", "How many events have occurred since this stat was created?", _lifetimeEventCount); - PersistenceHelper.add(buf, prefix, ".lifetimeTotalEventTime", "How many milliseconds have the events since this stat was created consumed?", _lifetimeTotalEventTime); - out.write(buf.toString().getBytes()); - } - + StringBuffer buf = new StringBuffer(2048); + PersistenceHelper.add(buf, prefix, ".period", "Number of milliseconds in the period", _period); + PersistenceHelper.add(buf, prefix, ".creationDate", + "When was this rate created? (milliseconds since the epoch, GMT)", _creationDate); + PersistenceHelper.add(buf, prefix, ".lastCoallesceDate", + "When did we last coallesce this rate? (milliseconds since the epoch, GMT)", + _lastCoallesceDate); + PersistenceHelper.add(buf, prefix, ".currentDate", + "When did this data get written? (milliseconds since the epoch, GMT)", now()); + PersistenceHelper.add(buf, prefix, ".currentTotalValue", + "Total value of data points in the current (uncoallesced) period", _currentTotalValue); + PersistenceHelper + .add(buf, prefix, ".currentEventCount", + "How many events have occurred in the current (uncoallesced) period?", _currentEventCount); + PersistenceHelper.add(buf, prefix, ".currentTotalEventTime", + "How many milliseconds have the events in the current (uncoallesced) period consumed?", + _currentTotalEventTime); + PersistenceHelper.add(buf, prefix, ".lastTotalValue", + "Total value of data points in the most recent (coallesced) period", _lastTotalValue); + PersistenceHelper.add(buf, prefix, ".lastEventCount", + "How many events have occurred in the most recent (coallesced) period?", _lastEventCount); + PersistenceHelper.add(buf, prefix, ".lastTotalEventTime", + "How many milliseconds have the events in the most recent (coallesced) period consumed?", + _lastTotalEventTime); + PersistenceHelper.add(buf, prefix, ".extremeTotalValue", + "Total value of data points in the most extreme period", _extremeTotalValue); + PersistenceHelper.add(buf, prefix, ".extremeEventCount", + "How many events have occurred in the most extreme period?", _extremeEventCount); + PersistenceHelper.add(buf, prefix, ".extremeTotalEventTime", + "How many milliseconds have the events in the most extreme period consumed?", + _extremeTotalEventTime); + PersistenceHelper.add(buf, prefix, ".lifetimeTotalValue", + "Total value of data points since this stat was created", _lifetimeTotalValue); + PersistenceHelper.add(buf, prefix, ".lifetimeEventCount", + "How many events have occurred since this stat was created?", _lifetimeEventCount); + PersistenceHelper.add(buf, prefix, ".lifetimeTotalEventTime", + "How many milliseconds have the events since this stat was created consumed?", + _lifetimeTotalEventTime); + out.write(buf.toString().getBytes()); + } + /** * Load this rate from the properties, taking data from the data points * underneath the given prefix. @@ -335,98 +402,100 @@ public class Rate { * @throws IllegalArgumentException if the data was formatted incorrectly */ public void load(Properties props, String prefix, boolean treatAsCurrent) throws IllegalArgumentException { - _period = PersistenceHelper.getLong(props, prefix, ".period"); - _creationDate = PersistenceHelper.getLong(props, prefix, ".creationDate"); - _lastCoallesceDate = PersistenceHelper.getLong(props, prefix, ".lastCoallesceDate"); - _currentTotalValue = PersistenceHelper.getDouble(props, prefix, ".currentTotalValue"); - _currentEventCount = PersistenceHelper.getLong(props, prefix, ".currentEventCount"); - _currentTotalEventTime = PersistenceHelper.getLong(props, prefix, ".currentTotalEventTime"); - _lastTotalValue = PersistenceHelper.getDouble(props, prefix, ".lastTotalValue"); - _lastEventCount = PersistenceHelper.getLong(props, prefix, ".lastEventCount"); - _lastTotalEventTime = PersistenceHelper.getLong(props, prefix, ".lastTotalEventTime"); - _extremeTotalValue = PersistenceHelper.getDouble(props, prefix, ".extremeTotalValue"); - _extremeEventCount = PersistenceHelper.getLong(props, prefix, ".extremeEventCount"); - _extremeTotalEventTime = PersistenceHelper.getLong(props, prefix, ".extremeTotalEventTime"); - _lifetimeTotalValue = PersistenceHelper.getDouble(props, prefix, ".lifetimeTotalValue"); - _lifetimeEventCount = PersistenceHelper.getLong(props, prefix, ".lifetimeEventCount"); - _lifetimeTotalEventTime = PersistenceHelper.getLong(props, prefix, ".lifetimeTotalEventTime"); - - if (treatAsCurrent) - _lastCoallesceDate = now(); - - if (_period <= 0) - throw new IllegalArgumentException("Period for " + prefix + " is invalid"); - coallesce(); - } - + _period = PersistenceHelper.getLong(props, prefix, ".period"); + _creationDate = PersistenceHelper.getLong(props, prefix, ".creationDate"); + _lastCoallesceDate = PersistenceHelper.getLong(props, prefix, ".lastCoallesceDate"); + _currentTotalValue = PersistenceHelper.getDouble(props, prefix, ".currentTotalValue"); + _currentEventCount = PersistenceHelper.getLong(props, prefix, ".currentEventCount"); + _currentTotalEventTime = PersistenceHelper.getLong(props, prefix, ".currentTotalEventTime"); + _lastTotalValue = PersistenceHelper.getDouble(props, prefix, ".lastTotalValue"); + _lastEventCount = PersistenceHelper.getLong(props, prefix, ".lastEventCount"); + _lastTotalEventTime = PersistenceHelper.getLong(props, prefix, ".lastTotalEventTime"); + _extremeTotalValue = PersistenceHelper.getDouble(props, prefix, ".extremeTotalValue"); + _extremeEventCount = PersistenceHelper.getLong(props, prefix, ".extremeEventCount"); + _extremeTotalEventTime = PersistenceHelper.getLong(props, prefix, ".extremeTotalEventTime"); + _lifetimeTotalValue = PersistenceHelper.getDouble(props, prefix, ".lifetimeTotalValue"); + _lifetimeEventCount = PersistenceHelper.getLong(props, prefix, ".lifetimeEventCount"); + _lifetimeTotalEventTime = PersistenceHelper.getLong(props, prefix, ".lifetimeTotalEventTime"); + + if (treatAsCurrent) _lastCoallesceDate = now(); + + if (_period <= 0) throw new IllegalArgumentException("Period for " + prefix + " is invalid"); + coallesce(); + } + public boolean equals(Object obj) { - if ( (obj == null) || (obj.getClass() != Rate.class) ) return false; - Rate r = (Rate)obj; - return _period == r.getPeriod() && - _creationDate == r.getCreationDate() && - //_lastCoallesceDate == r.getLastCoallesceDate() && - _currentTotalValue == r.getCurrentTotalValue() && - _currentEventCount == r.getCurrentEventCount() && - _currentTotalEventTime == r.getCurrentTotalEventTime() && - _lastTotalValue == r.getLastTotalValue() && - _lastEventCount == r.getLastEventCount() && - _lastTotalEventTime == r.getLastTotalEventTime() && - _extremeTotalValue == r.getExtremeTotalValue() && - _extremeEventCount == r.getExtremeEventCount() && - _extremeTotalEventTime == r.getExtremeTotalEventTime() && - _lifetimeTotalValue == r.getLifetimeTotalValue() && - _lifetimeEventCount == r.getLifetimeEventCount() && - _lifetimeTotalEventTime == r.getLifetimeTotalEventTime(); - } - + if ((obj == null) || (obj.getClass() != Rate.class)) return false; + Rate r = (Rate) obj; + return _period == r.getPeriod() && _creationDate == r.getCreationDate() && + //_lastCoallesceDate == r.getLastCoallesceDate() && + _currentTotalValue == r.getCurrentTotalValue() && _currentEventCount == r.getCurrentEventCount() + && _currentTotalEventTime == r.getCurrentTotalEventTime() && _lastTotalValue == r.getLastTotalValue() + && _lastEventCount == r.getLastEventCount() && _lastTotalEventTime == r.getLastTotalEventTime() + && _extremeTotalValue == r.getExtremeTotalValue() && _extremeEventCount == r.getExtremeEventCount() + && _extremeTotalEventTime == r.getExtremeTotalEventTime() + && _lifetimeTotalValue == r.getLifetimeTotalValue() && _lifetimeEventCount == r.getLifetimeEventCount() + && _lifetimeTotalEventTime == r.getLifetimeTotalEventTime(); + } + public String toString() { - StringBuffer buf = new StringBuffer(2048); - buf.append("\n\t total value: ").append(getLastTotalValue()); - buf.append("\n\t highest total value: ").append(getExtremeTotalValue()); - buf.append("\n\t lifetime total value: ").append(getLifetimeTotalValue()); - buf.append("\n\t # periods: ").append(getLifetimePeriods()); - buf.append("\n\t average value: ").append(getAverageValue()); - buf.append("\n\t highest average value: ").append(getExtremeAverageValue()); - buf.append("\n\t lifetime average value: ").append(getLifetimeAverageValue()); - buf.append("\n\t % of lifetime rate: ").append(100.0d * getPercentageOfLifetimeValue()); - buf.append("\n\t % of highest rate: ").append(100.0d * getPercentageOfExtremeValue()); - buf.append("\n\t # events: ").append(getLastEventCount()); - buf.append("\n\t lifetime events: ").append(getLifetimeEventCount()); - if (getLifetimeTotalEventTime() > 0) { - // we have some actual event durations - buf.append("\n\t % of time spent processing events: ").append(100.0d * getLastEventSaturation()); - buf.append("\n\t total value if we were always processing events: ").append(getLastSaturationLimit()); - buf.append("\n\t max % of time spent processing events: ").append(100.0d * getExtremeEventSaturation()); - buf.append("\n\t max total value if we were always processing events: ").append(getExtremeSaturationLimit()); - } - return buf.toString(); - } - private final static long now() { return Clock.getInstance().now(); } - + StringBuffer buf = new StringBuffer(2048); + buf.append("\n\t total value: ").append(getLastTotalValue()); + buf.append("\n\t highest total value: ").append(getExtremeTotalValue()); + buf.append("\n\t lifetime total value: ").append(getLifetimeTotalValue()); + buf.append("\n\t # periods: ").append(getLifetimePeriods()); + buf.append("\n\t average value: ").append(getAverageValue()); + buf.append("\n\t highest average value: ").append(getExtremeAverageValue()); + buf.append("\n\t lifetime average value: ").append(getLifetimeAverageValue()); + buf.append("\n\t % of lifetime rate: ").append(100.0d * getPercentageOfLifetimeValue()); + buf.append("\n\t % of highest rate: ").append(100.0d * getPercentageOfExtremeValue()); + buf.append("\n\t # events: ").append(getLastEventCount()); + buf.append("\n\t lifetime events: ").append(getLifetimeEventCount()); + if (getLifetimeTotalEventTime() > 0) { + // we have some actual event durations + buf.append("\n\t % of time spent processing events: ").append(100.0d * getLastEventSaturation()); + buf.append("\n\t total value if we were always processing events: ").append(getLastSaturationLimit()); + buf.append("\n\t max % of time spent processing events: ").append(100.0d * getExtremeEventSaturation()); + buf.append("\n\t max total value if we were always processing events: ") + .append(getExtremeSaturationLimit()); + } + return buf.toString(); + } + + private final static long now() { + return Clock.getInstance().now(); + } + public static void main(String args[]) { - Rate rate = new Rate(1000); - for (int i = 0; i < 50; i++) { - try { Thread.sleep(20); } catch (InterruptedException ie) {} - rate.addData(i*100, 20); - } - rate.coallesce(); - java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(2048); - try { - rate.store(baos, "rate.test"); - byte data[] = baos.toByteArray(); - _log.error("Stored rate: size = " + data.length + "\n" + new String(data)); - - Properties props = new Properties(); - props.load(new java.io.ByteArrayInputStream(data)); - - //_log.error("Properties loaded: \n" + props); - - Rate r = new Rate(props, "rate.test", true); - - _log.error("Comparison after store/load: " + r.equals(rate)); - } catch (Throwable t) { - _log.error("b0rk", t); - } - try { Thread.sleep(5000); } catch (InterruptedException ie) {} - } -} + Rate rate = new Rate(1000); + for (int i = 0; i < 50; i++) { + try { + Thread.sleep(20); + } catch (InterruptedException ie) { + } + rate.addData(i * 100, 20); + } + rate.coallesce(); + java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(2048); + try { + rate.store(baos, "rate.test"); + byte data[] = baos.toByteArray(); + _log.error("Stored rate: size = " + data.length + "\n" + new String(data)); + + Properties props = new Properties(); + props.load(new java.io.ByteArrayInputStream(data)); + + //_log.error("Properties loaded: \n" + props); + + Rate r = new Rate(props, "rate.test", true); + + _log.error("Comparison after store/load: " + r.equals(rate)); + } catch (Throwable t) { + _log.error("b0rk", t); + } + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/RateStat.java b/core/java/src/net/i2p/stat/RateStat.java index 55cdbef0cee90566a479f7842cdd5e60d405fec8..f770f0eb9f38ea7427e3c4ccec94b3d5446a51eb 100644 --- a/core/java/src/net/i2p/stat/RateStat.java +++ b/core/java/src/net/i2p/stat/RateStat.java @@ -1,8 +1,7 @@ package net.i2p.stat; -import java.io.OutputStream; import java.io.IOException; - +import java.io.OutputStream; import java.util.Arrays; import java.util.Properties; @@ -22,98 +21,108 @@ public class RateStat { private Rate _rates[]; public RateStat(String name, String description, String group, long periods[]) { - _statName = name; - _description = description; - _groupName = group; - _rates = new Rate[periods.length]; - for (int i = 0; i < periods.length; i++) - _rates[i] = new Rate(periods[i]); + _statName = name; + _description = description; + _groupName = group; + _rates = new Rate[periods.length]; + for (int i = 0; i < periods.length; i++) + _rates[i] = new Rate(periods[i]); } /** * update all of the rates for the various periods with the given value. */ public void addData(long value, long eventDuration) { - for (int i = 0; i < _rates.length; i++) - _rates[i].addData(value, eventDuration); + for (int i = 0; i < _rates.length; i++) + _rates[i].addData(value, eventDuration); } /** coallesce all the stats */ public void coallesceStats() { - for (int i = 0; i < _rates.length; i++) - _rates[i].coallesce(); + for (int i = 0; i < _rates.length; i++) + _rates[i].coallesce(); } + public String getName() { + return _statName; + } + + public String getGroupName() { + return _groupName; + } - public String getName() { return _statName; } - public String getGroupName() { return _groupName; } - public String getDescription() { return _description; } - public long[] getPeriods() { - long rv[] = new long[_rates.length]; - for (int i = 0; i < _rates.length; i++) - rv[i] = _rates[i].getPeriod(); - return rv; + public String getDescription() { + return _description; } + + public long[] getPeriods() { + long rv[] = new long[_rates.length]; + for (int i = 0; i < _rates.length; i++) + rv[i] = _rates[i].getPeriod(); + return rv; + } + public Rate getRate(long period) { - for (int i = 0; i < _rates.length; i++) { - if (_rates[i].getPeriod() == period) - return _rates[i]; - } - return null; + for (int i = 0; i < _rates.length; i++) { + if (_rates[i].getPeriod() == period) return _rates[i]; + } + return null; + } + + public int hashCode() { + return _statName.hashCode(); } - public int hashCode() { return _statName.hashCode(); } - - + private final static String NL = System.getProperty("line.separator"); + public String toString() { - StringBuffer buf = new StringBuffer(512); - buf.append(getGroupName()).append('.').append(getName()).append(": ").append(getDescription()).append('\n'); - long periods[] = getPeriods(); - Arrays.sort(periods); - for (int i = 0; i < periods.length; i++) { - buf.append('\t').append(periods[i]).append(':'); - Rate curRate = getRate(periods[i]); - buf.append(curRate.toString()); - buf.append(NL); - } - return buf.toString(); + StringBuffer buf = new StringBuffer(512); + buf.append(getGroupName()).append('.').append(getName()).append(": ").append(getDescription()).append('\n'); + long periods[] = getPeriods(); + Arrays.sort(periods); + for (int i = 0; i < periods.length; i++) { + buf.append('\t').append(periods[i]).append(':'); + Rate curRate = getRate(periods[i]); + buf.append(curRate.toString()); + buf.append(NL); + } + return buf.toString(); } - + public boolean equals(Object obj) { - if ( (obj == null) || (obj.getClass() != RateStat.class) ) return false; - RateStat rs = (RateStat)obj; - if (DataHelper.eq(getGroupName(), rs.getGroupName()) && - DataHelper.eq(getDescription(), rs.getDescription()) && - DataHelper.eq(getName(), rs.getName())) { - for (int i = 0; i < _rates.length; i++) - if (!_rates[i].equals(rs.getRate(_rates[i].getPeriod()))) - return false; - return true; - } else { - return false; - } + if ((obj == null) || (obj.getClass() != RateStat.class)) return false; + RateStat rs = (RateStat) obj; + if (DataHelper.eq(getGroupName(), rs.getGroupName()) && DataHelper.eq(getDescription(), rs.getDescription()) + && DataHelper.eq(getName(), rs.getName())) { + for (int i = 0; i < _rates.length; i++) + if (!_rates[i].equals(rs.getRate(_rates[i].getPeriod()))) return false; + return true; + } else { + return false; + } } - + public void store(OutputStream out, String prefix) throws IOException { - StringBuffer buf = new StringBuffer(128); - buf.append(NL); - buf.append("################################################################################").append(NL); - buf.append("# Rate: ").append(_groupName).append(": ").append(_statName).append(NL); - buf.append("# ").append(_description).append(NL); - buf.append("# ").append(NL).append(NL); - out.write(buf.toString().getBytes()); - buf = null; - for (int i = 0; i < _rates.length; i++) { - StringBuffer rbuf = new StringBuffer(256); - rbuf.append("#######").append(NL); - rbuf.append("# Period : ").append(DataHelper.formatDuration(_rates[i].getPeriod())).append(" for rate ").append(_groupName).append(" - ").append(_statName).append(NL); - rbuf.append(NL); - out.write(rbuf.toString().getBytes()); - String curPrefix = prefix + "." + DataHelper.formatDuration(_rates[i].getPeriod()); - _rates[i].store(out, curPrefix); - } + StringBuffer buf = new StringBuffer(128); + buf.append(NL); + buf.append("################################################################################").append(NL); + buf.append("# Rate: ").append(_groupName).append(": ").append(_statName).append(NL); + buf.append("# ").append(_description).append(NL); + buf.append("# ").append(NL).append(NL); + out.write(buf.toString().getBytes()); + buf = null; + for (int i = 0; i < _rates.length; i++) { + StringBuffer rbuf = new StringBuffer(256); + rbuf.append("#######").append(NL); + rbuf.append("# Period : ").append(DataHelper.formatDuration(_rates[i].getPeriod())).append(" for rate ") + .append(_groupName).append(" - ").append(_statName).append(NL); + rbuf.append(NL); + out.write(rbuf.toString().getBytes()); + String curPrefix = prefix + "." + DataHelper.formatDuration(_rates[i].getPeriod()); + _rates[i].store(out, curPrefix); + } } - + /** * Load this rate stat from the properties, populating all of the rates contained * underneath it. The comes from the given prefix (e.g. if we are given the prefix @@ -129,44 +138,53 @@ public class RateStat { * @throws IllegalArgumentException if the data was formatted incorrectly */ public void load(Properties props, String prefix, boolean treatAsCurrent) throws IllegalArgumentException { - for (int i = 0; i < _rates.length; i++) { - long period = _rates[i].getPeriod(); - String curPrefix = prefix + "." + DataHelper.formatDuration(period); - try { - _rates[i].load(props, curPrefix, treatAsCurrent); - } catch (IllegalArgumentException iae) { - _rates[i] = new Rate(period); - if (_log.shouldLog(Log.WARN)) - _log.warn("Rate for " + prefix + " is corrupt, reinitializing that period"); - } - } + for (int i = 0; i < _rates.length; i++) { + long period = _rates[i].getPeriod(); + String curPrefix = prefix + "." + DataHelper.formatDuration(period); + try { + _rates[i].load(props, curPrefix, treatAsCurrent); + } catch (IllegalArgumentException iae) { + _rates[i] = new Rate(period); + if (_log.shouldLog(Log.WARN)) + _log.warn("Rate for " + prefix + " is corrupt, reinitializing that period"); + } + } } - + public static void main(String args[]) { - RateStat rs = new RateStat("moo", "moo moo moo", "cow trueisms", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 }); - for (int i = 0; i < 50; i++) { - try { Thread.sleep(20); } catch (InterruptedException ie) {} - rs.addData(i*100, 20); - } - rs.coallesceStats(); - java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(2048); - try { - rs.store(baos, "rateStat.test"); - byte data[] = baos.toByteArray(); - _log.error("Stored rateStat: size = " + data.length + "\n" + new String(data)); - - Properties props = new Properties(); - props.load(new java.io.ByteArrayInputStream(data)); - - //_log.error("Properties loaded: \n" + props); - - RateStat loadedRs = new RateStat("moo", "moo moo moo", "cow trueisms", new long[] { 60*1000, 60*60*1000, 24*60*60*1000 }); - loadedRs.load(props, "rateStat.test", true); - - _log.error("Comparison after store/load: " + rs.equals(loadedRs)); - } catch (Throwable t) { - _log.error("b0rk", t); - } - try { Thread.sleep(5000); } catch (InterruptedException ie) {} + RateStat rs = new RateStat("moo", "moo moo moo", "cow trueisms", new long[] { 60 * 1000, 60 * 60 * 1000, + 24 * 60 * 60 * 1000}); + for (int i = 0; i < 50; i++) { + try { + Thread.sleep(20); + } catch (InterruptedException ie) { + } + rs.addData(i * 100, 20); + } + rs.coallesceStats(); + java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(2048); + try { + rs.store(baos, "rateStat.test"); + byte data[] = baos.toByteArray(); + _log.error("Stored rateStat: size = " + data.length + "\n" + new String(data)); + + Properties props = new Properties(); + props.load(new java.io.ByteArrayInputStream(data)); + + //_log.error("Properties loaded: \n" + props); + + RateStat loadedRs = new RateStat("moo", "moo moo moo", "cow trueisms", new long[] { 60 * 1000, + 60 * 60 * 1000, + 24 * 60 * 60 * 1000}); + loadedRs.load(props, "rateStat.test", true); + + _log.error("Comparison after store/load: " + rs.equals(loadedRs)); + } catch (Throwable t) { + _log.error("b0rk", t); + } + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/SimpleStatDumper.java b/core/java/src/net/i2p/stat/SimpleStatDumper.java index 632cade5180ea822dc0c423d22a18131d5ba86a7..f4cecd395064d84578e21d5477e6670c1f36b820 100644 --- a/core/java/src/net/i2p/stat/SimpleStatDumper.java +++ b/core/java/src/net/i2p/stat/SimpleStatDumper.java @@ -1,62 +1,64 @@ package net.i2p.stat; -import net.i2p.util.Log; - +import java.util.Arrays; +import java.util.Iterator; import java.util.Set; import java.util.TreeSet; -import java.util.Iterator; -import java.util.Arrays; + +import net.i2p.util.Log; public class SimpleStatDumper { private final static Log _log = new Log(SimpleStatDumper.class); - + public static void dumpStats(int logLevel) { - if (!_log.shouldLog(logLevel)) return; - - StringBuffer buf = new StringBuffer(4*1024); - dumpFrequencies(buf); - dumpRates(buf); - _log.log(logLevel, buf.toString()); + if (!_log.shouldLog(logLevel)) return; + + StringBuffer buf = new StringBuffer(4 * 1024); + dumpFrequencies(buf); + dumpRates(buf); + _log.log(logLevel, buf.toString()); } - + private static void dumpFrequencies(StringBuffer buf) { - Set frequencies = new TreeSet(StatManager.getInstance().getFrequencyNames()); - for (Iterator iter = frequencies.iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); - FrequencyStat freq = StatManager.getInstance().getFrequency(name); - buf.append('\n'); - buf.append(freq.getGroupName()).append('.').append(freq.getName()).append(": ").append(freq.getDescription()).append('\n'); - long periods[] = freq.getPeriods(); - Arrays.sort(periods); - for (int i = 0; i < periods.length; i++) { - buf.append('\t').append(periods[i]).append(':'); - Frequency curFreq = freq.getFrequency(periods[i]); - buf.append(" average interval: ").append(curFreq.getAverageInterval()); - buf.append(" min average interval: ").append(curFreq.getMinAverageInterval()); - buf.append('\n'); - } - } + Set frequencies = new TreeSet(StatManager.getInstance().getFrequencyNames()); + for (Iterator iter = frequencies.iterator(); iter.hasNext();) { + String name = (String) iter.next(); + FrequencyStat freq = StatManager.getInstance().getFrequency(name); + buf.append('\n'); + buf.append(freq.getGroupName()).append('.').append(freq.getName()).append(": ") + .append(freq.getDescription()).append('\n'); + long periods[] = freq.getPeriods(); + Arrays.sort(periods); + for (int i = 0; i < periods.length; i++) { + buf.append('\t').append(periods[i]).append(':'); + Frequency curFreq = freq.getFrequency(periods[i]); + buf.append(" average interval: ").append(curFreq.getAverageInterval()); + buf.append(" min average interval: ").append(curFreq.getMinAverageInterval()); + buf.append('\n'); + } + } } - + private static void dumpRates(StringBuffer buf) { - Set rates = new TreeSet(StatManager.getInstance().getRateNames()); - for (Iterator iter = rates.iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); - RateStat rate = StatManager.getInstance().getRate(name); - buf.append('\n'); - buf.append(rate.getGroupName()).append('.').append(rate.getName()).append(": ").append(rate.getDescription()).append('\n'); - long periods[] = rate.getPeriods(); - Arrays.sort(periods); - for (int i = 0; i < periods.length; i++) { - buf.append('\t').append(periods[i]).append(':'); - Rate curRate = rate.getRate(periods[i]); - dumpRate(curRate, buf); - buf.append('\n'); - } - } + Set rates = new TreeSet(StatManager.getInstance().getRateNames()); + for (Iterator iter = rates.iterator(); iter.hasNext();) { + String name = (String) iter.next(); + RateStat rate = StatManager.getInstance().getRate(name); + buf.append('\n'); + buf.append(rate.getGroupName()).append('.').append(rate.getName()).append(": ") + .append(rate.getDescription()).append('\n'); + long periods[] = rate.getPeriods(); + Arrays.sort(periods); + for (int i = 0; i < periods.length; i++) { + buf.append('\t').append(periods[i]).append(':'); + Rate curRate = rate.getRate(periods[i]); + dumpRate(curRate, buf); + buf.append('\n'); + } + } } - + static void dumpRate(Rate curRate, StringBuffer buf) { - buf.append(curRate.toString()); + buf.append(curRate.toString()); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/SizeTest.java b/core/java/src/net/i2p/stat/SizeTest.java index 147c37243ccc133746d2191e820231da7bef86e5..aaf157c1aa26378f7498e3a46285dcd5a6b44892 100644 --- a/core/java/src/net/i2p/stat/SizeTest.java +++ b/core/java/src/net/i2p/stat/SizeTest.java @@ -1,55 +1,58 @@ package net.i2p.stat; - public class SizeTest { public static void main(String args[]) { - testRateSize(100); //117KB - testRateSize(100000); // 4.5MB - testRateSize(440000); // 44MB - //testFrequencySize(100); // 114KB - //testFrequencySize(100000); // 5.3MB - //testFrequencySize(1000000); // 52MB + testRateSize(100); //117KB + testRateSize(100000); // 4.5MB + testRateSize(440000); // 44MB + //testFrequencySize(100); // 114KB + //testFrequencySize(100000); // 5.3MB + //testFrequencySize(1000000); // 52MB } - + private static void testRateSize(int num) { - Runtime.getRuntime().gc(); - Rate rate[] = new Rate[num]; - long used = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); - long usedPer = used / num; - System.out.println(num+ ": create array - Used: " + used + " bytes (or " + usedPer + " bytes per array entry)"); - - int i = 0; - try { - for (; i < num; i++) - rate[i] = new Rate(1234); - } catch (OutOfMemoryError oom) { - rate = null; - Runtime.getRuntime().gc(); - System.out.println("Ran out of memory when creating rate " + i); - return; - } - Runtime.getRuntime().gc(); - long usedObjects = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); - usedPer = usedObjects / num; - System.out.println(num + ": create objects - Used: " + usedObjects + " bytes (or " + usedPer + " bytes per rate)"); - rate = null; - Runtime.getRuntime().gc(); + Runtime.getRuntime().gc(); + Rate rate[] = new Rate[num]; + long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + long usedPer = used / num; + System.out + .println(num + ": create array - Used: " + used + " bytes (or " + usedPer + " bytes per array entry)"); + + int i = 0; + try { + for (; i < num; i++) + rate[i] = new Rate(1234); + } catch (OutOfMemoryError oom) { + rate = null; + Runtime.getRuntime().gc(); + System.out.println("Ran out of memory when creating rate " + i); + return; + } + Runtime.getRuntime().gc(); + long usedObjects = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + usedPer = usedObjects / num; + System.out.println(num + ": create objects - Used: " + usedObjects + " bytes (or " + usedPer + + " bytes per rate)"); + rate = null; + Runtime.getRuntime().gc(); } - + private static void testFrequencySize(int num) { - Runtime.getRuntime().gc(); - Frequency freq[] = new Frequency[num]; - long used = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); - long usedPer = used / num; - System.out.println(num+ ": create array - Used: " + used + " bytes (or " + usedPer + " bytes per array entry)"); - - for (int i = 0; i < num; i++) - freq[i] = new Frequency(1234); - Runtime.getRuntime().gc(); - long usedObjects = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); - usedPer = usedObjects / num; - System.out.println(num + ": create objects - Used: " + usedObjects + " bytes (or " + usedPer + " bytes per frequency)"); - freq = null; - Runtime.getRuntime().gc(); + Runtime.getRuntime().gc(); + Frequency freq[] = new Frequency[num]; + long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + long usedPer = used / num; + System.out + .println(num + ": create array - Used: " + used + " bytes (or " + usedPer + " bytes per array entry)"); + + for (int i = 0; i < num; i++) + freq[i] = new Frequency(1234); + Runtime.getRuntime().gc(); + long usedObjects = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + usedPer = usedObjects / num; + System.out.println(num + ": create objects - Used: " + usedObjects + " bytes (or " + usedPer + + " bytes per frequency)"); + freq = null; + Runtime.getRuntime().gc(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/stat/StatManager.java b/core/java/src/net/i2p/stat/StatManager.java index ed50c540ebc0f87159c4c97e5aff06cf1f7c3004..1ef3f9c6122e83e3d4f2c0cab4884a76714ba6af 100644 --- a/core/java/src/net/i2p/stat/StatManager.java +++ b/core/java/src/net/i2p/stat/StatManager.java @@ -1,13 +1,13 @@ package net.i2p.stat; -import java.util.Map; +import java.util.Collections; import java.util.HashMap; -import java.util.Set; import java.util.HashSet; -import java.util.TreeSet; -import java.util.TreeMap; import java.util.Iterator; -import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import net.i2p.util.Log; @@ -21,17 +21,20 @@ import net.i2p.util.Log; public class StatManager { private final static Log _log = new Log(StatManager.class); private final static StatManager _instance = new StatManager(); - public final static StatManager getInstance() { return _instance; } + + public final static StatManager getInstance() { + return _instance; + } /** stat name to FrequencyStat */ private Map _frequencyStats; /** stat name to RateStat */ private Map _rateStats; - + private StatManager() { - _frequencyStats = Collections.synchronizedMap(new HashMap(128)); - _rateStats = Collections.synchronizedMap(new HashMap(128)); + _frequencyStats = Collections.synchronizedMap(new HashMap(128)); + _rateStats = Collections.synchronizedMap(new HashMap(128)); } - + /** * Create a new statistic to monitor the frequency of some event. * @@ -41,9 +44,9 @@ public class StatManager { * @param periods array of period lengths (in milliseconds) */ public void createFrequencyStat(String name, String description, String group, long periods[]) { - _frequencyStats.put(name, new FrequencyStat(name, description, group, periods)); + _frequencyStats.put(name, new FrequencyStat(name, description, group, periods)); } - + /** * Create a new statistic to monitor the average value and confidence of some action. * @@ -53,66 +56,79 @@ public class StatManager { * @param periods array of period lengths (in milliseconds) */ public void createRateStat(String name, String description, String group, long periods[]) { - _rateStats.put(name, new RateStat(name, description, group, periods)); + _rateStats.put(name, new RateStat(name, description, group, periods)); } - + /** update the given frequency statistic, taking note that an event occurred (and recalculating all frequencies) */ public void updateFrequency(String name) { - FrequencyStat freq = (FrequencyStat)_frequencyStats.get(name); - if (freq != null) - freq.eventOccurred(); + FrequencyStat freq = (FrequencyStat) _frequencyStats.get(name); + if (freq != null) freq.eventOccurred(); } - + /** update the given rate statistic, taking note that the given data point was received (and recalculating all rates) */ public void addRateData(String name, long data, long eventDuration) { - RateStat stat = (RateStat)_rateStats.get(name); - if (stat != null) - stat.addData(data, eventDuration); + RateStat stat = (RateStat) _rateStats.get(name); + if (stat != null) stat.addData(data, eventDuration); } - + public void coallesceStats() { - for (Iterator iter = getFrequencyNames().iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); - FrequencyStat stat = getFrequency(name); - if (stat != null) { - stat.coallesceStats(); - } - } - for (Iterator iter = getRateNames().iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); - RateStat stat = getRate(name); - if (stat != null) { - stat.coallesceStats(); - } - } + for (Iterator iter = getFrequencyNames().iterator(); iter.hasNext();) { + String name = (String) iter.next(); + FrequencyStat stat = getFrequency(name); + if (stat != null) { + stat.coallesceStats(); + } + } + for (Iterator iter = getRateNames().iterator(); iter.hasNext();) { + String name = (String) iter.next(); + RateStat stat = getRate(name); + if (stat != null) { + stat.coallesceStats(); + } + } + } + + public FrequencyStat getFrequency(String name) { + return (FrequencyStat) _frequencyStats.get(name); + } + + public RateStat getRate(String name) { + return (RateStat) _rateStats.get(name); + } + + public Set getFrequencyNames() { + return Collections.unmodifiableSet(new HashSet(_frequencyStats.keySet())); } - - public FrequencyStat getFrequency(String name) { return (FrequencyStat)_frequencyStats.get(name); } - public RateStat getRate(String name) { return (RateStat)_rateStats.get(name); } - public Set getFrequencyNames() { return Collections.unmodifiableSet(new HashSet(_frequencyStats.keySet())); } - public Set getRateNames() { return Collections.unmodifiableSet(new HashSet(_rateStats.keySet())); } + + public Set getRateNames() { + return Collections.unmodifiableSet(new HashSet(_rateStats.keySet())); + } + /** is the given stat a monitored rate? */ - public boolean isRate(String statName) { return _rateStats.containsKey(statName); } + public boolean isRate(String statName) { + return _rateStats.containsKey(statName); + } + /** is the given stat a monitored frequency? */ - public boolean isFrequency(String statName) { return _frequencyStats.containsKey(statName); } - + public boolean isFrequency(String statName) { + return _frequencyStats.containsKey(statName); + } + /** Group name (String) to a Set of stat names */ public Map getStatsByGroup() { - Map groups = new TreeMap(); - for (Iterator iter = _frequencyStats.values().iterator(); iter.hasNext();) { - FrequencyStat stat = (FrequencyStat)iter.next(); - if (!groups.containsKey(stat.getGroupName())) - groups.put(stat.getGroupName(), new TreeSet()); - Set names = (Set)groups.get(stat.getGroupName()); - names.add(stat.getName()); - } - for (Iterator iter = _rateStats.values().iterator(); iter.hasNext();) { - RateStat stat = (RateStat)iter.next(); - if (!groups.containsKey(stat.getGroupName())) - groups.put(stat.getGroupName(), new TreeSet()); - Set names = (Set)groups.get(stat.getGroupName()); - names.add(stat.getName()); - } - return groups; + Map groups = new TreeMap(); + for (Iterator iter = _frequencyStats.values().iterator(); iter.hasNext();) { + FrequencyStat stat = (FrequencyStat) iter.next(); + if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet()); + Set names = (Set) groups.get(stat.getGroupName()); + names.add(stat.getName()); + } + for (Iterator iter = _rateStats.values().iterator(); iter.hasNext();) { + RateStat stat = (RateStat) iter.next(); + if (!groups.containsKey(stat.getGroupName())) groups.put(stat.getGroupName(), new TreeSet()); + Set names = (Set) groups.get(stat.getGroupName()); + names.add(stat.getName()); + } + return groups; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/Clock.java b/core/java/src/net/i2p/util/Clock.java index 3a22bb20150acf10a7ee59b0656cd1cec91ef2ce..9cd2ca36865de11a28b408dbcf019a0865591b42 100644 --- a/core/java/src/net/i2p/util/Clock.java +++ b/core/java/src/net/i2p/util/Clock.java @@ -1,8 +1,8 @@ package net.i2p.util; -import java.util.Set; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; /** * Alternate location for determining the time which takes into account an offset. @@ -14,79 +14,89 @@ import java.util.Iterator; public class Clock { private final static Log _log = new Log(Clock.class); private final static Clock _instance = new Clock(); - public final static Clock getInstance() { return _instance; } + + public final static Clock getInstance() { + return _instance; + } private volatile long _offset; private boolean _alreadyChanged; private Set _listeners; - + /** if the clock is skewed by 3+ days, fuck 'em */ - public final static long MAX_OFFSET = 3*24*60*60*1000; + public final static long MAX_OFFSET = 3 * 24 * 60 * 60 * 1000; /** if the clock skewed changes by less than 1s, ignore the update (so we don't slide all over the place) */ - public final static long MIN_OFFSET_CHANGE = 30*1000; - + public final static long MIN_OFFSET_CHANGE = 30 * 1000; + private Clock() { - _offset = 0; - _alreadyChanged = false; - _listeners = new HashSet(64); + _offset = 0; + _alreadyChanged = false; + _listeners = new HashSet(64); } - + /** * Specify how far away from the "correct" time the computer is - a positive * value means that we are slow, while a negative value means we are fast. * */ - public void setOffset(long offsetMs) { - if ( (offsetMs > MAX_OFFSET) || (offsetMs < 0-MAX_OFFSET) ) { - _log.error("Maximum offset shift exceeded [" + offsetMs + "], NOT HONORING IT"); - return; - } - long delta = offsetMs - _offset; - if ( (delta < MIN_OFFSET_CHANGE) && (delta > 0 - MIN_OFFSET_CHANGE) ) { - _log.debug("Not changing offset since it is only " + delta + "ms"); - return; - } - if (_alreadyChanged) - _log.log(Log.CRIT, "Updating clock offset to " + offsetMs + "ms from " + _offset + "ms"); - else - _log.log(Log.INFO, "Initializing clock offset to " + offsetMs + "ms from " + _offset + "ms"); - _alreadyChanged = true; - _offset = offsetMs; - fireOffsetChanged(delta); + public void setOffset(long offsetMs) { + if ((offsetMs > MAX_OFFSET) || (offsetMs < 0 - MAX_OFFSET)) { + _log.error("Maximum offset shift exceeded [" + offsetMs + "], NOT HONORING IT"); + return; + } + long delta = offsetMs - _offset; + if ((delta < MIN_OFFSET_CHANGE) && (delta > 0 - MIN_OFFSET_CHANGE)) { + _log.debug("Not changing offset since it is only " + delta + "ms"); + return; + } + if (_alreadyChanged) + _log.log(Log.CRIT, "Updating clock offset to " + offsetMs + "ms from " + _offset + "ms"); + else + _log.log(Log.INFO, "Initializing clock offset to " + offsetMs + "ms from " + _offset + "ms"); + _alreadyChanged = true; + _offset = offsetMs; + fireOffsetChanged(delta); + } + + public long getOffset() { + return _offset; } - public long getOffset() { return _offset; } - + public void setNow(long realTime) { - long diff = realTime - System.currentTimeMillis(); - setOffset(diff); + long diff = realTime - System.currentTimeMillis(); + setOffset(diff); } - + /** * Retrieve the current time synchronized with whatever reference clock is in * use. * */ - public long now() { return _offset + System.currentTimeMillis(); } - - public void addUpdateListener(ClockUpdateListener lsnr) { - synchronized (_listeners) { - _listeners.add(lsnr); - } + public long now() { + return _offset + System.currentTimeMillis(); + } + + public void addUpdateListener(ClockUpdateListener lsnr) { + synchronized (_listeners) { + _listeners.add(lsnr); + } } + public void removeUpdateListener(ClockUpdateListener lsnr) { - synchronized (_listeners) { - _listeners.remove(lsnr); - } + synchronized (_listeners) { + _listeners.remove(lsnr); + } } - + private void fireOffsetChanged(long delta) { - synchronized (_listeners) { - for (Iterator iter = _listeners.iterator(); iter.hasNext(); ) { - ClockUpdateListener lsnr = (ClockUpdateListener)iter.next(); - lsnr.offsetChanged(delta); - } - } + synchronized (_listeners) { + for (Iterator iter = _listeners.iterator(); iter.hasNext();) { + ClockUpdateListener lsnr = (ClockUpdateListener) iter.next(); + lsnr.offsetChanged(delta); + } + } } + public static interface ClockUpdateListener { - public void offsetChanged(long delta); + public void offsetChanged(long delta); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/EventDispatcher.java b/core/java/src/net/i2p/util/EventDispatcher.java index 83525943e749246f5adea01e2903702d4c3417d0..ba7cc43940ca143456634b3598d0f000976de8b7 100644 --- a/core/java/src/net/i2p/util/EventDispatcher.java +++ b/core/java/src/net/i2p/util/EventDispatcher.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others Written * by human in 2004 and released into the public domain with no @@ -33,13 +34,13 @@ import java.util.Set; * @author human */ public interface EventDispatcher { - + /** * Get an object to be used to deliver events (usually * <code>this</code>, but YMMV). */ public EventDispatcher getEventDispatcher(); - + /** * Attach an EventDispatcher object to the events dispatching chain. Note * that notification is not bidirectional (i.e. events notified to @@ -49,14 +50,14 @@ public interface EventDispatcher { * @param iev Event object to be attached */ public void attachEventDispatcher(EventDispatcher iev); - + /** * Detach the specified EventDispatcher object from the events dispatching chain. * * @param iev Event object to be detached */ public void detachEventDispatcher(EventDispatcher iev); - + /** * Deliver an event * @@ -64,7 +65,7 @@ public interface EventDispatcher { * @param args data being stored for that event */ public void notifyEvent(String event, Object args); - + /** * Retrieve the value currently associated with the specified * event value @@ -73,26 +74,26 @@ public interface EventDispatcher { * @return value (or null if none are available) */ public Object getEventValue(String name); - + /** * Retrieve the names of all the events that have been received * * @return A set of event names */ public Set getEvents(); - + /** * Ignore further event notifications * */ public void ignoreEvents(); - + /** * Almost like the method above :-) * */ public void unIgnoreEvents(); - + /** * Wait until the given event has received a value * @@ -100,4 +101,4 @@ public interface EventDispatcher { * @return value specified for that event */ public Object waitEventValue(String name); -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/EventDispatcherImpl.java b/core/java/src/net/i2p/util/EventDispatcherImpl.java index c872bb64e4c7b67ee0dfe9007e3be453440b5869..a30e26904f61355ac04b0fa3dbdc618ed84518c5 100644 --- a/core/java/src/net/i2p/util/EventDispatcherImpl.java +++ b/core/java/src/net/i2p/util/EventDispatcherImpl.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others Written * by human & jrandom in 2004 and released into the public domain with @@ -38,107 +39,104 @@ public class EventDispatcherImpl implements EventDispatcher { private ArrayList _attached = new ArrayList(); public EventDispatcher getEventDispatcher() { - return this; + return this; } public void attachEventDispatcher(EventDispatcher ev) { - if (ev == null) return; - synchronized (_attached) { - _log.debug(this.hashCode() + ": attaching EventDispatcher " - + ev.hashCode()); - _attached.add(ev); - } + if (ev == null) return; + synchronized (_attached) { + _log.debug(this.hashCode() + ": attaching EventDispatcher " + ev.hashCode()); + _attached.add(ev); + } } public void detachEventDispatcher(EventDispatcher ev) { - if (ev == null) return; - synchronized (_attached) { - ListIterator it = _attached.listIterator(); - while (it.hasNext()) { - if (((EventDispatcher)it.next()) == ev) { - it.remove(); - break; - } - } - } + if (ev == null) return; + synchronized (_attached) { + ListIterator it = _attached.listIterator(); + while (it.hasNext()) { + if (((EventDispatcher) it.next()) == ev) { + it.remove(); + break; + } + } + } } - public void notifyEvent(String eventName, Object args) { - if (_ignore) return; - if (args == null) { - args = "[null value]"; - } - _log.debug(this.hashCode() + ": got notification [" - + eventName + "] = [" + args + "]"); - synchronized (_events) { - _events.put(eventName, args); - _events.notifyAll(); - synchronized (_attached) { - Iterator it = _attached.iterator(); - EventDispatcher e; - while (it.hasNext()) { - e = (EventDispatcher)it.next(); - _log.debug(this.hashCode() - + ": notifying attached EventDispatcher " - + e.hashCode() + ": [" - + eventName + "] = [" + args + "]"); - e.notifyEvent(eventName, args); - } - } - } + public void notifyEvent(String eventName, Object args) { + if (_ignore) return; + if (args == null) { + args = "[null value]"; + } + _log.debug(this.hashCode() + ": got notification [" + eventName + "] = [" + args + "]"); + synchronized (_events) { + _events.put(eventName, args); + _events.notifyAll(); + synchronized (_attached) { + Iterator it = _attached.iterator(); + EventDispatcher e; + while (it.hasNext()) { + e = (EventDispatcher) it.next(); + _log.debug(this.hashCode() + ": notifying attached EventDispatcher " + e.hashCode() + ": [" + + eventName + "] = [" + args + "]"); + e.notifyEvent(eventName, args); + } + } + } } public Object getEventValue(String name) { - if (_ignore) return null; - Object val; + if (_ignore) return null; + Object val; - synchronized (_events) { - val = _events.get(name); - } + synchronized (_events) { + val = _events.get(name); + } - return val; + return val; } public Set getEvents() { - if (_ignore) return Collections.EMPTY_SET; - Set set; + if (_ignore) return Collections.EMPTY_SET; + Set set; - synchronized (_events) { - set = new HashSet(_events.keySet()); - } + synchronized (_events) { + set = new HashSet(_events.keySet()); + } - return set; + return set; } public void ignoreEvents() { - _ignore = true; - synchronized (_events) { - _events.clear(); - } - _events = null; + _ignore = true; + synchronized (_events) { + _events.clear(); + } + _events = null; } public void unIgnoreEvents() { - _ignore = false; + _ignore = false; } public Object waitEventValue(String name) { - if (_ignore) return null; - Object val; - - _log.debug(this.hashCode() + ": waiting for [" + name + "]"); - do { - synchronized (_events) { - if (_events.containsKey(name)) { - val = _events.get(name); - break; - } - try { - _events.wait(1*1000); - } catch (InterruptedException e) {} - } - } while (true); - - return val; + if (_ignore) return null; + Object val; + + _log.debug(this.hashCode() + ": waiting for [" + name + "]"); + do { + synchronized (_events) { + if (_events.containsKey(name)) { + val = _events.get(name); + break; + } + try { + _events.wait(1 * 1000); + } catch (InterruptedException e) { + } + } + } while (true); + + return val; } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/HTTPSendData.java b/core/java/src/net/i2p/util/HTTPSendData.java index 782da58cfb1b2666d7a7517a35330a8ac863cce1..1f7bf859a99b243caa99c9e16b0a7db22153a44b 100644 --- a/core/java/src/net/i2p/util/HTTPSendData.java +++ b/core/java/src/net/i2p/util/HTTPSendData.java @@ -15,7 +15,7 @@ import java.util.zip.GZIPOutputStream; */ public class HTTPSendData { private final static Log _log = new Log(HTTPSendData.class); - + /** * Submit an HTTP post to the given url, sending the data specified * @@ -25,14 +25,14 @@ public class HTTPSendData { * @return true if the data was posted successfully */ public static boolean postData(String url, long length, InputStream dataToSend) { - try { - URL rurl = new URL(url); - return postData(rurl, length, dataToSend); - } catch (MalformedURLException mue) { - return false; - } + try { + URL rurl = new URL(url); + return postData(rurl, length, dataToSend); + } catch (MalformedURLException mue) { + return false; + } } - + /** * Submit an HTTP post to the given url, sending the data specified * @@ -41,47 +41,50 @@ public class HTTPSendData { * @param dataToSend stream of bytes to be sent */ public static boolean postData(URL url, long length, InputStream dataToSend) { - try { - HttpURLConnection con = (HttpURLConnection)url.openConnection(); - con.setDoInput(true); - con.setDoOutput(true); - con.setUseCaches(false); - con.setRequestMethod("POST"); - con.setRequestProperty("Content-length", ""+length); - - OutputStream out = con.getOutputStream(); - byte buf[] = new byte[64*1024]; - int read; - long sent = 0; - GZIPOutputStream zipOut = new GZIPOutputStream(out); - while ( (read = dataToSend.read(buf)) != -1) { - zipOut.write(buf, 0, read); - sent += read; - if (sent >= length) break; - } - - zipOut.flush(); - zipOut.finish(); - zipOut.close(); - out.close(); - - - int rv = con.getResponseCode(); - _log.debug("Posted "+sent + " bytes: " + rv); - return length == sent; - } catch (IOException ioe) { - _log.error("Error posting the data", ioe); - return false; - } + try { + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-length", "" + length); + + OutputStream out = con.getOutputStream(); + byte buf[] = new byte[64 * 1024]; + int read; + long sent = 0; + GZIPOutputStream zipOut = new GZIPOutputStream(out); + while ((read = dataToSend.read(buf)) != -1) { + zipOut.write(buf, 0, read); + sent += read; + if (sent >= length) break; + } + + zipOut.flush(); + zipOut.finish(); + zipOut.close(); + out.close(); + + int rv = con.getResponseCode(); + _log.debug("Posted " + sent + " bytes: " + rv); + return length == sent; + } catch (IOException ioe) { + _log.error("Error posting the data", ioe); + return false; + } } - + public static void main(String args[]) { - byte data[] = new byte[4096]; - for (int i = 0; i < data.length; i++) - data[i] = (byte)((i%26)+'a'); - - boolean sent = HTTPSendData.postData("http://i2p.dnsalias.net/cgi-bin/submitMessageHistory", data.length, new ByteArrayInputStream(data)); - _log.debug("Sent? " + sent); - try { Thread.sleep(2000); } catch (InterruptedException ie) {} + byte data[] = new byte[4096]; + for (int i = 0; i < data.length; i++) + data[i] = (byte) ((i % 26) + 'a'); + + boolean sent = HTTPSendData.postData("http://i2p.dnsalias.net/cgi-bin/submitMessageHistory", data.length, + new ByteArrayInputStream(data)); + _log.debug("Sent? " + sent); + try { + Thread.sleep(2000); + } catch (InterruptedException ie) { + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/HexDump.java b/core/java/src/net/i2p/util/HexDump.java index c5013e0d6182e098b05f7e4d037b953e418e314f..10ce2cc33d32729df0f0a83f2ccb8b5f8814095d 100644 --- a/core/java/src/net/i2p/util/HexDump.java +++ b/core/java/src/net/i2p/util/HexDump.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by human in 2004 and released into the public domain @@ -8,9 +9,9 @@ package net.i2p.util; * */ +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.io.ByteArrayOutputStream; /** * Hexdump class (well, it's actually a namespace with some functions, @@ -32,15 +33,15 @@ public class HexDump { * @param data Data to be dumped */ public static String dump(byte[] data) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - dump(data, 0, data.length, out); - } catch (IOException e) { - e.printStackTrace(); - } + try { + dump(data, 0, data.length, out); + } catch (IOException e) { + e.printStackTrace(); + } - return out.toString(); + return out.toString(); } /** @@ -51,15 +52,15 @@ public class HexDump { * @param len Number of bytes of <code>data</code> to be dumped */ public static String dump(byte[] data, int off, int len) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - dump(data, off, len, out); - } catch (IOException e) { - e.printStackTrace(); - } + try { + dump(data, off, len, out); + } catch (IOException e) { + e.printStackTrace(); + } - return out.toString(); + return out.toString(); } /** @@ -69,7 +70,7 @@ public class HexDump { * @param out Output stream */ public static void dump(byte data[], OutputStream out) throws IOException { - dump(data, 0, data.length, out); + dump(data, 0, data.length, out); } /** @@ -81,56 +82,54 @@ public class HexDump { * @param out Output stream */ public static void dump(byte[] data, int off, int len, OutputStream out) throws IOException { - String hexoff; - int dumpoff, hexofflen, i, nextbytes, end = len+off; - int val; - - for (dumpoff = off; dumpoff < end; dumpoff += FORMAT_BYTES_PER_ROW) { - // Pad the offset with 0's (i miss my beloved sprintf()...) - hexoff = Integer.toString(dumpoff, 16); - hexofflen = hexoff.length(); - for (i = 0; i < FORMAT_OFFSET_PADDING - hexofflen; ++i) { - hexoff = "0" + hexoff; - } - out.write((hexoff + " ").getBytes()); - - // Bytes to be printed in the current line - nextbytes = (FORMAT_BYTES_PER_ROW < (end - dumpoff) - ? FORMAT_BYTES_PER_ROW - : (end - dumpoff)); - - for (i = 0; i < FORMAT_BYTES_PER_ROW; ++i) { - // Put two spaces to separate 8-bytes blocks - if ((i % 8) == 0) { - out.write(" ".getBytes()); - } - if (i >= nextbytes) { - out.write(" ".getBytes()); - } else { - val = ((int)data[dumpoff + i]) & 0xff; - out.write(HEXCHARS[val >>> 4]); - out.write(HEXCHARS[val & 0xf]); - out.write(" ".getBytes()); - } - } - - out.write(" |".getBytes()); - - for (i = 0; i < FORMAT_BYTES_PER_ROW; ++i) { - if (i >= nextbytes) { - out.write(" ".getBytes()); - } else { - val = data[i + dumpoff]; - // Is it a printable character? - if ((val > 31) && (val < 127)) { - out.write(val); - } else { - out.write(".".getBytes()); - } - } - } - - out.write("|\n".getBytes()); - } + String hexoff; + int dumpoff, hexofflen, i, nextbytes, end = len + off; + int val; + + for (dumpoff = off; dumpoff < end; dumpoff += FORMAT_BYTES_PER_ROW) { + // Pad the offset with 0's (i miss my beloved sprintf()...) + hexoff = Integer.toString(dumpoff, 16); + hexofflen = hexoff.length(); + for (i = 0; i < FORMAT_OFFSET_PADDING - hexofflen; ++i) { + hexoff = "0" + hexoff; + } + out.write((hexoff + " ").getBytes()); + + // Bytes to be printed in the current line + nextbytes = (FORMAT_BYTES_PER_ROW < (end - dumpoff) ? FORMAT_BYTES_PER_ROW : (end - dumpoff)); + + for (i = 0; i < FORMAT_BYTES_PER_ROW; ++i) { + // Put two spaces to separate 8-bytes blocks + if ((i % 8) == 0) { + out.write(" ".getBytes()); + } + if (i >= nextbytes) { + out.write(" ".getBytes()); + } else { + val = ((int) data[dumpoff + i]) & 0xff; + out.write(HEXCHARS[val >>> 4]); + out.write(HEXCHARS[val & 0xf]); + out.write(" ".getBytes()); + } + } + + out.write(" |".getBytes()); + + for (i = 0; i < FORMAT_BYTES_PER_ROW; ++i) { + if (i >= nextbytes) { + out.write(" ".getBytes()); + } else { + val = data[i + dumpoff]; + // Is it a printable character? + if ((val > 31) && (val < 127)) { + out.write(val); + } else { + out.write(".".getBytes()); + } + } + } + + out.write("|\n".getBytes()); + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/I2PThread.java b/core/java/src/net/i2p/util/I2PThread.java index 8949599366c62454016937bb079bb6ee85f08fd6..4efb27de9d9c52b45a5bdca34c2744ac0d7d67f4 100644 --- a/core/java/src/net/i2p/util/I2PThread.java +++ b/core/java/src/net/i2p/util/I2PThread.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -13,47 +14,59 @@ package net.i2p.util; * (e.g. w/ native programatic thread dumping, etc) * */ -public class I2PThread extends Thread { +public class I2PThread extends Thread { private static Log _log; private static OOMEventListener _lsnr; - + public I2PThread() { - super(); + super(); } + public I2PThread(String name) { - super(name); + super(name); } + public I2PThread(Runnable r) { - super(r); + super(r); } + public I2PThread(Runnable r, String name) { - super(r, name); + super(r, name); } - + public void run() { - try { - super.run(); - } catch (Throwable t) { - if ( (t instanceof OutOfMemoryError) && (_lsnr != null) ) - _lsnr.outOfMemory((OutOfMemoryError)t); - // we cant assume log is created - if (_log == null) _log = new Log(I2PThread.class); - _log.log(Log.CRIT, "Killing thread " + getName(), t); - } - } - - public static void setOOMEventListener(OOMEventListener lsnr) { _lsnr = lsnr; } - public static OOMEventListener getOOMEventListener() { return _lsnr; } - + try { + super.run(); + } catch (Throwable t) { + if ((t instanceof OutOfMemoryError) && (_lsnr != null)) _lsnr.outOfMemory((OutOfMemoryError) t); + // we cant assume log is created + if (_log == null) _log = new Log(I2PThread.class); + _log.log(Log.CRIT, "Killing thread " + getName(), t); + } + } + + public static void setOOMEventListener(OOMEventListener lsnr) { + _lsnr = lsnr; + } + + public static OOMEventListener getOOMEventListener() { + return _lsnr; + } + public interface OOMEventListener { - public void outOfMemory(OutOfMemoryError err); + public void outOfMemory(OutOfMemoryError err); } - + public static void main(String args[]) { - I2PThread t = new I2PThread(new Runnable() { - public void run() { throw new NullPointerException("blah"); } - }); - t.start(); - try { Thread.sleep(10000); } catch (Throwable tt) {} + I2PThread t = new I2PThread(new Runnable() { + public void run() { + throw new NullPointerException("blah"); + } + }); + t.start(); + try { + Thread.sleep(10000); + } catch (Throwable tt) { + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/Log.java b/core/java/src/net/i2p/util/Log.java index e192bc4bbad2c5261bf470fdf0384fc2db7bb233..ab2dfe94ab2e16426a18d16895054ef9ecc783c9 100644 --- a/core/java/src/net/i2p/util/Log.java +++ b/core/java/src/net/i2p/util/Log.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,7 +9,6 @@ package net.i2p.util; * */ - /** * Wrapper class for whatever logging system I2P uses. This class should be * instantiated and kept as a variable for each class it is used by, ala: @@ -24,84 +24,126 @@ public class Log { private Class _class; private String _name; private int _minPriority; - + public final static int DEBUG = 10; - public final static int INFO = 20; - public final static int WARN = 30; + public final static int INFO = 20; + public final static int WARN = 30; public final static int ERROR = 40; - public final static int CRIT = 50; + public final static int CRIT = 50; public final static String STR_DEBUG = "DEBUG"; - public final static String STR_INFO = "INFO"; - public final static String STR_WARN = "WARN"; + public final static String STR_INFO = "INFO"; + public final static String STR_WARN = "WARN"; public final static String STR_ERROR = "ERROR"; - public final static String STR_CRIT = "CRIT"; + public final static String STR_CRIT = "CRIT"; public static int getLevel(String level) { - if (level == null) return Log.CRIT; - level = level.toUpperCase(); - if (STR_DEBUG.startsWith(level)) return DEBUG; - if (STR_INFO.startsWith(level)) return INFO; - if (STR_WARN.startsWith(level)) return WARN; - if (STR_ERROR.startsWith(level)) return ERROR; - if (STR_CRIT.startsWith(level)) return CRIT; - return CRIT; - } - + if (level == null) return Log.CRIT; + level = level.toUpperCase(); + if (STR_DEBUG.startsWith(level)) return DEBUG; + if (STR_INFO.startsWith(level)) return INFO; + if (STR_WARN.startsWith(level)) return WARN; + if (STR_ERROR.startsWith(level)) return ERROR; + if (STR_CRIT.startsWith(level)) return CRIT; + return CRIT; + } + public static String toLevelString(int level) { - switch (level) { - case DEBUG: return STR_DEBUG; - case INFO: return STR_INFO; - case WARN: return STR_WARN; - case ERROR: return STR_ERROR; - case CRIT: return STR_CRIT; - } - return (level > CRIT ? STR_CRIT : STR_DEBUG); - } - - public Log(Class cls) { + switch (level) { + case DEBUG: + return STR_DEBUG; + case INFO: + return STR_INFO; + case WARN: + return STR_WARN; + case ERROR: + return STR_ERROR; + case CRIT: + return STR_CRIT; + } + return (level > CRIT ? STR_CRIT : STR_DEBUG); + } + + public Log(Class cls) { this(cls, null); } - public Log(String name) { + + public Log(String name) { this(null, name); } + public Log(Class cls, String name) { _class = cls; _name = name; - _minPriority = DEBUG; - LogManager.getInstance().registerLog(this); + _minPriority = DEBUG; + LogManager.getInstance().registerLog(this); } - + public void log(int priority, String msg) { if (priority >= _minPriority) { - LogManager.getInstance().addRecord(new LogRecord(_class, _name, Thread.currentThread().getName(), priority, msg, null)); - } + LogManager.getInstance().addRecord( + new LogRecord(_class, _name, Thread.currentThread().getName(), priority, + msg, null)); + } } + public void log(int priority, String msg, Throwable t) { if (priority >= _minPriority) { - LogManager.getInstance().addRecord(new LogRecord(_class, _name, Thread.currentThread().getName(), priority, msg, t)); + LogManager.getInstance().addRecord( + new LogRecord(_class, _name, Thread.currentThread().getName(), priority, + msg, t)); } } - - public void debug(String msg) { log(DEBUG, msg); } - public void debug(String msg, Throwable t) { log(DEBUG, msg, t); } - public void info(String msg) { log(INFO, msg); } - public void info(String msg, Throwable t) { log(INFO, msg, t); } - public void warn(String msg) { log(WARN, msg); } - public void warn(String msg, Throwable t) { log(WARN, msg, t); } - public void error(String msg) { log(ERROR, msg); } - public void error(String msg, Throwable t) { log(ERROR, msg, t); } - - public int getMinimumPriority() { return _minPriority; } - public void setMinimumPriority(int priority) { _minPriority = priority; } - - public boolean shouldLog(int priority) { return priority >= _minPriority; } + + public void debug(String msg) { + log(DEBUG, msg); + } + + public void debug(String msg, Throwable t) { + log(DEBUG, msg, t); + } + + public void info(String msg) { + log(INFO, msg); + } + + public void info(String msg, Throwable t) { + log(INFO, msg, t); + } + + public void warn(String msg) { + log(WARN, msg); + } + + public void warn(String msg, Throwable t) { + log(WARN, msg, t); + } + + public void error(String msg) { + log(ERROR, msg); + } + + public void error(String msg, Throwable t) { + log(ERROR, msg, t); + } + + public int getMinimumPriority() { + return _minPriority; + } + + public void setMinimumPriority(int priority) { + _minPriority = priority; + } + + public boolean shouldLog(int priority) { + return priority >= _minPriority; + } String getName() { - if (_class != null) - return _class.getName(); - else - return _name; + if (_class != null) + return _class.getName(); + else + return _name; } - -} + +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogConsoleBuffer.java b/core/java/src/net/i2p/util/LogConsoleBuffer.java index ce78cce2c1f60cbcc0c1a9f95e3bab3d3a660e00..c5b4e88c172b7fdbd996947b90b011e16d0d983a 100644 --- a/core/java/src/net/i2p/util/LogConsoleBuffer.java +++ b/core/java/src/net/i2p/util/LogConsoleBuffer.java @@ -1,7 +1,7 @@ package net.i2p.util; -import java.util.List; import java.util.LinkedList; +import java.util.List; /** * Offer a glimpse into the last few console messages generated @@ -9,22 +9,25 @@ import java.util.LinkedList; */ public class LogConsoleBuffer { private final static LogConsoleBuffer _instance = new LogConsoleBuffer(); - public final static LogConsoleBuffer getInstance() { return _instance; } + + public final static LogConsoleBuffer getInstance() { + return _instance; + } private List _buffer; - + private LogConsoleBuffer() { - _buffer = new LinkedList(); + _buffer = new LinkedList(); } - + void add(String msg) { - int lim = LogManager.getInstance().getConsoleBufferSize(); - synchronized (_buffer) { - while (_buffer.size() >= lim) - _buffer.remove(0); - _buffer.add(msg); - } + int lim = LogManager.getInstance().getConsoleBufferSize(); + synchronized (_buffer) { + while (_buffer.size() >= lim) + _buffer.remove(0); + _buffer.add(msg); + } } - + /** * Retrieve the currently bufferd messages, earlier values were generated... * earlier. All values are strings with no formatting (as they are written @@ -32,8 +35,8 @@ public class LogConsoleBuffer { * */ public List getMostRecentMessages() { - synchronized (_buffer) { - return new LinkedList(_buffer); - } + synchronized (_buffer) { + return new LinkedList(_buffer); + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogLimit.java b/core/java/src/net/i2p/util/LogLimit.java index cab603dc1c943a63f6d23f911ebde684209428a6..d26e4bc0c81f7ea84e6a621558945d064efe9712 100644 --- a/core/java/src/net/i2p/util/LogLimit.java +++ b/core/java/src/net/i2p/util/LogLimit.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -15,18 +16,23 @@ package net.i2p.util; class LogLimit { private String _rootName; private int _limit; - + public LogLimit(String name, int limit) { - _rootName = name; - _limit = limit; + _rootName = name; + _limit = limit; + } + + public String getRootName() { + return _rootName; } - - public String getRootName() { return _rootName; } - public int getLimit() { return _limit; } - + + public int getLimit() { + return _limit; + } + public boolean matches(Log log) { - String name = log.getName(); - if (name == null) return false; - return name.startsWith(_rootName); + String name = log.getName(); + if (name == null) return false; + return name.startsWith(_rootName); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java index 75497dce93f01b108bd45cbafcc087471da7bf56..55f1104e2b67acb58291ae937cb961c7f5231671 100644 --- a/core/java/src/net/i2p/util/LogManager.java +++ b/core/java/src/net/i2p/util/LogManager.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -30,19 +31,19 @@ public class LogManager { public final static String CONFIG_LOCATION_PROP = "loggerConfigLocation"; public final static String FILENAME_OVERRIDE_PROP = "loggerFilenameOverride"; public final static String CONFIG_LOCATION_DEFAULT = "logger.config"; - public static final LogManager getInstance() { return _instance; } - private static final LogManager _instance = new LogManager(System.getProperty(CONFIG_LOCATION_PROP, CONFIG_LOCATION_DEFAULT)); + + public static final LogManager getInstance() { + return _instance; + } + private static final LogManager _instance = new LogManager(System.getProperty(CONFIG_LOCATION_PROP, + CONFIG_LOCATION_DEFAULT)); private static final Log _log = new Log(LogManager.class); /** * These define the characters in the format line of the config file */ - public static final char DATE = 'd', - CLASS = 'c', - THREAD = 't', - PRIORITY = 'p', - MESSAGE = 'm'; - + public static final char DATE = 'd', CLASS = 'c', THREAD = 't', PRIORITY = 'p', MESSAGE = 'm'; + public final static String PROP_FORMAT = "logger.format"; public final static String PROP_DATEFORMAT = "logger.dateFormat"; public final static String PROP_FILENAME = "logger.logFileName"; @@ -53,7 +54,7 @@ public class LogManager { public final static String PROP_DISPLAYONSCREENLEVEL = "logger.minimumOnScreenLevel"; public final static String PROP_DEFALTLEVEL = "logger.defaultLevel"; public final static String PROP_RECORD_PREFIX = "logger.record."; - + public final static String DEFAULT_FORMAT = DATE + ' ' + PRIORITY + " [" + THREAD + "] " + CLASS + ": " + MESSAGE; public final static String DEFAULT_DATEFORMAT = "hh:mm:ss.SSS"; public final static String DEFAULT_FILENAME = "log-#.txt"; @@ -79,289 +80,326 @@ public class LogManager { private int _fileSize; private int _rotationLimit; private int _onScreenLimit; - + private boolean _displayOnScreen; private int _consoleBufferSize; - - public void setDisplayOnScreen(boolean yes) { _displayOnScreen = yes; } - public boolean displayOnScreen() { return _displayOnScreen; } - public int getDisplayOnScreenLevel() { return _onScreenLimit; } - public void setDisplayOnScreenLevel(int level) { _onScreenLimit = level; } - public int getConsoleBufferSize() { return _consoleBufferSize; } - public void setConsoleBufferSize(int numRecords) { _consoleBufferSize = numRecords; } - + + public void setDisplayOnScreen(boolean yes) { + _displayOnScreen = yes; + } + + public boolean displayOnScreen() { + return _displayOnScreen; + } + + public int getDisplayOnScreenLevel() { + return _onScreenLimit; + } + + public void setDisplayOnScreenLevel(int level) { + _onScreenLimit = level; + } + + public int getConsoleBufferSize() { + return _consoleBufferSize; + } + + public void setConsoleBufferSize(int numRecords) { + _consoleBufferSize = numRecords; + } + public void setConfig(String filename) { - _log.debug("Config filename set to " + filename); - _location = filename; - loadConfig(); + _log.debug("Config filename set to " + filename); + _location = filename; + loadConfig(); } - + /** * Used by Log to add records to the queue * */ void addRecord(LogRecord record) { - synchronized (_records) { - _records.add(record); - } + synchronized (_records) { + _records.add(record); + } } - + /** * Called during Log construction * */ void registerLog(Log log) { - synchronized (_logs) { - _logs.add(log); - } - updateLimit(log); + synchronized (_logs) { + _logs.add(log); + } + updateLimit(log); } - + /** * Called periodically by the log writer's thread * */ void rereadConfig() { - // perhaps check modification time - _log.debug("Rereading configuration file"); - loadConfig(); + // perhaps check modification time + _log.debug("Rereading configuration file"); + loadConfig(); } /// /// private LogManager(String location) { - _displayOnScreen = true; - _location = location; - _records = new ArrayList(); - _limits = new HashSet(); - _logs = new HashSet(); - _defaultLimit = Log.DEBUG; - _configLastRead = 0; - loadConfig(); - _writer = new LogWriter(); - Thread t = new I2PThread(_writer); - t.setName("LogWriter"); - t.setDaemon(true); - t.start(); - Runtime.getRuntime().addShutdownHook(new ShutdownHook()); + _displayOnScreen = true; + _location = location; + _records = new ArrayList(); + _limits = new HashSet(); + _logs = new HashSet(); + _defaultLimit = Log.DEBUG; + _configLastRead = 0; + loadConfig(); + _writer = new LogWriter(); + Thread t = new I2PThread(_writer); + t.setName("LogWriter"); + t.setDaemon(true); + t.start(); + Runtime.getRuntime().addShutdownHook(new ShutdownHook()); } - + // // // - + private void loadConfig() { - Properties p = new Properties(); - File cfgFile = new File(_location); - if ( (_configLastRead > 0) && (_configLastRead > cfgFile.lastModified()) ) { - _log.debug("Short circuiting config read"); - return; - } - FileInputStream fis = null; - try { - fis = new FileInputStream(cfgFile); - p.load(fis); - _configLastRead = cfgFile.lastModified(); - } catch (IOException ioe) { - System.err.println("Error loading logger config from " + new File(_location).getAbsolutePath()); - } finally { - if (fis != null) try { fis.close(); } catch (IOException ioe) {} - } - parseConfig(p); - updateLimits(); + Properties p = new Properties(); + File cfgFile = new File(_location); + if ((_configLastRead > 0) && (_configLastRead > cfgFile.lastModified())) { + _log.debug("Short circuiting config read"); + return; + } + FileInputStream fis = null; + try { + fis = new FileInputStream(cfgFile); + p.load(fis); + _configLastRead = cfgFile.lastModified(); + } catch (IOException ioe) { + System.err.println("Error loading logger config from " + new File(_location).getAbsolutePath()); + } finally { + if (fis != null) try { + fis.close(); + } catch (IOException ioe) { + } + } + parseConfig(p); + updateLimits(); } - + private void parseConfig(Properties config) { - String fmt = config.getProperty(PROP_FORMAT, new String(DEFAULT_FORMAT)); - _format = fmt.toCharArray(); - - String df = config.getProperty(PROP_DATEFORMAT, DEFAULT_DATEFORMAT); - _dateFormat = new SimpleDateFormat(df); - - String disp = config.getProperty(PROP_DISPLAYONSCREEN); - if (disp == null) - _displayOnScreen = DEFAULT_DISPLAYONSCREEN; - else { - if ("TRUE".equals(disp.toUpperCase().trim())) - _displayOnScreen = true; - else if ("YES".equals(disp.toUpperCase().trim())) - _displayOnScreen = true; - else - _displayOnScreen = false; - } - - String filenameOverride = System.getProperty(FILENAME_OVERRIDE_PROP); - if (filenameOverride != null) - _baseLogfilename = filenameOverride; - else - _baseLogfilename = config.getProperty(PROP_FILENAME, DEFAULT_FILENAME); - - _fileSize = getFilesize(config.getProperty(PROP_FILESIZE, DEFAULT_FILESIZE)); - _rotationLimit = -1; - try { - String str = config.getProperty(PROP_ROTATIONLIMIT); - if (str == null) System.err.println("Rotation limit not specified"); - _rotationLimit = Integer.parseInt(config.getProperty(PROP_ROTATIONLIMIT, DEFAULT_ROTATIONLIMIT)); - } catch (NumberFormatException nfe) { - System.err.println("Invalid rotation limit"); - nfe.printStackTrace(); - } - _defaultLimit = Log.getLevel(config.getProperty(PROP_DEFALTLEVEL, DEFAULT_DEFALTLEVEL)); - - _onScreenLimit = Log.getLevel(config.getProperty(PROP_DISPLAYONSCREENLEVEL, DEFAULT_ONSCREENLEVEL)); - - try { - String str = config.getProperty(PROP_CONSOLEBUFFERSIZE); - if (str == null) - _consoleBufferSize = DEFAULT_CONSOLEBUFFERSIZE; - else - _consoleBufferSize = Integer.parseInt(str); - } catch (NumberFormatException nfe) { - System.err.println("Invalid console buffer size"); - nfe.printStackTrace(); - _consoleBufferSize = DEFAULT_CONSOLEBUFFERSIZE; - } - - parseLimits(config); + String fmt = config.getProperty(PROP_FORMAT, new String(DEFAULT_FORMAT)); + _format = fmt.toCharArray(); + + String df = config.getProperty(PROP_DATEFORMAT, DEFAULT_DATEFORMAT); + _dateFormat = new SimpleDateFormat(df); + + String disp = config.getProperty(PROP_DISPLAYONSCREEN); + if (disp == null) + _displayOnScreen = DEFAULT_DISPLAYONSCREEN; + else { + if ("TRUE".equals(disp.toUpperCase().trim())) + _displayOnScreen = true; + else if ("YES".equals(disp.toUpperCase().trim())) + _displayOnScreen = true; + else + _displayOnScreen = false; + } + + String filenameOverride = System.getProperty(FILENAME_OVERRIDE_PROP); + if (filenameOverride != null) + _baseLogfilename = filenameOverride; + else + _baseLogfilename = config.getProperty(PROP_FILENAME, DEFAULT_FILENAME); + + _fileSize = getFilesize(config.getProperty(PROP_FILESIZE, DEFAULT_FILESIZE)); + _rotationLimit = -1; + try { + String str = config.getProperty(PROP_ROTATIONLIMIT); + if (str == null) System.err.println("Rotation limit not specified"); + _rotationLimit = Integer.parseInt(config.getProperty(PROP_ROTATIONLIMIT, DEFAULT_ROTATIONLIMIT)); + } catch (NumberFormatException nfe) { + System.err.println("Invalid rotation limit"); + nfe.printStackTrace(); + } + _defaultLimit = Log.getLevel(config.getProperty(PROP_DEFALTLEVEL, DEFAULT_DEFALTLEVEL)); + + _onScreenLimit = Log.getLevel(config.getProperty(PROP_DISPLAYONSCREENLEVEL, DEFAULT_ONSCREENLEVEL)); + + try { + String str = config.getProperty(PROP_CONSOLEBUFFERSIZE); + if (str == null) + _consoleBufferSize = DEFAULT_CONSOLEBUFFERSIZE; + else + _consoleBufferSize = Integer.parseInt(str); + } catch (NumberFormatException nfe) { + System.err.println("Invalid console buffer size"); + nfe.printStackTrace(); + _consoleBufferSize = DEFAULT_CONSOLEBUFFERSIZE; + } + + parseLimits(config); } - + private void parseLimits(Properties config) { - synchronized (_limits) { - _limits.clear(); - } - for (Iterator iter = config.keySet().iterator(); iter.hasNext(); ) { - String key = (String)iter.next(); - String val = config.getProperty(key); - if (key.startsWith(PROP_RECORD_PREFIX)) { - String name = key.substring(PROP_RECORD_PREFIX.length()); - LogLimit lim = new LogLimit(name, Log.getLevel(val)); - //_log.debug("Limit found for " + name + " as " + val); - synchronized (_limits) { - _limits.add(lim); - } - } - } - updateLimits(); + synchronized (_limits) { + _limits.clear(); + } + for (Iterator iter = config.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = config.getProperty(key); + if (key.startsWith(PROP_RECORD_PREFIX)) { + String name = key.substring(PROP_RECORD_PREFIX.length()); + LogLimit lim = new LogLimit(name, Log.getLevel(val)); + //_log.debug("Limit found for " + name + " as " + val); + synchronized (_limits) { + _limits.add(lim); + } + } + } + updateLimits(); } - + private int getFilesize(String size) { - int sz = -1; - try { - String v = size; - char mod = size.toUpperCase().charAt(size.length()-1); - if (!Character.isDigit(mod)) - v = size.substring(0, size.length()-1); - int val = Integer.parseInt(v); - switch ((int)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; - } - return val; - } catch (Throwable t) { - System.err.println("Error parsing config for filesize: [" + size + "]"); - t.printStackTrace(); - return -1; - } + int sz = -1; + try { + String v = size; + char mod = size.toUpperCase().charAt(size.length() - 1); + if (!Character.isDigit(mod)) v = size.substring(0, size.length() - 1); + int val = Integer.parseInt(v); + switch ((int) 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; + } + return val; + } catch (Throwable t) { + System.err.println("Error parsing config for filesize: [" + size + "]"); + t.printStackTrace(); + return -1; + } } - + private void updateLimits() { - Set logs = new HashSet(); - synchronized (_logs) { - logs.addAll(_logs); - } - for (Iterator iter = logs.iterator(); iter.hasNext();) { - Log log = (Log)iter.next(); - updateLimit(log); - } + Set logs = new HashSet(); + synchronized (_logs) { + logs.addAll(_logs); + } + for (Iterator iter = logs.iterator(); iter.hasNext();) { + Log log = (Log) iter.next(); + updateLimit(log); + } } - + private void updateLimit(Log log) { - List limits = getLimits(log); - LogLimit max = null; - LogLimit notMax = null; - for (int i = 0; i < limits.size(); i++) { - LogLimit cur = (LogLimit)limits.get(i); - if (max == null) - max = cur; - else { - if (cur.getRootName().length() > max.getRootName().length()) { - notMax = max; - max = cur; - } - } - } - if (max != null) - log.setMinimumPriority(max.getLimit()); - else - log.setMinimumPriority(_defaultLimit); + List limits = getLimits(log); + LogLimit max = null; + LogLimit notMax = null; + for (int i = 0; i < limits.size(); i++) { + LogLimit cur = (LogLimit) limits.get(i); + if (max == null) + max = cur; + else { + if (cur.getRootName().length() > max.getRootName().length()) { + notMax = max; + max = cur; + } + } + } + if (max != null) + log.setMinimumPriority(max.getLimit()); + else + log.setMinimumPriority(_defaultLimit); } - + private List getLimits(Log log) { - ArrayList limits = new ArrayList(); - synchronized (_limits) { - for (Iterator iter = _limits.iterator(); iter.hasNext(); ) { - LogLimit limit = (LogLimit)iter.next(); - if (limit.matches(log)) - limits.add(limit); - } - } - return limits; + ArrayList limits = new ArrayList(); + synchronized (_limits) { + for (Iterator iter = _limits.iterator(); iter.hasNext();) { + LogLimit limit = (LogLimit) iter.next(); + if (limit.matches(log)) limits.add(limit); + } + } + return limits; } - + /// /// would be friend methods for LogWriter... /// - String _getBaseLogfilename() { return _baseLogfilename; } - int _getFileSize() { return _fileSize; } - int _getRotationLimit() { return _rotationLimit; } + String _getBaseLogfilename() { + return _baseLogfilename; + } + + int _getFileSize() { + return _fileSize; + } + + int _getRotationLimit() { + return _rotationLimit; + } + //List _getRecords() { return _records; } List _removeAll() { - List vals = null; - synchronized (_records) { - vals = new ArrayList(_records); - _records.clear(); - } - return vals; + List vals = null; + synchronized (_records) { + vals = new ArrayList(_records); + _records.clear(); + } + return vals; + } + + char[] _getFormat() { + return _format; + } + + SimpleDateFormat _getDateFormat() { + return _dateFormat; } - char[] _getFormat() { return _format; } - SimpleDateFormat _getDateFormat() { return _dateFormat; } - + public static void main(String args[]) { - Log l1 = new Log("test.1"); - Log l2 = new Log("test.2"); - Log l21 = new Log("test.2.1"); - Log l = new Log("test"); - l.debug("this should fail"); - l.info("this should pass"); - l1.warn("this should pass"); - l1.info("this should fail"); - l2.error("this should fail"); - l21.debug("this should pass"); - l1.error("test exception", new Exception("test")); - l1.error("test exception", new Exception("test")); - try { Thread.sleep(2*1000); } catch (Throwable t) {} - System.exit(0); + Log l1 = new Log("test.1"); + Log l2 = new Log("test.2"); + Log l21 = new Log("test.2.1"); + Log l = new Log("test"); + l.debug("this should fail"); + l.info("this should pass"); + l1.warn("this should pass"); + l1.info("this should fail"); + l2.error("this should fail"); + l21.debug("this should pass"); + l1.error("test exception", new Exception("test")); + l1.error("test exception", new Exception("test")); + try { + Thread.sleep(2 * 1000); + } catch (Throwable t) { + } + System.exit(0); } - + public void shutdown() { - _log.log(Log.CRIT, "Shutting down logger", new Exception("Shutdown")); - _writer.flushRecords(); + _log.log(Log.CRIT, "Shutting down logger", new Exception("Shutdown")); + _writer.flushRecords(); } - + private class ShutdownHook extends Thread { - public void run() { - shutdown(); - } + public void run() { + shutdown(); + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogRecord.java b/core/java/src/net/i2p/util/LogRecord.java index 45e6b729cd9d1127ec21a977f827a5d798243dba..fa1df45197cc9400472f8071375f401af3c4c9c3 100644 --- a/core/java/src/net/i2p/util/LogRecord.java +++ b/core/java/src/net/i2p/util/LogRecord.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -20,22 +21,42 @@ class LogRecord { private int _priority; private String _message; private Throwable _throwable; - + public LogRecord(Class src, String name, String threadName, int priority, String msg, Throwable t) { - _date = Clock.getInstance().now(); - _source = src; - _name = name; - _threadName = threadName; - _priority = priority; - _message = msg; - _throwable = t; - } - - public long getDate() { return _date; } - public Class getSource() { return _source; } - public String getSourceName() { return _name; } - public String getThreadName() { return _threadName; } - public int getPriority() { return _priority; } - public String getMessage() { return _message; } - public Throwable getThrowable() { return _throwable; } -} + _date = Clock.getInstance().now(); + _source = src; + _name = name; + _threadName = threadName; + _priority = priority; + _message = msg; + _throwable = t; + } + + public long getDate() { + return _date; + } + + public Class getSource() { + return _source; + } + + public String getSourceName() { + return _name; + } + + public String getThreadName() { + return _threadName; + } + + public int getPriority() { + return _priority; + } + + public String getMessage() { + return _message; + } + + public Throwable getThrowable() { + return _throwable; + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogRecordFormatter.java b/core/java/src/net/i2p/util/LogRecordFormatter.java index 24fe736f2352bdacd77b267d9db9b8ec69d22d36..b186e7e1068f69db637d691a1d6e6813b9bbd842 100644 --- a/core/java/src/net/i2p/util/LogRecordFormatter.java +++ b/core/java/src/net/i2p/util/LogRecordFormatter.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -9,9 +10,8 @@ package net.i2p.util; */ import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; import java.io.IOException; - +import java.io.PrintWriter; import java.util.Date; /** @@ -25,53 +25,77 @@ class LogRecordFormatter { // if we're going to have one for where... be consistent private final static int MAX_THREAD_LENGTH = 12; private final static int MAX_PRIORITY_LENGTH = 5; - - + public static String formatRecord(LogRecord rec) { - StringBuffer buf = new StringBuffer(); - char format[] = LogManager.getInstance()._getFormat(); - for (int i=0; i<format.length; ++i) { - switch ((int)format[i]) { - case (int)LogManager.DATE: buf.append(getWhen(rec)); break; - case (int)LogManager.CLASS: buf.append(getWhere(rec)); break; - case (int)LogManager.THREAD: buf.append(getThread(rec)); break; - case (int)LogManager.PRIORITY: buf.append(getPriority(rec)); break; - case (int)LogManager.MESSAGE: buf.append(getWhat(rec)); break; - default: buf.append(format[i]); break; - } - } - buf.append(NL); - if (rec.getThrowable() != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); - PrintWriter pw = new PrintWriter(baos, true); - rec.getThrowable().printStackTrace(pw); - try { - pw.flush(); - baos.flush(); - } catch (IOException ioe) {} - byte tb[] = baos.toByteArray(); - buf.append(new String(tb)); - } - return buf.toString(); + StringBuffer buf = new StringBuffer(); + char format[] = LogManager.getInstance()._getFormat(); + for (int i = 0; i < format.length; ++i) { + switch ((int) format[i]) { + case (int) LogManager.DATE: + buf.append(getWhen(rec)); + break; + case (int) LogManager.CLASS: + buf.append(getWhere(rec)); + break; + case (int) LogManager.THREAD: + buf.append(getThread(rec)); + break; + case (int) LogManager.PRIORITY: + buf.append(getPriority(rec)); + break; + case (int) LogManager.MESSAGE: + buf.append(getWhat(rec)); + break; + default: + buf.append(format[i]); + break; + } + } + buf.append(NL); + if (rec.getThrowable() != null) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + PrintWriter pw = new PrintWriter(baos, true); + rec.getThrowable().printStackTrace(pw); + try { + pw.flush(); + baos.flush(); + } catch (IOException ioe) { + } + byte tb[] = baos.toByteArray(); + buf.append(new String(tb)); + } + return buf.toString(); + } + + private static String getThread(LogRecord logRecord) { + return toString(logRecord.getThreadName(), MAX_THREAD_LENGTH); } - private static String getThread(LogRecord logRecord) { return toString(logRecord.getThreadName(), MAX_THREAD_LENGTH); } - private static String getWhen(LogRecord logRecord) { return LogManager.getInstance()._getDateFormat().format(new Date(logRecord.getDate())); } - private static String getPriority(LogRecord rec) { return toString(Log.toLevelString(rec.getPriority()), MAX_PRIORITY_LENGTH); } - private static String getWhat(LogRecord rec) { return rec.getMessage(); } - private static String getWhere(LogRecord rec) { - String src = (rec.getSource() != null ? rec.getSource().getName() : rec.getSourceName()); - if (src == null) src = "<none>"; - return toString(src, MAX_WHERE_LENGTH); + private static String getWhen(LogRecord logRecord) { + return LogManager.getInstance()._getDateFormat().format(new Date(logRecord.getDate())); } - + + private static String getPriority(LogRecord rec) { + return toString(Log.toLevelString(rec.getPriority()), MAX_PRIORITY_LENGTH); + } + + private static String getWhat(LogRecord rec) { + return rec.getMessage(); + } + + private static String getWhere(LogRecord rec) { + String src = (rec.getSource() != null ? rec.getSource().getName() : rec.getSourceName()); + if (src == null) src = "<none>"; + return toString(src, MAX_WHERE_LENGTH); + } + private static String toString(String str, int size) { - StringBuffer buf = new StringBuffer(); - if (str == null) str = ""; - if (str.length() > size) - str = str.substring(str.length() - size); - buf.append(str); - while (buf.length() < size) buf.append(' '); - return buf.toString(); + StringBuffer buf = new StringBuffer(); + if (str == null) str = ""; + if (str.length() > size) str = str.substring(str.length() - size); + buf.append(str); + while (buf.length() < size) + buf.append(' '); + return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/LogWriter.java b/core/java/src/net/i2p/util/LogWriter.java index d295d8b02055f3c9b868959ba0f3010929fd19ef..19eca261a2ee6693956ae27cd11ce861ecfb75e7 100644 --- a/core/java/src/net/i2p/util/LogWriter.java +++ b/core/java/src/net/i2p/util/LogWriter.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -21,158 +22,163 @@ import java.util.List; * */ class LogWriter implements Runnable { - private final static long CONFIG_READ_ITERVAL = 10*1000; + private final static long CONFIG_READ_ITERVAL = 10 * 1000; private long _lastReadConfig = 0; private long _numBytesInCurrentFile = 0; - private OutputStream _currentOut; // = System.out + private OutputStream _currentOut; // = System.out private int _rotationNum = -1; private String _logFilenamePattern; private File _currentFile; private boolean _write; - public void stopWriting() { _write = false; } - + + public void stopWriting() { + _write = false; + } + public void run() { - _write = true; - rotateFile(); - while (_write) { - flushRecords(); - } + _write = true; + rotateFile(); + while (_write) { + flushRecords(); + } } - + public void flushRecords() { - try { - List records = LogManager.getInstance()._removeAll(); - for (int i = 0; i < records.size(); i++) { - LogRecord rec = (LogRecord)records.get(i); - writeRecord(rec); - } - if (records.size() > 0) { - try { - _currentOut.flush(); - } catch (IOException ioe) { - System.err.println("Error flushing the records"); - } - } - records.clear(); - try { Thread.sleep(30); } catch (InterruptedException ie) {} - } catch (Throwable t) { - t.printStackTrace(); - } - long now = Clock.getInstance().now(); - if (now - _lastReadConfig > CONFIG_READ_ITERVAL) { - LogManager.getInstance().rereadConfig(); - _lastReadConfig = now; - } + try { + List records = LogManager.getInstance()._removeAll(); + for (int i = 0; i < records.size(); i++) { + LogRecord rec = (LogRecord) records.get(i); + writeRecord(rec); + } + if (records.size() > 0) { + try { + _currentOut.flush(); + } catch (IOException ioe) { + System.err.println("Error flushing the records"); + } + } + records.clear(); + try { + Thread.sleep(30); + } catch (InterruptedException ie) { + } + } catch (Throwable t) { + t.printStackTrace(); + } + long now = Clock.getInstance().now(); + if (now - _lastReadConfig > CONFIG_READ_ITERVAL) { + LogManager.getInstance().rereadConfig(); + _lastReadConfig = now; + } } private void writeRecord(LogRecord rec) { - String val = LogRecordFormatter.formatRecord(rec); - writeRecord(val); - - if (LogManager.getInstance().getDisplayOnScreenLevel() <= rec.getPriority()) { - // we always add to the console buffer, but only sometimes write to stdout - LogConsoleBuffer.getInstance().add(val); - if (LogManager.getInstance().displayOnScreen()) { - System.out.print(val); - } - } + String val = LogRecordFormatter.formatRecord(rec); + writeRecord(val); + + if (LogManager.getInstance().getDisplayOnScreenLevel() <= rec.getPriority()) { + // we always add to the console buffer, but only sometimes write to stdout + LogConsoleBuffer.getInstance().add(val); + if (LogManager.getInstance().displayOnScreen()) { + System.out.print(val); + } + } } - + private void writeRecord(String val) { - if (val == null) return; - if (_currentOut == null) rotateFile(); - - byte b[] = val.getBytes(); - try { - _currentOut.write(b); - _numBytesInCurrentFile += b.length; - } catch (Throwable t) { - System.err.println("Error writing record, disk full?"); - t.printStackTrace(); - } - if (_numBytesInCurrentFile >= LogManager.getInstance()._getFileSize()) { - rotateFile(); - } + if (val == null) return; + if (_currentOut == null) rotateFile(); + + byte b[] = val.getBytes(); + try { + _currentOut.write(b); + _numBytesInCurrentFile += b.length; + } catch (Throwable t) { + System.err.println("Error writing record, disk full?"); + t.printStackTrace(); + } + if (_numBytesInCurrentFile >= LogManager.getInstance()._getFileSize()) { + rotateFile(); + } } - + /** * Rotate to the next file (or the first file if this is the first call) * */ private void rotateFile() { - String pattern = LogManager.getInstance()._getBaseLogfilename(); - File f = getNextFile(pattern); - _currentFile = f; - _numBytesInCurrentFile = 0; - try { - _currentOut = new FileOutputStream(f); - } catch (IOException ioe) { - System.err.println("Error rotating into [" + f.getAbsolutePath() + "]"); - ioe.printStackTrace(); - } + String pattern = LogManager.getInstance()._getBaseLogfilename(); + File f = getNextFile(pattern); + _currentFile = f; + _numBytesInCurrentFile = 0; + try { + _currentOut = new FileOutputStream(f); + } catch (IOException ioe) { + System.err.println("Error rotating into [" + f.getAbsolutePath() + "]"); + ioe.printStackTrace(); + } } - + /** * Get the next file in the rotation * */ private File getNextFile(String pattern) { - File f = null; - if (pattern.indexOf('#') < 0) { - return new File(pattern); - } else { - int max = LogManager.getInstance()._getRotationLimit(); - if (_rotationNum == -1) { - return getFirstFile(pattern, max); - } else { - // we're in rotation, just go to the next - _rotationNum++; - if (_rotationNum > max) - _rotationNum = 0; - return new File(replace(pattern, _rotationNum)); - } - } + File f = null; + if (pattern.indexOf('#') < 0) { + return new File(pattern); + } else { + int max = LogManager.getInstance()._getRotationLimit(); + if (_rotationNum == -1) { + return getFirstFile(pattern, max); + } else { + // we're in rotation, just go to the next + _rotationNum++; + if (_rotationNum > max) _rotationNum = 0; + return new File(replace(pattern, _rotationNum)); + } + } } - + /** * Retrieve the first file, updating the rotation number accordingly * */ private File getFirstFile(String pattern, int max) { - for (int i = 0; i < max; i++) { - File f = new File(replace(pattern, i)); - if (!f.exists()) { - _rotationNum = i; - return f; - } - } - - // all exist, pick the oldest to replace - File oldest = null; - for (int i = 0; i < max; i++) { - File f = new File(replace(pattern, i)); - if (oldest == null) { - oldest = f; - } else { - if (f.lastModified() < oldest.lastModified()) { - _rotationNum = i; - oldest = f; - } - } - } - return oldest; + for (int i = 0; i < max; i++) { + File f = new File(replace(pattern, i)); + if (!f.exists()) { + _rotationNum = i; + return f; + } + } + + // all exist, pick the oldest to replace + File oldest = null; + for (int i = 0; i < max; i++) { + File f = new File(replace(pattern, i)); + if (oldest == null) { + oldest = f; + } else { + if (f.lastModified() < oldest.lastModified()) { + _rotationNum = i; + oldest = f; + } + } + } + return oldest; } - + private static final String replace(String pattern, int num) { - char c[] = pattern.toCharArray(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < c.length; i++) { - if (c[i] != '#') - buf.append(c[i]); - else - buf.append(num); - } - return buf.toString(); + char c[] = pattern.toCharArray(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < c.length; i++) { + if (c[i] != '#') + buf.append(c[i]); + else + buf.append(num); + } + return buf.toString(); } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java index 97fe536a1d0b70a3479f08b010323e61de8418bc..ccec548016b46701d978b5943c796509fd659b30 100644 --- a/core/java/src/net/i2p/util/NativeBigInteger.java +++ b/core/java/src/net/i2p/util/NativeBigInteger.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -8,25 +9,25 @@ package net.i2p.util; * */ -import net.i2p.crypto.CryptoConstants; - import java.math.BigInteger; import java.util.Random; +import net.i2p.crypto.CryptoConstants; + public class NativeBigInteger extends BigInteger { private final static Log _log = new Log(NativeBigInteger.class); private static boolean _nativeOk = false; static { - try { - System.loadLibrary("jbigi"); - _nativeOk = true; - _log.info("Native BigInteger library jbigi loaded"); - } catch (UnsatisfiedLinkError ule) { - _nativeOk = false; - _log.warn("Native BigInteger library jbigi not loaded - using pure java", ule); - } + try { + System.loadLibrary("jbigi"); + _nativeOk = true; + _log.info("Native BigInteger library jbigi loaded"); + } catch (UnsatisfiedLinkError ule) { + _nativeOk = false; + _log.warn("Native BigInteger library jbigi not loaded - using pure java", ule); + } } - + /** * calculate (base ^ exponent) % modulus. * @param base big endian twos complement representation of the base (but it must be positive) @@ -35,88 +36,100 @@ public class NativeBigInteger extends BigInteger { * @return big endian twos complement representation of (base ^ exponent) % modulus */ public native static byte[] nativeModPow(byte base[], byte exponent[], byte modulus[]); - + public NativeBigInteger(byte val[]) { - super(val); + super(val); } + public NativeBigInteger(int signum, byte magnitude[]) { - super(signum, magnitude); + super(signum, magnitude); } + public NativeBigInteger(int bitlen, int certainty, Random rnd) { - super(bitlen, certainty, rnd); + super(bitlen, certainty, rnd); } + public NativeBigInteger(int numbits, Random rnd) { - super(numbits, rnd); + super(numbits, rnd); } + public NativeBigInteger(String val) { - super(val); + super(val); } + public NativeBigInteger(String val, int radix) { - super(val, radix); + super(val, radix); } - + public BigInteger modPow(BigInteger exponent, BigInteger m) { - if (_nativeOk) - return new NativeBigInteger(nativeModPow(toByteArray(), exponent.toByteArray(), m.toByteArray())); - else - return super.modPow(exponent, m); + if (_nativeOk) + return new NativeBigInteger(nativeModPow(toByteArray(), exponent.toByteArray(), m.toByteArray())); + else + return super.modPow(exponent, m); } - + public static void main(String args[]) { - if (_nativeOk) System.out.println("Native library loaded"); - else System.out.println("Native library NOT loaded"); - System.out.println("Warming up the random number generator..."); - RandomSource.getInstance().nextBoolean(); - System.out.println("Random number generator warmed up"); - - int numRuns = 100; - if (args.length == 1) { - try { numRuns = Integer.parseInt(args[0]); } catch (NumberFormatException nfe) {} - } - BigInteger jg = new BigInteger(CryptoConstants.elgg.toByteArray()); - BigInteger jp = new BigInteger(CryptoConstants.elgp.toByteArray()); - - long totalTime = 0; - long javaTime = 0; - - int runsProcessed = 0; - for (runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) { - BigInteger bi = new BigInteger(2048, RandomSource.getInstance()); - NativeBigInteger g = new NativeBigInteger(CryptoConstants.elgg.toByteArray()); - NativeBigInteger p = new NativeBigInteger(CryptoConstants.elgp.toByteArray()); - NativeBigInteger k = new NativeBigInteger(1, bi.toByteArray()); - long beforeModPow = System.currentTimeMillis(); - BigInteger myValue = g.modPow(k, p); - long afterModPow = System.currentTimeMillis(); - BigInteger jval = jg.modPow(bi, jp); - long afterJavaModPow = System.currentTimeMillis(); - - totalTime += (afterModPow - beforeModPow); - javaTime += (afterJavaModPow - afterModPow); - if (!myValue.equals(jval)) { - _log.error("[" + runsProcessed + "]\tnative modPow != java modPow"); - _log.error("native modPow value: " + myValue.toString()); - _log.error("java modPow value: " + jval.toString()); - _log.error("run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)"); - System.err.println("[" + runsProcessed + "]\tnative modPow != java modPow"); - break; - } else { - _log.debug("current run time: " + (afterModPow-beforeModPow) + "ms (total: " + totalTime + "ms, " + (totalTime / (runsProcessed + 1)) + "ms each)"); - } - } - _log.info(numRuns + " runs complete without any errors"); - _log.info("run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)"); - if (numRuns == runsProcessed) - System.out.println(runsProcessed + " runs complete without any errors"); - else - System.out.println(runsProcessed + " runs until we got an error"); - - if (_nativeOk) { - System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)"); - System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)"); - System.out.println("native = " + ((totalTime*100.0d) / (double)javaTime) + "% of pure java time"); - } else { - System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)"); - } + if (_nativeOk) + System.out.println("Native library loaded"); + else + System.out.println("Native library NOT loaded"); + System.out.println("Warming up the random number generator..."); + RandomSource.getInstance().nextBoolean(); + System.out.println("Random number generator warmed up"); + + int numRuns = 100; + if (args.length == 1) { + try { + numRuns = Integer.parseInt(args[0]); + } catch (NumberFormatException nfe) { + } + } + BigInteger jg = new BigInteger(CryptoConstants.elgg.toByteArray()); + BigInteger jp = new BigInteger(CryptoConstants.elgp.toByteArray()); + + long totalTime = 0; + long javaTime = 0; + + int runsProcessed = 0; + for (runsProcessed = 0; runsProcessed < numRuns; runsProcessed++) { + BigInteger bi = new BigInteger(2048, RandomSource.getInstance()); + NativeBigInteger g = new NativeBigInteger(CryptoConstants.elgg.toByteArray()); + NativeBigInteger p = new NativeBigInteger(CryptoConstants.elgp.toByteArray()); + NativeBigInteger k = new NativeBigInteger(1, bi.toByteArray()); + long beforeModPow = System.currentTimeMillis(); + BigInteger myValue = g.modPow(k, p); + long afterModPow = System.currentTimeMillis(); + BigInteger jval = jg.modPow(bi, jp); + long afterJavaModPow = System.currentTimeMillis(); + + totalTime += (afterModPow - beforeModPow); + javaTime += (afterJavaModPow - afterModPow); + if (!myValue.equals(jval)) { + _log.error("[" + runsProcessed + "]\tnative modPow != java modPow"); + _log.error("native modPow value: " + myValue.toString()); + _log.error("java modPow value: " + jval.toString()); + _log.error("run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)"); + System.err.println("[" + runsProcessed + "]\tnative modPow != java modPow"); + break; + } else { + _log.debug("current run time: " + (afterModPow - beforeModPow) + "ms (total: " + totalTime + "ms, " + + (totalTime / (runsProcessed + 1)) + "ms each)"); + } + } + _log.info(numRuns + " runs complete without any errors"); + _log.info("run time: " + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + "ms each)"); + if (numRuns == runsProcessed) + System.out.println(runsProcessed + " runs complete without any errors"); + else + System.out.println(runsProcessed + " runs until we got an error"); + + if (_nativeOk) { + System.out.println("native run time: \t" + totalTime + "ms (" + (totalTime / (runsProcessed + 1)) + + "ms each)"); + System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)"); + System.out.println("native = " + ((totalTime * 100.0d) / (double) javaTime) + "% of pure java time"); + } else { + System.out.println("java run time: \t" + javaTime + "ms (" + (javaTime / (runsProcessed + 1)) + "ms each)"); + } } -} +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/OrderedProperties.java b/core/java/src/net/i2p/util/OrderedProperties.java index 1b5695020dd295efdff85163736bf25b1e3ad8ac..5d2d1aaa1f15f9319a7a5eddcccf9d4c25f887ae 100644 --- a/core/java/src/net/i2p/util/OrderedProperties.java +++ b/core/java/src/net/i2p/util/OrderedProperties.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -37,234 +38,269 @@ public class OrderedProperties extends Properties { private TreeSet _order; /** simple key=value mapping of the actual data */ private Map _data; - + /** lock this before touching _order or _data */ private Object _lock = new Object(); - + public OrderedProperties() { - super(); - _order = new TreeSet(); - _data = new HashMap(); + super(); + _order = new TreeSet(); + _data = new HashMap(); + } + + public boolean contains(Object value) { + return containsValue(value); } - - public boolean contains(Object value) { return containsValue(value); } + public boolean containsKey(Object key) { - synchronized (_lock) { - return _data.containsKey(key); - } + synchronized (_lock) { + return _data.containsKey(key); + } } + public boolean containsValue(Object value) { - synchronized (_lock) { - return _data.containsValue(value); - } - } - - public boolean equals(Object obj) { - if ( (obj != null) && (obj instanceof OrderedProperties) ) { - synchronized (_lock) { - return _data.equals(obj); - } - } else { - return false; - } + synchronized (_lock) { + return _data.containsValue(value); + } + } + + public boolean equals(Object obj) { + if ((obj != null) && (obj instanceof OrderedProperties)) { + synchronized (_lock) { + return _data.equals(obj); + } + } else { + return false; + } } + public int hashCode() { - synchronized (_lock) { - return _data.hashCode(); - } - } - public boolean isEmpty() { return size() == 0; } - - public String getProperty(String key) { return getProperty((Object)key); } - public Object get(Object key) { return getProperty(key); } + synchronized (_lock) { + return _data.hashCode(); + } + } + + public boolean isEmpty() { + return size() == 0; + } + + public String getProperty(String key) { + return getProperty((Object) key); + } + + public Object get(Object key) { + return getProperty(key); + } + private String getProperty(Object key) { - if (key == null) return null; - synchronized (_lock) { - Object rv = _data.get(key); - if ( (rv != null) && (rv instanceof String) ) - return (String)rv; - else - return null; - } + if (key == null) return null; + synchronized (_lock) { + Object rv = _data.get(key); + if ((rv != null) && (rv instanceof String)) + return (String) rv; + else + return null; + } } public Object setProperty(String key, String val) { - if ( (key == null) || (val == null) ) - throw new IllegalArgumentException("Null values are not supported"); - synchronized (_lock) { - _order.add(key); - Object rv = _data.put(key, val); - return rv; - } + if ((key == null) || (val == null)) throw new IllegalArgumentException("Null values are not supported"); + synchronized (_lock) { + _order.add(key); + Object rv = _data.put(key, val); + return rv; + } } public Object put(Object key, Object val) { - if ( (key == null) || (val == null) ) - throw new NullPointerException("Null values or keys are not allowed"); - if ( !(key instanceof String) || !(val instanceof String) ) - throw new IllegalArgumentException("Key or value is not a string"); - return setProperty((String)key, (String)val); + if ((key == null) || (val == null)) throw new NullPointerException("Null values or keys are not allowed"); + if (!(key instanceof String) || !(val instanceof String)) + throw new IllegalArgumentException("Key or value is not a string"); + return setProperty((String) key, (String) val); } - + public void putAll(Map data) { - if (data == null) return; - for (Iterator iter = data.keySet().iterator(); iter.hasNext(); ) { - Object key = iter.next(); - Object val = data.get(key); - put(key, val); - } - } - + if (data == null) return; + for (Iterator iter = data.keySet().iterator(); iter.hasNext();) { + Object key = iter.next(); + Object val = data.get(key); + put(key, val); + } + } + public Object clone() { - synchronized (_lock) { - OrderedProperties rv = new OrderedProperties(); - rv.putAll(this); - return rv; - } + synchronized (_lock) { + OrderedProperties rv = new OrderedProperties(); + rv.putAll(this); + return rv; + } } - + public void clear() { - synchronized (_lock) { - _order.clear(); - _data.clear(); - } + synchronized (_lock) { + _order.clear(); + _data.clear(); + } } - + public int size() { - synchronized (_lock) { return _order.size(); } + synchronized (_lock) { + return _order.size(); + } } - + public Object remove(Object key) { - synchronized (_lock) { - _order.remove(key); - Object rv = _data.remove(key); - return rv; - } + synchronized (_lock) { + _order.remove(key); + Object rv = _data.remove(key); + return rv; + } } - + public Set keySet() { - synchronized (_lock) { - return Collections.unmodifiableSortedSet((TreeSet)_order.clone()); - } + synchronized (_lock) { + return Collections.unmodifiableSortedSet((TreeSet) _order.clone()); + } } - + public Set entrySet() { - synchronized (_lock) { - return Collections.unmodifiableSet(buildEntrySet((TreeSet)_order.clone())); - } + synchronized (_lock) { + return Collections.unmodifiableSet(buildEntrySet((TreeSet) _order.clone())); + } } - + public Collection values() { - synchronized (_lock) { - Collection values = new ArrayList(_data.size()); - for (Iterator iter = _data.values().iterator(); iter.hasNext();) { - values.add(iter.next()); - } - return values; - } - } - - public Enumeration elements() { return Collections.enumeration(values()); } - public Enumeration keys() { return Collections.enumeration(keySet()); } - public Enumeration propertyNames() { return Collections.enumeration(keySet()); } - - public void list(PrintStream out) {} - public void list(PrintWriter out) {} - public void load(InputStream in) {} + synchronized (_lock) { + Collection values = new ArrayList(_data.size()); + for (Iterator iter = _data.values().iterator(); iter.hasNext();) { + values.add(iter.next()); + } + return values; + } + } + + public Enumeration elements() { + return Collections.enumeration(values()); + } + + public Enumeration keys() { + return Collections.enumeration(keySet()); + } + + public Enumeration propertyNames() { + return Collections.enumeration(keySet()); + } + + public void list(PrintStream out) { + } + + public void list(PrintWriter out) { + } + + public void load(InputStream in) { + } + //public void save(OutputStream out, String header) {} - public void store(OutputStream out, String header) {} - + public void store(OutputStream out, String header) { + } + private Set buildEntrySet(Set data) { - TreeSet ts = new TreeSet(); - for (Iterator iter = data.iterator(); iter.hasNext(); ) { - String key = (String)iter.next(); - String val = getProperty(key); - ts.add(new StringMapEntry(key, val)); - } - return ts; - } - + TreeSet ts = new TreeSet(); + for (Iterator iter = data.iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = getProperty(key); + ts.add(new StringMapEntry(key, val)); + } + return ts; + } + private static class StringMapEntry implements Map.Entry, Comparable { - private Object _key; - private Object _value; - public StringMapEntry(String key, String val) { - _key = key; - _value = val; - } - public Object getKey() { return _key; } - public Object getValue() { return _value; } - public Object setValue(Object value) { - Object old = _value; - _value = value; - return old; - } - - public int compareTo(Object o) { - if (o == null) return -1; - if (o instanceof StringMapEntry) - return ((String)getKey()).compareTo(((StringMapEntry)o).getKey()); - if (o instanceof String) - return ((String)getKey()).compareTo(o); - return -2; - } - public boolean equals(Object o) { - if (o == null) return false; - if (!(o instanceof StringMapEntry)) return false; - StringMapEntry e = (StringMapEntry)o; - return DataHelper.eq(e.getKey(), getKey()) && - DataHelper.eq(e.getValue(), getValue()); - } - } - + private Object _key; + private Object _value; + + public StringMapEntry(String key, String val) { + _key = key; + _value = val; + } + + public Object getKey() { + return _key; + } + + public Object getValue() { + return _value; + } + + public Object setValue(Object value) { + Object old = _value; + _value = value; + return old; + } + + public int compareTo(Object o) { + if (o == null) return -1; + if (o instanceof StringMapEntry) return ((String) getKey()).compareTo(((StringMapEntry) o).getKey()); + if (o instanceof String) return ((String) getKey()).compareTo(o); + return -2; + } + + public boolean equals(Object o) { + if (o == null) return false; + if (!(o instanceof StringMapEntry)) return false; + StringMapEntry e = (StringMapEntry) o; + return DataHelper.eq(e.getKey(), getKey()) && DataHelper.eq(e.getValue(), getValue()); + } + } + /// /// tests /// - + public static void main(String args[]) { - test(new OrderedProperties()); - _log.debug("After ordered"); - //test(new Properties()); - //System.out.println("After normal"); - test2(); - testThrash(); - } - + test(new OrderedProperties()); + _log.debug("After ordered"); + //test(new Properties()); + //System.out.println("After normal"); + test2(); + testThrash(); + } + private static void test2() { - OrderedProperties p = new OrderedProperties(); - p.setProperty("a", "b"); - p.setProperty("c", "d"); - OrderedProperties p2 = new OrderedProperties(); - try { - p2.putAll(p); - } catch (Throwable t) { - t.printStackTrace(); - } - _log.debug("After test2"); - } - + OrderedProperties p = new OrderedProperties(); + p.setProperty("a", "b"); + p.setProperty("c", "d"); + OrderedProperties p2 = new OrderedProperties(); + try { + p2.putAll(p); + } catch (Throwable t) { + t.printStackTrace(); + } + _log.debug("After test2"); + } + private static void test(Properties p) { - for (int i = 0; i < 10; i++) - p.setProperty(i + "asdfasdfasdf", "qwerasdfqwer"); - for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { - String key = (String)iter.next(); - String val = p.getProperty(key); - _log.debug("[" + key + "] = [" + val + "]"); - } - p.remove(4 + "asdfasdfasdf"); - _log.debug("After remove"); - for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { - String key = (String)iter.next(); - String val = p.getProperty(key); - _log.debug("[" + key + "] = [" + val + "]"); - } - try { - p.put("nullVal", null); - _log.debug("Null put did NOT fail!"); - } catch (NullPointerException npe) { - _log.debug("Null put failed correctly"); - } - } - + for (int i = 0; i < 10; i++) + p.setProperty(i + "asdfasdfasdf", "qwerasdfqwer"); + for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = p.getProperty(key); + _log.debug("[" + key + "] = [" + val + "]"); + } + p.remove(4 + "asdfasdfasdf"); + _log.debug("After remove"); + for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { + String key = (String) iter.next(); + String val = p.getProperty(key); + _log.debug("[" + key + "] = [" + val + "]"); + } + try { + p.put("nullVal", null); + _log.debug("Null put did NOT fail!"); + } catch (NullPointerException npe) { + _log.debug("Null put failed correctly"); + } + } + /** * Set 100 concurrent threads trying to do some operations against a single * OrderedProperties object a thousand times. Hopefully this will help @@ -272,43 +308,45 @@ public class OrderedProperties extends Properties { * */ private static void testThrash() { - OrderedProperties prop = new OrderedProperties(); - for (int i = 0; i < 100; i++) - prop.setProperty(i+"", i+" value"); - _log.debug("Thrash properties built"); - for (int i = 0; i < 100; i++) - thrash(prop, i); - } - + OrderedProperties prop = new OrderedProperties(); + for (int i = 0; i < 100; i++) + prop.setProperty(i + "", i + " value"); + _log.debug("Thrash properties built"); + for (int i = 0; i < 100; i++) + thrash(prop, i); + } + private static void thrash(Properties props, int i) { - I2PThread t = new I2PThread(new Thrash(props)); - t.setName("Thrash" + i); - t.start(); + I2PThread t = new I2PThread(new Thrash(props)); + t.setName("Thrash" + i); + t.start(); } - + private static class Thrash implements Runnable { - private Properties _props; - public Thrash(Properties props) { - _props = props; - } - public void run() { - int numRuns = 1000; - _log.debug("Begin thrashing " + numRuns + " times"); - for (int i = 0; i < numRuns; i++) { - Set keys = _props.keySet(); - //_log.debug("keySet fetched"); - int cur = 0; - for (Iterator iter = keys.iterator(); iter.hasNext(); ) { - Object o = iter.next(); - Object val = _props.get(o); - //_log.debug("Value " + cur + " fetched"); - cur++; - } - //_log.debug("Values fetched"); - int size = _props.size(); - _log.debug("Size calculated"); - } - _log.debug("Done thrashing " + numRuns + " times"); - } - } -} + private Properties _props; + + public Thrash(Properties props) { + _props = props; + } + + public void run() { + int numRuns = 1000; + _log.debug("Begin thrashing " + numRuns + " times"); + for (int i = 0; i < numRuns; i++) { + Set keys = _props.keySet(); + //_log.debug("keySet fetched"); + int cur = 0; + for (Iterator iter = keys.iterator(); iter.hasNext();) { + Object o = iter.next(); + Object val = _props.get(o); + //_log.debug("Value " + cur + " fetched"); + cur++; + } + //_log.debug("Values fetched"); + int size = _props.size(); + _log.debug("Size calculated"); + } + _log.debug("Done thrashing " + numRuns + " times"); + } + } +} \ No newline at end of file diff --git a/core/java/src/net/i2p/util/RandomSource.java b/core/java/src/net/i2p/util/RandomSource.java index 47932ae61f90461a13853822b9fb44b257b9e323..3929bac1be561fbd5a1c72fc7045f90a882c098f 100644 --- a/core/java/src/net/i2p/util/RandomSource.java +++ b/core/java/src/net/i2p/util/RandomSource.java @@ -1,4 +1,5 @@ package net.i2p.util; + /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain @@ -17,11 +18,15 @@ import java.security.SecureRandom; */ public class RandomSource extends SecureRandom { private final static RandomSource _random = new RandomSource(); + private RandomSource() { - super(); + super(); + } + + public static RandomSource getInstance() { + return _random; } - public static RandomSource getInstance() { return _random; } - + /** * According to the java docs (http://java.sun.com/j2se/1.4.1/docs/api/java/util/Random.html#nextInt(int)) * nextInt(n) should return a number between 0 and n inclusive. However, their pseudocode, @@ -31,30 +36,27 @@ public class RandomSource extends SecureRandom { * */ public int nextInt(int n) { - if (n == 0) return 0; - int val = super.nextInt(n); - if (val < 0) - val = 0 - val; - return val; + if (n == 0) return 0; + int val = super.nextInt(n); + if (val < 0) val = 0 - val; + return val; } - + /** * Like the modified nextInt, nextLong(n) returns a random number from 0 through n, * inclusive. */ public long nextLong(long n) { - long v = super.nextLong(); - if (v < 0) - v = 0 - v; - if (v > n) - v = v % n; - return v; + long v = super.nextLong(); + if (v < 0) v = 0 - v; + if (v > n) v = v % n; + return v; } - + /** synchronized for older versions of kaffe */ public void nextBytes(byte bytes[]) { - synchronized (this) { - super.nextBytes(bytes); - } + synchronized (this) { + super.nextBytes(bytes); + } } -} +} \ No newline at end of file diff --git a/installer/java/src/CliInstall.java b/installer/java/src/CliInstall.java index 9c66533784edaae09a5a3ed21089d2231c2cb54a..ed976194d1cb11a74def518932904be9993e8c11 100644 --- a/installer/java/src/CliInstall.java +++ b/installer/java/src/CliInstall.java @@ -1,4 +1,7 @@ -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; public class CliInstall extends Install { diff --git a/installer/java/src/FetchSeeds.java b/installer/java/src/FetchSeeds.java index 88362985b07d77357652468eefdd150b4c98b7ea..122f5e7e061ae58edd93b776ed9cf4865cabf9bc 100644 --- a/installer/java/src/FetchSeeds.java +++ b/installer/java/src/FetchSeeds.java @@ -7,8 +7,15 @@ * http://www.fsf.org/copyleft/ */ -import java.io.*; -import java.net.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; public class FetchSeeds { diff --git a/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java b/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java index 4200cb1fb638979317d0f04f1675dff91169f39c..0bd5abbd58797602e05df9e2438312625ba42f0b 100644 --- a/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java +++ b/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java @@ -8,8 +8,8 @@ package net.i2p.data.i2np; * */ -import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; diff --git a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java index 58c33e988499d63998d338f8bd16f5a5a6c600ff..233d894bd2b59044ce238496b8d32e269f1b5dfe 100644 --- a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java +++ b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java @@ -8,19 +8,18 @@ package net.i2p.data.i2np; * */ -import java.io.InputStream; -import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; -import net.i2p.util.Log; - +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.Hash; import net.i2p.data.SessionKey; import net.i2p.data.TunnelId; +import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/data/i2np/EndPointPrivateKey.java b/router/java/src/net/i2p/data/i2np/EndPointPrivateKey.java index 417217518b98e6fd4bed374253d10bd7a8feccc7..8f5763ae4819af4c7e30715ee8d001abd4d6cf67 100644 --- a/router/java/src/net/i2p/data/i2np/EndPointPrivateKey.java +++ b/router/java/src/net/i2p/data/i2np/EndPointPrivateKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.PrivateKey; +import net.i2p.util.Log; /** * Contains the private key which matches the EndPointPublicKey which, in turn, diff --git a/router/java/src/net/i2p/data/i2np/EndPointPublicKey.java b/router/java/src/net/i2p/data/i2np/EndPointPublicKey.java index 303e236c498840392da1cb006488d7d16ed0efaf..3920d0bda2ae6a3dedb5eb21efd2853dab6085a4 100644 --- a/router/java/src/net/i2p/data/i2np/EndPointPublicKey.java +++ b/router/java/src/net/i2p/data/i2np/EndPointPublicKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.PublicKey; +import net.i2p.util.Log; /** * Contains the public key which matches the EndPointPrivateKey. This is diff --git a/router/java/src/net/i2p/data/i2np/GarlicClove.java b/router/java/src/net/i2p/data/i2np/GarlicClove.java index 4fbc0139c4daea989d4493497cbde59a4ee52fa8..aec216751fa24642205de6d0dbab0f54418131d5 100644 --- a/router/java/src/net/i2p/data/i2np/GarlicClove.java +++ b/router/java/src/net/i2p/data/i2np/GarlicClove.java @@ -8,18 +8,16 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import java.util.Date; +import net.i2p.data.Certificate; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; -import net.i2p.data.Certificate; - -import java.util.Date; +import net.i2p.util.Log; /** * Contains one deliverable message encrypted to a router along with instructions diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java index 79b7743c7d8c5da0db82dcc5297148a4ff5a76ca..196311610b4bea7497c2448bc6695e0cc054b723 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java @@ -8,15 +8,14 @@ package net.i2p.data.i2np; * */ -import java.io.InputStream; -import java.io.IOException; import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; -import net.i2p.data.DataHelper; import net.i2p.data.DataFormatException; - -import net.i2p.util.Log; +import net.i2p.data.DataHelper; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Handle messages from router to router diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java b/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java index c5ed08060c2711064f3164ccc7534389ed5bd325..581d89a61dd922b54027654ecdb1747fb3c5a7a9 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java @@ -16,8 +16,8 @@ import java.util.Date; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; /** diff --git a/router/java/src/net/i2p/data/i2np/TunnelConfigurationSessionKey.java b/router/java/src/net/i2p/data/i2np/TunnelConfigurationSessionKey.java index 6d4d1a382011b43cd30d293dd52e7bb85e806ff8..9384033fcde03bc51e3aa5ceceebffaf22a732b8 100644 --- a/router/java/src/net/i2p/data/i2np/TunnelConfigurationSessionKey.java +++ b/router/java/src/net/i2p/data/i2np/TunnelConfigurationSessionKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.SessionKey; +import net.i2p.util.Log; /** * Contains the session key used by the owner/creator of the tunnel to modify diff --git a/router/java/src/net/i2p/data/i2np/TunnelSessionKey.java b/router/java/src/net/i2p/data/i2np/TunnelSessionKey.java index d5f4bd822e9f336717c4c3d86e14fd46a87738c7..310341ef8ad31d871e205615ab6766811b1ed367 100644 --- a/router/java/src/net/i2p/data/i2np/TunnelSessionKey.java +++ b/router/java/src/net/i2p/data/i2np/TunnelSessionKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.SessionKey; +import net.i2p.util.Log; /** * Contains the session key used by the tunnel gateway to encrypt the DeliveryInstructions diff --git a/router/java/src/net/i2p/data/i2np/TunnelSigningPrivateKey.java b/router/java/src/net/i2p/data/i2np/TunnelSigningPrivateKey.java index 15c41acead851abf45046a4fdbe3e785260f05a1..5b95411e0db74999413bac6bd21862d9c323a6ca 100644 --- a/router/java/src/net/i2p/data/i2np/TunnelSigningPrivateKey.java +++ b/router/java/src/net/i2p/data/i2np/TunnelSigningPrivateKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.SigningPrivateKey; +import net.i2p.util.Log; /** * Contains the private key which constructs a signature for the TunnelMessage diff --git a/router/java/src/net/i2p/data/i2np/TunnelSigningPublicKey.java b/router/java/src/net/i2p/data/i2np/TunnelSigningPublicKey.java index 4845c175b73940a2c8f3130d81f95a7f8350ba3b..d125e5620f3472b94868f7843c5d41ce93edee84 100644 --- a/router/java/src/net/i2p/data/i2np/TunnelSigningPublicKey.java +++ b/router/java/src/net/i2p/data/i2np/TunnelSigningPublicKey.java @@ -8,16 +8,15 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.SigningPublicKey; +import net.i2p.util.Log; /** * Contains the public key which every participant in a tunnel uses to verify diff --git a/router/java/src/net/i2p/data/i2np/TunnelVerificationStructure.java b/router/java/src/net/i2p/data/i2np/TunnelVerificationStructure.java index 7bef3dbd2ed600f471afa59914df43fa1c310e30..8309e62b55656afcbb2acbe5b3d7a893f2ad690d 100644 --- a/router/java/src/net/i2p/data/i2np/TunnelVerificationStructure.java +++ b/router/java/src/net/i2p/data/i2np/TunnelVerificationStructure.java @@ -8,20 +8,19 @@ package net.i2p.data.i2np; * */ +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import net.i2p.util.Log; +import net.i2p.crypto.DSAEngine; +import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DataStructureImpl; -import net.i2p.data.DataFormatException; import net.i2p.data.Hash; import net.i2p.data.Signature; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; -import net.i2p.crypto.DSAEngine; +import net.i2p.util.Log; /** * diff --git a/router/java/src/net/i2p/router/ClientManagerFacade.java b/router/java/src/net/i2p/router/ClientManagerFacade.java index 048278f37e49ca49571b231c35ba8908b12e2aa5..73d39024b34b9fb1ea9f0bb4b98af2afc36f909c 100644 --- a/router/java/src/net/i2p/router/ClientManagerFacade.java +++ b/router/java/src/net/i2p/router/ClientManagerFacade.java @@ -8,14 +8,12 @@ package net.i2p.router; * */ -import net.i2p.router.client.ClientManagerFacadeImpl; - -import net.i2p.data.i2cp.MessageId; -import net.i2p.data.i2cp.SessionConfig; - import net.i2p.data.Destination; -import net.i2p.data.LeaseSet; import net.i2p.data.Hash; +import net.i2p.data.LeaseSet; +import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.SessionConfig; +import net.i2p.router.client.ClientManagerFacadeImpl; /** * Manage all interactions with clients diff --git a/router/java/src/net/i2p/router/ClientMessage.java b/router/java/src/net/i2p/router/ClientMessage.java index 46855b50ca2a1240173fa06c1dfda3af7b11c5ad..005f69a2d2580b4806012aa38a7ba7b4242f2e2a 100644 --- a/router/java/src/net/i2p/router/ClientMessage.java +++ b/router/java/src/net/i2p/router/ClientMessage.java @@ -8,11 +8,11 @@ package net.i2p.router; * */ -import net.i2p.data.Payload; import net.i2p.data.Destination; import net.i2p.data.Hash; -import net.i2p.data.i2cp.SessionConfig; +import net.i2p.data.Payload; import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.SessionConfig; /** * Wrap a message either destined for a local client or received from one. diff --git a/router/java/src/net/i2p/router/ClientMessagePool.java b/router/java/src/net/i2p/router/ClientMessagePool.java index 3fc437a026049b5388ab1c07b55defaf1fd884bc..05fd9d3c342161b5cfb7993ba07d001ced2230e7 100644 --- a/router/java/src/net/i2p/router/ClientMessagePool.java +++ b/router/java/src/net/i2p/router/ClientMessagePool.java @@ -9,12 +9,11 @@ package net.i2p.router; */ //import net.i2p.router.message.ProcessOutboundClientMessageJob; -import net.i2p.router.message.OutboundClientMessageJob; - -import java.util.List; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import net.i2p.router.message.OutboundClientMessageJob; import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/router/ClientTunnelSettings.java b/router/java/src/net/i2p/router/ClientTunnelSettings.java index 69198c1e0b225bc9e03180dea4d74da618787239..b40f2df19b128e0d80d4ac354ca57b3e4f76de36 100644 --- a/router/java/src/net/i2p/router/ClientTunnelSettings.java +++ b/router/java/src/net/i2p/router/ClientTunnelSettings.java @@ -8,8 +8,8 @@ package net.i2p.router; * */ -import java.util.Properties; import java.util.Iterator; +import java.util.Properties; /** * Wrap up the client settings specifying their tunnel criteria diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index bed961673121059a12ac50fee17ebed5d4bd922e..2f2eec57304f1eaa53e21ba5cfa8ff9db4cc41b2 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -8,11 +8,11 @@ package net.i2p.router; * */ -import net.i2p.router.transport.CommSystemFacadeImpl; - import java.util.HashSet; import java.util.Set; +import net.i2p.router.transport.CommSystemFacadeImpl; + /** * Manages the communication subsystem between peers, including connections, * listeners, transports, connection keys, etc. diff --git a/router/java/src/net/i2p/router/GenerateStatusConsoleJob.java b/router/java/src/net/i2p/router/GenerateStatusConsoleJob.java index f0f3fee0c121619a1b8920d6c3df4ca728e3d104..8faa129c366c5d35d342c995d958842b63157e3b 100644 --- a/router/java/src/net/i2p/router/GenerateStatusConsoleJob.java +++ b/router/java/src/net/i2p/router/GenerateStatusConsoleJob.java @@ -8,11 +8,11 @@ package net.i2p.router; * */ -import net.i2p.util.Log; - import java.io.FileOutputStream; import java.io.IOException; +import net.i2p.util.Log; + public class GenerateStatusConsoleJob extends JobImpl { private final static Log _log = new Log(GenerateStatusConsoleJob.class); diff --git a/router/java/src/net/i2p/router/HandlerJobBuilder.java b/router/java/src/net/i2p/router/HandlerJobBuilder.java index d7c7086e3d9edb6c5d993ffe4bc4789cbfa96e60..2119c20586a565a78b9f50e2144e6f784d9397e6 100644 --- a/router/java/src/net/i2p/router/HandlerJobBuilder.java +++ b/router/java/src/net/i2p/router/HandlerJobBuilder.java @@ -8,10 +8,10 @@ package net.i2p.router; * */ +import net.i2p.data.Hash; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.SourceRouteBlock; -import net.i2p.data.RouterIdentity; -import net.i2p.data.Hash; /** * Defines a class that builds jobs to handle a particular message - these diff --git a/router/java/src/net/i2p/router/InNetMessage.java b/router/java/src/net/i2p/router/InNetMessage.java index 16dfec99cdbcd15da7c792d72fcee7202b1e104f..31d01ad9d6f964ee0ba207d0cc0d9c6f86cf7764 100644 --- a/router/java/src/net/i2p/router/InNetMessage.java +++ b/router/java/src/net/i2p/router/InNetMessage.java @@ -8,10 +8,10 @@ package net.i2p.router; * */ -import net.i2p.data.i2np.I2NPMessage; -import net.i2p.data.i2np.SourceRouteBlock; import net.i2p.data.Hash; import net.i2p.data.RouterIdentity; +import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.i2np.SourceRouteBlock; /** * Wrap an I2NP message received from the network prior to handling and processing. diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index cae83369d8e491de042cd00e7b5308740448d72a..60a0d9f5f089d36ae8e97df9f5ae77efd08dc5f4 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -16,8 +16,8 @@ import java.util.List; import java.util.Map; import net.i2p.router.transport.OutboundMessageRegistry; -import net.i2p.util.Log; import net.i2p.stat.StatManager; +import net.i2p.util.Log; /** * Manage a pool of inbound InNetMessages. This pool is filled by the diff --git a/router/java/src/net/i2p/router/JobQueueRunner.java b/router/java/src/net/i2p/router/JobQueueRunner.java index 0bc41579926e434241bd6eeeb9d526d0b78c2259..c593001498635ca829d19467a80177c76b9746fd 100644 --- a/router/java/src/net/i2p/router/JobQueueRunner.java +++ b/router/java/src/net/i2p/router/JobQueueRunner.java @@ -1,9 +1,8 @@ package net.i2p.router; -import net.i2p.util.Log; -import net.i2p.util.Clock; - import net.i2p.stat.StatManager; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** a do run run run a do run run */ class JobQueueRunner implements Runnable { diff --git a/router/java/src/net/i2p/router/MessageHistory.java b/router/java/src/net/i2p/router/MessageHistory.java index 6aabd113b68ae39c64e97510d4f24ced117f455f..fde358b709669776f16e7cacb36e22f2e889fc57 100644 --- a/router/java/src/net/i2p/router/MessageHistory.java +++ b/router/java/src/net/i2p/router/MessageHistory.java @@ -1,21 +1,19 @@ package net.i2p.router; -import java.util.List; -import java.util.LinkedList; -import java.util.Iterator; - -import java.util.Date; +import java.io.FileOutputStream; +import java.io.IOException; import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.TimeZone; -import net.i2p.data.TunnelId; import net.i2p.data.Hash; +import net.i2p.data.TunnelId; import net.i2p.data.i2np.I2NPMessage; -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.io.IOException; -import java.io.FileOutputStream; +import net.i2p.util.Log; /** * Simply act as a pen register of messages sent in and out of the router. diff --git a/router/java/src/net/i2p/router/MessageValidator.java b/router/java/src/net/i2p/router/MessageValidator.java index 918fdf5aaffdd917c6132c3d31fd5624fe2b50c7..01191ef12d388ecefe0d8adf6b7099cf9af09b25 100644 --- a/router/java/src/net/i2p/router/MessageValidator.java +++ b/router/java/src/net/i2p/router/MessageValidator.java @@ -1,12 +1,12 @@ package net.i2p.router; -import net.i2p.util.Log; -import net.i2p.util.Clock; - -import java.util.TreeMap; -import java.util.Set; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; +import java.util.TreeMap; + +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Singleton to manage the logic (and historical data) to determine whether a message diff --git a/router/java/src/net/i2p/router/OutNetMessagePool.java b/router/java/src/net/i2p/router/OutNetMessagePool.java index aeb49884d27ba43cb6e22d1f31f216c437e4d235..86897e2d2182c6618954230e9281a339ed509edf 100644 --- a/router/java/src/net/i2p/router/OutNetMessagePool.java +++ b/router/java/src/net/i2p/router/OutNetMessagePool.java @@ -8,15 +8,15 @@ package net.i2p.router; * */ -import java.util.List; import java.util.ArrayList; -import java.util.TreeMap; -import java.util.Iterator; import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; -import net.i2p.util.Log; -import net.i2p.util.Clock; import net.i2p.router.transport.OutboundMessageRegistry; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Maintain a pool of OutNetMessages destined for other routers, organized by diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 735db46f7d5b880cdb3ce5cdce4e341500793dee..4862b9199fc30371de7ec955292c45b8c2fddcae 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -26,28 +26,28 @@ import java.util.TimeZone; import net.i2p.CoreVersion; import net.i2p.crypto.DHSessionKeyBuilder; import net.i2p.data.DataFormatException; +import net.i2p.data.DataHelper; import net.i2p.data.RouterInfo; import net.i2p.data.RoutingKeyGenerator; -import net.i2p.data.DataHelper; import net.i2p.data.i2np.GarlicMessage; import net.i2p.data.i2np.SourceRouteReplyMessage; import net.i2p.data.i2np.TunnelMessage; +import net.i2p.router.admin.StatsGenerator; import net.i2p.router.message.GarlicMessageHandler; import net.i2p.router.message.SourceRouteReplyMessageHandler; import net.i2p.router.message.TunnelMessageHandler; import net.i2p.router.startup.StartupJob; import net.i2p.router.transport.BandwidthLimiter; import net.i2p.router.transport.OutboundMessageRegistry; +import net.i2p.stat.Rate; +import net.i2p.stat.RateStat; +import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.LogConsoleBuffer; import net.i2p.util.LogManager; import net.i2p.util.RandomSource; -import net.i2p.stat.StatManager; -import net.i2p.stat.Rate; -import net.i2p.stat.RateStat; -import net.i2p.router.admin.StatsGenerator; /** * Main driver for the router. diff --git a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java b/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java index 65925af8ab94097bdef79631924170ad8f852aa5..3f922d2cf37fffe26e5365ee0ce78573c7783d43 100644 --- a/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java +++ b/router/java/src/net/i2p/router/SessionKeyPersistenceHelper.java @@ -1,14 +1,14 @@ package net.i2p.router; -import net.i2p.util.Log; -import net.i2p.crypto.SessionKeyManager; -import net.i2p.crypto.PersistentSessionKeyManager; - import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import net.i2p.crypto.PersistentSessionKeyManager; +import net.i2p.crypto.SessionKeyManager; +import net.i2p.util.Log; + /** * Centralize the sessionKeyManager persistence (rather than leave it to a private * job in the startup job) diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java index 4a6a8836d0a6681d23b067bb95b1a870920fdeab..942790dcbd6d013318b5fecee64bb287143b5621 100644 --- a/router/java/src/net/i2p/router/Shitlist.java +++ b/router/java/src/net/i2p/router/Shitlist.java @@ -8,14 +8,14 @@ package net.i2p.router; * */ -import net.i2p.data.Hash; -import net.i2p.util.Log; -import net.i2p.util.Clock; - -import java.util.Map; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; -import java.util.Date; +import java.util.Map; + +import net.i2p.data.Hash; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Manage in memory the routers we are oh so fond of. diff --git a/router/java/src/net/i2p/router/SubmitMessageHistoryJob.java b/router/java/src/net/i2p/router/SubmitMessageHistoryJob.java index cea5c84c217388f3118e3b79b8f00c7492fb6a16..0f9fe0d138dbfdcfa5b42d1a4b15107d682b94aa 100644 --- a/router/java/src/net/i2p/router/SubmitMessageHistoryJob.java +++ b/router/java/src/net/i2p/router/SubmitMessageHistoryJob.java @@ -1,16 +1,15 @@ package net.i2p.router; -import net.i2p.util.Log; -import net.i2p.util.Clock; -import net.i2p.util.HTTPSendData; -import net.i2p.util.I2PThread; - -import net.i2p.router.transport.BandwidthLimiter; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import net.i2p.router.transport.BandwidthLimiter; +import net.i2p.util.Clock; +import net.i2p.util.HTTPSendData; +import net.i2p.util.I2PThread; +import net.i2p.util.Log; + /** * Job that, if its allowed to, will submit the data gathered by the MessageHistory * component to some URL so that the network can be debugged more easily. By default diff --git a/router/java/src/net/i2p/router/admin/AdminListener.java b/router/java/src/net/i2p/router/admin/AdminListener.java index e779c775b71476559277b4c634cdd5266314e79c..10be7be4b974a64ade235d71598d5ed95685e798 100644 --- a/router/java/src/net/i2p/router/admin/AdminListener.java +++ b/router/java/src/net/i2p/router/admin/AdminListener.java @@ -8,13 +8,12 @@ package net.i2p.router.admin; * */ +import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; -import java.io.IOException; - -import net.i2p.util.Log; import net.i2p.util.I2PThread; +import net.i2p.util.Log; /** * Listen for connections on the specified port, and toss them onto the client manager's diff --git a/router/java/src/net/i2p/router/admin/AdminManager.java b/router/java/src/net/i2p/router/admin/AdminManager.java index 5707f3f39d49f4bff9ac84332b92e80d9a084d42..e536ad95be276953fb30de6f1b1c878fe80d9913 100644 --- a/router/java/src/net/i2p/router/admin/AdminManager.java +++ b/router/java/src/net/i2p/router/admin/AdminManager.java @@ -1,10 +1,9 @@ package net.i2p.router.admin; -import net.i2p.util.Log; -import net.i2p.util.I2PThread; - -import net.i2p.router.Service; import net.i2p.router.Router; +import net.i2p.router.Service; +import net.i2p.util.I2PThread; +import net.i2p.util.Log; public class AdminManager implements Service { private final static Log _log = new Log(AdminManager.class); diff --git a/router/java/src/net/i2p/router/admin/AdminRunner.java b/router/java/src/net/i2p/router/admin/AdminRunner.java index 033ae366e3c9cebf08c0b458014324acd31247a3..86982ad0c5f5eedd18d18cb91292a9201443d61b 100644 --- a/router/java/src/net/i2p/router/admin/AdminRunner.java +++ b/router/java/src/net/i2p/router/admin/AdminRunner.java @@ -6,11 +6,11 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; -import java.util.Set; import java.util.Iterator; +import java.util.Set; -import net.i2p.router.Router; import net.i2p.data.Hash; +import net.i2p.router.Router; import net.i2p.router.peermanager.ProfileOrganizer; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/admin/StatsGenerator.java b/router/java/src/net/i2p/router/admin/StatsGenerator.java index c7f4d97e8ebbff97f96d1278bdfa0cfe6c9df13f..dfc5f4d56dbc13796ad4bb7373a1fa875d5b274e 100644 --- a/router/java/src/net/i2p/router/admin/StatsGenerator.java +++ b/router/java/src/net/i2p/router/admin/StatsGenerator.java @@ -1,25 +1,23 @@ package net.i2p.router.admin; -import net.i2p.util.Log; -import net.i2p.stat.StatManager; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import net.i2p.data.DataHelper; +import net.i2p.router.Router; import net.i2p.stat.Frequency; import net.i2p.stat.FrequencyStat; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; -import net.i2p.router.Router; -import net.i2p.data.DataHelper; - -import java.util.Set; -import java.util.Map; -import java.util.Iterator; -import java.util.Arrays; - -import java.text.DecimalFormat; - -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.io.IOException; +import net.i2p.stat.StatManager; +import net.i2p.util.Log; /** * Dump the stats to the web admin interface diff --git a/router/java/src/net/i2p/router/client/ClientListenerRunner.java b/router/java/src/net/i2p/router/client/ClientListenerRunner.java index 3873893b6039dfe02d48fcb7e1ba93b35b6914ec..664f17b8bc00e177d22e741590553c5cd3dfe694 100644 --- a/router/java/src/net/i2p/router/client/ClientListenerRunner.java +++ b/router/java/src/net/i2p/router/client/ClientListenerRunner.java @@ -8,11 +8,10 @@ package net.i2p.router.client; * */ +import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; -import java.io.IOException; - import net.i2p.client.I2PClient; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index b0f3c08c4eba05b79bb5b17ccf16447c8d352500..da3f731d35d8ddc526a38cc3fdf6b3c12257fdd9 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -25,11 +25,10 @@ import net.i2p.router.ClientMessagePool; import net.i2p.router.Job; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; +import net.i2p.stat.StatManager; +import net.i2p.util.Clock; import net.i2p.util.I2PThread; import net.i2p.util.Log; -import net.i2p.util.Clock; - -import net.i2p.stat.StatManager; /** * Coordinate connections and various tasks diff --git a/router/java/src/net/i2p/router/client/CreateSessionJob.java b/router/java/src/net/i2p/router/client/CreateSessionJob.java index 37a54acab6b41b888057792b50481db75ddbab5f..80012135e3c4d8987e86a8b8b667d21e74a4c770 100644 --- a/router/java/src/net/i2p/router/client/CreateSessionJob.java +++ b/router/java/src/net/i2p/router/client/CreateSessionJob.java @@ -10,10 +10,10 @@ package net.i2p.router.client; import java.util.Properties; +import net.i2p.data.i2cp.SessionConfig; import net.i2p.router.ClientTunnelSettings; import net.i2p.router.JobImpl; import net.i2p.router.TunnelManagerFacade; -import net.i2p.data.i2cp.SessionConfig; import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/router/client/MessageReceivedJob.java b/router/java/src/net/i2p/router/client/MessageReceivedJob.java index 83cb64813081dbd8a0dc80b687eb1bc3117805b2..b3856c3bf62ed5aa0489c39be6ed57f7f2db9c15 100644 --- a/router/java/src/net/i2p/router/client/MessageReceivedJob.java +++ b/router/java/src/net/i2p/router/client/MessageReceivedJob.java @@ -8,17 +8,16 @@ package net.i2p.router.client; * */ -import net.i2p.router.JobImpl; -import net.i2p.data.Payload; +import java.io.IOException; + import net.i2p.data.Destination; +import net.i2p.data.Payload; +import net.i2p.data.i2cp.I2CPMessageException; import net.i2p.data.i2cp.MessageId; import net.i2p.data.i2cp.MessageStatusMessage; -import net.i2p.data.i2cp.I2CPMessageException; - +import net.i2p.router.JobImpl; import net.i2p.util.Log; -import java.io.IOException; - /** * Async job to notify the client that a new message is available for them * diff --git a/router/java/src/net/i2p/router/client/ReportAbuseJob.java b/router/java/src/net/i2p/router/client/ReportAbuseJob.java index dcdc586b466f47ee0f2ebe3ae857f6d542e485a5..b5690ebf5a339bc0aba9009e76936ff807aa88ee 100644 --- a/router/java/src/net/i2p/router/client/ReportAbuseJob.java +++ b/router/java/src/net/i2p/router/client/ReportAbuseJob.java @@ -8,16 +8,15 @@ package net.i2p.router.client; * */ +import java.io.IOException; + import net.i2p.data.i2cp.AbuseReason; import net.i2p.data.i2cp.AbuseSeverity; -import net.i2p.data.i2cp.ReportAbuseMessage; import net.i2p.data.i2cp.I2CPMessageException; - +import net.i2p.data.i2cp.ReportAbuseMessage; import net.i2p.router.JobImpl; import net.i2p.util.Log; -import java.io.IOException; - /** * Async job to send an abuse message to the client * diff --git a/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java b/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java index 180bdff93e6dd82c10d2f4988529b39fabca3988..2c83446422434c55ec5cdd8059e2fe11061f1d4a 100644 --- a/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java +++ b/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java @@ -8,18 +8,17 @@ package net.i2p.router.client; * */ -import net.i2p.router.Job; -import net.i2p.router.JobImpl; -import net.i2p.router.JobQueue; +import java.io.IOException; +import java.util.Date; import net.i2p.data.LeaseSet; -import net.i2p.data.i2cp.RequestLeaseSetMessage; import net.i2p.data.i2cp.I2CPMessageException; - +import net.i2p.data.i2cp.RequestLeaseSetMessage; +import net.i2p.router.Job; +import net.i2p.router.JobImpl; +import net.i2p.router.JobQueue; import net.i2p.util.Clock; import net.i2p.util.Log; -import java.io.IOException; -import java.util.Date; /** * Async job to walk the client through generating a lease set. First sends it diff --git a/router/java/src/net/i2p/router/message/BuildTestMessageJob.java b/router/java/src/net/i2p/router/message/BuildTestMessageJob.java index 26813ab623370aca9422e55057c21a8ed3ac9f7a..f46fb4ae25ec71b12c93094ed1716430a898f63f 100644 --- a/router/java/src/net/i2p/router/message/BuildTestMessageJob.java +++ b/router/java/src/net/i2p/router/message/BuildTestMessageJob.java @@ -8,32 +8,29 @@ package net.i2p.router.message; * */ -import net.i2p.router.Job; -import net.i2p.router.ReplyJob; -import net.i2p.router.JobImpl; -import net.i2p.router.JobQueue; -import net.i2p.router.Router; -import net.i2p.router.MessageSelector; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; -import net.i2p.data.RouterInfo; +import net.i2p.crypto.SessionKeyManager; import net.i2p.data.Certificate; +import net.i2p.data.Hash; import net.i2p.data.PublicKey; +import net.i2p.data.RouterInfo; import net.i2p.data.SessionKey; -import net.i2p.data.Hash; -import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.DeliveryInstructions; import net.i2p.data.i2np.DeliveryStatusMessage; - -import net.i2p.crypto.SessionKeyManager; - -import net.i2p.util.Log; +import net.i2p.data.i2np.I2NPMessage; +import net.i2p.router.Job; +import net.i2p.router.JobImpl; +import net.i2p.router.JobQueue; +import net.i2p.router.MessageSelector; +import net.i2p.router.ReplyJob; +import net.i2p.router.Router; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; -import java.util.Date; -import java.util.Set; -import java.util.HashSet; - /** * Build a test message that will be sent to the target to make sure they're alive. * Once that is verified, onSendJob is enqueued. If their reachability isn't diff --git a/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java b/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java index 5551462c72c5ba0dfb5e8721a263aed1b44ed912..c537e44340e6b73199e3763e761e0676bcff85fc 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageBuilder.java @@ -24,8 +24,8 @@ import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.data.i2np.GarlicClove; import net.i2p.data.i2np.GarlicMessage; -import net.i2p.data.i2np.SourceRouteBlock; import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.i2np.SourceRouteBlock; import net.i2p.router.MessageHistory; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/message/GarlicMessageHandler.java b/router/java/src/net/i2p/router/message/GarlicMessageHandler.java index b4b775e00ea1c2e235a3a5304bd3e0e8fa15bdfc..9817086b0fb0e1049b29fb8098ae88fc4ad0f16b 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageHandler.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageHandler.java @@ -8,14 +8,13 @@ package net.i2p.router.message; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; - -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; -import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.GarlicMessage; +import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * HandlerJobBuilder to build jobs to handle GarlicMessages diff --git a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java index 3fca37197a8db2f8a0a4adc7ebd38fc99ea9b9ae..397d8bb4f9cdc9309ad081d3c73d0c0653510050 100644 --- a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java +++ b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java @@ -23,10 +23,10 @@ import net.i2p.data.i2np.GarlicMessage; import net.i2p.router.JobImpl; import net.i2p.router.KeyManager; import net.i2p.router.LeaseSetKeys; -import net.i2p.router.Router; import net.i2p.router.MessageHistory; -import net.i2p.util.Log; +import net.i2p.router.Router; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Unencrypt a garlic message and handle each of the cloves - locally destined diff --git a/router/java/src/net/i2p/router/message/HandleSourceRouteReplyMessageJob.java b/router/java/src/net/i2p/router/message/HandleSourceRouteReplyMessageJob.java index b1132380193cd11e250b0c0d2916d758adcee3aa..d3fcbd6dc55a2661585fc653345002738c2028d8 100644 --- a/router/java/src/net/i2p/router/message/HandleSourceRouteReplyMessageJob.java +++ b/router/java/src/net/i2p/router/message/HandleSourceRouteReplyMessageJob.java @@ -22,10 +22,10 @@ import net.i2p.data.i2np.DeliveryInstructions; import net.i2p.data.i2np.SourceRouteReplyMessage; import net.i2p.router.JobImpl; import net.i2p.router.KeyManager; -import net.i2p.router.Router; import net.i2p.router.MessageHistory; -import net.i2p.util.Log; +import net.i2p.router.Router; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Handle a source route reply - decrypt the instructions and forward the message diff --git a/router/java/src/net/i2p/router/message/HandleTunnelMessageJob.java b/router/java/src/net/i2p/router/message/HandleTunnelMessageJob.java index 7f4dd71e7cdf97167bd4c2979c133a12180ff4e6..7a91809c930d027d7f7e7f840eb851a206d8f0db 100644 --- a/router/java/src/net/i2p/router/message/HandleTunnelMessageJob.java +++ b/router/java/src/net/i2p/router/message/HandleTunnelMessageJob.java @@ -36,16 +36,15 @@ import net.i2p.router.InNetMessage; import net.i2p.router.InNetMessagePool; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; +import net.i2p.router.MessageHistory; import net.i2p.router.MessageReceptionInfo; +import net.i2p.router.MessageValidator; import net.i2p.router.Router; import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; -import net.i2p.router.MessageHistory; -import net.i2p.router.MessageValidator; -import net.i2p.util.Log; -import net.i2p.util.Clock; - import net.i2p.stat.StatManager; +import net.i2p.util.Clock; +import net.i2p.util.Log; public class HandleTunnelMessageJob extends JobImpl { private final static Log _log = new Log(HandleTunnelMessageJob.class); diff --git a/router/java/src/net/i2p/router/message/MessageHandler.java b/router/java/src/net/i2p/router/message/MessageHandler.java index 8b7d75de8717cc08023e6ac25864799ff43f4580..85ec2f0439d5e7e3c1756e2406b20e7346f07297 100644 --- a/router/java/src/net/i2p/router/message/MessageHandler.java +++ b/router/java/src/net/i2p/router/message/MessageHandler.java @@ -30,8 +30,8 @@ import net.i2p.router.MessageHistory; import net.i2p.router.MessageReceptionInfo; import net.i2p.router.MessageValidator; import net.i2p.router.Router; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Implement the inbound message processing logic to forward based on delivery instructions and diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java index cf97e5ead242153deec2730e7ae8b280f152c013..7f4ee85f73deff45be1bad47a76fab8f6da02aff 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageJob.java @@ -35,12 +35,11 @@ import net.i2p.router.ReplyJob; import net.i2p.router.Router; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.TunnelSelectionCriteria; +import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.Log; import net.i2p.util.RandomSource; -import net.i2p.stat.StatManager; - /** * Send a client message, taking into consideration the fact that there may be * multiple inbound tunnels that the target provides. This job sends it to one diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java index 0534508c391c8c675e8bf2fbe2e4faf96342a73c..3f17f0c4e17149b931865311256fbfbd3d19ae6f 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java @@ -27,8 +27,8 @@ import net.i2p.router.Router; import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.TunnelSelectionCriteria; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; /** diff --git a/router/java/src/net/i2p/router/message/SendGarlicJob.java b/router/java/src/net/i2p/router/message/SendGarlicJob.java index 6b93b63e85c0065f1f17942811be9b01c5dd4236..5268039e249b8c7580b3debf7439cc1df1970a64 100644 --- a/router/java/src/net/i2p/router/message/SendGarlicJob.java +++ b/router/java/src/net/i2p/router/message/SendGarlicJob.java @@ -21,8 +21,8 @@ import net.i2p.router.OutNetMessage; import net.i2p.router.OutNetMessagePool; import net.i2p.router.ReplyJob; import net.i2p.router.Router; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Build a garlic message from config, encrypt it, and enqueue it for delivery. diff --git a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java index 521c84ce5766e20a8f825bb84bd9da120fe3ffaa..ed595174e5d50f5b949b19ad80cd5e7956447143 100644 --- a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java +++ b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java @@ -8,27 +8,25 @@ package net.i2p.router.message; * */ -import net.i2p.router.JobImpl; +import java.util.Date; + +import net.i2p.data.Hash; +import net.i2p.data.RouterInfo; +import net.i2p.data.i2np.I2NPMessage; +import net.i2p.router.InNetMessage; +import net.i2p.router.InNetMessagePool; import net.i2p.router.Job; -import net.i2p.router.ReplyJob; +import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.MessageSelector; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.OutNetMessage; import net.i2p.router.OutNetMessagePool; -import net.i2p.router.transport.OutboundMessageRegistry; -import net.i2p.router.InNetMessage; -import net.i2p.router.InNetMessagePool; +import net.i2p.router.ReplyJob; import net.i2p.router.Router; - -import net.i2p.data.i2np.I2NPMessage; -import net.i2p.data.Hash; -import net.i2p.data.RouterInfo; - -import net.i2p.util.Log; +import net.i2p.router.transport.OutboundMessageRegistry; import net.i2p.util.Clock; - -import java.util.Date; +import net.i2p.util.Log; public class SendMessageDirectJob extends JobImpl { private final static Log _log = new Log(SendMessageDirectJob.class); diff --git a/router/java/src/net/i2p/router/message/SendTunnelMessageJob.java b/router/java/src/net/i2p/router/message/SendTunnelMessageJob.java index 0b1d527a08c61bbda3b113c7d00f54e117a74a51..c5684aa75283544d82c8d1cfe6d2fffc7215ca14 100644 --- a/router/java/src/net/i2p/router/message/SendTunnelMessageJob.java +++ b/router/java/src/net/i2p/router/message/SendTunnelMessageJob.java @@ -10,6 +10,7 @@ package net.i2p.router.message; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Date; import net.i2p.crypto.AESEngine; import net.i2p.crypto.KeyGenerator; @@ -43,10 +44,8 @@ import net.i2p.router.Router; import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.transport.OutboundMessageRegistry; -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Date; +import net.i2p.util.Log; /** * Send a message down a tunnel that we are the gateway for diff --git a/router/java/src/net/i2p/router/message/SourceRouteReplyMessageHandler.java b/router/java/src/net/i2p/router/message/SourceRouteReplyMessageHandler.java index 3f3c02e97427cccf2507cb1ca3ed08e73cf8a3a7..d8d99431e2605d62db971c4c4f8712966e89b49b 100644 --- a/router/java/src/net/i2p/router/message/SourceRouteReplyMessageHandler.java +++ b/router/java/src/net/i2p/router/message/SourceRouteReplyMessageHandler.java @@ -8,14 +8,13 @@ package net.i2p.router.message; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; - -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; -import net.i2p.data.i2np.SourceRouteReplyMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.data.i2np.SourceRouteReplyMessage; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * HandlerJobBuilder to build jobs to handle SourceRouteReplyMessages diff --git a/router/java/src/net/i2p/router/message/TunnelMessageHandler.java b/router/java/src/net/i2p/router/message/TunnelMessageHandler.java index ab5fa08e33bc32382f708761826f43a479669931..613d269d675ad423b6791ee80b14df404a2d0fe2 100644 --- a/router/java/src/net/i2p/router/message/TunnelMessageHandler.java +++ b/router/java/src/net/i2p/router/message/TunnelMessageHandler.java @@ -8,14 +8,13 @@ package net.i2p.router.message; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; - -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.I2NPMessage; -import net.i2p.data.i2np.TunnelMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.data.i2np.TunnelMessage; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * HandlerJobBuilder to build jobs to handle TunnelMessages diff --git a/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java b/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java index 04d1af26225f82f1d0cd557e025e2c8db42a7c4b..3ea5ecb3ec77ee64768d3959e6e8398fe6951fb1 100644 --- a/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/DatabaseLookupMessageHandler.java @@ -8,13 +8,13 @@ package net.i2p.router.networkdb; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; -import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.DatabaseLookupMessage; +import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * Build a HandleDatabaseLookupMessageJob whenever a DatabaseLookupMessage arrives diff --git a/router/java/src/net/i2p/router/networkdb/DatabaseSearchReplyMessageHandler.java b/router/java/src/net/i2p/router/networkdb/DatabaseSearchReplyMessageHandler.java index 9ddeda12e761166a7e1b4587f7521a74d2106b1e..9471c8f9592aa874a843d778e7402d2d43f4ca69 100644 --- a/router/java/src/net/i2p/router/networkdb/DatabaseSearchReplyMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/DatabaseSearchReplyMessageHandler.java @@ -8,13 +8,13 @@ package net.i2p.router.networkdb; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; -import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.DatabaseSearchReplyMessage; +import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * Build a HandleDatabaseSearchReplyMessageJob whenever a DatabaseSearchReplyMessage arrives diff --git a/router/java/src/net/i2p/router/networkdb/DatabaseStoreMessageHandler.java b/router/java/src/net/i2p/router/networkdb/DatabaseStoreMessageHandler.java index 649a9a755347136f32d8e2025e4f1895eda75427..7130d608d34dd9856aeedef0fe0d86a5130a2b8a 100644 --- a/router/java/src/net/i2p/router/networkdb/DatabaseStoreMessageHandler.java +++ b/router/java/src/net/i2p/router/networkdb/DatabaseStoreMessageHandler.java @@ -8,13 +8,13 @@ package net.i2p.router.networkdb; * */ -import net.i2p.router.HandlerJobBuilder; -import net.i2p.router.Job; -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; -import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.RouterIdentity; import net.i2p.data.i2np.DatabaseStoreMessage; +import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.SourceRouteBlock; +import net.i2p.router.HandlerJobBuilder; +import net.i2p.router.Job; /** * Create a HandleDatabaseStoreMessageJob whenever a DatabaseStoreMessage arrives diff --git a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java index 96986c5ea805d7a653c6a882801444fff9fe04de..34dbb734f0a8a06fede8e2cbad6439cf0f777280 100644 --- a/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java +++ b/router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java @@ -8,24 +8,26 @@ package net.i2p.router.networkdb; * */ -import java.util.Set; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.Date; +import java.util.Set; +import net.i2p.data.DataFormatException; import net.i2p.data.DataStructure; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; import net.i2p.data.RouterIdentity; import net.i2p.data.RouterInfo; import net.i2p.data.TunnelId; -import net.i2p.data.DataFormatException; import net.i2p.data.i2np.DatabaseLookupMessage; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.TunnelMessage; import net.i2p.router.Job; -import net.i2p.router.JobQueue; import net.i2p.router.JobImpl; +import net.i2p.router.JobQueue; import net.i2p.router.MessageHistory; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.Router; @@ -33,11 +35,8 @@ import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.message.SendMessageDirectJob; import net.i2p.router.message.SendTunnelMessageJob; -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; +import net.i2p.util.Log; /** * Handle a lookup for a key received from a remote peer. Needs to be implemented diff --git a/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java b/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java index 1981f44550d88a84e356da53c53d4a9599645d45..9ad1ae4c3aeb3c05ae3250e17a270e58e3d987b9 100644 --- a/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java +++ b/router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java @@ -13,14 +13,14 @@ import java.util.Properties; import net.i2p.data.DataFormatException; import net.i2p.data.RouterInfo; +import net.i2p.router.CommSystemFacade; import net.i2p.router.JobImpl; import net.i2p.router.KeyManager; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.Router; -import net.i2p.router.CommSystemFacade; import net.i2p.router.StatisticsManager; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; /** diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/DataPublisherJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/DataPublisherJob.java index fd6105519afcf6a06f9ae7aa64fa56fe834fbd29..3225e779e09026f140228d23d6c5453c5751ef07 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/DataPublisherJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/DataPublisherJob.java @@ -8,19 +8,18 @@ package net.i2p.router.networkdb.kademlia; * */ +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import net.i2p.data.DataStructure; import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.data.DataStructure; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.Router; - -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; +import net.i2p.util.Log; class DataPublisherJob extends JobImpl { private final static Log _log = new Log(DataPublisherJob.class); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/DataRepublishingSelectorJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/DataRepublishingSelectorJob.java index 1b3b5b420a35cd61dc123f746749997ef12cf59c..e5ac6c50d070b69a42ed1cef86947693d8e4b5cd 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/DataRepublishingSelectorJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/DataRepublishingSelectorJob.java @@ -18,8 +18,8 @@ import net.i2p.data.LeaseSet; import net.i2p.data.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; class DataRepublishingSelectorJob extends JobImpl { diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java index 84dc6f019dc751737be47d6d582ffa3f56fadc91..8fcaeaa9c90c4947711e0797a07439705a664a44 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java @@ -8,11 +8,11 @@ package net.i2p.router.networkdb.kademlia; * */ -import net.i2p.data.Hash; -import net.i2p.data.DataStructure; - import java.util.Set; +import net.i2p.data.DataStructure; +import net.i2p.data.Hash; + public interface DataStore { public boolean isKnown(Hash key); public DataStructure get(Hash key); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index ca65f7545103fae5537d877b8c95596cf6c65021..f51818c8049b76effbabf6bc0e5104affa18a95c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -10,10 +10,10 @@ package net.i2p.router.networkdb.kademlia; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; -import java.io.FileNotFoundException; import net.i2p.data.DataFormatException; import net.i2p.data.DataStructure; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/RepublishLeaseSetJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/RepublishLeaseSetJob.java index eef98ae62530aac201d74d14ad2e34c669de6d12..e3cf23378304957615392d65c8becb2840d0f022 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/RepublishLeaseSetJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/RepublishLeaseSetJob.java @@ -8,19 +8,17 @@ package net.i2p.router.networkdb.kademlia; * */ +import java.util.HashSet; +import java.util.Set; + import net.i2p.data.Hash; import net.i2p.data.LeaseSet; - import net.i2p.router.ClientManagerFacade; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.Router; - -import net.i2p.util.Log; import net.i2p.util.Clock; - -import java.util.Set; -import java.util.HashSet; +import net.i2p.util.Log; /** * Run periodically for each locally created leaseSet to cause it to be republished diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java index 55cffcaed871cf9a4f496ea3bea68fcb226405a6..2cb4b3d6e4cce34175221166dea22dff67515958 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java @@ -29,8 +29,8 @@ import net.i2p.router.Router; import net.i2p.router.TunnelInfo; import net.i2p.router.TunnelManagerFacade; import net.i2p.router.TunnelSelectionCriteria; -import net.i2p.router.message.SendTunnelMessageJob; import net.i2p.router.message.SendMessageDirectJob; +import net.i2p.router.message.SendTunnelMessageJob; import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/SearchState.java b/router/java/src/net/i2p/router/networkdb/kademlia/SearchState.java index 806f3ffd49d8b3888f2981557333438fe5190ef4..8a221c2c1ec4e20294e134b2508a9d89492078dc 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/SearchState.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/SearchState.java @@ -1,14 +1,14 @@ package net.i2p.router.networkdb.kademlia; -import net.i2p.data.Hash; -import net.i2p.util.Clock; - -import java.util.Set; -import java.util.HashSet; -import java.util.HashMap; -import java.util.Iterator; import java.util.Collection; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import net.i2p.data.Hash; +import net.i2p.util.Clock; /** * Data related to a particular search diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java index 770e8e9d48ee13bce789b852fd91ed244cbfda51..fe427c02dbb16f3278f7f555b0d173cd2fc9abd9 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java @@ -45,8 +45,8 @@ import net.i2p.router.message.GarlicConfig; import net.i2p.router.message.PayloadGarlicConfig; import net.i2p.router.message.SendGarlicJob; import net.i2p.router.message.SendTunnelMessageJob; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; import net.i2p.util.RandomSource; class StoreJob extends JobImpl { diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java index 40e53ec7d3e9afe6bad961eadd1afeae33cb8534..4f082ac31e0e6225fa21e79d5e92bfb53b119b2d 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java @@ -8,22 +8,21 @@ package net.i2p.router.networkdb.kademlia; * */ +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + import net.i2p.data.DataHelper; -import net.i2p.data.Hash; import net.i2p.data.DataStructure; -import net.i2p.data.RouterInfo; +import net.i2p.data.Hash; import net.i2p.data.LeaseSet; -import net.i2p.util.Log; -import net.i2p.util.Clock; - +import net.i2p.data.RouterInfo; import net.i2p.router.ProfileManager; - -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Date; +import net.i2p.util.Clock; +import net.i2p.util.Log; class TransientDataStore implements DataStore { private final static Log _log = new Log(TransientDataStore.class); diff --git a/router/java/src/net/i2p/router/peermanager/DBHistory.java b/router/java/src/net/i2p/router/peermanager/DBHistory.java index 766dc8797f1d7ecdbdc58afce2eb1f640bfcc3df..2a41eebb22bf9c34c410f8017dfcbbed5e7815bb 100644 --- a/router/java/src/net/i2p/router/peermanager/DBHistory.java +++ b/router/java/src/net/i2p/router/peermanager/DBHistory.java @@ -3,6 +3,7 @@ package net.i2p.router.peermanager; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; + import net.i2p.stat.RateStat; import net.i2p.util.Clock; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/peermanager/IsFailingCalculator.java b/router/java/src/net/i2p/router/peermanager/IsFailingCalculator.java index 9472f7e76a445c0e9fe857392f865e8c2dac1b6d..4bda17112e7b0fd85e3ab07dea80e9fe6ca79933 100644 --- a/router/java/src/net/i2p/router/peermanager/IsFailingCalculator.java +++ b/router/java/src/net/i2p/router/peermanager/IsFailingCalculator.java @@ -1,7 +1,7 @@ package net.i2p.router.peermanager; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Simple boolean calculation to determine whether the given profile is "failing" - diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index 8095300ab8e6f7d7b3d1892eb7cf3229a7ceb596..9c0625ed8c4bfafc0da2a557bb251e7bf0c78606 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -8,15 +8,15 @@ package net.i2p.router.peermanager; * */ -import java.util.Set; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import net.i2p.data.Hash; -import net.i2p.router.PeerSelectionCriteria; -import net.i2p.router.Router; import net.i2p.router.JobQueue; import net.i2p.router.NetworkDatabaseFacade; +import net.i2p.router.PeerSelectionCriteria; +import net.i2p.router.Router; import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/router/peermanager/PeerManagerFacadeImpl.java b/router/java/src/net/i2p/router/peermanager/PeerManagerFacadeImpl.java index 2a71383cc2eaf6bf051a2aa57e5e35d8d6273f3a..f3189cfebec015cad0835d0aa2d696f339205973 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManagerFacadeImpl.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManagerFacadeImpl.java @@ -8,8 +8,8 @@ package net.i2p.router.peermanager; * */ -import java.util.List; import java.util.ArrayList; +import java.util.List; import net.i2p.router.PeerManagerFacade; import net.i2p.router.PeerSelectionCriteria; diff --git a/router/java/src/net/i2p/router/peermanager/PersistProfilesJob.java b/router/java/src/net/i2p/router/peermanager/PersistProfilesJob.java index 9e90c8d9b591cb0d829abfd83c58d653270455ba..a71af150db0a5db376aeacd5bb6f0d297b1f791a 100644 --- a/router/java/src/net/i2p/router/peermanager/PersistProfilesJob.java +++ b/router/java/src/net/i2p/router/peermanager/PersistProfilesJob.java @@ -1,12 +1,12 @@ package net.i2p.router.peermanager; -import java.util.Set; import java.util.Iterator; +import java.util.Set; import net.i2p.data.Hash; -import net.i2p.util.Clock; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; +import net.i2p.util.Clock; class PersistProfilesJob extends JobImpl { private PeerManager _mgr; diff --git a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java index 7e7fd9c3addbf7ea67975689ff2cff72b8c70188..21139f84f504735da93922ed6cf063ae3034b782 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Properties; import java.util.Set; + import net.i2p.data.Hash; import net.i2p.router.ProfileManager; import net.i2p.util.Clock; diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index b64a3a655adc431b4f26c951dd476e31ed6af8d0..534d16a6ecc1b4f43d4bb4d4a464994fc3b27893 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -1,19 +1,15 @@ package net.i2p.router.peermanager; -import net.i2p.data.Hash; -import net.i2p.data.DataHelper; -import net.i2p.util.Clock; -import net.i2p.util.Log; - +import java.io.IOException; +import java.io.OutputStream; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; - import java.util.ArrayList; -import java.util.Iterator; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -22,8 +18,10 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.io.IOException; -import java.io.OutputStream; +import net.i2p.data.DataHelper; +import net.i2p.data.Hash; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Keep the peer profiles organized according to the tiered model. This does not diff --git a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java index 0a4ab9d728bebb2eeb57fe05d5d8ee11ef60f31d..c1e93988c6808b22108e4eeb5a903e6565403eec 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java +++ b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java @@ -6,8 +6,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; -import java.io.InputStreamReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStream; import java.util.HashSet; import java.util.Iterator; diff --git a/router/java/src/net/i2p/router/peermanager/ReliabilityCalculator.java b/router/java/src/net/i2p/router/peermanager/ReliabilityCalculator.java index cea6e1febe32baea5bcfdac407c94523c32487aa..3fb7aa0afeb40ed3d7067bff487b7740358d4091 100644 --- a/router/java/src/net/i2p/router/peermanager/ReliabilityCalculator.java +++ b/router/java/src/net/i2p/router/peermanager/ReliabilityCalculator.java @@ -1,7 +1,7 @@ package net.i2p.router.peermanager; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Determine how reliable the peer is - how likely they'll be able to respond or diff --git a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java index 11d50316923a9fb8da540052854574cc4d5c0f34..124afec745c27f43e2d2c70e7cd2231095bc74c1 100644 --- a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java +++ b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java @@ -3,6 +3,7 @@ package net.i2p.router.peermanager; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; + import net.i2p.util.Clock; /** diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 9f20594851e0090650a7e75cb8bbc61728facbcb..002529df2f37790573ab28bb0253708f3b947540 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -21,8 +21,8 @@ import net.i2p.data.SigningPublicKey; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.KeyManager; -import net.i2p.router.Router; import net.i2p.router.MessageHistory; +import net.i2p.router.Router; import net.i2p.util.Log; public class LoadRouterInfoJob extends JobImpl { diff --git a/router/java/src/net/i2p/router/startup/ProcessInboundNetMessageJob.java b/router/java/src/net/i2p/router/startup/ProcessInboundNetMessageJob.java index 0f3383b3bc00e9ae39636c125b8c6e37ce282cba..f31d1f2c0cabb971d744a0d49b149328227c2cc5 100644 --- a/router/java/src/net/i2p/router/startup/ProcessInboundNetMessageJob.java +++ b/router/java/src/net/i2p/router/startup/ProcessInboundNetMessageJob.java @@ -12,8 +12,8 @@ import net.i2p.router.InNetMessage; import net.i2p.router.InNetMessagePool; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Pull a message off the inbound net message pool and begin its processing. diff --git a/router/java/src/net/i2p/router/startup/ReadConfigJob.java b/router/java/src/net/i2p/router/startup/ReadConfigJob.java index cfc6a569504619f554261aa4a7a06c1898d17f1f..ae7d8454f386c1314634d93726a89f5e3a7d9d09 100644 --- a/router/java/src/net/i2p/router/startup/ReadConfigJob.java +++ b/router/java/src/net/i2p/router/startup/ReadConfigJob.java @@ -8,17 +8,17 @@ package net.i2p.router.startup; * */ +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.Properties; + import net.i2p.router.JobImpl; -import net.i2p.router.Router; import net.i2p.router.JobQueue; -import net.i2p.util.Log; +import net.i2p.router.Router; import net.i2p.util.Clock; - -import java.util.Properties; -import java.util.Iterator; -import java.io.FileInputStream; -import java.io.File; -import java.io.IOException; +import net.i2p.util.Log; /** * Simply read the router config diff --git a/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java b/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java index a6629ce3cf906e2e8d18cd629dad569f6e32b9ca..8bc280f55c71246d140869a28e6540d889c9c192 100644 --- a/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java +++ b/router/java/src/net/i2p/router/startup/StartAcceptingClientsJob.java @@ -9,17 +9,17 @@ package net.i2p.router.startup; */ import java.lang.reflect.Method; -import java.util.List; import java.util.ArrayList; +import java.util.List; import net.i2p.router.ClientManagerFacade; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.Router; import net.i2p.router.admin.AdminManager; -import net.i2p.util.Log; -import net.i2p.util.I2PThread; import net.i2p.util.Clock; +import net.i2p.util.I2PThread; +import net.i2p.util.Log; public class StartAcceptingClientsJob extends JobImpl { private static Log _log = new Log(StartAcceptingClientsJob.class); diff --git a/router/java/src/net/i2p/router/transport/BandwidthLimitedInputStream.java b/router/java/src/net/i2p/router/transport/BandwidthLimitedInputStream.java index 5832b0a04f63b360e7dff6c228b81fdb1a6d0c4f..453865af95934dc528b515d026fb813c05fe866b 100644 --- a/router/java/src/net/i2p/router/transport/BandwidthLimitedInputStream.java +++ b/router/java/src/net/i2p/router/transport/BandwidthLimitedInputStream.java @@ -8,11 +8,11 @@ package net.i2p.router.transport; * */ -import net.i2p.data.RouterIdentity; - import java.io.FilterInputStream; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; + +import net.i2p.data.RouterIdentity; public class BandwidthLimitedInputStream extends FilterInputStream { private RouterIdentity _peer; diff --git a/router/java/src/net/i2p/router/transport/BandwidthLimitedOutputStream.java b/router/java/src/net/i2p/router/transport/BandwidthLimitedOutputStream.java index 0afa5c505e6548f4f7856b92f840dca77048d6f5..f3d93389e0b385702d1e77ffe0c6033e1c92b26d 100644 --- a/router/java/src/net/i2p/router/transport/BandwidthLimitedOutputStream.java +++ b/router/java/src/net/i2p/router/transport/BandwidthLimitedOutputStream.java @@ -8,10 +8,11 @@ package net.i2p.router.transport; * */ -import net.i2p.data.RouterIdentity; import java.io.FilterOutputStream; -import java.io.OutputStream; import java.io.IOException; +import java.io.OutputStream; + +import net.i2p.data.RouterIdentity; public class BandwidthLimitedOutputStream extends FilterOutputStream { private RouterIdentity _peer; diff --git a/router/java/src/net/i2p/router/transport/BandwidthLimiter.java b/router/java/src/net/i2p/router/transport/BandwidthLimiter.java index 45207baa9424fdc0053cfa8d90c7dbca14a144f2..81daa3c5fa1f83155244d2cb80a0bc8c3fd73f06 100644 --- a/router/java/src/net/i2p/router/transport/BandwidthLimiter.java +++ b/router/java/src/net/i2p/router/transport/BandwidthLimiter.java @@ -9,7 +9,6 @@ package net.i2p.router.transport; */ import net.i2p.data.RouterIdentity; - import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/router/transport/FetchOutNetMessageJob.java b/router/java/src/net/i2p/router/transport/FetchOutNetMessageJob.java index e12f25f5d529f26a77283454a349f9184c3475bc..1e4154ff9ba8f7e76857bd0a9537e0aeb1112e40 100644 --- a/router/java/src/net/i2p/router/transport/FetchOutNetMessageJob.java +++ b/router/java/src/net/i2p/router/transport/FetchOutNetMessageJob.java @@ -12,8 +12,8 @@ import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.OutNetMessage; import net.i2p.router.OutNetMessagePool; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Fetch an outbound message from the outbound pool, check its validity, get a bid diff --git a/router/java/src/net/i2p/router/transport/GetBidsJob.java b/router/java/src/net/i2p/router/transport/GetBidsJob.java index 0adaf91bbb30a04f7189ba0750af7491ad4b93f7..af7285b1a60274735448bde069e49966b4fce49c 100644 --- a/router/java/src/net/i2p/router/transport/GetBidsJob.java +++ b/router/java/src/net/i2p/router/transport/GetBidsJob.java @@ -10,14 +10,14 @@ package net.i2p.router.transport; import java.util.List; +import net.i2p.data.Hash; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.MessageSelector; import net.i2p.router.OutNetMessage; import net.i2p.router.ProfileManager; -import net.i2p.router.Shitlist; import net.i2p.router.Router; -import net.i2p.data.Hash; +import net.i2p.router.Shitlist; import net.i2p.util.Log; /** diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index 4ef8eaefc1355ca39311f516cfa01f9e970ca042..f481204aca1e26e671e2bb39cab9d94670b4593f 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -8,13 +8,13 @@ package net.i2p.router.transport; * */ -import net.i2p.data.RouterInfo; -import net.i2p.data.RouterAddress; -import net.i2p.router.OutNetMessage; - import java.util.Properties; import java.util.Set; +import net.i2p.data.RouterAddress; +import net.i2p.data.RouterInfo; +import net.i2p.router.OutNetMessage; + /** * Defines a way to send a message to another peer and start listening for messages * diff --git a/router/java/src/net/i2p/router/transport/TransportBid.java b/router/java/src/net/i2p/router/transport/TransportBid.java index 1bada1675ad81a582f023f08c9f4dcab9f730981..6c926c6ef933d10b78f90b5b5b31442e090beaf8 100644 --- a/router/java/src/net/i2p/router/transport/TransportBid.java +++ b/router/java/src/net/i2p/router/transport/TransportBid.java @@ -8,10 +8,10 @@ package net.i2p.router.transport; * */ -import net.i2p.data.RouterInfo; - import java.util.Date; +import net.i2p.data.RouterInfo; + /** * Provide a bid for how much it would "cost" to transfer a message of a * particular peer diff --git a/router/java/src/net/i2p/router/transport/TransportEventListener.java b/router/java/src/net/i2p/router/transport/TransportEventListener.java index bd98ee9da31318d1fcca68f913084d902873e071..31d52758c8a35d41d18ce46968f0425288676796 100644 --- a/router/java/src/net/i2p/router/transport/TransportEventListener.java +++ b/router/java/src/net/i2p/router/transport/TransportEventListener.java @@ -8,10 +8,9 @@ package net.i2p.router.transport; * */ -import net.i2p.data.i2np.I2NPMessage; - -import net.i2p.data.RouterIdentity; import net.i2p.data.Hash; +import net.i2p.data.RouterIdentity; +import net.i2p.data.i2np.I2NPMessage; public interface TransportEventListener { public void messageReceived(I2NPMessage message, RouterIdentity fromRouter, Hash fromRouterHash); diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index dc324447789c79ee7e78a12b3a3748254732a382..512b6d50921cd12433900480b13e213898d9d4c4 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -8,10 +8,10 @@ package net.i2p.router.transport; * */ -import java.util.LinkedList; import java.util.Date; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -22,15 +22,14 @@ import net.i2p.data.RouterInfo; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.Job; import net.i2p.router.JobQueue; +import net.i2p.router.MessageHistory; import net.i2p.router.MessageSelector; import net.i2p.router.OutNetMessage; import net.i2p.router.OutNetMessagePool; import net.i2p.router.ProfileManager; -import net.i2p.router.MessageHistory; -import net.i2p.util.Log; -import net.i2p.util.Clock; - import net.i2p.stat.StatManager; +import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Defines a way to send a message to another peer and start listening for messages diff --git a/router/java/src/net/i2p/router/transport/TrivialBandwidthLimiter.java b/router/java/src/net/i2p/router/transport/TrivialBandwidthLimiter.java index 83d56d00e356d115021be29184887506e20c7bad..fe7c308e93f4a1963fd6d6b3af51fb4f92e552af 100644 --- a/router/java/src/net/i2p/router/transport/TrivialBandwidthLimiter.java +++ b/router/java/src/net/i2p/router/transport/TrivialBandwidthLimiter.java @@ -12,9 +12,8 @@ import net.i2p.data.RouterIdentity; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.Router; - -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * Coordinate the bandwidth limiting across all classes of peers. Currently diff --git a/router/java/src/net/i2p/router/transport/phttp/PHTTPPoller.java b/router/java/src/net/i2p/router/transport/phttp/PHTTPPoller.java index a31fcb89c4b254eb099a2e97863638848d69a3a5..d4cd9c1b1f0b385b69ce1de5055f70e5bdba26b9 100644 --- a/router/java/src/net/i2p/router/transport/phttp/PHTTPPoller.java +++ b/router/java/src/net/i2p/router/transport/phttp/PHTTPPoller.java @@ -24,12 +24,12 @@ import net.i2p.data.Signature; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.I2NPMessageException; import net.i2p.data.i2np.I2NPMessageHandler; -import net.i2p.util.Log; -import net.i2p.util.RandomSource; +import net.i2p.router.Router; +import net.i2p.router.transport.BandwidthLimiter; import net.i2p.util.Clock; import net.i2p.util.I2PThread; -import net.i2p.router.transport.BandwidthLimiter; -import net.i2p.router.Router; +import net.i2p.util.Log; +import net.i2p.util.RandomSource; class PHTTPPoller { private final static Log _log = new Log(PHTTPPoller.class); diff --git a/router/java/src/net/i2p/router/transport/phttp/PHTTPSender.java b/router/java/src/net/i2p/router/transport/phttp/PHTTPSender.java index 29f923482c45e0db489a3b05a255b7af4c712856..eb890f757340949aa14624c4f16a79f48469b228 100644 --- a/router/java/src/net/i2p/router/transport/phttp/PHTTPSender.java +++ b/router/java/src/net/i2p/router/transport/phttp/PHTTPSender.java @@ -22,9 +22,9 @@ import java.util.Iterator; import net.i2p.data.RouterAddress; import net.i2p.router.OutNetMessage; import net.i2p.router.transport.BandwidthLimiter; -import net.i2p.util.Log; import net.i2p.util.Clock; import net.i2p.util.I2PThread; +import net.i2p.util.Log; class PHTTPSender { private final static Log _log = new Log(PHTTPSender.class); diff --git a/router/java/src/net/i2p/router/transport/phttp/PHTTPTransport.java b/router/java/src/net/i2p/router/transport/phttp/PHTTPTransport.java index aeb4a73e962c7bec665b3d71fd486bb1465378c0..3f79e61c06c0d8e2cb8955c5b13549a1bba21a82 100644 --- a/router/java/src/net/i2p/router/transport/phttp/PHTTPTransport.java +++ b/router/java/src/net/i2p/router/transport/phttp/PHTTPTransport.java @@ -28,8 +28,8 @@ import net.i2p.router.Router; import net.i2p.router.transport.BandwidthLimiter; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; -import net.i2p.util.Log; import net.i2p.util.Clock; +import net.i2p.util.Log; /** * diff --git a/router/java/src/net/i2p/router/transport/tcp/RestrictiveTCPConnection.java b/router/java/src/net/i2p/router/transport/tcp/RestrictiveTCPConnection.java index 4a95f9d28dbbfaf92771de9b99758c152687244b..6882141774c99aeab42bd26647dfa7a93f575b2e 100644 --- a/router/java/src/net/i2p/router/transport/tcp/RestrictiveTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/tcp/RestrictiveTCPConnection.java @@ -27,12 +27,11 @@ import net.i2p.router.Router; import net.i2p.router.Shitlist; import net.i2p.router.transport.BandwidthLimitedInputStream; import net.i2p.router.transport.BandwidthLimitedOutputStream; +import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.I2PThread; import net.i2p.util.Log; -import net.i2p.stat.StatManager; - /** * TCPConnection that validates the time and protocol version, dropping connection if * the clocks are too skewed or the versions don't match. diff --git a/router/java/src/net/i2p/router/transport/tcp/SocketCreator.java b/router/java/src/net/i2p/router/transport/tcp/SocketCreator.java index 49083268ff58f0542990c6d77310fc7c5e345b0f..b8c7ac14e91078579bbec913f09962a7c4f9fc25 100644 --- a/router/java/src/net/i2p/router/transport/tcp/SocketCreator.java +++ b/router/java/src/net/i2p/router/transport/tcp/SocketCreator.java @@ -1,10 +1,10 @@ package net.i2p.router.transport.tcp; -import net.i2p.util.Log; - +import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; -import java.io.IOException; + +import net.i2p.util.Log; class SocketCreator implements Runnable { private final static Log _log = new Log(SocketCreator.class); diff --git a/router/java/src/net/i2p/router/transport/tcp/TCPAddress.java b/router/java/src/net/i2p/router/transport/tcp/TCPAddress.java index 58da7509f87418743cc572edfdf291f9abdaa25d..d081451e6434ba00b19087ae81ce4aaf295082b3 100644 --- a/router/java/src/net/i2p/router/transport/tcp/TCPAddress.java +++ b/router/java/src/net/i2p/router/transport/tcp/TCPAddress.java @@ -9,6 +9,7 @@ package net.i2p.router.transport.tcp; */ import java.net.InetAddress; + import net.i2p.data.DataHelper; import net.i2p.data.RouterAddress; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java b/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java index 0b079eb45e3636a84ad8d2c1f2afa5f860805417..13eb4338958b64fb60393cb8a55496ee62d08ac2 100644 --- a/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java +++ b/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java @@ -20,27 +20,26 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.data.RouterAddress; import net.i2p.data.RouterIdentity; import net.i2p.data.RouterInfo; import net.i2p.data.SigningPrivateKey; -import net.i2p.data.DataHelper; import net.i2p.router.JobImpl; import net.i2p.router.JobQueue; import net.i2p.router.NetworkDatabaseFacade; import net.i2p.router.OutNetMessage; +import net.i2p.router.ProfileManager; import net.i2p.router.Router; import net.i2p.router.Shitlist; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; -import net.i2p.router.ProfileManager; +import net.i2p.stat.StatManager; import net.i2p.util.Clock; import net.i2p.util.I2PThread; import net.i2p.util.Log; -import net.i2p.stat.StatManager; - /** * Defines a way to send a message to another peer and start listening for messages *