2004-10-16 jrandom
* More aggressively fail peers if their tunnels are failing so that we move off them quicker. * Simplify some data structure serialization for reuse in the streaming lib, as well as add support for signing and verifying partial byte arrays. * Logging updates
This commit is contained in:
@ -50,8 +50,10 @@ public class DSAEngine {
|
|||||||
public static DSAEngine getInstance() {
|
public static DSAEngine getInstance() {
|
||||||
return I2PAppContext.getGlobalContext().dsa();
|
return I2PAppContext.getGlobalContext().dsa();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verifySignature(Signature signature, byte signedData[], SigningPublicKey verifyingKey) {
|
public boolean verifySignature(Signature signature, byte signedData[], SigningPublicKey verifyingKey) {
|
||||||
|
return verifySignature(signature, signedData, 0, signedData.length, verifyingKey);
|
||||||
|
}
|
||||||
|
public boolean verifySignature(Signature signature, byte signedData[], int offset, int size, SigningPublicKey verifyingKey) {
|
||||||
long start = _context.clock().now();
|
long start = _context.clock().now();
|
||||||
|
|
||||||
byte[] sigbytes = signature.getData();
|
byte[] sigbytes = signature.getData();
|
||||||
@ -68,7 +70,7 @@ public class DSAEngine {
|
|||||||
BigInteger r = new NativeBigInteger(1, rbytes);
|
BigInteger r = new NativeBigInteger(1, rbytes);
|
||||||
BigInteger y = new NativeBigInteger(1, verifyingKey.getData());
|
BigInteger y = new NativeBigInteger(1, verifyingKey.getData());
|
||||||
BigInteger w = s.modInverse(CryptoConstants.dsaq);
|
BigInteger w = s.modInverse(CryptoConstants.dsaq);
|
||||||
byte data[] = calculateHash(signedData).getData();
|
byte data[] = calculateHash(signedData, offset, size).getData();
|
||||||
NativeBigInteger bi = new NativeBigInteger(1, data);
|
NativeBigInteger bi = new NativeBigInteger(1, data);
|
||||||
BigInteger u1 = bi.multiply(w).mod(CryptoConstants.dsaq);
|
BigInteger u1 = bi.multiply(w).mod(CryptoConstants.dsaq);
|
||||||
BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq);
|
BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq);
|
||||||
@ -88,6 +90,9 @@ public class DSAEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Signature sign(byte data[], SigningPrivateKey signingKey) {
|
public Signature sign(byte data[], SigningPrivateKey signingKey) {
|
||||||
|
return sign(data, 0, data.length, signingKey);
|
||||||
|
}
|
||||||
|
public Signature sign(byte data[], int offset, int length, SigningPrivateKey signingKey) {
|
||||||
if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
|
if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
|
||||||
long start = _context.clock().now();
|
long start = _context.clock().now();
|
||||||
|
|
||||||
@ -100,7 +105,7 @@ public class DSAEngine {
|
|||||||
|
|
||||||
BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq);
|
BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq);
|
||||||
BigInteger kinv = k.modInverse(CryptoConstants.dsaq);
|
BigInteger kinv = k.modInverse(CryptoConstants.dsaq);
|
||||||
Hash h = calculateHash(data);
|
Hash h = calculateHash(data, offset, length);
|
||||||
|
|
||||||
if (h == null) return null;
|
if (h == null) return null;
|
||||||
|
|
||||||
@ -150,42 +155,42 @@ public class DSAEngine {
|
|||||||
|
|
||||||
private int[] H0 = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
|
private int[] H0 = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
|
||||||
|
|
||||||
private Hash calculateHash(byte[] source) {
|
private Hash calculateHash(byte[] source, int offset, int len) {
|
||||||
long length = source.length * 8;
|
long length = len * 8;
|
||||||
int k = 448 - (int) ((length + 1) % 512);
|
int k = 448 - (int) ((length + 1) % 512);
|
||||||
if (k < 0) {
|
if (k < 0) {
|
||||||
k += 512;
|
k += 512;
|
||||||
}
|
}
|
||||||
int padbytes = k / 8;
|
int padbytes = k / 8;
|
||||||
int wordlength = source.length / 4 + padbytes / 4 + 3;
|
int wordlength = len / 4 + padbytes / 4 + 3;
|
||||||
int[] M0 = new int[wordlength];
|
int[] M0 = new int[wordlength];
|
||||||
int wordcount = 0;
|
int wordcount = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
for (x = 0; x < (source.length / 4) * 4; x += 4) {
|
for (x = 0; x < (len / 4) * 4; x += 4) {
|
||||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||||
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
|
M0[wordcount] |= source[offset + x + 2] << 24 >>> 24 << 8;
|
||||||
M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0;
|
M0[wordcount] |= source[offset + x + 3] << 24 >>> 24 << 0;
|
||||||
wordcount++;
|
wordcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (source.length - (wordcount + 1) * 4 + 4) {
|
switch (len - (wordcount + 1) * 4 + 4) {
|
||||||
case 0:
|
case 0:
|
||||||
M0[wordcount] |= 0x80000000;
|
M0[wordcount] |= 0x80000000;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||||
M0[wordcount] |= 0x00800000;
|
M0[wordcount] |= 0x00800000;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||||
M0[wordcount] |= 0x00008000;
|
M0[wordcount] |= 0x00008000;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||||
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
|
M0[wordcount] |= source[offset + x + 2] << 24 >>> 24 << 8;
|
||||||
M0[wordcount] |= 0x00000080;
|
M0[wordcount] |= 0x00000080;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,41 @@ public class Certificate extends DataStructureImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int writeBytes(byte target[], int offset) {
|
||||||
|
int cur = offset;
|
||||||
|
DataHelper.toLong(target, cur, 1, _type);
|
||||||
|
cur++;
|
||||||
|
if (_payload != null) {
|
||||||
|
DataHelper.toLong(target, cur, 2, _payload.length);
|
||||||
|
cur += 2;
|
||||||
|
System.arraycopy(_payload, 0, target, cur, _payload.length);
|
||||||
|
cur += _payload.length;
|
||||||
|
} else {
|
||||||
|
DataHelper.toLong(target, cur, 2, 0);
|
||||||
|
cur += 2;
|
||||||
|
}
|
||||||
|
return cur - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readBytes(byte source[], int offset) {
|
||||||
|
int cur = offset;
|
||||||
|
_type = (int)DataHelper.fromLong(source, cur, 1);
|
||||||
|
cur++;
|
||||||
|
int length = (int)DataHelper.fromLong(source, cur, 2);
|
||||||
|
cur += 2;
|
||||||
|
if (length > 0) {
|
||||||
|
_payload = new byte[length];
|
||||||
|
System.arraycopy(source, cur, _payload, 0, length);
|
||||||
|
cur += length;
|
||||||
|
}
|
||||||
|
return cur - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return 1 + 2 + (_payload != null ? _payload.length : 0);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if ((object == null) || !(object instanceof Certificate)) return false;
|
if ((object == null) || !(object instanceof Certificate)) return false;
|
||||||
Certificate cert = (Certificate) object;
|
Certificate cert = (Certificate) object;
|
||||||
|
@ -263,12 +263,16 @@ public class DataHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] toLong(int numBytes, long value) throws IllegalArgumentException {
|
public static byte[] toLong(int numBytes, long value) throws IllegalArgumentException {
|
||||||
|
byte val[] = new byte[numBytes];
|
||||||
|
toLong(val, 0, numBytes, value);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void toLong(byte target[], int offset, int numBytes, long value) throws IllegalArgumentException {
|
||||||
if (numBytes <= 0) throw new IllegalArgumentException("Invalid number of bytes");
|
if (numBytes <= 0) throw new IllegalArgumentException("Invalid number of bytes");
|
||||||
if (value < 0) throw new IllegalArgumentException("Negative value not allowed");
|
if (value < 0) throw new IllegalArgumentException("Negative value not allowed");
|
||||||
byte val[] = new byte[numBytes];
|
|
||||||
for (int i = 0; i < numBytes; i++)
|
for (int i = 0; i < numBytes; i++)
|
||||||
val[numBytes-i-1] = (byte)(value >>> (i*8));
|
target[offset+numBytes-i-1] = (byte)(value >>> (i*8));
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long fromLong(byte src[], int offset, int numBytes) {
|
public static long fromLong(byte src[], int offset, int numBytes) {
|
||||||
|
@ -80,6 +80,40 @@ public class Destination extends DataStructureImpl {
|
|||||||
_certificate.writeBytes(out);
|
_certificate.writeBytes(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int writeBytes(byte target[], int offset) {
|
||||||
|
int cur = offset;
|
||||||
|
System.arraycopy(_publicKey.getData(), 0, target, cur, PublicKey.KEYSIZE_BYTES);
|
||||||
|
cur += PublicKey.KEYSIZE_BYTES;
|
||||||
|
System.arraycopy(_signingKey.getData(), 0, target, cur, SigningPublicKey.KEYSIZE_BYTES);
|
||||||
|
cur += SigningPublicKey.KEYSIZE_BYTES;
|
||||||
|
cur += _certificate.writeBytes(target, cur);
|
||||||
|
return cur - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readBytes(byte source[], int offset) {
|
||||||
|
int cur = offset;
|
||||||
|
|
||||||
|
_publicKey = new PublicKey();
|
||||||
|
byte buf[] = new byte[PublicKey.KEYSIZE_BYTES];
|
||||||
|
System.arraycopy(source, cur, buf, 0, PublicKey.KEYSIZE_BYTES);
|
||||||
|
_publicKey.setData(buf);
|
||||||
|
cur += PublicKey.KEYSIZE_BYTES;
|
||||||
|
|
||||||
|
_signingKey = new SigningPublicKey();
|
||||||
|
buf = new byte[SigningPublicKey.KEYSIZE_BYTES];
|
||||||
|
System.arraycopy(source, cur, buf, 0, SigningPublicKey.KEYSIZE_BYTES);
|
||||||
|
cur += SigningPublicKey.KEYSIZE_BYTES;
|
||||||
|
|
||||||
|
_certificate = new Certificate();
|
||||||
|
cur += _certificate.readBytes(buf, cur);
|
||||||
|
|
||||||
|
return cur - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return PublicKey.KEYSIZE_BYTES + SigningPublicKey.KEYSIZE_BYTES + _certificate.size();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if ((object == null) || !(object instanceof Destination)) return false;
|
if ((object == null) || !(object instanceof Destination)) return false;
|
||||||
Destination dst = (Destination) object;
|
Destination dst = (Destination) object;
|
||||||
|
10
history.txt
10
history.txt
@ -1,4 +1,12 @@
|
|||||||
$Id: history.txt,v 1.49 2004/10/15 12:39:19 jrandom Exp $
|
$Id: history.txt,v 1.50 2004/10/16 13:00:47 jrandom Exp $
|
||||||
|
|
||||||
|
2004-10-16 jrandom
|
||||||
|
* More aggressively fail peers if their tunnels are failing so that we
|
||||||
|
move off them quicker.
|
||||||
|
* Simplify some data structure serialization for reuse in the streaming
|
||||||
|
lib, as well as add support for signing and verifying partial byte
|
||||||
|
arrays.
|
||||||
|
* Logging updates
|
||||||
|
|
||||||
2004-10-16 jrandom
|
2004-10-16 jrandom
|
||||||
* Increased the default minimum tunnel test time to 5 seconds, since we
|
* Increased the default minimum tunnel test time to 5 seconds, since we
|
||||||
|
@ -302,6 +302,19 @@ public class JobQueue {
|
|||||||
}
|
}
|
||||||
return when;
|
return when;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* When did the most recently begin job start?
|
||||||
|
*/
|
||||||
|
public long getLastJobEnd() {
|
||||||
|
long when = -1;
|
||||||
|
// not synchronized, so might b0rk if the runners are changed
|
||||||
|
for (Iterator iter = _queueRunners.values().iterator(); iter.hasNext(); ) {
|
||||||
|
long cur = ((JobQueueRunner)iter.next()).getLastEnd();
|
||||||
|
if (cur > when)
|
||||||
|
cur = when;
|
||||||
|
}
|
||||||
|
return when;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* retrieve the most recently begin and still currently active job, or null if
|
* retrieve the most recently begin and still currently active job, or null if
|
||||||
* no jobs are running
|
* no jobs are running
|
||||||
|
@ -12,6 +12,7 @@ class JobQueueRunner implements Runnable {
|
|||||||
private Job _currentJob;
|
private Job _currentJob;
|
||||||
private Job _lastJob;
|
private Job _lastJob;
|
||||||
private long _lastBegin;
|
private long _lastBegin;
|
||||||
|
private long _lastEnd;
|
||||||
|
|
||||||
public JobQueueRunner(RouterContext context, int id) {
|
public JobQueueRunner(RouterContext context, int id) {
|
||||||
_context = context;
|
_context = context;
|
||||||
@ -33,6 +34,7 @@ class JobQueueRunner implements Runnable {
|
|||||||
public void stopRunning() { _keepRunning = false; }
|
public void stopRunning() { _keepRunning = false; }
|
||||||
public void startRunning() { _keepRunning = true; }
|
public void startRunning() { _keepRunning = true; }
|
||||||
public long getLastBegin() { return _lastBegin; }
|
public long getLastBegin() { return _lastBegin; }
|
||||||
|
public long getLastEnd() { return _lastEnd; }
|
||||||
public void run() {
|
public void run() {
|
||||||
long lastActive = _context.clock().now();
|
long lastActive = _context.clock().now();
|
||||||
long jobNum = 0;
|
long jobNum = 0;
|
||||||
@ -88,6 +90,7 @@ class JobQueueRunner implements Runnable {
|
|||||||
lastActive = _context.clock().now();
|
lastActive = _context.clock().now();
|
||||||
_lastJob = _currentJob;
|
_lastJob = _currentJob;
|
||||||
_currentJob = null;
|
_currentJob = null;
|
||||||
|
_lastEnd = lastActive;
|
||||||
jobNum++;
|
jobNum++;
|
||||||
|
|
||||||
//if ( (jobNum % 10) == 0)
|
//if ( (jobNum % 10) == 0)
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.56 $ $Date: 2004/10/15 12:39:18 $";
|
public final static String ID = "$Revision: 1.57 $ $Date: 2004/10/16 13:00:47 $";
|
||||||
public final static String VERSION = "0.4.1.2";
|
public final static String VERSION = "0.4.1.2";
|
||||||
public final static long BUILD = 6;
|
public final static long BUILD = 7;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION);
|
System.out.println("I2P Router version: " + VERSION);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
@ -55,6 +55,12 @@ class RouterWatchdog implements Runnable {
|
|||||||
Job cur = _context.jobQueue().getLastJob();
|
Job cur = _context.jobQueue().getLastJob();
|
||||||
if (cur != null)
|
if (cur != null)
|
||||||
_log.error("Most recent job: " + cur);
|
_log.error("Most recent job: " + cur);
|
||||||
|
_log.error("Last job began: "
|
||||||
|
+ DataHelper.formatDuration(_context.clock().now()-_context.jobQueue().getLastJobBegin())
|
||||||
|
+ " ago");
|
||||||
|
_log.error("Last job ended: "
|
||||||
|
+ DataHelper.formatDuration(_context.clock().now()-_context.jobQueue().getLastJobEnd())
|
||||||
|
+ " ago");
|
||||||
_log.error("Ready and waiting jobs: " + _context.jobQueue().getReadyCount());
|
_log.error("Ready and waiting jobs: " + _context.jobQueue().getReadyCount());
|
||||||
_log.error("Job lag: " + _context.jobQueue().getMaxLag());
|
_log.error("Job lag: " + _context.jobQueue().getMaxLag());
|
||||||
_log.error("Participating tunnel count: " + _context.tunnelManager().getParticipatingCount());
|
_log.error("Participating tunnel count: " + _context.tunnelManager().getParticipatingCount());
|
||||||
|
@ -328,12 +328,12 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
buf.append("\n*Hop ").append(i).append(": ").append(cur.getThisHop());
|
buf.append("\n*Hop ").append(i).append(": ").append(cur.getThisHop());
|
||||||
if (cur.getEncryptionKey() != null)
|
//if (cur.getEncryptionKey() != null)
|
||||||
buf.append("\n Encryption key: ").append(cur.getEncryptionKey());
|
// buf.append("\n Encryption key: ").append(cur.getEncryptionKey());
|
||||||
if (cur.getSigningKey() != null)
|
//if (cur.getSigningKey() != null)
|
||||||
buf.append("\n Signing key: ").append(cur.getSigningKey());
|
// buf.append("\n Signing key: ").append(cur.getSigningKey());
|
||||||
if (cur.getVerificationKey() != null)
|
//if (cur.getVerificationKey() != null)
|
||||||
buf.append("\n Verification key: ").append(cur.getVerificationKey());
|
// buf.append("\n Verification key: ").append(cur.getVerificationKey());
|
||||||
if (cur.getDestination() != null)
|
if (cur.getDestination() != null)
|
||||||
buf.append("\n Destination: ").append(cur.getDestination().calculateHash().toBase64());
|
buf.append("\n Destination: ").append(cur.getDestination().calculateHash().toBase64());
|
||||||
if (cur.getNextHop() != null)
|
if (cur.getNextHop() != null)
|
||||||
@ -344,7 +344,7 @@ public class TunnelInfo extends DataStructureImpl {
|
|||||||
buf.append("\n Expiration: ").append("none");
|
buf.append("\n Expiration: ").append("none");
|
||||||
else
|
else
|
||||||
buf.append("\n Expiration: ").append(new Date(cur.getSettings().getExpiration()));
|
buf.append("\n Expiration: ").append(new Date(cur.getSettings().getExpiration()));
|
||||||
buf.append("\n Ready: ").append(getIsReady());
|
//buf.append("\n Ready: ").append(getIsReady());
|
||||||
cur = cur.getNextHopInfo();
|
cur = cur.getNextHopInfo();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,12 @@ public class CapacityCalculator extends Calculator {
|
|||||||
long failed = 0;
|
long failed = 0;
|
||||||
if (curFailed != null)
|
if (curFailed != null)
|
||||||
failed = curFailed.getCurrentEventCount() + curFailed.getLastEventCount();
|
failed = curFailed.getCurrentEventCount() + curFailed.getLastEventCount();
|
||||||
if (failed > 0)
|
if (failed > 0) {
|
||||||
val -= failed * stretch;
|
if ( (period == 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
|
||||||
|
return 0.0d; // their tunnels have failed in the last 0-10 minutes
|
||||||
|
else
|
||||||
|
val -= failed * stretch;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (period == 10*60*1000) && (curRejected.getCurrentEventCount() + curRejected.getLastEventCount() > 0) )
|
if ( (period == 10*60*1000) && (curRejected.getCurrentEventCount() + curRejected.getLastEventCount() > 0) )
|
||||||
return 0.0d;
|
return 0.0d;
|
||||||
|
Reference in New Issue
Block a user