forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test' (head 128a31611abc6a88e58133f3bf6a577fe6dd5b1c)
to branch 'i2p.i2p.zzz.test4' (head fa9a871892517271eb2531b433fe80a2a713be9c)
This commit is contained in:
@@ -16,7 +16,7 @@ package net.i2p;
|
||||
public class CoreVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = "0.7.14";
|
||||
public final static String VERSION = "0.8";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Core version: " + VERSION);
|
||||
|
||||
@@ -211,6 +211,7 @@ public class I2PAppContext {
|
||||
* need to look there as well.
|
||||
*
|
||||
* All dirs except the base are created if they don't exist, but the creation will fail silently.
|
||||
* @since 0.7.6
|
||||
*/
|
||||
private void initializeDirs() {
|
||||
String s = getProperty("i2p.dir.base", System.getProperty("user.dir"));
|
||||
@@ -266,12 +267,78 @@ public class I2PAppContext {
|
||||
******/
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the installation dir, often referred to as $I2P.
|
||||
* Applilcations should consider this directory read-only and never
|
||||
* attempt to write to it.
|
||||
* It may actually be read-only on a multi-user installation.
|
||||
* The config files in this directory are templates for user
|
||||
* installations and should not be accessed by applications.
|
||||
* The only thing that may be useful in here is the lib/ dir
|
||||
* containing the .jars.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getBaseDir() { return _baseDir; }
|
||||
|
||||
/**
|
||||
* The base dir for config files.
|
||||
* Applications may use this to access router configuration files if necessary.
|
||||
* Usually ~/.i2p on Linux and %APPDIR%\I2P on Windows.
|
||||
* In installations originally installed with 0.7.5 or earlier, and in
|
||||
* "portable" installations, this will be the same as the base dir.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getConfigDir() { return _configDir; }
|
||||
|
||||
/**
|
||||
* Where the router keeps its files.
|
||||
* Applications should not use this.
|
||||
* The same as the config dir for now.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getRouterDir() { return _routerDir; }
|
||||
|
||||
/**
|
||||
* Where router.ping goes.
|
||||
* Applications should not use this.
|
||||
* The same as the system temp dir for now.
|
||||
* Which is a problem for multi-user installations.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getPIDDir() { return _pidDir; }
|
||||
|
||||
/**
|
||||
* Where the router keeps its log directory.
|
||||
* Applications should not use this.
|
||||
* The same as the config dir for now.
|
||||
* (i.e. ~/.i2p, NOT ~/.i2p/logs)
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getLogDir() { return _logDir; }
|
||||
|
||||
/**
|
||||
* Where applications may store data.
|
||||
* The same as the config dir for now, but may change in the future.
|
||||
* Apps should be careful not to overwrite router files.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getAppDir() { return _appDir; }
|
||||
|
||||
/**
|
||||
* Where anybody may store temporary data.
|
||||
* This is a directory created in the system temp dir on the
|
||||
* first call in this context, and is deleted on JVM exit.
|
||||
* Applications should create their own directory inside this directory
|
||||
* to avoid collisions with other apps.
|
||||
* @since 0.7.6
|
||||
* @return dir constant for the life of the context
|
||||
*/
|
||||
public File getTempDir() {
|
||||
// fixme don't synchronize every time
|
||||
synchronized (this) {
|
||||
@@ -587,12 +654,14 @@ public class I2PAppContext {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
public HMAC256Generator hmac256() {
|
||||
if (!_hmac256Initialized)
|
||||
initializeHMAC256();
|
||||
return _hmac256;
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
private void initializeHMAC256() {
|
||||
synchronized (this) {
|
||||
if (_hmac256 == null) {
|
||||
|
||||
@@ -18,9 +18,9 @@ import net.i2p.util.Log;
|
||||
* @author jrandom
|
||||
*/
|
||||
abstract class HandlerImpl implements I2CPMessageHandler {
|
||||
protected Log _log;
|
||||
private int _type;
|
||||
protected I2PAppContext _context;
|
||||
protected final Log _log;
|
||||
private final int _type;
|
||||
protected final I2PAppContext _context;
|
||||
|
||||
public HandlerImpl(I2PAppContext context, int type) {
|
||||
_context = context;
|
||||
|
||||
@@ -34,6 +34,8 @@ public interface I2PClient {
|
||||
public final static String PROP_RELIABILITY_BEST_EFFORT = "BestEffort";
|
||||
/** Reliability value: guaranteed */
|
||||
public final static String PROP_RELIABILITY_GUARANTEED = "Guaranteed";
|
||||
/** @since 0.8.1 */
|
||||
public final static String PROP_RELIABILITY_NONE = "none";
|
||||
|
||||
/** protocol flag that must be sent when opening the i2cp connection to the router */
|
||||
public final static int PROTOCOL_BYTE = 0x2A;
|
||||
@@ -64,4 +66,4 @@ public interface I2PClient {
|
||||
* @return newly created destination
|
||||
*/
|
||||
public Destination createDestination(OutputStream destKeyStream, Certificate cert) throws I2PException, IOException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,14 @@ import net.i2p.util.Log;
|
||||
class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
|
||||
/** set of MessageState objects, representing all of the messages in the process of being sent */
|
||||
private /* FIXME final FIXME */ Set _sendingStates;
|
||||
private /* FIXME final FIXME */ Set<MessageState> _sendingStates;
|
||||
/** max # seconds to wait for confirmation of the message 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;
|
||||
private final static boolean SHOULD_DECOMPRESS = true;
|
||||
/** Don't expect any MSMs from the router for outbound traffic @since 0.8.1 */
|
||||
private boolean _noEffort;
|
||||
|
||||
/** for extension */
|
||||
public I2PSessionImpl2() {}
|
||||
@@ -53,6 +55,8 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
super(ctx, destKeyStream, options);
|
||||
_log = ctx.logManager().getLog(I2PSessionImpl2.class);
|
||||
_sendingStates = new HashSet(32);
|
||||
// default is BestEffort
|
||||
_noEffort = "none".equalsIgnoreCase(options.getProperty(I2PClient.PROP_RELIABILITY));
|
||||
|
||||
ctx.statManager().createRateStat("i2cp.sendBestEffortTotalTime", "how long to do the full sendBestEffort call?", "i2cp", new long[] { 10*60*1000 } );
|
||||
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage0", "first part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
|
||||
@@ -60,15 +64,16 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage2", "third part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
|
||||
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage3", "fourth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
|
||||
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage4", "fifth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.0", "How long it took to get status=0 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.1", "How long it took to get status=1 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.2", "How long it took to get status=2 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.3", "How long it took to get status=3 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.4", "How long it took to get status=4 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.5", "How long it took to get status=5 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime", "How long it took to get any status", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.tx.msgCompressed", "compressed size transferred", "i2cp", new long[] { 60*1000, 30*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.tx.msgExpanded", "size before compression", "i2cp", new long[] { 60*1000, 30*60*1000 });
|
||||
//_context.statManager().createRateStat("i2cp.receiveStatusTime.0", "How long it took to get status=0 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.1", "How long it took to get status=1 back", "i2cp", new long[] { 10*60*1000 });
|
||||
// best effort codes unused
|
||||
//_context.statManager().createRateStat("i2cp.receiveStatusTime.2", "How long it took to get status=2 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
//_context.statManager().createRateStat("i2cp.receiveStatusTime.3", "How long it took to get status=3 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.4", "How long it took to get status=4 back", "i2cp", new long[] { 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime.5", "How long it took to get status=5 back", "i2cp", new long[] { 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.receiveStatusTime", "How long it took to get any status", "i2cp", new long[] { 10*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.tx.msgCompressed", "compressed size transferred", "i2cp", new long[] { 30*60*1000 });
|
||||
_context.statManager().createRateStat("i2cp.tx.msgExpanded", "size before compression", "i2cp", new long[] { 30*60*1000 });
|
||||
}
|
||||
|
||||
protected long getTimeout() {
|
||||
@@ -186,7 +191,10 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
}
|
||||
_context.statManager().addRateData("i2cp.tx.msgCompressed", compressed, 0);
|
||||
_context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
|
||||
return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
|
||||
if (_noEffort)
|
||||
return sendNoEffort(dest, payload, expires);
|
||||
else
|
||||
return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,6 +221,9 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
private static final int NUM_TAGS = 50;
|
||||
|
||||
/**
|
||||
* TODO - Don't need to save MessageState since actuallyWait is false...
|
||||
* But for now just use sendNoEffort() instead.
|
||||
*
|
||||
* @param keyUsed unused - no end-to-end crypto
|
||||
* @param tagsSent unused - no end-to-end crypto
|
||||
*/
|
||||
@@ -257,7 +268,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
+ "ms left, " + oldTags + " tags known and "
|
||||
+ (tag == null ? "no tag" : " a valid tag"));
|
||||
}
|
||||
|
||||
|
||||
if (false) // rekey
|
||||
newKey = _context.keyGenerator().generateSessionKey();
|
||||
|
||||
@@ -371,6 +382,37 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as sendBestEffort(), except we do not expect any MessageStatusMessage responses -
|
||||
* not for accepted, or success, or failure.
|
||||
* So we don't create a MessageState and save it on the _sendingStates HashSet
|
||||
*
|
||||
* @return true always
|
||||
* @since 0.8.1
|
||||
*/
|
||||
protected boolean sendNoEffort(Destination dest, byte payload[], long expires)
|
||||
throws I2PSessionException {
|
||||
// nonce always 0
|
||||
_producer.sendMessage(this, dest, 0, payload, null, null, null, null, expires);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only call this with nonzero status, i.e. for outbound messages
|
||||
* whose MessageState may be queued on _sendingStates.
|
||||
*
|
||||
* Even when using sendBestEffort(), this is a waste, because the
|
||||
* MessageState is removed from _sendingStates immediately and
|
||||
* so the lookup here fails.
|
||||
* And iterating through the HashSet instead of having a map
|
||||
* is bad too.
|
||||
*
|
||||
* This is now pretty much avoided since streaming now sets
|
||||
* i2cp.messageReliability = none, which forces sendNoEffort() instead of sendBestEffort(),
|
||||
* so the router won't send us any MSM's for outbound traffic.
|
||||
*
|
||||
* @param status != 0
|
||||
*/
|
||||
@Override
|
||||
public void receiveStatus(int msgId, long nonce, int status) {
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Received status " + status + " for msgId " + msgId + " / " + nonce);
|
||||
@@ -413,12 +455,13 @@ class I2PSessionImpl2 extends I2PSessionImpl {
|
||||
case 1:
|
||||
_context.statManager().addRateData("i2cp.receiveStatusTime.1", lifetime, 0);
|
||||
break;
|
||||
case 2:
|
||||
_context.statManager().addRateData("i2cp.receiveStatusTime.2", lifetime, 0);
|
||||
break;
|
||||
case 3:
|
||||
_context.statManager().addRateData("i2cp.receiveStatusTime.3", lifetime, 0);
|
||||
break;
|
||||
// best effort codes unused
|
||||
//case 2:
|
||||
// _context.statManager().addRateData("i2cp.receiveStatusTime.2", lifetime, 0);
|
||||
// break;
|
||||
//case 3:
|
||||
// _context.statManager().addRateData("i2cp.receiveStatusTime.3", lifetime, 0);
|
||||
// break;
|
||||
case 4:
|
||||
_context.statManager().addRateData("i2cp.receiveStatusTime.4", lifetime, 0);
|
||||
break;
|
||||
|
||||
@@ -37,13 +37,7 @@ class MessageState {
|
||||
_context = ctx;
|
||||
_nonce = nonce;
|
||||
_prefix = prefix + "[" + _stateId + "]: ";
|
||||
_id = null;
|
||||
_receivedStatus = new HashSet();
|
||||
_cancelled = false;
|
||||
_key = null;
|
||||
_newKey = null;
|
||||
_tags = null;
|
||||
_to = null;
|
||||
_created = ctx.clock().now();
|
||||
//ctx.statManager().createRateStat("i2cp.checkStatusTime", "how long it takes to go through the states", "i2cp", new long[] { 60*1000 });
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ import net.i2p.util.SimpleTimer;
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
public class SessionIdleTimer implements SimpleTimer.TimedEvent {
|
||||
class SessionIdleTimer implements SimpleTimer.TimedEvent {
|
||||
public static final long MINIMUM_TIME = 5*60*1000;
|
||||
private static final long DEFAULT_REDUCE_TIME = 20*60*1000;
|
||||
private static final long DEFAULT_CLOSE_TIME = 30*60*1000;
|
||||
private final static Log _log = new Log(SessionIdleTimer.class);
|
||||
private I2PAppContext _context;
|
||||
private I2PSessionImpl _session;
|
||||
private final I2PAppContext _context;
|
||||
private final I2PSessionImpl _session;
|
||||
private boolean _reduceEnabled;
|
||||
private int _reduceQuantity;
|
||||
private long _reduceTime;
|
||||
@@ -36,7 +36,6 @@ public class SessionIdleTimer implements SimpleTimer.TimedEvent {
|
||||
/**
|
||||
* reduce, shutdown, or both must be true
|
||||
*/
|
||||
/* FIXME Exporting non-public type through public API FIXME */
|
||||
public SessionIdleTimer(I2PAppContext context, I2PSessionImpl session, boolean reduce, boolean shutdown) {
|
||||
_context = context;
|
||||
_session = session;
|
||||
|
||||
@@ -66,6 +66,10 @@ public class EepGetNamingService extends NamingService {
|
||||
|
||||
hostname = hostname.toLowerCase();
|
||||
|
||||
// If you want b32, chain with HostsTxtNamingService
|
||||
if (hostname.length() == 60 && hostname.endsWith(".b32.i2p"))
|
||||
return null;
|
||||
|
||||
// check the cache
|
||||
Destination d = getCache(hostname);
|
||||
if (d != null)
|
||||
|
||||
@@ -66,6 +66,10 @@ public class ExecNamingService extends NamingService {
|
||||
|
||||
hostname = hostname.toLowerCase();
|
||||
|
||||
// If you want b32, chain with HostsTxtNamingService
|
||||
if (hostname.length() == 60 && hostname.endsWith(".b32.i2p"))
|
||||
return null;
|
||||
|
||||
// check the cache
|
||||
Destination d = getCache(hostname);
|
||||
if (d != null)
|
||||
|
||||
@@ -27,6 +27,7 @@ class LookupDest {
|
||||
|
||||
protected LookupDest(I2PAppContext context) {}
|
||||
|
||||
/** @param key 52 chars (do not include the .b32.i2p suffix) */
|
||||
static Destination lookupBase32Hash(I2PAppContext ctx, String key) {
|
||||
byte[] h = Base32.decode(key);
|
||||
if (h == null)
|
||||
@@ -44,6 +45,7 @@ class LookupDest {
|
||||
}
|
||||
****/
|
||||
|
||||
/** @param h 32 byte hash */
|
||||
static Destination lookupHash(I2PAppContext ctx, byte[] h) {
|
||||
Hash key = new Hash(h);
|
||||
Destination rv = null;
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class NamingService {
|
||||
public static final String PROP_IMPL = "i2p.naming.impl";
|
||||
private static final String DEFAULT_IMPL = "net.i2p.client.naming.HostsTxtNamingService";
|
||||
|
||||
protected static final int CACHE_MAX_SIZE = 8;
|
||||
protected static final int CACHE_MAX_SIZE = 16;
|
||||
|
||||
|
||||
/**
|
||||
@@ -107,7 +107,7 @@ public abstract class NamingService {
|
||||
* The service may override the age and/or size limit
|
||||
*/
|
||||
/** Don't know why a dest would ever change but keep this short anyway */
|
||||
protected static final long CACHE_MAX_AGE = 60*1000;
|
||||
protected static final long CACHE_MAX_AGE = 7*60*1000;
|
||||
|
||||
private class CacheEntry {
|
||||
public Destination dest;
|
||||
@@ -174,4 +174,11 @@ public abstract class NamingService {
|
||||
return ce.dest;
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.8.1 */
|
||||
public void clearCache() {
|
||||
synchronized (_cache) {
|
||||
_cache.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ import net.i2p.util.RandomSource;
|
||||
|
||||
/**
|
||||
* Dummy wrapper for AES cipher operation.
|
||||
*
|
||||
* UNUSED unless i2p.encryption = off
|
||||
* See CryptixAESEngine for the real thing.
|
||||
*/
|
||||
public class AESEngine {
|
||||
private Log _log;
|
||||
@@ -145,7 +146,10 @@ public class AESEngine {
|
||||
_log.warn("Warning: AES is disabled");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Just copies payload to out
|
||||
* @param sessionKey unused
|
||||
*/
|
||||
public void encryptBlock(byte payload[], int inIndex, SessionKey sessionKey, byte out[], int outIndex) {
|
||||
System.arraycopy(payload, inIndex, out, outIndex, out.length - outIndex);
|
||||
}
|
||||
@@ -158,6 +162,7 @@ public class AESEngine {
|
||||
System.arraycopy(payload, inIndex, rv, outIndex, rv.length - outIndex);
|
||||
}
|
||||
|
||||
/******
|
||||
public static void main(String args[]) {
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
@@ -178,4 +183,5 @@ public class AESEngine {
|
||||
byte ld[] = ctx.aes().safeDecrypt(le, key, iv);
|
||||
ctx.logManager().getLog(AESEngine.class).debug("Long test: " + DataHelper.eq(ld, lbuf));
|
||||
}
|
||||
}
|
||||
******/
|
||||
}
|
||||
|
||||
@@ -41,11 +41,13 @@ public class CryptixAESEngine extends AESEngine {
|
||||
_cache = new CryptixAESKeyCache();
|
||||
}
|
||||
|
||||
/** @param length must be a multiple of 16 */
|
||||
@Override
|
||||
public void encrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int length) {
|
||||
encrypt(payload, payloadIndex, out, outIndex, sessionKey, iv, 0, length);
|
||||
}
|
||||
|
||||
/** @param length must be a multiple of 16 */
|
||||
@Override
|
||||
public void encrypt(byte payload[], int payloadIndex, byte out[], int outIndex, SessionKey sessionKey, byte iv[], int ivOffset, int length) {
|
||||
if ( (payload == null) || (out == null) || (sessionKey == null) || (iv == null) )
|
||||
@@ -126,6 +128,7 @@ public class CryptixAESEngine extends AESEngine {
|
||||
_prevCache.release(curA);
|
||||
}
|
||||
|
||||
/** encrypt exactly 16 bytes using the session key */
|
||||
@Override
|
||||
public final void encryptBlock(byte payload[], int inIndex, SessionKey sessionKey, byte out[], int outIndex) {
|
||||
if (sessionKey.getPreparedKey() == null) {
|
||||
@@ -141,7 +144,7 @@ public class CryptixAESEngine extends AESEngine {
|
||||
CryptixRijndael_Algorithm.blockEncrypt(payload, out, inIndex, outIndex, sessionKey.getPreparedKey(), 16);
|
||||
}
|
||||
|
||||
/** decrypt the data with the session key provided
|
||||
/** decrypt exactly 16 bytes of data with the session key provided
|
||||
* @param payload encrypted data
|
||||
* @param sessionKey private session key
|
||||
*/
|
||||
@@ -166,6 +169,7 @@ public class CryptixAESEngine extends AESEngine {
|
||||
CryptixRijndael_Algorithm.blockDecrypt(payload, rv, inIndex, outIndex, sessionKey.getPreparedKey(), 16);
|
||||
}
|
||||
|
||||
/********
|
||||
public static void main(String args[]) {
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
try {
|
||||
@@ -278,4 +282,5 @@ public class CryptixAESEngine extends AESEngine {
|
||||
else
|
||||
System.out.println("block D(E(orig)) == orig");
|
||||
}
|
||||
}
|
||||
*******/
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* Cache the objects used in CryptixRijndael_Algorithm.makeKey to reduce
|
||||
@@ -11,7 +10,7 @@ import java.util.List;
|
||||
*
|
||||
*/
|
||||
public final class CryptixAESKeyCache {
|
||||
private final List _availableKeys;
|
||||
private final LinkedBlockingQueue<KeyCacheEntry> _availableKeys;
|
||||
|
||||
private static final int KEYSIZE = 32; // 256bit AES
|
||||
private static final int BLOCKSIZE = 16;
|
||||
@@ -22,7 +21,7 @@ public final class CryptixAESKeyCache {
|
||||
private static final int MAX_KEYS = 64;
|
||||
|
||||
public CryptixAESKeyCache() {
|
||||
_availableKeys = new ArrayList(MAX_KEYS);
|
||||
_availableKeys = new LinkedBlockingQueue(MAX_KEYS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,10 +29,9 @@ public final class CryptixAESKeyCache {
|
||||
*
|
||||
*/
|
||||
public final KeyCacheEntry acquireKey() {
|
||||
synchronized (_availableKeys) {
|
||||
if (!_availableKeys.isEmpty())
|
||||
return (KeyCacheEntry)_availableKeys.remove(0);
|
||||
}
|
||||
KeyCacheEntry rv = _availableKeys.poll();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return createNew();
|
||||
}
|
||||
|
||||
@@ -42,10 +40,7 @@ public final class CryptixAESKeyCache {
|
||||
*
|
||||
*/
|
||||
public final void releaseKey(KeyCacheEntry key) {
|
||||
synchronized (_availableKeys) {
|
||||
if (_availableKeys.size() < MAX_KEYS)
|
||||
_availableKeys.add(key);
|
||||
}
|
||||
_availableKeys.offer(key);
|
||||
}
|
||||
|
||||
public static final KeyCacheEntry createNew() {
|
||||
|
||||
@@ -34,22 +34,22 @@ import java.math.BigInteger;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
/**
|
||||
* Primes for ElGamal and DSA from
|
||||
* http://www.ietf.org/proceedings/03mar/I-D/draft-ietf-ipsec-ike-modp-groups-05.txt
|
||||
* Prime for ElGamal from http://tools.ietf.org/html/rfc3526
|
||||
* Primes for DSA: Generated by TheCrypto http://article.gmane.org/gmane.comp.security.invisiblenet.iip.devel/343
|
||||
*/
|
||||
public class CryptoConstants {
|
||||
public static final BigInteger dsap = new NativeBigInteger(
|
||||
"9c05b2aa960d9b97b8931963c9cc9e8c3026e9b8ed92fad0a69cc886d5bf8015fcadae31"
|
||||
+ "a0ad18fab3f01b00a358de237655c4964afaa2b337e96ad316b9fb1cc564b5aec5b69a9f"
|
||||
+ "f6c3e4548707fef8503d91dd8602e867e6d35d2235c1869ce2479c3b9d5401de04e0727f"
|
||||
+ "b33d6511285d4cf29538d9e3b6051f5b22cc1c93",
|
||||
+ "a0ad18fab3f01b00a358de237655c4964afaa2b337e96ad316b9fb1cc564b5aec5b69a9f"
|
||||
+ "f6c3e4548707fef8503d91dd8602e867e6d35d2235c1869ce2479c3b9d5401de04e0727f"
|
||||
+ "b33d6511285d4cf29538d9e3b6051f5b22cc1c93",
|
||||
16);
|
||||
public static final BigInteger dsaq = new NativeBigInteger("a5dfc28fef4ca1e286744cd8eed9d29d684046b7", 16);
|
||||
public static final BigInteger dsag = new NativeBigInteger(
|
||||
"c1f4d27d40093b429e962d7223824e0bbc47e7c832a39236fc683af84889581075ff9082"
|
||||
+ "ed32353d4374d7301cda1d23c431f4698599dda02451824ff369752593647cc3ddc197de"
|
||||
+ "985e43d136cdcfc6bd5409cd2f450821142a5e6f8eb1c3ab5d0484b8129fcf17bce4f7f3"
|
||||
+ "3321c3cb3dbb14a905e7b2b3e93be4708cbcc82",
|
||||
+ "ed32353d4374d7301cda1d23c431f4698599dda02451824ff369752593647cc3ddc197de"
|
||||
+ "985e43d136cdcfc6bd5409cd2f450821142a5e6f8eb1c3ab5d0484b8129fcf17bce4f7f3"
|
||||
+ "3321c3cb3dbb14a905e7b2b3e93be4708cbcc82",
|
||||
16);
|
||||
public static final BigInteger elgp = new NativeBigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
+ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
@@ -63,4 +63,4 @@ public class CryptoConstants {
|
||||
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
+ "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16);
|
||||
public static final BigInteger elgg = new NativeBigInteger("2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,35 +65,17 @@ public class DHSessionKeyBuilder {
|
||||
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 = "50";
|
||||
public final static String DEFAULT_DH_PRECALC_DELAY = "10000";
|
||||
public final static int DEFAULT_DH_PRECALC_MIN = 5;
|
||||
public final static int DEFAULT_DH_PRECALC_MAX = 50;
|
||||
public final static int DEFAULT_DH_PRECALC_DELAY = 10000;
|
||||
|
||||
static {
|
||||
I2PAppContext ctx = _context;
|
||||
ctx.statManager().createRateStat("crypto.dhGeneratePublicTime", "How long it takes to create x and X", "Encryption", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
|
||||
ctx.statManager().createRateStat("crypto.dhCalculateSessionTime", "How long it takes to create the session key", "Encryption", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
|
||||
try {
|
||||
int val = Integer.parseInt(ctx.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(ctx.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(ctx.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;
|
||||
}
|
||||
MIN_NUM_BUILDERS = ctx.getProperty(PROP_DH_PRECALC_MIN, DEFAULT_DH_PRECALC_MIN);
|
||||
MAX_NUM_BUILDERS = ctx.getProperty(PROP_DH_PRECALC_MAX, DEFAULT_DH_PRECALC_MAX);
|
||||
CALC_DELAY = ctx.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("DH Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
|
||||
|
||||
@@ -41,6 +41,10 @@ import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
/**
|
||||
* Params and rv's changed from Hash to SHA1Hash for version 0.8.1
|
||||
* There shouldn't be any external users of those variants.
|
||||
*/
|
||||
public class DSAEngine {
|
||||
private Log _log;
|
||||
private I2PAppContext _context;
|
||||
@@ -61,7 +65,9 @@ public class DSAEngine {
|
||||
public boolean verifySignature(Signature signature, InputStream in, SigningPublicKey verifyingKey) {
|
||||
return verifySignature(signature, calculateHash(in), verifyingKey);
|
||||
}
|
||||
public boolean verifySignature(Signature signature, Hash hash, SigningPublicKey verifyingKey) {
|
||||
|
||||
/** @param hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
public boolean verifySignature(Signature signature, SHA1Hash hash, SigningPublicKey verifyingKey) {
|
||||
long start = _context.clock().now();
|
||||
|
||||
try {
|
||||
@@ -111,17 +117,18 @@ public class DSAEngine {
|
||||
}
|
||||
public Signature sign(byte data[], int offset, int length, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
|
||||
Hash h = calculateHash(data, offset, length);
|
||||
SHA1Hash h = calculateHash(data, offset, length);
|
||||
return sign(h, signingKey);
|
||||
}
|
||||
|
||||
public Signature sign(InputStream in, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (in == null) ) return null;
|
||||
Hash h = calculateHash(in);
|
||||
SHA1Hash h = calculateHash(in);
|
||||
return sign(h, signingKey);
|
||||
}
|
||||
|
||||
public Signature sign(Hash hash, SigningPrivateKey signingKey) {
|
||||
/** @param hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
public Signature sign(SHA1Hash hash, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (hash == null)) return null;
|
||||
long start = _context.clock().now();
|
||||
|
||||
@@ -186,7 +193,8 @@ public class DSAEngine {
|
||||
return sig;
|
||||
}
|
||||
|
||||
public Hash calculateHash(InputStream in) {
|
||||
/** @return hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
public SHA1Hash calculateHash(InputStream in) {
|
||||
SHA1 digest = new SHA1();
|
||||
byte buf[] = new byte[64];
|
||||
int read = 0;
|
||||
@@ -199,14 +207,15 @@ public class DSAEngine {
|
||||
_log.warn("Unable to hash the stream", ioe);
|
||||
return null;
|
||||
}
|
||||
return new Hash(digest.engineDigest());
|
||||
return new SHA1Hash(digest.engineDigest());
|
||||
}
|
||||
|
||||
public static Hash calculateHash(byte[] source, int offset, int len) {
|
||||
/** @return hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
public static SHA1Hash calculateHash(byte[] source, int offset, int len) {
|
||||
SHA1 h = new SHA1();
|
||||
h.engineUpdate(source, offset, len);
|
||||
byte digested[] = h.digest();
|
||||
return new Hash(digested);
|
||||
return new SHA1Hash(digested);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
@@ -43,19 +43,19 @@ public class ElGamalAESEngine {
|
||||
|
||||
_context.statManager().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});
|
||||
"Encryption", new long[] { 60*60*1000l});
|
||||
_context.statManager().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});
|
||||
"Encryption", new long[] { 60*60*1000l});
|
||||
_context.statManager().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});
|
||||
"Encryption", new long[] { 60*60*1000l});
|
||||
_context.statManager().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});
|
||||
"Encryption", new long[] { 60*60*1000l});
|
||||
_context.statManager().createFrequencyStat("crypto.elGamalAES.decryptFailed",
|
||||
"how frequently we fail to decrypt with ElGamal/AES+SessionTag?", "Encryption",
|
||||
new long[] { 60 * 60 * 1000l, 24 * 60 * 60 * 1000l});
|
||||
"how frequently we fail to decrypt with ElGamal/AES+SessionTag?",
|
||||
"Encryption", new long[] { 60*60*1000l});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,6 +73,7 @@ public class ElGamalAESEngine {
|
||||
* This works according to the
|
||||
* ElGamal+AES algorithm in the data structure spec.
|
||||
*
|
||||
* @return decrypted data or null on failure
|
||||
*/
|
||||
public byte[] decrypt(byte data[], PrivateKey targetPrivateKey, SessionKeyManager keyManager) throws DataFormatException {
|
||||
if (data == null) {
|
||||
@@ -148,9 +149,12 @@ public class ElGamalAESEngine {
|
||||
/**
|
||||
* scenario 1:
|
||||
* Begin with 222 bytes, ElG encrypted, containing:
|
||||
* <pre>
|
||||
* - 32 byte SessionKey
|
||||
* - 32 byte pre-IV for the AES
|
||||
* - 158 bytes of random padding
|
||||
* </pre>
|
||||
* After encryption, the ElG section is 514 bytes long.
|
||||
* Then encrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV, using
|
||||
* the decryptAESBlock method & structure.
|
||||
*
|
||||
@@ -213,6 +217,7 @@ public class ElGamalAESEngine {
|
||||
* scenario 2:
|
||||
* The data begins with 32 byte session tag, which also serves as the preIV.
|
||||
* Then decrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
|
||||
* <pre>
|
||||
* - 2 byte integer specifying the # of session tags
|
||||
* - that many 32 byte session tags
|
||||
* - 4 byte integer specifying data.length
|
||||
@@ -220,11 +225,13 @@ public class ElGamalAESEngine {
|
||||
* - 1 byte flag that, if == 1, is followed by a new SessionKey
|
||||
* - data
|
||||
* - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
|
||||
* </pre>
|
||||
*
|
||||
* If anything doesn't match up in decryption, it falls back to decryptNewSession
|
||||
*
|
||||
* @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
|
||||
* @return decrypted data or null on failure
|
||||
*
|
||||
*/
|
||||
byte[] decryptExistingSession(byte data[], SessionKey key, PrivateKey targetPrivateKey, Set foundTags,
|
||||
@@ -264,6 +271,7 @@ public class ElGamalAESEngine {
|
||||
|
||||
/**
|
||||
* Decrypt the AES data with the session key and IV. The result should be:
|
||||
* <pre>
|
||||
* - 2 byte integer specifying the # of session tags
|
||||
* - that many 32 byte session tags
|
||||
* - 4 byte integer specifying data.length
|
||||
@@ -271,6 +279,7 @@ public class ElGamalAESEngine {
|
||||
* - 1 byte flag that, if == 1, is followed by a new SessionKey
|
||||
* - data
|
||||
* - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
|
||||
* </pre>
|
||||
*
|
||||
* If anything doesn't match up in decryption, return null. Otherwise, return
|
||||
* the decrypted data and update the session as necessary. If the sentTag is not null,
|
||||
@@ -278,6 +287,7 @@ 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
|
||||
* @return decrypted data or null on failure
|
||||
*/
|
||||
byte[] decryptAESBlock(byte encrypted[], SessionKey key, byte iv[],
|
||||
byte sentTag[], Set foundTags, SessionKey foundKey) throws DataFormatException {
|
||||
@@ -299,10 +309,10 @@ public class ElGamalAESEngine {
|
||||
//ByteArrayInputStream bais = new ByteArrayInputStream(decrypted);
|
||||
int cur = 0;
|
||||
long numTags = DataHelper.fromLong(decrypted, cur, 2);
|
||||
if ((numTags < 0) || (numTags > 200)) throw new Exception("Invalid number of session tags");
|
||||
if (numTags > 0) tags = new ArrayList((int)numTags);
|
||||
cur += 2;
|
||||
//_log.debug("# tags: " + numTags);
|
||||
if ((numTags < 0) || (numTags > 200)) throw new Exception("Invalid number of session tags");
|
||||
if (numTags * SessionTag.BYTE_LENGTH > decrypted.length - 2) {
|
||||
throw new Exception("# tags: " + numTags + " is too many for " + (decrypted.length - 2));
|
||||
}
|
||||
@@ -363,6 +373,8 @@ public class ElGamalAESEngine {
|
||||
* @param newKey key to be delivered to the target, with which the tagsForDelivery should be associated, or null
|
||||
* @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)
|
||||
*
|
||||
* Unused externally, only called by below (i.e. newKey is always null)
|
||||
*/
|
||||
public byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery,
|
||||
SessionTag currentTag, SessionKey newKey, long paddedSize) {
|
||||
@@ -384,6 +396,7 @@ public class ElGamalAESEngine {
|
||||
/**
|
||||
* Encrypt the data to the target using the given key and deliver the specified tags
|
||||
* No new session key
|
||||
* This is the one called from GarlicMessageBuilder and is the primary entry point.
|
||||
*/
|
||||
public byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery,
|
||||
SessionTag currentTag, long paddedSize) {
|
||||
@@ -394,6 +407,8 @@ public class ElGamalAESEngine {
|
||||
* Encrypt the data to the target using the given key and deliver the specified tags
|
||||
* No new session key
|
||||
* No current tag (encrypt as new session)
|
||||
*
|
||||
* @deprecated unused
|
||||
*/
|
||||
public byte[] encrypt(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery, long paddedSize) {
|
||||
return encrypt(data, target, key, tagsForDelivery, null, null, paddedSize);
|
||||
@@ -403,6 +418,8 @@ public class ElGamalAESEngine {
|
||||
* Encrypt the data to the target using the given key delivering no tags
|
||||
* No new session key
|
||||
* No current tag (encrypt as new session)
|
||||
*
|
||||
* @deprecated unused
|
||||
*/
|
||||
public byte[] encrypt(byte data[], PublicKey target, SessionKey key, long paddedSize) {
|
||||
return encrypt(data, target, key, null, null, null, paddedSize);
|
||||
@@ -411,10 +428,14 @@ public class ElGamalAESEngine {
|
||||
/**
|
||||
* scenario 1:
|
||||
* Begin with 222 bytes, ElG encrypted, containing:
|
||||
* <pre>
|
||||
* - 32 byte SessionKey
|
||||
* - 32 byte pre-IV for the AES
|
||||
* - 158 bytes of random padding
|
||||
* Then encrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
|
||||
* </pre>
|
||||
* After encryption, the ElG section is 514 bytes long.
|
||||
* Then encrypt the following with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
|
||||
* <pre>
|
||||
* - 2 byte integer specifying the # of session tags
|
||||
* - that many 32 byte session tags
|
||||
* - 4 byte integer specifying data.length
|
||||
@@ -422,6 +443,7 @@ public class ElGamalAESEngine {
|
||||
* - 1 byte flag that, if == 1, is followed by a new SessionKey
|
||||
* - data
|
||||
* - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
byte[] encryptNewSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery,
|
||||
@@ -440,10 +462,12 @@ public class ElGamalAESEngine {
|
||||
//_log.debug("SessionKey for encryptNewSession: " + DataHelper.toString(key.getData(), 32));
|
||||
long before = _context.clock().now();
|
||||
byte elgEncr[] = _context.elGamalEngine().encrypt(elgSrcData, target);
|
||||
long after = _context.clock().now();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
long after = _context.clock().now();
|
||||
_log.info("elgEngine.encrypt of the session key took " + (after - before) + "ms");
|
||||
}
|
||||
if (elgEncr.length < 514) {
|
||||
// ??? ElGamalEngine.encrypt() always returns 514 bytes
|
||||
byte elg[] = new byte[514];
|
||||
int diff = elg.length - elgEncr.length;
|
||||
//if (_log.shouldLog(Log.DEBUG)) _log.debug("Difference in size: " + diff);
|
||||
@@ -474,6 +498,7 @@ public class ElGamalAESEngine {
|
||||
* scenario 2:
|
||||
* Begin with 32 byte session tag, which also serves as the preIV.
|
||||
* Then encrypt with AES using that session key and the first 16 bytes of the SHA256 of the pre-IV:
|
||||
* <pre>
|
||||
* - 2 byte integer specifying the # of session tags
|
||||
* - that many 32 byte session tags
|
||||
* - 4 byte integer specifying data.length
|
||||
@@ -481,6 +506,7 @@ public class ElGamalAESEngine {
|
||||
* - 1 byte flag that, if == 1, is followed by a new SessionKey
|
||||
* - data
|
||||
* - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
byte[] encryptExistingSession(byte data[], PublicKey target, SessionKey key, Set tagsForDelivery,
|
||||
@@ -506,6 +532,7 @@ public class ElGamalAESEngine {
|
||||
* 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
|
||||
* also mod 16 bytes. The contents of the encrypted data is:
|
||||
* <pre>
|
||||
* - 2 byte integer specifying the # of session tags
|
||||
* - that many 32 byte session tags
|
||||
* - 4 byte integer specifying data.length
|
||||
@@ -513,6 +540,7 @@ public class ElGamalAESEngine {
|
||||
* - 1 byte flag that, if == 1, is followed by a new SessionKey
|
||||
* - data
|
||||
* - random bytes, padding the total size to greater than paddedSize with a mod 16 = 0
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
final byte[] encryptAESBlock(byte data[], SessionKey key, byte[] iv, Set tagsForDelivery, SessionKey newKey,
|
||||
|
||||
@@ -45,7 +45,7 @@ import net.i2p.util.RandomSource;
|
||||
/**
|
||||
* Wrapper for ElGamal encryption/signature schemes.
|
||||
*
|
||||
* Does all of Elgamal now for data sizes of 223 bytes and less. The data to be
|
||||
* Does all of Elgamal now for data sizes of 222 bytes and less. The data to be
|
||||
* encrypted is first prepended with a random nonzero byte, then the 32 bytes
|
||||
* making up the SHA256 of the data, then the data itself. The random byte and
|
||||
* the SHA256 hash is stripped on decrypt so the original data is returned.
|
||||
@@ -66,10 +66,10 @@ public class ElGamalEngine {
|
||||
public ElGamalEngine(I2PAppContext context) {
|
||||
context.statManager().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});
|
||||
new long[] { 60 * 60 * 1000});
|
||||
context.statManager().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});
|
||||
new long[] { 60 * 60 * 1000});
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(ElGamalEngine.class);
|
||||
}
|
||||
@@ -85,9 +85,17 @@ public class ElGamalEngine {
|
||||
}
|
||||
|
||||
/** encrypt the data to the public key
|
||||
* @return encrypted data
|
||||
* @return encrypted data, will be exactly 514 bytes long
|
||||
* Contains the two-part encrypted data starting at bytes 0 and 257.
|
||||
* If the encrypted parts are smaller than 257 bytes, they will be
|
||||
* padded with leading zeros.
|
||||
* The parts appear to always be 256 bytes or less, in other words,
|
||||
* bytes 0 and 257 are always zero.
|
||||
* @param publicKey public key encrypt to
|
||||
* @param data data to encrypt
|
||||
* @param data data to encrypt, must be 222 bytes or less
|
||||
* As the encrypted data may contain a substantial number of zeros if the
|
||||
* cleartext is smaller than 222 bytes, it is recommended that the caller pad
|
||||
* the cleartext to 222 bytes with random data.
|
||||
*/
|
||||
public byte[] encrypt(byte data[], PublicKey publicKey) {
|
||||
if ((data == null) || (data.length >= 223))
|
||||
@@ -97,6 +105,7 @@ public class ElGamalEngine {
|
||||
long start = _context.clock().now();
|
||||
|
||||
byte d2[] = new byte[1+Hash.HASH_LENGTH+data.length];
|
||||
// FIXME this isn't a random nonzero byte!
|
||||
d2[0] = (byte)0xFF;
|
||||
Hash hash = _context.sha().calculateHash(data);
|
||||
System.arraycopy(hash.getData(), 0, d2, 1, Hash.HASH_LENGTH);
|
||||
@@ -156,11 +165,15 @@ public class ElGamalEngine {
|
||||
}
|
||||
|
||||
/** Decrypt the data
|
||||
* @param encrypted encrypted data
|
||||
* @param encrypted encrypted data, must be exactly 514 bytes
|
||||
* Contains the two-part encrypted data starting at bytes 0 and 257.
|
||||
* If the encrypted parts are smaller than 257 bytes, they must be
|
||||
* padded with leading zeros.
|
||||
* @param privateKey private key to decrypt with
|
||||
* @return unencrypted data
|
||||
* @return unencrypted data or null on failure
|
||||
*/
|
||||
public byte[] decrypt(byte encrypted[], PrivateKey privateKey) {
|
||||
// actually it must be exactly 514 bytes or the arraycopy below will AIOOBE
|
||||
if ((encrypted == null) || (encrypted.length > 514))
|
||||
throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment");
|
||||
long start = _context.clock().now();
|
||||
|
||||
@@ -15,16 +15,16 @@ import org.bouncycastle.crypto.macs.I2PHMac;
|
||||
* in {@link org.bouncycastle.crypto.macs.I2PHMac} and
|
||||
* {@link org.bouncycastle.crypto.digests.MD5Digest}.
|
||||
*
|
||||
* deprecated unused
|
||||
*/
|
||||
public class HMAC256Generator extends HMACGenerator {
|
||||
public HMAC256Generator(I2PAppContext context) { super(context); }
|
||||
|
||||
@Override
|
||||
protected I2PHMac acquire() {
|
||||
synchronized (_available) {
|
||||
if (!_available.isEmpty())
|
||||
return (I2PHMac)_available.remove(0);
|
||||
}
|
||||
I2PHMac rv = _available.poll();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
// the HMAC is hardcoded to use SHA256 digest size
|
||||
// for backwards compatability. next time we have a backwards
|
||||
// incompatible change, we should update this by removing ", 32"
|
||||
@@ -43,6 +43,7 @@ public class HMAC256Generator extends HMACGenerator {
|
||||
|
||||
}
|
||||
|
||||
/******
|
||||
public static void main(String args[]) {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
byte data[] = new byte[64];
|
||||
@@ -51,4 +52,5 @@ public class HMAC256Generator extends HMACGenerator {
|
||||
Hash mac = ctx.hmac256().calculate(key, data);
|
||||
System.out.println(Base64.encode(mac.getData()));
|
||||
}
|
||||
******/
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
@@ -22,14 +21,14 @@ import org.bouncycastle.crypto.macs.I2PHMac;
|
||||
public class HMACGenerator {
|
||||
private I2PAppContext _context;
|
||||
/** set of available HMAC instances for calculate */
|
||||
protected final List _available;
|
||||
protected final LinkedBlockingQueue<I2PHMac> _available;
|
||||
/** set of available byte[] buffers for verify */
|
||||
private final List _availableTmp;
|
||||
private final LinkedBlockingQueue<byte[]> _availableTmp;
|
||||
|
||||
public HMACGenerator(I2PAppContext context) {
|
||||
_context = context;
|
||||
_available = new ArrayList(32);
|
||||
_availableTmp = new ArrayList(32);
|
||||
_available = new LinkedBlockingQueue(32);
|
||||
_availableTmp = new LinkedBlockingQueue(32);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,39 +87,30 @@ public class HMACGenerator {
|
||||
}
|
||||
|
||||
protected I2PHMac acquire() {
|
||||
synchronized (_available) {
|
||||
if (!_available.isEmpty())
|
||||
return (I2PHMac)_available.remove(0);
|
||||
}
|
||||
I2PHMac rv = _available.poll();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
// the HMAC is hardcoded to use SHA256 digest size
|
||||
// for backwards compatability. next time we have a backwards
|
||||
// incompatible change, we should update this by removing ", 32"
|
||||
return new I2PHMac(new MD5Digest(), 32);
|
||||
}
|
||||
private void release(Mac mac) {
|
||||
synchronized (_available) {
|
||||
if (_available.size() < 64)
|
||||
_available.add(mac);
|
||||
}
|
||||
|
||||
private void release(I2PHMac mac) {
|
||||
_available.offer(mac);
|
||||
}
|
||||
|
||||
// temp buffers for verify(..)
|
||||
private byte[] acquireTmp() {
|
||||
byte rv[] = null;
|
||||
synchronized (_availableTmp) {
|
||||
if (!_availableTmp.isEmpty())
|
||||
rv = (byte[])_availableTmp.remove(0);
|
||||
}
|
||||
byte rv[] = _availableTmp.poll();
|
||||
if (rv != null)
|
||||
Arrays.fill(rv, (byte)0x0);
|
||||
else
|
||||
rv = new byte[Hash.HASH_LENGTH];
|
||||
return rv;
|
||||
}
|
||||
|
||||
private void releaseTmp(byte tmp[]) {
|
||||
synchronized (_availableTmp) {
|
||||
if (_availableTmp.size() < 64)
|
||||
_availableTmp.add((Object)tmp);
|
||||
}
|
||||
_availableTmp.offer(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import net.i2p.util.Log;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
/** Define a way of generating asymetrical key pairs as well as symetrical keys
|
||||
/** Define a way of generating asymmetrical key pairs as well as symmetrical keys
|
||||
* @author jrandom
|
||||
*/
|
||||
public class KeyGenerator {
|
||||
@@ -157,7 +157,7 @@ public class KeyGenerator {
|
||||
* Pad the buffer w/ leading 0s or trim off leading bits so the result is the
|
||||
* given length.
|
||||
*/
|
||||
final static byte[] padBuffer(byte src[], int 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
|
||||
@@ -171,6 +171,7 @@ public class KeyGenerator {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/******
|
||||
public static void main(String args[]) {
|
||||
Log log = new Log("keygenTest");
|
||||
RandomSource.getInstance().nextBoolean();
|
||||
@@ -222,4 +223,5 @@ public class KeyGenerator {
|
||||
} catch (InterruptedException ie) { // nop
|
||||
}
|
||||
}
|
||||
}
|
||||
******/
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class SHA1 extends MessageDigest implements Cloneable {
|
||||
/**
|
||||
* This implementation returns a fixed-size digest.
|
||||
*/
|
||||
private static final int HASH_LENGTH = 20; // bytes == 160 bits
|
||||
static final int HASH_LENGTH = 20; // bytes == 160 bits
|
||||
|
||||
/**
|
||||
* Private context for incomplete blocks and padding bytes.
|
||||
|
||||
81
core/java/src/net/i2p/crypto/SHA1Hash.java
Normal file
81
core/java/src/net/i2p/crypto/SHA1Hash.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataStructureImpl;
|
||||
|
||||
/**
|
||||
* Because DSAEngine was abusing Hash for 20-byte hashes
|
||||
*
|
||||
* @since 0.8.1
|
||||
* @author zzz
|
||||
*/
|
||||
public class SHA1Hash extends DataStructureImpl {
|
||||
private byte[] _data;
|
||||
private int _cachedHashCode;
|
||||
|
||||
public final static int HASH_LENGTH = SHA1.HASH_LENGTH;
|
||||
|
||||
/** @throws IllegalArgumentException if data is not 20 bytes (null is ok) */
|
||||
public SHA1Hash(byte data[]) {
|
||||
setData(data);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
/** @throws IllegalArgumentException if data is not 20 bytes (null is ok) */
|
||||
public void setData(byte[] data) {
|
||||
// FIXME DSAEngine uses a SHA-1 "Hash" as parameters and return values!
|
||||
if (data != null && data.length != HASH_LENGTH)
|
||||
throw new IllegalArgumentException("Hash must be 20 bytes");
|
||||
_data = data;
|
||||
_cachedHashCode = calcHashCode();
|
||||
}
|
||||
|
||||
/** @throws IOException always */
|
||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
||||
throw new IOException("unimplemented");
|
||||
}
|
||||
|
||||
/** @throws IOException always */
|
||||
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
|
||||
throw new IOException("unimplemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj == null) || !(obj instanceof SHA1Hash)) return false;
|
||||
return DataHelper.eq(_data, ((SHA1Hash) obj)._data);
|
||||
}
|
||||
|
||||
/** a Hash is a hash, so just use the first 4 bytes for speed */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return _cachedHashCode;
|
||||
}
|
||||
|
||||
/** a Hash is a hash, so just use the first 4 bytes for speed */
|
||||
private int calcHashCode() {
|
||||
int rv = 0;
|
||||
if (_data != null) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
rv ^= (_data[i] << (i*8));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,7 @@ package net.i2p.crypto;
|
||||
|
||||
import gnu.crypto.hash.Sha256Standalone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
@@ -15,11 +14,9 @@ import net.i2p.data.Hash;
|
||||
*
|
||||
*/
|
||||
public final class SHA256Generator {
|
||||
private List _digests;
|
||||
private final List _digestsGnu;
|
||||
private final LinkedBlockingQueue<Sha256Standalone> _digestsGnu;
|
||||
public SHA256Generator(I2PAppContext context) {
|
||||
_digests = new ArrayList(32);
|
||||
_digestsGnu = new ArrayList(32);
|
||||
_digestsGnu = new LinkedBlockingQueue(32);
|
||||
}
|
||||
|
||||
public static final SHA256Generator getInstance() {
|
||||
@@ -50,11 +47,7 @@ public final class SHA256Generator {
|
||||
}
|
||||
|
||||
private Sha256Standalone acquireGnu() {
|
||||
Sha256Standalone rv = null;
|
||||
synchronized (_digestsGnu) {
|
||||
if (!_digestsGnu.isEmpty())
|
||||
rv = (Sha256Standalone)_digestsGnu.remove(0);
|
||||
}
|
||||
Sha256Standalone rv = _digestsGnu.poll();
|
||||
if (rv != null)
|
||||
rv.reset();
|
||||
else
|
||||
@@ -63,11 +56,7 @@ public final class SHA256Generator {
|
||||
}
|
||||
|
||||
private void releaseGnu(Sha256Standalone digest) {
|
||||
synchronized (_digestsGnu) {
|
||||
if (_digestsGnu.size() < 32) {
|
||||
_digestsGnu.add(digest);
|
||||
}
|
||||
}
|
||||
_digestsGnu.offer(digest);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
@@ -75,4 +64,4 @@ public final class SHA256Generator {
|
||||
for (int i = 0; i < args.length; i++)
|
||||
System.out.println("SHA256 [" + args[i] + "] = [" + Base64.encode(ctx.sha().calculateHash(args[i].getBytes()).getData()) + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,24 +10,22 @@ package net.i2p.crypto;
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Precalculate the Y and K for ElGamal encryption operations.
|
||||
*
|
||||
* This class precalcs a set of values on its own thread, using those transparently
|
||||
* when a new instance is created. By default, the minimum threshold for creating
|
||||
* new values for the pool is 5, and the max pool size is 10. Whenever the pool has
|
||||
* new values for the pool is 20, and the max pool size is 50. Whenever the pool has
|
||||
* less than the minimum, it fills it up again to the max. There is a delay after
|
||||
* each precalculation so that the CPU isn't hosed during startup (defaulting to 10 seconds).
|
||||
* each precalculation so that the CPU isn't hosed during startup.
|
||||
* These three parameters are controlled by java environmental variables and
|
||||
* can be adjusted via:
|
||||
* -Dcrypto.yk.precalc.min=40 -Dcrypto.yk.precalc.max=100 -Dcrypto.yk.precalc.delay=60000
|
||||
@@ -39,51 +37,36 @@ import net.i2p.util.RandomSource;
|
||||
* @author jrandom
|
||||
*/
|
||||
class YKGenerator {
|
||||
private final static Log _log = new Log(YKGenerator.class);
|
||||
private static int MIN_NUM_BUILDERS = -1;
|
||||
private static int MAX_NUM_BUILDERS = -1;
|
||||
private static int CALC_DELAY = -1;
|
||||
/* FIXME final type if you are to syncronize FIXME */
|
||||
private static volatile List _values = new ArrayList(50); // list of BigInteger[] values (y and k)
|
||||
private static Thread _precalcThread = null;
|
||||
//private final static Log _log = new Log(YKGenerator.class);
|
||||
private static final int MIN_NUM_BUILDERS;
|
||||
private static final int MAX_NUM_BUILDERS;
|
||||
private static final int CALC_DELAY;
|
||||
private static final LinkedBlockingQueue<BigInteger[]> _values = new LinkedBlockingQueue(50); // list of BigInteger[] values (y and k)
|
||||
private static final Thread _precalcThread;
|
||||
private static final I2PAppContext ctx;
|
||||
|
||||
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";
|
||||
public final static int DEFAULT_YK_PRECALC_MIN = 20;
|
||||
public final static int DEFAULT_YK_PRECALC_MAX = 50;
|
||||
public final static int DEFAULT_YK_PRECALC_DELAY = 200;
|
||||
|
||||
/** check every 30 seconds whether we have less than the minimum */
|
||||
private final static long CHECK_DELAY = 30 * 1000;
|
||||
private static long CHECK_DELAY = 30 * 1000;
|
||||
|
||||
static {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
try {
|
||||
int val = Integer.parseInt(ctx.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(ctx.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(ctx.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;
|
||||
}
|
||||
ctx = I2PAppContext.getGlobalContext();
|
||||
MIN_NUM_BUILDERS = ctx.getProperty(PROP_YK_PRECALC_MIN, DEFAULT_YK_PRECALC_MIN);
|
||||
MAX_NUM_BUILDERS = ctx.getProperty(PROP_YK_PRECALC_MAX, DEFAULT_YK_PRECALC_MAX);
|
||||
CALC_DELAY = ctx.getProperty(PROP_YK_PRECALC_DELAY, DEFAULT_YK_PRECALC_DELAY);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
|
||||
+ CALC_DELAY + ")");
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
|
||||
// + CALC_DELAY + ")");
|
||||
|
||||
ctx.statManager().createRateStat("crypto.YKUsed", "Need a YK from the queue", "Encryption", new long[] { 60*60*1000 });
|
||||
ctx.statManager().createRateStat("crypto.YKEmpty", "YK queue empty", "Encryption", new long[] { 60*60*1000 });
|
||||
|
||||
_precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS));
|
||||
_precalcThread.setName("YK Precalc");
|
||||
@@ -93,45 +76,36 @@ class YKGenerator {
|
||||
}
|
||||
|
||||
private static final int getSize() {
|
||||
synchronized (_values) {
|
||||
return _values.size();
|
||||
}
|
||||
return _values.size();
|
||||
}
|
||||
|
||||
private static final int addValues(BigInteger yk[]) {
|
||||
int sz = 0;
|
||||
synchronized (_values) {
|
||||
_values.add(yk);
|
||||
sz = _values.size();
|
||||
}
|
||||
return sz;
|
||||
/** @return true if successful, false if full */
|
||||
private static final boolean addValues(BigInteger yk[]) {
|
||||
return _values.offer(yk);
|
||||
}
|
||||
|
||||
/** @return rv[0] = Y; rv[1] = K */
|
||||
public static BigInteger[] getNextYK() {
|
||||
if (true) {
|
||||
synchronized (_values) {
|
||||
if (!_values.isEmpty()) {
|
||||
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");
|
||||
ctx.statManager().addRateData("crypto.YKUsed", 1, 0);
|
||||
BigInteger[] rv = _values.poll();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
ctx.statManager().addRateData("crypto.YKEmpty", 1, 0);
|
||||
return generateYK();
|
||||
}
|
||||
|
||||
private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02});
|
||||
|
||||
/** @return rv[0] = Y; rv[1] = K */
|
||||
private static final BigInteger[] generateYK() {
|
||||
NativeBigInteger k = null;
|
||||
BigInteger y = null;
|
||||
long t0 = 0;
|
||||
long t1 = 0;
|
||||
//long t0 = 0;
|
||||
//long t1 = 0;
|
||||
while (k == null) {
|
||||
t0 = Clock.getInstance().now();
|
||||
k = new NativeBigInteger(KeyGenerator.PUBKEY_EXPONENT_SIZE, RandomSource.getInstance());
|
||||
t1 = Clock.getInstance().now();
|
||||
//t0 = Clock.getInstance().now();
|
||||
k = new NativeBigInteger(KeyGenerator.PUBKEY_EXPONENT_SIZE, ctx.random());
|
||||
//t1 = Clock.getInstance().now();
|
||||
if (BigInteger.ZERO.compareTo(k) == 0) {
|
||||
k = null;
|
||||
continue;
|
||||
@@ -139,39 +113,31 @@ class YKGenerator {
|
||||
BigInteger kPlus2 = k.add(_two);
|
||||
if (kPlus2.compareTo(CryptoConstants.elgp) > 0) k = null;
|
||||
}
|
||||
long t2 = Clock.getInstance().now();
|
||||
//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)");
|
||||
}
|
||||
//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) { // nop
|
||||
}
|
||||
_log.debug("\n\n\n\nBegin test\n");
|
||||
System.out.println("\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();
|
||||
negTime += endNeg - startNeg;
|
||||
}
|
||||
_log.debug("YK fetch time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each");
|
||||
try {
|
||||
Thread.sleep(30 * 1000);
|
||||
} catch (InterruptedException ie) { // nop
|
||||
}
|
||||
System.out.println("YK fetch time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each");
|
||||
}
|
||||
|
||||
private static class YKPrecalcRunner implements Runnable {
|
||||
@@ -186,15 +152,21 @@ class YKGenerator {
|
||||
public void run() {
|
||||
while (true) {
|
||||
int curSize = 0;
|
||||
long start = Clock.getInstance().now();
|
||||
//long start = Clock.getInstance().now();
|
||||
int startSize = getSize();
|
||||
// Adjust delay
|
||||
if (startSize <= (_minSize / 2) && CHECK_DELAY > 1000)
|
||||
CHECK_DELAY -= 1000;
|
||||
else if (startSize > (_minSize * 2) && CHECK_DELAY < 60000)
|
||||
CHECK_DELAY += 1000;
|
||||
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");
|
||||
if (curSize < _minSize) {
|
||||
for (int i = curSize; i < _maxSize; i++) {
|
||||
//long begin = Clock.getInstance().now();
|
||||
if (!addValues(generateYK()))
|
||||
break;
|
||||
//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);
|
||||
@@ -202,14 +174,14 @@ class YKGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
//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) { // nop
|
||||
@@ -217,4 +189,4 @@ class YKGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,14 @@ import net.i2p.util.Log;
|
||||
* No whitespace allowed.
|
||||
*
|
||||
* Decode accepts upper or lower case.
|
||||
* @author zzz
|
||||
* @since 0.7
|
||||
*/
|
||||
public class Base32 {
|
||||
|
||||
private final static Log _log = new Log(Base32.class);
|
||||
|
||||
/** The 64 valid Base32 values. */
|
||||
/** The 32 valid Base32 values. */
|
||||
private final static char[] ALPHABET = {'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p',
|
||||
@@ -132,10 +134,16 @@ public class Base32 {
|
||||
System.out.println("or : Base32 decode");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
*/
|
||||
public static String encode(String source) {
|
||||
return (source != null ? encode(source.getBytes()) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source The data to convert non-null
|
||||
*/
|
||||
public static String encode(byte[] source) {
|
||||
StringBuilder buf = new StringBuilder((source.length + 7) * 8 / 5);
|
||||
encodeBytes(source, buf);
|
||||
@@ -147,7 +155,7 @@ public class Base32 {
|
||||
/**
|
||||
* Encodes a byte array into Base32 notation.
|
||||
*
|
||||
* @param source The data to convert
|
||||
* @param source The data to convert non-null
|
||||
*/
|
||||
private static void encodeBytes(byte[] source, StringBuilder out) {
|
||||
int usedbits = 0;
|
||||
@@ -174,7 +182,7 @@ public class Base32 {
|
||||
* Decodes data from Base32 notation and
|
||||
* returns it as a string.
|
||||
*
|
||||
* @param s the string to decode
|
||||
* @param s the string to decode, if null returns null
|
||||
* @return The data as a string or null on failure
|
||||
*/
|
||||
public static String decodeToString(String s) {
|
||||
@@ -184,6 +192,10 @@ public class Base32 {
|
||||
return new String(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s non-null
|
||||
* @return decoded data, null on error
|
||||
*/
|
||||
public static byte[] decode(String s) {
|
||||
return decode(s.getBytes());
|
||||
}
|
||||
@@ -194,8 +206,8 @@ public class Base32 {
|
||||
* Decodes Base32 content in byte array format and returns
|
||||
* the decoded byte array.
|
||||
*
|
||||
* @param source The Base32 encoded data
|
||||
* @return decoded data
|
||||
* @param source The Base32 encoded data non-null
|
||||
* @return decoded data, null on error
|
||||
*/
|
||||
private static byte[] decode(byte[] source) {
|
||||
int len58;
|
||||
|
||||
@@ -42,23 +42,46 @@ public class Base64 {
|
||||
|
||||
private final static Log _log = new Log(Base64.class);
|
||||
|
||||
/** added by aum */
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
*/
|
||||
public static String encode(String source) {
|
||||
return (source != null ? encode(source.getBytes()) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
*/
|
||||
public static String encode(byte[] source) {
|
||||
return (source != null ? encode(source, 0, source.length) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
*/
|
||||
public static String encode(byte[] source, int off, int len) {
|
||||
return (source != null ? encode(source, off, len, false) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
* @param useStandardAlphabet Warning, must be false for I2P compatibility
|
||||
*/
|
||||
public static String encode(byte[] source, boolean useStandardAlphabet) {
|
||||
return (source != null ? encode(source, 0, source.length, useStandardAlphabet) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source if null will return ""
|
||||
* @param useStandardAlphabet Warning, must be false for I2P compatibility
|
||||
*/
|
||||
public static String encode(byte[] source, int off, int len, boolean useStandardAlphabet) {
|
||||
return (source != null ? safeEncode(source, off, len, useStandardAlphabet) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s Base 64 encoded string using the I2P alphabet A-Z, a-z, 0-9, -, ~
|
||||
*/
|
||||
public static byte[] decode(String s) {
|
||||
return safeDecode(s, false);
|
||||
}
|
||||
@@ -84,6 +107,8 @@ public class Base64 {
|
||||
(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) '/'};
|
||||
|
||||
/** The 64 valid Base64 values for I2P. */
|
||||
private final static byte[] ALPHABET_ALT = { (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',
|
||||
@@ -241,7 +266,7 @@ public class Base64 {
|
||||
* @return four byte array in Base64 notation.
|
||||
* @since 1.3
|
||||
*/
|
||||
/***** unused
|
||||
/***** unused (standard alphabet)
|
||||
private static byte[] encode3to4(byte[] threeBytes) {
|
||||
return encode3to4(threeBytes, 3);
|
||||
} // end encodeToBytes
|
||||
@@ -260,11 +285,13 @@ public class Base64 {
|
||||
* @return four byte array in Base64 notation.
|
||||
* @since 1.3
|
||||
*/
|
||||
/***** unused (standard alphabet)
|
||||
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>
|
||||
@@ -287,6 +314,7 @@ public class Base64 {
|
||||
* @return the <var>destination</var> array
|
||||
* @since 1.3
|
||||
*/
|
||||
/***** unused (standard alphabet)
|
||||
private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset) {
|
||||
// 1 2 3
|
||||
// 01234567890123456789012345678901 Bit position
|
||||
@@ -329,7 +357,11 @@ public class Base64 {
|
||||
return destination;
|
||||
} // end switch
|
||||
} // end encode3to4
|
||||
******/
|
||||
|
||||
/**
|
||||
* @param alpha alphabet
|
||||
*/
|
||||
private static void encode3to4(byte[] source, int srcOffset, int numSigBytes, StringBuilder buf, byte alpha[]) {
|
||||
// 1 2 3
|
||||
// 01234567890123456789012345678901 Bit position
|
||||
@@ -628,7 +660,7 @@ public class Base64 {
|
||||
* Decodes data from Base64 notation.
|
||||
*
|
||||
* @param s the string to decode
|
||||
* @return the decoded data
|
||||
* @return the decoded data, null on error
|
||||
* @since 1.4
|
||||
*/
|
||||
private static byte[] standardDecode(String s) {
|
||||
@@ -647,6 +679,7 @@ public class Base64 {
|
||||
* @param s the strind to decode
|
||||
* @return The data as a string
|
||||
* @since 1.4
|
||||
* @throws NPE on error?
|
||||
*/
|
||||
public static String decodeToString(String s) {
|
||||
return new String(decode(s));
|
||||
@@ -659,7 +692,7 @@ public class Base64 {
|
||||
* @param source The Base64 encoded data
|
||||
* @param off The offset of where to begin decoding
|
||||
* @param len The length of characters to decode
|
||||
* @return decoded data
|
||||
* @return decoded data, null on error
|
||||
* @since 1.3
|
||||
*/
|
||||
private static byte[] decode(byte[] source, int off, int len) {
|
||||
|
||||
@@ -98,6 +98,10 @@ public class DataHelper {
|
||||
/**
|
||||
* 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.
|
||||
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
|
||||
* Keys and values must be 255 bytes or less,
|
||||
* Formatted length must not exceed 65535 bytes
|
||||
* @throws DataFormatException if either is too long.
|
||||
*
|
||||
* @param rawStream stream to write to
|
||||
* @param props properties to write out
|
||||
@@ -111,6 +115,11 @@ public class DataHelper {
|
||||
|
||||
/**
|
||||
* Writes the props to the stream, sorted by property name.
|
||||
* See readProperties() for the format.
|
||||
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
|
||||
* Keys and values must be 255 bytes or less,
|
||||
* Formatted length must not exceed 65535 bytes
|
||||
* @throws DataFormatException if either is too long.
|
||||
*
|
||||
* jrandom disabled UTF-8 in mid-2004, for performance reasons,
|
||||
* i.e. slow foo.getBytes("UTF-8")
|
||||
@@ -151,8 +160,19 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads the props from the byte array
|
||||
* @param props returned OrderedProperties (sorted by property name)
|
||||
* Writes the props to the byte array, sorted
|
||||
* See readProperties() for the format.
|
||||
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
|
||||
* Keys and values must be 255 bytes or less,
|
||||
* @throws DataFormatException if too long.
|
||||
* Formatted length must not exceed 65535 bytes
|
||||
* Should throw DataFormatException if too long but it doesn't.
|
||||
* Warning - confusing method name, Properties is the source.
|
||||
*
|
||||
* @deprecated unused
|
||||
*
|
||||
* @param target returned array as specified in data structure spec
|
||||
* @param props source
|
||||
* @return new offset
|
||||
*/
|
||||
public static int toProperties(byte target[], int offset, Properties props) throws DataFormatException, IOException {
|
||||
@@ -185,8 +205,14 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the props to the byte array, not sorted
|
||||
* (unless the target param is an OrderedProperties)
|
||||
* Reads the props from the byte array and puts them in the Properties target
|
||||
* See readProperties() for the format.
|
||||
* Warning - confusing method name, Properties is the target.
|
||||
*
|
||||
* @deprecated unused
|
||||
*
|
||||
* @param source source
|
||||
* @param target returned Properties
|
||||
* @return new offset
|
||||
*/
|
||||
public static int fromProperties(byte source[], int offset, Properties target) throws DataFormatException, IOException {
|
||||
@@ -214,6 +240,15 @@ public class DataHelper {
|
||||
/**
|
||||
* Writes the props to returned byte array, not sorted
|
||||
* (unless the opts param is an OrderedProperties)
|
||||
* See readProperties() for the format.
|
||||
* Property keys and values must not contain '=' or ';', this is not checked and they are not escaped
|
||||
* Keys and values must be 255 bytes or less,
|
||||
* Formatted length must not exceed 65535 bytes
|
||||
* Warning - confusing method name, Properties is the source.
|
||||
*
|
||||
* @deprecated unused
|
||||
*
|
||||
* @throws RuntimeException if either is too long.
|
||||
*/
|
||||
public static byte[] toProperties(Properties opts) {
|
||||
try {
|
||||
@@ -605,6 +640,7 @@ public class DataHelper {
|
||||
* @throws DataFormatException if the boolean is not valid
|
||||
* @throws IOException if there is an IO error reading the boolean
|
||||
* @return boolean value, or null
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static Boolean readBoolean(InputStream in) throws DataFormatException, IOException {
|
||||
int val = (int) readLong(in, 1);
|
||||
@@ -627,6 +663,7 @@ public class DataHelper {
|
||||
* @param bool boolean value, or null
|
||||
* @throws DataFormatException if the boolean is not valid
|
||||
* @throws IOException if there is an IO error writing the boolean
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static void writeBoolean(OutputStream out, Boolean bool)
|
||||
throws DataFormatException, IOException {
|
||||
@@ -638,6 +675,7 @@ public class DataHelper {
|
||||
writeLong(out, 1, BOOLEAN_FALSE);
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
public static Boolean fromBoolean(byte data[], int offset) {
|
||||
if (data[offset] == BOOLEAN_TRUE)
|
||||
return Boolean.TRUE;
|
||||
@@ -647,9 +685,12 @@ public class DataHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
public static void toBoolean(byte data[], int offset, boolean value) {
|
||||
data[offset] = (value ? BOOLEAN_TRUE : BOOLEAN_FALSE);
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
public static void toBoolean(byte data[], int offset, Boolean value) {
|
||||
if (value == null)
|
||||
data[offset] = BOOLEAN_UNKNOWN;
|
||||
@@ -657,9 +698,13 @@ public class DataHelper {
|
||||
data[offset] = (value.booleanValue() ? BOOLEAN_TRUE : BOOLEAN_FALSE);
|
||||
}
|
||||
|
||||
/** deprecated - used only in DatabaseLookupMessage */
|
||||
public static final byte BOOLEAN_TRUE = 0x1;
|
||||
/** deprecated - used only in DatabaseLookupMessage */
|
||||
public static final byte BOOLEAN_FALSE = 0x0;
|
||||
/** @deprecated unused */
|
||||
public static final byte BOOLEAN_UNKNOWN = 0x2;
|
||||
/** @deprecated unused */
|
||||
public static final int BOOLEAN_LENGTH = 1;
|
||||
|
||||
//
|
||||
@@ -830,14 +875,14 @@ public class DataHelper {
|
||||
*/
|
||||
public static int hashCode(byte b[]) {
|
||||
// Java 5 now has its own method, and the old way
|
||||
// is horrible for arrays smaller than 32.
|
||||
// was horrible for arrays much smaller than 32.
|
||||
// otoh, for sizes >> 32, java's method may be too slow
|
||||
int rv = 0;
|
||||
if (b != null) {
|
||||
if (b.length <= 32) {
|
||||
rv = Arrays.hashCode(b);
|
||||
} else {
|
||||
for (int i = 0; i < b.length && i < 32; i++)
|
||||
for (int i = 0; i < 32; i++)
|
||||
rv ^= (b[i] << i); // xor better than + in tests
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public class Hash extends DataStructureImpl {
|
||||
public Hash() {
|
||||
}
|
||||
|
||||
/** @throws IllegalArgumentException if data is not 32 bytes (null is ok) */
|
||||
public Hash(byte data[]) {
|
||||
setData(data);
|
||||
}
|
||||
@@ -39,7 +40,10 @@ public class Hash extends DataStructureImpl {
|
||||
return _data;
|
||||
}
|
||||
|
||||
/** @throws IllegalArgumentException if data is not 32 bytes (null is ok) */
|
||||
public void setData(byte[] data) {
|
||||
if (data != null && data.length != HASH_LENGTH)
|
||||
throw new IllegalArgumentException("Hash must be 32 bytes");
|
||||
_data = data;
|
||||
_stringified = null;
|
||||
_base64ed = null;
|
||||
|
||||
@@ -14,8 +14,11 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.util.OrderedProperties;
|
||||
|
||||
/**
|
||||
* Defines a method of communicating with a router
|
||||
*
|
||||
@@ -28,7 +31,7 @@ public class RouterAddress extends DataStructureImpl {
|
||||
private Properties _options;
|
||||
|
||||
public RouterAddress() {
|
||||
setCost(-1);
|
||||
_cost = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,18 +137,27 @@ public class RouterAddress extends DataStructureImpl {
|
||||
return DataHelper.hashCode(_transportStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used on peers.jsp so sort options so it looks better.
|
||||
* We don't just use OrderedProperties for _options because DataHelper.writeProperties()
|
||||
* sorts also.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("[RouterAddress: ");
|
||||
buf.append("\n\tTransportStyle: ").append(getTransportStyle());
|
||||
buf.append("\n\tCost: ").append(getCost());
|
||||
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 val = getOptions().getProperty(key);
|
||||
buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
|
||||
buf.append("\n\tTransportStyle: ").append(_transportStyle);
|
||||
buf.append("\n\tCost: ").append(_cost);
|
||||
buf.append("\n\tExpiration: ").append(_expiration);
|
||||
if (_options != null) {
|
||||
buf.append("\n\tOptions: #: ").append(_options.size());
|
||||
Properties p = new OrderedProperties();
|
||||
p.putAll(_options);
|
||||
for (Map.Entry e : p.entrySet()) {
|
||||
String key = (String) e.getKey();
|
||||
String val = (String) e.getValue();
|
||||
buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
|
||||
}
|
||||
}
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
|
||||
@@ -49,16 +49,16 @@ public class AbuseReason extends DataStructureImpl {
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if ((object == null) || !(object instanceof AbuseReason)) return false;
|
||||
return DataHelper.eq(getReason(), ((AbuseReason) object).getReason());
|
||||
return DataHelper.eq(_reason, ((AbuseReason) object).getReason());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return DataHelper.hashCode(getReason());
|
||||
return DataHelper.hashCode(_reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[AbuseReason: " + getReason() + "]";
|
||||
return "[AbuseReason: " + _reason + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class AbuseSeverity extends DataStructureImpl {
|
||||
private int _severityId;
|
||||
|
||||
public AbuseSeverity() {
|
||||
setSeverity(-1);
|
||||
_severityId = -1;
|
||||
}
|
||||
|
||||
public int getSeverity() {
|
||||
@@ -56,11 +56,11 @@ public class AbuseSeverity extends DataStructureImpl {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getSeverity();
|
||||
return _severityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[AbuseSeverity: " + getSeverity() + "]";
|
||||
return "[AbuseSeverity: " + _severityId + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ public class CreateSessionMessage extends I2CPMessageImpl {
|
||||
private SessionConfig _sessionConfig;
|
||||
|
||||
public CreateSessionMessage(SessionConfig config) {
|
||||
setSessionConfig(config);
|
||||
_sessionConfig = config;
|
||||
}
|
||||
|
||||
public CreateSessionMessage() {
|
||||
setSessionConfig(new SessionConfig());
|
||||
_sessionConfig = new SessionConfig();
|
||||
}
|
||||
|
||||
public SessionConfig getSessionConfig() {
|
||||
@@ -75,7 +75,7 @@ public class CreateSessionMessage extends I2CPMessageImpl {
|
||||
public boolean equals(Object object) {
|
||||
if ((object != null) && (object instanceof CreateSessionMessage)) {
|
||||
CreateSessionMessage msg = (CreateSessionMessage) object;
|
||||
return DataHelper.eq(getSessionConfig(), msg.getSessionConfig());
|
||||
return DataHelper.eq(_sessionConfig, msg.getSessionConfig());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -85,7 +85,7 @@ public class CreateSessionMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[CreateSessionMessage: ");
|
||||
buf.append("\n\tConfig: ").append(getSessionConfig());
|
||||
buf.append("\n\tConfig: ").append(_sessionConfig);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class DestroySessionMessage extends I2CPMessageImpl {
|
||||
public boolean equals(Object object) {
|
||||
if ((object != null) && (object instanceof DestroySessionMessage)) {
|
||||
DestroySessionMessage msg = (DestroySessionMessage) object;
|
||||
return DataHelper.eq(getSessionId(), msg.getSessionId());
|
||||
return DataHelper.eq(_sessionId, msg.getSessionId());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -86,7 +86,7 @@ public class DestroySessionMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[DestroySessionMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class I2CPMessageHandler {
|
||||
try {
|
||||
if (length < 0) throw new I2CPMessageException("Invalid message length specified");
|
||||
int type = (int) DataHelper.readLong(in, 1);
|
||||
I2CPMessage msg = createMessage(in, length, type);
|
||||
I2CPMessage msg = createMessage(type);
|
||||
msg.readMessage(in, length, type);
|
||||
return msg;
|
||||
} catch (DataFormatException dfe) {
|
||||
@@ -53,8 +53,8 @@ public class I2CPMessageHandler {
|
||||
* 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(int type) throws IOException,
|
||||
I2CPMessageException {
|
||||
switch (type) {
|
||||
case CreateLeaseSetMessage.MESSAGE_TYPE:
|
||||
return new CreateLeaseSetMessage();
|
||||
@@ -101,6 +101,7 @@ public class I2CPMessageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
public static void main(String args[]) {
|
||||
try {
|
||||
I2CPMessage msg = readMessage(new FileInputStream(args[0]));
|
||||
@@ -109,4 +110,5 @@ public class I2CPMessageHandler {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
***/
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ public class MessageId extends DataStructureImpl {
|
||||
private long _messageId;
|
||||
|
||||
public MessageId() {
|
||||
setMessageId(-1);
|
||||
_messageId = -1;
|
||||
}
|
||||
public MessageId(long id) {
|
||||
setMessageId(id);
|
||||
_messageId = id;
|
||||
}
|
||||
|
||||
public long getMessageId() {
|
||||
@@ -58,11 +58,11 @@ public class MessageId extends DataStructureImpl {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int)getMessageId();
|
||||
return (int)_messageId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[MessageId: " + getMessageId() + "]";
|
||||
return "[MessageId: " + _messageId + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ public class MessagePayloadMessage extends I2CPMessageImpl {
|
||||
private Payload _payload;
|
||||
|
||||
public MessagePayloadMessage() {
|
||||
setSessionId(-1);
|
||||
setMessageId(-1);
|
||||
_sessionId = -1;
|
||||
_messageId = -1;
|
||||
}
|
||||
|
||||
public long getSessionId() {
|
||||
@@ -113,7 +113,7 @@ public class MessagePayloadMessage extends I2CPMessageImpl {
|
||||
MessagePayloadMessage msg = (MessagePayloadMessage) object;
|
||||
return _sessionId == msg.getSessionId()
|
||||
&& _messageId == msg.getMessageId()
|
||||
&& DataHelper.eq(getPayload(), msg.getPayload());
|
||||
&& DataHelper.eq(_payload, msg.getPayload());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -123,9 +123,9 @@ public class MessagePayloadMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[MessagePayloadMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tMessageId: ").append(getMessageId());
|
||||
buf.append("\n\tPayload: ").append(getPayload());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("\n\tMessageId: ").append(_messageId);
|
||||
buf.append("\n\tPayload: ").append(_payload);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -32,17 +32,19 @@ public class MessageStatusMessage extends I2CPMessageImpl {
|
||||
|
||||
public final static int STATUS_AVAILABLE = 0;
|
||||
public final static int STATUS_SEND_ACCEPTED = 1;
|
||||
/** unused */
|
||||
public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2;
|
||||
/** unused */
|
||||
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() {
|
||||
setSessionId(-1);
|
||||
setStatus(-1);
|
||||
setMessageId(-1);
|
||||
setSize(-1);
|
||||
setNonce(-1);
|
||||
_sessionId = -1;
|
||||
_status = -1;
|
||||
_messageId = -1;
|
||||
_size = -1;
|
||||
_nonce = -1;
|
||||
}
|
||||
|
||||
public long getSessionId() {
|
||||
@@ -169,11 +171,11 @@ public class MessageStatusMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[MessageStatusMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tNonce: ").append(getNonce());
|
||||
buf.append("\n\tMessageId: ").append(getMessageId());
|
||||
buf.append("\n\tStatus: ").append(getStatusString(getStatus()));
|
||||
buf.append("\n\tSize: ").append(getSize());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("\n\tNonce: ").append(_nonce);
|
||||
buf.append("\n\tMessageId: ").append(_messageId);
|
||||
buf.append("\n\tStatus: ").append(getStatusString(_status));
|
||||
buf.append("\n\tSize: ").append(_size);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl {
|
||||
private long _messageId;
|
||||
|
||||
public ReceiveMessageBeginMessage() {
|
||||
setSessionId(-1);
|
||||
setMessageId(-1);
|
||||
_sessionId = -1;
|
||||
_messageId = -1;
|
||||
}
|
||||
|
||||
public long getSessionId() {
|
||||
@@ -103,8 +103,8 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[ReceiveMessageBeginMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tMessageId: ").append(getMessageId());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("\n\tMessageId: ").append(_messageId);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl {
|
||||
private long _messageId;
|
||||
|
||||
public ReceiveMessageEndMessage() {
|
||||
setSessionId(-1);
|
||||
setMessageId(-1);
|
||||
_sessionId = -1;
|
||||
_messageId = -1;
|
||||
}
|
||||
|
||||
public long getSessionId() {
|
||||
@@ -87,8 +87,8 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[ReceiveMessageEndMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tMessageId: ").append(getMessageId());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("\n\tMessageId: ").append(_messageId);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ public class ReconfigureSessionMessage extends I2CPMessageImpl {
|
||||
public boolean equals(Object object) {
|
||||
if ((object != null) && (object instanceof ReconfigureSessionMessage)) {
|
||||
ReconfigureSessionMessage msg = (ReconfigureSessionMessage) object;
|
||||
return DataHelper.eq(getSessionId(), msg.getSessionId())
|
||||
&& DataHelper.eq(getSessionConfig(), msg.getSessionConfig());
|
||||
return DataHelper.eq(_sessionId, msg.getSessionId())
|
||||
&& DataHelper.eq(_sessionConfig, msg.getSessionConfig());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -92,8 +92,8 @@ public class ReconfigureSessionMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[ReconfigureSessionMessage: ");
|
||||
buf.append("\n\tSessionId: ").append(getSessionId());
|
||||
buf.append("\n\tSessionConfig: ").append(getSessionConfig());
|
||||
buf.append("\n\tSessionId: ").append(_sessionId);
|
||||
buf.append("\n\tSessionConfig: ").append(_sessionConfig);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import net.i2p.data.TunnelId;
|
||||
public class RequestLeaseSetMessage extends I2CPMessageImpl {
|
||||
public final static int MESSAGE_TYPE = 21;
|
||||
private SessionId _sessionId;
|
||||
private List _endpoints;
|
||||
private List<TunnelEndpoint> _endpoints;
|
||||
private Date _end;
|
||||
|
||||
public RequestLeaseSetMessage() {
|
||||
@@ -51,12 +51,12 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl {
|
||||
|
||||
public Hash getRouter(int endpoint) {
|
||||
if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null;
|
||||
return ((TunnelEndpoint) _endpoints.get(endpoint)).getRouter();
|
||||
return _endpoints.get(endpoint).getRouter();
|
||||
}
|
||||
|
||||
public TunnelId getTunnelId(int endpoint) {
|
||||
if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null;
|
||||
return ((TunnelEndpoint) _endpoints.get(endpoint)).getTunnelId();
|
||||
return _endpoints.get(endpoint).getTunnelId();
|
||||
}
|
||||
|
||||
/** @deprecated unused - presumably he meant remove? */
|
||||
@@ -159,8 +159,6 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl {
|
||||
private TunnelId _tunnelId;
|
||||
|
||||
public TunnelEndpoint() {
|
||||
_router = null;
|
||||
_tunnelId = null;
|
||||
}
|
||||
|
||||
public TunnelEndpoint(Hash router, TunnelId id) {
|
||||
|
||||
@@ -168,8 +168,8 @@ public class SessionConfig extends DataStructureImpl {
|
||||
|
||||
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, true); // UTF-8
|
||||
DataHelper.writeDate(out, _creationDate);
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SessionId extends DataStructureImpl {
|
||||
private int _sessionId;
|
||||
|
||||
public SessionId() {
|
||||
setSessionId(-1);
|
||||
_sessionId = -1;
|
||||
}
|
||||
|
||||
public int getSessionId() {
|
||||
@@ -49,16 +49,16 @@ public class SessionId extends DataStructureImpl {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj == null) || !(obj instanceof SessionId)) return false;
|
||||
return getSessionId() == ((SessionId) obj).getSessionId();
|
||||
return _sessionId == ((SessionId) obj).getSessionId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getSessionId();
|
||||
return _sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[SessionId: " + getSessionId() + "]";
|
||||
return "[SessionId: " + _sessionId + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class SetDateMessage extends I2CPMessageImpl {
|
||||
|
||||
public SetDateMessage() {
|
||||
super();
|
||||
setDate(new Date(Clock.getInstance().now()));
|
||||
_date = new Date(Clock.getInstance().now());
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
@@ -70,7 +70,7 @@ public class SetDateMessage extends I2CPMessageImpl {
|
||||
public boolean equals(Object object) {
|
||||
if ((object != null) && (object instanceof SetDateMessage)) {
|
||||
SetDateMessage msg = (SetDateMessage) object;
|
||||
return DataHelper.eq(getDate(), msg.getDate());
|
||||
return DataHelper.eq(_date, msg.getDate());
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -80,7 +80,7 @@ public class SetDateMessage extends I2CPMessageImpl {
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[SetDateMessage");
|
||||
buf.append("\n\tDate: ").append(getDate());
|
||||
buf.append("\n\tDate: ").append(_date);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.Set;
|
||||
* public Object waitEventValue(String n) { return _event.waitEventValue(n); }
|
||||
* </code>
|
||||
*
|
||||
* Deprecated - Used only by I2PTunnel
|
||||
*
|
||||
* @author human
|
||||
*/
|
||||
public interface EventDispatcher {
|
||||
@@ -101,4 +103,4 @@ public interface EventDispatcher {
|
||||
* @return value specified for that event
|
||||
*/
|
||||
public Object waitEventValue(String name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.Set;
|
||||
* each object it is used by, ala:
|
||||
* <code>private final EventDispatcher _event = new EventDispatcher();</code>
|
||||
*
|
||||
* Deprecated - Used only by I2PTunnel
|
||||
*
|
||||
* If there is anything in here that doesn't make sense, turn off
|
||||
* your computer and go fly a kite - (c) 2004 by jrandom
|
||||
|
||||
@@ -32,10 +34,10 @@ import java.util.Set;
|
||||
*/
|
||||
public class EventDispatcherImpl implements EventDispatcher {
|
||||
|
||||
private final static Log _log = new Log(EventDispatcherImpl.class);
|
||||
//private final static Log _log = new Log(EventDispatcherImpl.class);
|
||||
|
||||
private boolean _ignore = false;
|
||||
private /* FIXME final FIXME */ HashMap _events = new HashMap(4);
|
||||
private final HashMap _events = new HashMap(4);
|
||||
private final ArrayList _attached = new ArrayList();
|
||||
|
||||
public EventDispatcher getEventDispatcher() {
|
||||
@@ -45,7 +47,7 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
public void attachEventDispatcher(EventDispatcher ev) {
|
||||
if (ev == null) return;
|
||||
synchronized (_attached) {
|
||||
_log.debug(this.hashCode() + ": attaching EventDispatcher " + ev.hashCode());
|
||||
//_log.debug(this.hashCode() + ": attaching EventDispatcher " + ev.hashCode());
|
||||
_attached.add(ev);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +70,7 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
if (args == null) {
|
||||
args = "[null value]";
|
||||
}
|
||||
_log.debug(this.hashCode() + ": got notification [" + eventName + "] = [" + args + "]");
|
||||
//_log.debug(this.hashCode() + ": got notification [" + eventName + "] = [" + args + "]");
|
||||
synchronized (_events) {
|
||||
_events.put(eventName, args);
|
||||
_events.notifyAll();
|
||||
@@ -77,8 +79,8 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
EventDispatcher e;
|
||||
while (it.hasNext()) {
|
||||
e = (EventDispatcher) it.next();
|
||||
_log.debug(this.hashCode() + ": notifying attached EventDispatcher " + e.hashCode() + ": ["
|
||||
+ eventName + "] = [" + args + "]");
|
||||
//_log.debug(this.hashCode() + ": notifying attached EventDispatcher " + e.hashCode() + ": ["
|
||||
// + eventName + "] = [" + args + "]");
|
||||
e.notifyEvent(eventName, args);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +114,6 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
synchronized (_events) {
|
||||
_events.clear();
|
||||
}
|
||||
_events = null;
|
||||
}
|
||||
|
||||
public void unIgnoreEvents() {
|
||||
@@ -123,7 +124,7 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
if (_ignore) return null;
|
||||
Object val;
|
||||
|
||||
_log.debug(this.hashCode() + ": waiting for [" + name + "]");
|
||||
//_log.debug(this.hashCode() + ": waiting for [" + name + "]");
|
||||
do {
|
||||
synchronized (_events) {
|
||||
if (_events.containsKey(name)) {
|
||||
@@ -139,4 +140,4 @@ public class EventDispatcherImpl implements EventDispatcher {
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import net.i2p.I2PAppContext;
|
||||
*/
|
||||
public class LogConsoleBuffer {
|
||||
private I2PAppContext _context;
|
||||
private final List _buffer;
|
||||
private final List _critBuffer;
|
||||
private final List<String> _buffer;
|
||||
private final List<String> _critBuffer;
|
||||
|
||||
public LogConsoleBuffer(I2PAppContext context) {
|
||||
_context = context;
|
||||
@@ -43,7 +43,7 @@ public class LogConsoleBuffer {
|
||||
* in the logs)
|
||||
*
|
||||
*/
|
||||
public List getMostRecentMessages() {
|
||||
public List<String> getMostRecentMessages() {
|
||||
synchronized (_buffer) {
|
||||
return new ArrayList(_buffer);
|
||||
}
|
||||
@@ -54,9 +54,9 @@ public class LogConsoleBuffer {
|
||||
* in the logs)
|
||||
*
|
||||
*/
|
||||
public List getMostRecentCriticalMessages() {
|
||||
public List<String> getMostRecentCriticalMessages() {
|
||||
synchronized (_critBuffer) {
|
||||
return new ArrayList(_critBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user