mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Whitespace-only code formatting changes.
This commit is contained in:
@@ -26,15 +26,15 @@ class AuthenticatedCipherImpl implements AuthenticatedCipher {
|
||||
public int process(byte[] input, int inputOff, int len, byte[] output,
|
||||
int outputOff) throws GeneralSecurityException {
|
||||
int processed = 0;
|
||||
if(len != 0) {
|
||||
if (len != 0) {
|
||||
processed = cipher.processBytes(input, inputOff, len, output,
|
||||
outputOff);
|
||||
}
|
||||
try {
|
||||
return processed + cipher.doFinal(output, outputOff + processed);
|
||||
} catch(DataLengthException e) {
|
||||
} catch (DataLengthException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
} catch(InvalidCipherTextException e) {
|
||||
} catch (InvalidCipherTextException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class AuthenticatedCipherImpl implements AuthenticatedCipher {
|
||||
AEADParameters params = new AEADParameters(k, MAC_LENGTH * 8, iv, iv);
|
||||
try {
|
||||
cipher.init(encrypt, params);
|
||||
} catch(IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new GeneralSecurityException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,17 @@ class CombinedSecureRandom extends SecureRandom {
|
||||
private final SecureRandom[] randoms;
|
||||
|
||||
private CombinedSecureRandomSpi(SecureRandom... randoms) {
|
||||
if(randoms.length < 2) throw new IllegalArgumentException();
|
||||
if (randoms.length < 2) throw new IllegalArgumentException();
|
||||
this.randoms = randoms;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] engineGenerateSeed(int numBytes) {
|
||||
byte[] combined = new byte[numBytes];
|
||||
for(SecureRandom random : randoms) {
|
||||
for (SecureRandom random : randoms) {
|
||||
byte[] b = random.generateSeed(numBytes);
|
||||
int length = Math.min(numBytes, b.length);
|
||||
for(int i = 0; i < length; i++)
|
||||
for (int i = 0; i < length; i++)
|
||||
combined[i] = (byte) (combined[i] ^ b[i]);
|
||||
}
|
||||
return combined;
|
||||
@@ -43,16 +43,16 @@ class CombinedSecureRandom extends SecureRandom {
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] b) {
|
||||
byte[] temp = new byte[b.length];
|
||||
for(SecureRandom random : randoms) {
|
||||
for (SecureRandom random : randoms) {
|
||||
random.nextBytes(temp);
|
||||
for(int i = 0; i < b.length; i++)
|
||||
for (int i = 0; i < b.length; i++)
|
||||
b[i] = (byte) (b[i] ^ temp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineSetSeed(byte[] seed) {
|
||||
for(SecureRandom random : randoms) random.setSeed(seed);
|
||||
for (SecureRandom random : randoms) random.setSeed(seed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
@Inject
|
||||
CryptoComponentImpl(SeedProvider r) {
|
||||
if(!FortunaSecureRandom.selfTest()) throw new RuntimeException();
|
||||
if (!FortunaSecureRandom.selfTest()) throw new RuntimeException();
|
||||
SecureRandom secureRandom1 = new SecureRandom();
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String provider = secureRandom1.getProvider().getName();
|
||||
String algorithm = secureRandom1.getAlgorithm();
|
||||
LOG.info("Default SecureRandom: " + provider + " " + algorithm);
|
||||
@@ -168,7 +168,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public int[] deriveConfirmationCodes(byte[] secret) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] alice = counterModeKdf(secret, CODE, 0);
|
||||
byte[] bob = counterModeKdf(secret, CODE, 1);
|
||||
@@ -179,7 +179,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[][] deriveInvitationNonces(byte[] secret) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] alice = counterModeKdf(secret, NONCE, 0);
|
||||
byte[] bob = counterModeKdf(secret, NONCE, 1);
|
||||
@@ -193,7 +193,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
byte[] ourHash = messageDigest.digest(ourPublicKey);
|
||||
byte[] theirHash = messageDigest.digest(theirPublicKey);
|
||||
byte[] aliceInfo, bobInfo;
|
||||
if(alice) {
|
||||
if (alice) {
|
||||
aliceInfo = ourHash;
|
||||
bobInfo = theirHash;
|
||||
} else {
|
||||
@@ -212,9 +212,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
// Package access for testing
|
||||
byte[] deriveSharedSecret(PrivateKey priv, PublicKey pub)
|
||||
throws GeneralSecurityException {
|
||||
if(!(priv instanceof Sec1PrivateKey))
|
||||
if (!(priv instanceof Sec1PrivateKey))
|
||||
throw new IllegalArgumentException();
|
||||
if(!(pub instanceof Sec1PublicKey))
|
||||
if (!(pub instanceof Sec1PublicKey))
|
||||
throw new IllegalArgumentException();
|
||||
ECPrivateKeyParameters ecPriv = ((Sec1PrivateKey) priv).getKey();
|
||||
ECPublicKeyParameters ecPub = ((Sec1PublicKey) pub).getKey();
|
||||
@@ -223,46 +223,46 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
agreement.init(ecPriv);
|
||||
byte[] secret = agreement.calculateAgreement(ecPub).toByteArray();
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Deriving shared secret took " + duration + " ms");
|
||||
return secret;
|
||||
}
|
||||
|
||||
public byte[] deriveGroupSalt(byte[] secret) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
return counterModeKdf(secret, SALT, 0);
|
||||
}
|
||||
|
||||
public byte[] deriveInitialSecret(byte[] secret, int transportIndex) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(transportIndex < 0) throw new IllegalArgumentException();
|
||||
if (transportIndex < 0) throw new IllegalArgumentException();
|
||||
return counterModeKdf(secret, FIRST, transportIndex);
|
||||
}
|
||||
|
||||
public byte[] deriveNextSecret(byte[] secret, long period) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(period < 0 || period > MAX_32_BIT_UNSIGNED)
|
||||
if (period < 0 || period > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
return counterModeKdf(secret, ROTATE, period);
|
||||
}
|
||||
|
||||
public SecretKey deriveTagKey(byte[] secret, boolean alice) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(alice) return deriveKey(secret, A_TAG, 0);
|
||||
if (alice) return deriveKey(secret, A_TAG, 0);
|
||||
else return deriveKey(secret, B_TAG, 0);
|
||||
}
|
||||
|
||||
public SecretKey deriveFrameKey(byte[] secret, long streamNumber,
|
||||
boolean alice) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(streamNumber < 0 || streamNumber > MAX_32_BIT_UNSIGNED)
|
||||
if (streamNumber < 0 || streamNumber > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
if(alice) return deriveKey(secret, A_FRAME, streamNumber);
|
||||
if (alice) return deriveKey(secret, A_FRAME, streamNumber);
|
||||
else return deriveKey(secret, B_FRAME, streamNumber);
|
||||
}
|
||||
|
||||
@@ -271,10 +271,10 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public void encodeTag(byte[] tag, SecretKey tagKey, long streamNumber) {
|
||||
if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
|
||||
if(streamNumber < 0 || streamNumber > MAX_32_BIT_UNSIGNED)
|
||||
if (tag.length < TAG_LENGTH) throw new IllegalArgumentException();
|
||||
if (streamNumber < 0 || streamNumber > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
|
||||
for (int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
|
||||
ByteUtils.writeUint32(streamNumber, tag, 0);
|
||||
BlockCipher cipher = new AESLightEngine();
|
||||
assert cipher.getBlockSize() == TAG_LENGTH;
|
||||
@@ -308,7 +308,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
int outputOff = salt.length + 4 + iv.length;
|
||||
cipher.process(input, 0, input.length, output, outputOff);
|
||||
return output;
|
||||
} catch(GeneralSecurityException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -317,12 +317,12 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
AuthenticatedCipher cipher = new AuthenticatedCipherImpl();
|
||||
int macBytes = cipher.getMacBytes();
|
||||
// The input contains the salt, iterations, IV, ciphertext and MAC
|
||||
if(input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + macBytes)
|
||||
if (input.length < PBKDF_SALT_BYTES + 4 + STORAGE_IV_BYTES + macBytes)
|
||||
return null; // Invalid input
|
||||
byte[] salt = new byte[PBKDF_SALT_BYTES];
|
||||
System.arraycopy(input, 0, salt, 0, salt.length);
|
||||
long iterations = ByteUtils.readUint32(input, salt.length);
|
||||
if(iterations < 0 || iterations > Integer.MAX_VALUE)
|
||||
if (iterations < 0 || iterations > Integer.MAX_VALUE)
|
||||
return null; // Invalid iteration count
|
||||
byte[] iv = new byte[STORAGE_IV_BYTES];
|
||||
System.arraycopy(input, salt.length + 4, iv, 0, iv.length);
|
||||
@@ -331,7 +331,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
// Initialise the cipher
|
||||
try {
|
||||
cipher.init(false, key, iv);
|
||||
} catch(GeneralSecurityException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// Try to decrypt the ciphertext (may be invalid)
|
||||
@@ -341,7 +341,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
byte[] output = new byte[inputLen - macBytes];
|
||||
cipher.process(input, inputOff, inputLen, output, 0);
|
||||
return output;
|
||||
} catch(GeneralSecurityException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
return null; // Invalid ciphertext
|
||||
}
|
||||
}
|
||||
@@ -351,18 +351,18 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private byte[] concatenationKdf(byte[]... inputs) {
|
||||
// The output of the hash function must be long enough to use as a key
|
||||
MessageDigest messageDigest = getMessageDigest();
|
||||
if(messageDigest.getDigestLength() < SecretKey.LENGTH)
|
||||
if (messageDigest.getDigestLength() < SecretKey.LENGTH)
|
||||
throw new RuntimeException();
|
||||
// Each input is length-prefixed - the length must fit in an
|
||||
// unsigned 8-bit integer
|
||||
for(byte[] input : inputs) {
|
||||
if(input.length > 255) throw new IllegalArgumentException();
|
||||
for (byte[] input : inputs) {
|
||||
if (input.length > 255) throw new IllegalArgumentException();
|
||||
messageDigest.update((byte) input.length);
|
||||
messageDigest.update(input);
|
||||
}
|
||||
byte[] hash = messageDigest.digest();
|
||||
// The output is the first SecretKey.LENGTH bytes of the hash
|
||||
if(hash.length == SecretKey.LENGTH) return hash;
|
||||
if (hash.length == SecretKey.LENGTH) return hash;
|
||||
byte[] truncated = new byte[SecretKey.LENGTH];
|
||||
System.arraycopy(hash, 0, truncated, 0, truncated.length);
|
||||
return truncated;
|
||||
@@ -371,10 +371,10 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
// Key derivation function based on a PRF in counter mode - see
|
||||
// NIST SP 800-108, section 5.1
|
||||
private byte[] counterModeKdf(byte[] secret, byte[] label, long context) {
|
||||
if(secret.length != SecretKey.LENGTH)
|
||||
if (secret.length != SecretKey.LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
// The label must be null-terminated
|
||||
if(label[label.length - 1] != '\0')
|
||||
if (label[label.length - 1] != '\0')
|
||||
throw new IllegalArgumentException();
|
||||
// Initialise the PRF
|
||||
Mac prf = new HMac(new SHA256Digest());
|
||||
@@ -382,7 +382,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
prf.init(k);
|
||||
int macLength = prf.getMacSize();
|
||||
// The output of the PRF must be long enough to use as a key
|
||||
if(macLength < SecretKey.LENGTH) throw new RuntimeException();
|
||||
if (macLength < SecretKey.LENGTH) throw new RuntimeException();
|
||||
byte[] mac = new byte[macLength];
|
||||
prf.update((byte) 0); // Counter
|
||||
prf.update(label, 0, label.length); // Null-terminated
|
||||
@@ -392,7 +392,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
prf.update((byte) SecretKey.LENGTH); // Output length
|
||||
prf.doFinal(mac, 0);
|
||||
// The output is the first SecretKey.LENGTH bytes of the MAC
|
||||
if(mac.length == SecretKey.LENGTH) return mac;
|
||||
if (mac.length == SecretKey.LENGTH) return mac;
|
||||
byte[] truncated = new byte[SecretKey.LENGTH];
|
||||
System.arraycopy(mac, 0, truncated, 0, truncated.length);
|
||||
return truncated;
|
||||
@@ -414,9 +414,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
List<Long> quickSamples = new ArrayList<Long>(PBKDF_SAMPLES);
|
||||
List<Long> slowSamples = new ArrayList<Long>(PBKDF_SAMPLES);
|
||||
long iterationNanos = 0, initNanos = 0;
|
||||
while(iterationNanos <= 0 || initNanos <= 0) {
|
||||
while (iterationNanos <= 0 || initNanos <= 0) {
|
||||
// Sample the running time with one iteration and two iterations
|
||||
for(int i = 0; i < PBKDF_SAMPLES; i++) {
|
||||
for (int i = 0; i < PBKDF_SAMPLES; i++) {
|
||||
quickSamples.add(sampleRunningTime(1));
|
||||
slowSamples.add(sampleRunningTime(2));
|
||||
}
|
||||
@@ -425,16 +425,16 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
long slowMedian = median(slowSamples);
|
||||
iterationNanos = slowMedian - quickMedian;
|
||||
initNanos = quickMedian - iterationNanos;
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Init: " + initNanos + ", iteration: "
|
||||
+ iterationNanos);
|
||||
}
|
||||
}
|
||||
long targetNanos = targetMillis * 1000L * 1000L;
|
||||
long iterations = (targetNanos - initNanos) / iterationNanos;
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Target iterations: " + iterations);
|
||||
if(iterations < 1) return 1;
|
||||
if(iterations > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Target iterations: " + iterations);
|
||||
if (iterations < 1) return 1;
|
||||
if (iterations > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
||||
return (int) iterations;
|
||||
}
|
||||
|
||||
@@ -452,9 +452,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
private long median(List<Long> list) {
|
||||
int size = list.size();
|
||||
if(size == 0) throw new IllegalArgumentException();
|
||||
if (size == 0) throw new IllegalArgumentException();
|
||||
Collections.sort(list);
|
||||
if(size % 2 == 1) return list.get(size / 2);
|
||||
if (size % 2 == 1) return list.get(size / 2);
|
||||
return list.get(size / 2 - 1) + list.get(size / 2) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ class FortunaGenerator {
|
||||
synchLock.lock();
|
||||
try {
|
||||
counter[0]++;
|
||||
for(int i = 0; counter[i] == 0; i++) {
|
||||
if(i + 1 == BLOCK_BYTES)
|
||||
for (int i = 0; counter[i] == 0; i++) {
|
||||
if (i + 1 == BLOCK_BYTES)
|
||||
throw new RuntimeException("Counter exhausted");
|
||||
counter[i + 1]++;
|
||||
}
|
||||
@@ -76,31 +76,31 @@ class FortunaGenerator {
|
||||
synchLock.lock();
|
||||
try {
|
||||
// Don't write more than the maximum number of bytes in one request
|
||||
if(len > MAX_BYTES_PER_REQUEST) len = MAX_BYTES_PER_REQUEST;
|
||||
if (len > MAX_BYTES_PER_REQUEST) len = MAX_BYTES_PER_REQUEST;
|
||||
cipher.init(true, new KeyParameter(key));
|
||||
// Generate full blocks directly into the output buffer
|
||||
int fullBlocks = len / BLOCK_BYTES;
|
||||
for(int i = 0; i < fullBlocks; i++) {
|
||||
for (int i = 0; i < fullBlocks; i++) {
|
||||
cipher.processBlock(counter, 0, dest, off + i * BLOCK_BYTES);
|
||||
incrementCounter();
|
||||
}
|
||||
// Generate a partial block if needed
|
||||
int done = fullBlocks * BLOCK_BYTES, remaining = len - done;
|
||||
assert remaining < BLOCK_BYTES;
|
||||
if(remaining > 0) {
|
||||
if (remaining > 0) {
|
||||
cipher.processBlock(counter, 0, buffer, 0);
|
||||
incrementCounter();
|
||||
// Copy the partial block to the output buffer and erase our copy
|
||||
System.arraycopy(buffer, 0, dest, off + done, remaining);
|
||||
for(int i = 0; i < BLOCK_BYTES; i++) buffer[i] = 0;
|
||||
for (int i = 0; i < BLOCK_BYTES; i++) buffer[i] = 0;
|
||||
}
|
||||
// Generate a new key
|
||||
for(int i = 0; i < KEY_BYTES / BLOCK_BYTES; i++) {
|
||||
for (int i = 0; i < KEY_BYTES / BLOCK_BYTES; i++) {
|
||||
cipher.processBlock(counter, 0, newKey, i * BLOCK_BYTES);
|
||||
incrementCounter();
|
||||
}
|
||||
System.arraycopy(newKey, 0, key, 0, KEY_BYTES);
|
||||
for(int i = 0; i < KEY_BYTES; i++) newKey[i] = 0;
|
||||
for (int i = 0; i < KEY_BYTES; i++) newKey[i] = 0;
|
||||
// Return the number of bytes written
|
||||
return len;
|
||||
} finally {
|
||||
|
||||
@@ -37,12 +37,12 @@ class FortunaSecureRandom extends SecureRandom {
|
||||
SecureRandom r = new FortunaSecureRandom(seed);
|
||||
byte[] output = new byte[16];
|
||||
r.nextBytes(output);
|
||||
if(!Arrays.equals(SELF_TEST_VECTOR_1, output)) return false;
|
||||
if (!Arrays.equals(SELF_TEST_VECTOR_1, output)) return false;
|
||||
r.nextBytes(output);
|
||||
if(!Arrays.equals(SELF_TEST_VECTOR_2, output)) return false;
|
||||
if (!Arrays.equals(SELF_TEST_VECTOR_2, output)) return false;
|
||||
r.setSeed(seed);
|
||||
r.nextBytes(output);
|
||||
if(!Arrays.equals(SELF_TEST_VECTOR_3, output)) return false;
|
||||
if (!Arrays.equals(SELF_TEST_VECTOR_3, output)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class FortunaSecureRandom extends SecureRandom {
|
||||
@Override
|
||||
protected void engineNextBytes(byte[] b) {
|
||||
int offset = 0;
|
||||
while(offset < b.length)
|
||||
while (offset < b.length)
|
||||
offset += generator.nextBytes(b, offset, b.length - offset);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,39 +10,39 @@ import org.briarproject.util.ByteUtils;
|
||||
class FrameEncoder {
|
||||
|
||||
static void encodeIv(byte[] iv, long frameNumber, boolean header) {
|
||||
if(iv.length < IV_LENGTH) throw new IllegalArgumentException();
|
||||
if(frameNumber < 0 || frameNumber > MAX_32_BIT_UNSIGNED)
|
||||
if (iv.length < IV_LENGTH) throw new IllegalArgumentException();
|
||||
if (frameNumber < 0 || frameNumber > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
ByteUtils.writeUint32(frameNumber, iv, 0);
|
||||
if(header) iv[4] = 1;
|
||||
if (header) iv[4] = 1;
|
||||
else iv[4] = 0;
|
||||
for(int i = 5; i < IV_LENGTH; i++) iv[i] = 0;
|
||||
for (int i = 5; i < IV_LENGTH; i++) iv[i] = 0;
|
||||
}
|
||||
|
||||
static void encodeHeader(byte[] header, boolean finalFrame,
|
||||
int payloadLength, int paddingLength) {
|
||||
if(header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
if(payloadLength < 0) throw new IllegalArgumentException();
|
||||
if(paddingLength < 0) throw new IllegalArgumentException();
|
||||
if(payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
if (header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
if (payloadLength < 0) throw new IllegalArgumentException();
|
||||
if (paddingLength < 0) throw new IllegalArgumentException();
|
||||
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
ByteUtils.writeUint16(payloadLength, header, 0);
|
||||
ByteUtils.writeUint16(paddingLength, header, 2);
|
||||
if(finalFrame) header[0] |= 0x80;
|
||||
if (finalFrame) header[0] |= 0x80;
|
||||
}
|
||||
|
||||
static boolean isFinalFrame(byte[] header) {
|
||||
if(header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
if (header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
return (header[0] & 0x80) == 0x80;
|
||||
}
|
||||
|
||||
static int getPayloadLength(byte[] header) {
|
||||
if(header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
if (header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
return ByteUtils.readUint16(header, 0) & 0x7FFF;
|
||||
}
|
||||
|
||||
static int getPaddingLength(byte[] header) {
|
||||
if(header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
if (header.length < HEADER_LENGTH) throw new IllegalArgumentException();
|
||||
return ByteUtils.readUint16(header, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ class PasswordStrengthEstimatorImpl implements PasswordStrengthEstimator {
|
||||
public float estimateStrength(String password) {
|
||||
HashSet<Character> unique = new HashSet<Character>();
|
||||
int length = password.length();
|
||||
for(int i = 0; i < length; i++) unique.add(password.charAt(i));
|
||||
for (int i = 0; i < length; i++) unique.add(password.charAt(i));
|
||||
boolean lower = false, upper = false, digit = false, other = false;
|
||||
for(char c : unique) {
|
||||
if(Character.isLowerCase(c)) lower = true;
|
||||
else if(Character.isUpperCase(c)) upper = true;
|
||||
else if(Character.isDigit(c)) digit = true;
|
||||
for (char c : unique) {
|
||||
if (Character.isLowerCase(c)) lower = true;
|
||||
else if (Character.isUpperCase(c)) upper = true;
|
||||
else if (Character.isDigit(c)) digit = true;
|
||||
else other = true;
|
||||
}
|
||||
int alphabetSize = 0;
|
||||
if(lower) alphabetSize += LOWER;
|
||||
if(upper) alphabetSize += UPPER;
|
||||
if(digit) alphabetSize += DIGIT;
|
||||
if(other) alphabetSize += OTHER;
|
||||
if (lower) alphabetSize += LOWER;
|
||||
if (upper) alphabetSize += UPPER;
|
||||
if (digit) alphabetSize += DIGIT;
|
||||
if (other) alphabetSize += OTHER;
|
||||
double score = Math.log(Math.pow(alphabetSize, unique.size()));
|
||||
return Math.min(1, (float) (score / STRONG));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class PseudoRandomImpl implements PseudoRandom {
|
||||
public byte[] nextBytes(int length) {
|
||||
byte[] b = new byte[length];
|
||||
int offset = 0;
|
||||
while(offset < length) offset += generator.nextBytes(b, offset, length);
|
||||
while (offset < length) offset += generator.nextBytes(b, offset, length);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,39 +43,39 @@ class Sec1KeyParser implements KeyParser {
|
||||
// The validation procedure comes from SEC 1, section 3.2.2.1. Note
|
||||
// that SEC 1 parameter names are used below, not RFC 5639 names
|
||||
long now = System.currentTimeMillis();
|
||||
if(encodedKey.length != publicKeyBytes)
|
||||
if (encodedKey.length != publicKeyBytes)
|
||||
throw new GeneralSecurityException();
|
||||
// The first byte must be 0x04
|
||||
if(encodedKey[0] != 4) throw new GeneralSecurityException();
|
||||
if (encodedKey[0] != 4) throw new GeneralSecurityException();
|
||||
// The x co-ordinate must be >= 0 and < p
|
||||
byte[] xBytes = new byte[bytesPerInt];
|
||||
System.arraycopy(encodedKey, 1, xBytes, 0, bytesPerInt);
|
||||
BigInteger x = new BigInteger(1, xBytes); // Positive signum
|
||||
if(x.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||
if (x.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||
// The y co-ordinate must be >= 0 and < p
|
||||
byte[] yBytes = new byte[bytesPerInt];
|
||||
System.arraycopy(encodedKey, 1 + bytesPerInt, yBytes, 0, bytesPerInt);
|
||||
BigInteger y = new BigInteger(1, yBytes); // Positive signum
|
||||
if(y.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||
if (y.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||
// Verify that y^2 == x^3 + ax + b (mod p)
|
||||
ECCurve curve = params.getCurve();
|
||||
BigInteger a = curve.getA().toBigInteger();
|
||||
BigInteger b = curve.getB().toBigInteger();
|
||||
BigInteger lhs = y.multiply(y).mod(modulus);
|
||||
BigInteger rhs = x.multiply(x).add(a).multiply(x).add(b).mod(modulus);
|
||||
if(!lhs.equals(rhs)) throw new GeneralSecurityException();
|
||||
if (!lhs.equals(rhs)) throw new GeneralSecurityException();
|
||||
// We know the point (x, y) is on the curve, so we can create the point
|
||||
ECPoint pub = curve.createPoint(x, y).normalize();
|
||||
// Verify that the point (x, y) is not the point at infinity
|
||||
if(pub.isInfinity()) throw new GeneralSecurityException();
|
||||
if (pub.isInfinity()) throw new GeneralSecurityException();
|
||||
// Verify that the point (x, y) times n is the point at infinity
|
||||
if(!pub.multiply(params.getN()).isInfinity())
|
||||
if (!pub.multiply(params.getN()).isInfinity())
|
||||
throw new GeneralSecurityException();
|
||||
// Construct a public key from the point (x, y) and the params
|
||||
ECPublicKeyParameters k = new ECPublicKeyParameters(pub, params);
|
||||
PublicKey p = new Sec1PublicKey(k, keyBits);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Parsing public key took " + duration + " ms");
|
||||
return p;
|
||||
}
|
||||
@@ -83,17 +83,17 @@ class Sec1KeyParser implements KeyParser {
|
||||
public PrivateKey parsePrivateKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
long now = System.currentTimeMillis();
|
||||
if(encodedKey.length != privateKeyBytes)
|
||||
if (encodedKey.length != privateKeyBytes)
|
||||
throw new GeneralSecurityException();
|
||||
BigInteger d = new BigInteger(1, encodedKey); // Positive signum
|
||||
// Verify that the private value is < n
|
||||
if(d.compareTo(params.getN()) >= 0)
|
||||
if (d.compareTo(params.getN()) >= 0)
|
||||
throw new GeneralSecurityException();
|
||||
// Construct a private key from the private value and the params
|
||||
ECPrivateKeyParameters k = new ECPrivateKeyParameters(d, params);
|
||||
PrivateKey p = new Sec1PrivateKey(k, keyBits);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Parsing private key took " + duration + " ms");
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ class Sec1Utils {
|
||||
|
||||
static void convertToFixedLength(byte[] src, byte[] dest, int destOff,
|
||||
int destLen) {
|
||||
if(src.length < destLen) {
|
||||
if (src.length < destLen) {
|
||||
int padding = destLen - src.length;
|
||||
for(int i = destOff; i < destOff + padding; i++) dest[i] = 0;
|
||||
for (int i = destOff; i < destOff + padding; i++) dest[i] = 0;
|
||||
System.arraycopy(src, 0, dest, destOff + padding, src.length);
|
||||
} else {
|
||||
int srcOff = src.length - destLen;
|
||||
|
||||
@@ -35,13 +35,13 @@ class SignatureImpl implements Signature {
|
||||
}
|
||||
|
||||
public void initSign(PrivateKey k) throws GeneralSecurityException {
|
||||
if(!(k instanceof Sec1PrivateKey)) throw new GeneralSecurityException();
|
||||
if (!(k instanceof Sec1PrivateKey)) throw new GeneralSecurityException();
|
||||
ECPrivateKeyParameters priv = ((Sec1PrivateKey) k).getKey();
|
||||
signer.init(true, new ParametersWithRandom(priv, secureRandom));
|
||||
}
|
||||
|
||||
public void initVerify(PublicKey k) throws GeneralSecurityException {
|
||||
if(!(k instanceof Sec1PublicKey)) throw new GeneralSecurityException();
|
||||
if (!(k instanceof Sec1PublicKey)) throw new GeneralSecurityException();
|
||||
ECPublicKeyParameters pub = ((Sec1PublicKey) k).getKey();
|
||||
signer.init(false, pub);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class SignatureImpl implements Signature {
|
||||
long now = System.currentTimeMillis();
|
||||
byte[] signature = signer.generateSignature();
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generating signature took " + duration + " ms");
|
||||
return signature;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class SignatureImpl implements Signature {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean valid = signer.verifySignature(signature);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Verifying signature took " + duration + " ms");
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,14 @@ class StreamDecrypterImpl implements StreamDecrypter {
|
||||
}
|
||||
|
||||
public int readFrame(byte[] payload) throws IOException {
|
||||
if(payload.length < MAX_PAYLOAD_LENGTH)
|
||||
if (payload.length < MAX_PAYLOAD_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(finalFrame) return -1;
|
||||
if (finalFrame) return -1;
|
||||
// Read the header
|
||||
int offset = 0;
|
||||
while(offset < HEADER_LENGTH) {
|
||||
while (offset < HEADER_LENGTH) {
|
||||
int read = in.read(ciphertext, offset, HEADER_LENGTH - offset);
|
||||
if(read == -1) throw new EOFException();
|
||||
if (read == -1) throw new EOFException();
|
||||
offset += read;
|
||||
}
|
||||
// Decrypt and authenticate the header
|
||||
@@ -54,23 +54,23 @@ class StreamDecrypterImpl implements StreamDecrypter {
|
||||
frameCipher.init(false, frameKey, iv);
|
||||
int decrypted = frameCipher.process(ciphertext, 0, HEADER_LENGTH,
|
||||
header, 0);
|
||||
if(decrypted != HEADER_LENGTH - MAC_LENGTH)
|
||||
if (decrypted != HEADER_LENGTH - MAC_LENGTH)
|
||||
throw new RuntimeException();
|
||||
} catch(GeneralSecurityException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new FormatException();
|
||||
}
|
||||
// Decode and validate the header
|
||||
finalFrame = FrameEncoder.isFinalFrame(header);
|
||||
int payloadLength = FrameEncoder.getPayloadLength(header);
|
||||
int paddingLength = FrameEncoder.getPaddingLength(header);
|
||||
if(payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
throw new FormatException();
|
||||
// Read the payload and padding
|
||||
int frameLength = HEADER_LENGTH + payloadLength + paddingLength
|
||||
+ MAC_LENGTH;
|
||||
while(offset < frameLength) {
|
||||
while (offset < frameLength) {
|
||||
int read = in.read(ciphertext, offset, frameLength - offset);
|
||||
if(read == -1) throw new EOFException();
|
||||
if (read == -1) throw new EOFException();
|
||||
offset += read;
|
||||
}
|
||||
// Decrypt and authenticate the payload and padding
|
||||
@@ -79,14 +79,14 @@ class StreamDecrypterImpl implements StreamDecrypter {
|
||||
frameCipher.init(false, frameKey, iv);
|
||||
int decrypted = frameCipher.process(ciphertext, HEADER_LENGTH,
|
||||
payloadLength + paddingLength + MAC_LENGTH, payload, 0);
|
||||
if(decrypted != payloadLength + paddingLength)
|
||||
if (decrypted != payloadLength + paddingLength)
|
||||
throw new RuntimeException();
|
||||
} catch(GeneralSecurityException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new FormatException();
|
||||
}
|
||||
// If there's any padding it must be all zeroes
|
||||
for(int i = 0; i < paddingLength; i++)
|
||||
if(payload[payloadLength + i] != 0) throw new FormatException();
|
||||
for (int i = 0; i < paddingLength; i++)
|
||||
if (payload[payloadLength + i] != 0) throw new FormatException();
|
||||
frameNumber++;
|
||||
return payloadLength;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
||||
|
||||
public void writeFrame(byte[] payload, int payloadLength,
|
||||
int paddingLength, boolean finalFrame) throws IOException {
|
||||
if(payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
// Don't allow the frame counter to wrap
|
||||
if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IOException();
|
||||
if (frameNumber > MAX_32_BIT_UNSIGNED) throw new IOException();
|
||||
// Write the tag if required
|
||||
if(writeTag) {
|
||||
if (writeTag) {
|
||||
out.write(tag, 0, tag.length);
|
||||
writeTag = false;
|
||||
}
|
||||
@@ -57,13 +57,13 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
||||
frameCipher.init(true, frameKey, iv);
|
||||
int encrypted = frameCipher.process(plaintext, 0,
|
||||
HEADER_LENGTH - MAC_LENGTH, ciphertext, 0);
|
||||
if(encrypted != HEADER_LENGTH) throw new RuntimeException();
|
||||
} catch(GeneralSecurityException badCipher) {
|
||||
if (encrypted != HEADER_LENGTH) throw new RuntimeException();
|
||||
} catch (GeneralSecurityException badCipher) {
|
||||
throw new RuntimeException(badCipher);
|
||||
}
|
||||
// Combine the payload and padding
|
||||
System.arraycopy(payload, 0, plaintext, HEADER_LENGTH, payloadLength);
|
||||
for(int i = 0; i < paddingLength; i++)
|
||||
for (int i = 0; i < paddingLength; i++)
|
||||
plaintext[HEADER_LENGTH + payloadLength + i] = 0;
|
||||
// Encrypt and authenticate the payload and padding
|
||||
FrameEncoder.encodeIv(iv, frameNumber, false);
|
||||
@@ -71,9 +71,9 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
||||
frameCipher.init(true, frameKey, iv);
|
||||
int encrypted = frameCipher.process(plaintext, HEADER_LENGTH,
|
||||
payloadLength + paddingLength, ciphertext, HEADER_LENGTH);
|
||||
if(encrypted != payloadLength + paddingLength + MAC_LENGTH)
|
||||
if (encrypted != payloadLength + paddingLength + MAC_LENGTH)
|
||||
throw new RuntimeException();
|
||||
} catch(GeneralSecurityException badCipher) {
|
||||
} catch (GeneralSecurityException badCipher) {
|
||||
throw new RuntimeException(badCipher);
|
||||
}
|
||||
// Write the frame
|
||||
@@ -84,7 +84,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
||||
|
||||
public void flush() throws IOException {
|
||||
// Write the tag if required
|
||||
if(writeTag) {
|
||||
if (writeTag) {
|
||||
out.write(tag, 0, tag.length);
|
||||
writeTag = false;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class ReaderImpl implements Reader {
|
||||
assert !hasLookahead;
|
||||
// Read a lookahead byte
|
||||
int i = in.read();
|
||||
if(i == -1) {
|
||||
if (i == -1) {
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
@@ -58,49 +58,49 @@ class ReaderImpl implements Reader {
|
||||
|
||||
private void consumeLookahead() throws IOException {
|
||||
assert hasLookahead;
|
||||
for(Consumer c : consumers) c.write(next);
|
||||
for (Consumer c : consumers) c.write(next);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
private void readIntoBuffer(byte[] b, int length, boolean consume)
|
||||
throws IOException {
|
||||
int offset = 0;
|
||||
while(offset < length) {
|
||||
while (offset < length) {
|
||||
int read = in.read(b, offset, length - offset);
|
||||
if(read == -1) throw new FormatException();
|
||||
if (read == -1) throw new FormatException();
|
||||
offset += read;
|
||||
}
|
||||
if(consume) for(Consumer c : consumers) c.write(b, 0, length);
|
||||
if (consume) for (Consumer c : consumers) c.write(b, 0, length);
|
||||
}
|
||||
|
||||
private void readIntoBuffer(int length, boolean consume)
|
||||
throws IOException {
|
||||
if(buf.length < length) buf = new byte[length];
|
||||
if (buf.length < length) buf = new byte[length];
|
||||
readIntoBuffer(buf, length, consume);
|
||||
}
|
||||
|
||||
private void skip(int length) throws IOException {
|
||||
while(length > 0) {
|
||||
while (length > 0) {
|
||||
int read = in.read(buf, 0, Math.min(length, buf.length));
|
||||
if(read == -1) throw new FormatException();
|
||||
if (read == -1) throw new FormatException();
|
||||
length -= read;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipObject() throws IOException {
|
||||
if(hasBoolean()) skipBoolean();
|
||||
else if(hasInteger()) skipInteger();
|
||||
else if(hasFloat()) skipFloat();
|
||||
else if(hasString()) skipString();
|
||||
else if(hasRaw()) skipRaw();
|
||||
else if(hasList()) skipList();
|
||||
else if(hasMap()) skipMap();
|
||||
else if(hasNull()) skipNull();
|
||||
if (hasBoolean()) skipBoolean();
|
||||
else if (hasInteger()) skipInteger();
|
||||
else if (hasFloat()) skipFloat();
|
||||
else if (hasString()) skipString();
|
||||
else if (hasRaw()) skipRaw();
|
||||
else if (hasList()) skipList();
|
||||
else if (hasMap()) skipMap();
|
||||
else if (hasNull()) skipNull();
|
||||
else throw new FormatException();
|
||||
}
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if (!hasLookahead) readLookahead();
|
||||
return eof;
|
||||
}
|
||||
|
||||
@@ -113,56 +113,56 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
public void removeConsumer(Consumer c) {
|
||||
if(!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
if (!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public boolean hasNull() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == NULL;
|
||||
}
|
||||
|
||||
public void readNull() throws IOException {
|
||||
if(!hasNull()) throw new FormatException();
|
||||
if (!hasNull()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public void skipNull() throws IOException {
|
||||
if(!hasNull()) throw new FormatException();
|
||||
if (!hasNull()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasBoolean() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == FALSE || next == TRUE;
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
if(!hasBoolean()) throw new FormatException();
|
||||
if (!hasBoolean()) throw new FormatException();
|
||||
boolean bool = next == TRUE;
|
||||
consumeLookahead();
|
||||
return bool;
|
||||
}
|
||||
|
||||
public void skipBoolean() throws IOException {
|
||||
if(!hasBoolean()) throw new FormatException();
|
||||
if (!hasBoolean()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasInteger() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == INT_8 || next == INT_16 || next == INT_32 ||
|
||||
next == INT_64;
|
||||
}
|
||||
|
||||
public long readInteger() throws IOException {
|
||||
if(!hasInteger()) throw new FormatException();
|
||||
if (!hasInteger()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
if(next == INT_8) return readInt8(true);
|
||||
if(next == INT_16) return readInt16(true);
|
||||
if(next == INT_32) return readInt32(true);
|
||||
if (next == INT_8) return readInt8(true);
|
||||
if (next == INT_16) return readInt16(true);
|
||||
if (next == INT_32) return readInt32(true);
|
||||
return readInt64(true);
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ class ReaderImpl implements Reader {
|
||||
private short readInt16(boolean consume) throws IOException {
|
||||
readIntoBuffer(2, consume);
|
||||
short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
|
||||
if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
||||
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
@@ -182,8 +182,8 @@ class ReaderImpl implements Reader {
|
||||
private int readInt32(boolean consume) throws IOException {
|
||||
readIntoBuffer(4, consume);
|
||||
int value = 0;
|
||||
for(int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
|
||||
if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
|
||||
for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
|
||||
if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
@@ -191,113 +191,113 @@ class ReaderImpl implements Reader {
|
||||
private long readInt64(boolean consume) throws IOException {
|
||||
readIntoBuffer(8, consume);
|
||||
long value = 0;
|
||||
for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
if(value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE)
|
||||
for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE)
|
||||
throw new FormatException();
|
||||
return value;
|
||||
}
|
||||
|
||||
public void skipInteger() throws IOException {
|
||||
if(!hasInteger()) throw new FormatException();
|
||||
if(next == INT_8) skip(1);
|
||||
else if(next == INT_16) skip(2);
|
||||
else if(next == INT_32) skip(4);
|
||||
if (!hasInteger()) throw new FormatException();
|
||||
if (next == INT_8) skip(1);
|
||||
else if (next == INT_16) skip(2);
|
||||
else if (next == INT_32) skip(4);
|
||||
else skip(8);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasFloat() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == FLOAT_64;
|
||||
}
|
||||
|
||||
public double readFloat() throws IOException {
|
||||
if(!hasFloat()) throw new FormatException();
|
||||
if (!hasFloat()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
readIntoBuffer(8, true);
|
||||
long value = 0;
|
||||
for(int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||
return Double.longBitsToDouble(value);
|
||||
}
|
||||
|
||||
public void skipFloat() throws IOException {
|
||||
if(!hasFloat()) throw new FormatException();
|
||||
if (!hasFloat()) throw new FormatException();
|
||||
skip(8);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasString() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == STRING_8 || next == STRING_16 || next == STRING_32;
|
||||
}
|
||||
|
||||
public String readString(int maxLength) throws IOException {
|
||||
if(!hasString()) throw new FormatException();
|
||||
if (!hasString()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
int length = readStringLength(true);
|
||||
if(length < 0 || length > maxLength) throw new FormatException();
|
||||
if(length == 0) return "";
|
||||
if (length < 0 || length > maxLength) throw new FormatException();
|
||||
if (length == 0) return "";
|
||||
readIntoBuffer(length, true);
|
||||
return new String(buf, 0, length, "UTF-8");
|
||||
}
|
||||
|
||||
private int readStringLength(boolean consume) throws IOException {
|
||||
if(next == STRING_8) return readInt8(consume);
|
||||
if(next == STRING_16) return readInt16(consume);
|
||||
if(next == STRING_32) return readInt32(consume);
|
||||
if (next == STRING_8) return readInt8(consume);
|
||||
if (next == STRING_16) return readInt16(consume);
|
||||
if (next == STRING_32) return readInt32(consume);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public void skipString() throws IOException {
|
||||
if(!hasString()) throw new FormatException();
|
||||
if (!hasString()) throw new FormatException();
|
||||
int length = readStringLength(false);
|
||||
if(length < 0) throw new FormatException();
|
||||
if (length < 0) throw new FormatException();
|
||||
skip(length);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasRaw() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == RAW_8 || next == RAW_16 || next == RAW_32;
|
||||
}
|
||||
|
||||
public byte[] readRaw(int maxLength) throws IOException {
|
||||
if(!hasRaw()) throw new FormatException();
|
||||
if (!hasRaw()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
int length = readRawLength(true);
|
||||
if(length < 0 || length > maxLength) throw new FormatException();
|
||||
if(length == 0) return EMPTY_BUFFER;
|
||||
if (length < 0 || length > maxLength) throw new FormatException();
|
||||
if (length == 0) return EMPTY_BUFFER;
|
||||
byte[] b = new byte[length];
|
||||
readIntoBuffer(b, length, true);
|
||||
return b;
|
||||
}
|
||||
|
||||
private int readRawLength(boolean consume) throws IOException {
|
||||
if(next == RAW_8) return readInt8(consume);
|
||||
if(next == RAW_16) return readInt16(consume);
|
||||
if(next == RAW_32) return readInt32(consume);
|
||||
if (next == RAW_8) return readInt8(consume);
|
||||
if (next == RAW_16) return readInt16(consume);
|
||||
if (next == RAW_32) return readInt32(consume);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public void skipRaw() throws IOException {
|
||||
if(!hasRaw()) throw new FormatException();
|
||||
if (!hasRaw()) throw new FormatException();
|
||||
int length = readRawLength(false);
|
||||
if(length < 0) throw new FormatException();
|
||||
if (length < 0) throw new FormatException();
|
||||
skip(length);
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasList() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == LIST;
|
||||
}
|
||||
|
||||
public void readListStart() throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
if (!hasList()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
@@ -306,8 +306,8 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
private boolean hasEnd() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == END;
|
||||
}
|
||||
|
||||
@@ -316,25 +316,25 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
private void readEnd() throws IOException {
|
||||
if(!hasEnd()) throw new FormatException();
|
||||
if (!hasEnd()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
public void skipList() throws IOException {
|
||||
if(!hasList()) throw new FormatException();
|
||||
if (!hasList()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
while(!hasListEnd()) skipObject();
|
||||
while (!hasListEnd()) skipObject();
|
||||
hasLookahead = false;
|
||||
}
|
||||
|
||||
public boolean hasMap() throws IOException {
|
||||
if(!hasLookahead) readLookahead();
|
||||
if(eof) return false;
|
||||
if (!hasLookahead) readLookahead();
|
||||
if (eof) return false;
|
||||
return next == MAP;
|
||||
}
|
||||
|
||||
public void readMapStart() throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
if (!hasMap()) throw new FormatException();
|
||||
consumeLookahead();
|
||||
}
|
||||
|
||||
@@ -347,9 +347,9 @@ class ReaderImpl implements Reader {
|
||||
}
|
||||
|
||||
public void skipMap() throws IOException {
|
||||
if(!hasMap()) throw new FormatException();
|
||||
if (!hasMap()) throw new FormatException();
|
||||
hasLookahead = false;
|
||||
while(!hasMapEnd()) {
|
||||
while (!hasMapEnd()) {
|
||||
skipObject();
|
||||
skipObject();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class WriterImpl implements Writer {
|
||||
}
|
||||
|
||||
public void removeConsumer(Consumer c) {
|
||||
if(!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
if (!consumers.remove(c)) throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public void writeNull() throws IOException {
|
||||
@@ -61,18 +61,18 @@ class WriterImpl implements Writer {
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean b) throws IOException {
|
||||
if(b) write(TRUE);
|
||||
if (b) write(TRUE);
|
||||
else write(FALSE);
|
||||
}
|
||||
|
||||
public void writeInteger(long i) throws IOException {
|
||||
if(i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
|
||||
if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
|
||||
write(INT_8);
|
||||
write((byte) i);
|
||||
} else if(i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
|
||||
} else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
|
||||
write(INT_16);
|
||||
writeInt16((short) i);
|
||||
} else if(i >= Integer.MIN_VALUE && i <= Integer.MAX_VALUE) {
|
||||
} else if (i >= Integer.MIN_VALUE && i <= Integer.MAX_VALUE) {
|
||||
write(INT_32);
|
||||
writeInt32((int) i);
|
||||
} else {
|
||||
@@ -111,10 +111,10 @@ class WriterImpl implements Writer {
|
||||
|
||||
public void writeString(String s) throws IOException {
|
||||
byte[] b = s.getBytes("UTF-8");
|
||||
if(b.length <= Byte.MAX_VALUE) {
|
||||
if (b.length <= Byte.MAX_VALUE) {
|
||||
write(STRING_8);
|
||||
write((byte) b.length);
|
||||
} else if(b.length <= Short.MAX_VALUE) {
|
||||
} else if (b.length <= Short.MAX_VALUE) {
|
||||
write(STRING_16);
|
||||
writeInt16((short) b.length);
|
||||
} else {
|
||||
@@ -125,10 +125,10 @@ class WriterImpl implements Writer {
|
||||
}
|
||||
|
||||
public void writeRaw(byte[] b) throws IOException {
|
||||
if(b.length <= Byte.MAX_VALUE) {
|
||||
if (b.length <= Byte.MAX_VALUE) {
|
||||
write(RAW_8);
|
||||
write((byte) b.length);
|
||||
} else if(b.length <= Short.MAX_VALUE) {
|
||||
} else if (b.length <= Short.MAX_VALUE) {
|
||||
write(RAW_16);
|
||||
writeInt16((short) b.length);
|
||||
} else {
|
||||
@@ -140,24 +140,24 @@ class WriterImpl implements Writer {
|
||||
|
||||
public void writeList(Collection<?> c) throws IOException {
|
||||
write(LIST);
|
||||
for(Object o : c) writeObject(o);
|
||||
for (Object o : c) writeObject(o);
|
||||
write(END);
|
||||
}
|
||||
|
||||
private void writeObject(Object o) throws IOException {
|
||||
if(o instanceof Boolean) writeBoolean((Boolean) o);
|
||||
else if(o instanceof Byte) writeInteger((Byte) o);
|
||||
else if(o instanceof Short) writeInteger((Short) o);
|
||||
else if(o instanceof Integer) writeInteger((Integer) o);
|
||||
else if(o instanceof Long) writeInteger((Long) o);
|
||||
else if(o instanceof Float) writeFloat((Float) o);
|
||||
else if(o instanceof Double) writeFloat((Double) o);
|
||||
else if(o instanceof String) writeString((String) o);
|
||||
else if(o instanceof byte[]) writeRaw((byte[]) o);
|
||||
else if(o instanceof Bytes) writeRaw(((Bytes) o).getBytes());
|
||||
else if(o instanceof List<?>) writeList((List<?>) o);
|
||||
else if(o instanceof Map<?, ?>) writeMap((Map<?, ?>) o);
|
||||
else if(o == null) writeNull();
|
||||
if (o instanceof Boolean) writeBoolean((Boolean) o);
|
||||
else if (o instanceof Byte) writeInteger((Byte) o);
|
||||
else if (o instanceof Short) writeInteger((Short) o);
|
||||
else if (o instanceof Integer) writeInteger((Integer) o);
|
||||
else if (o instanceof Long) writeInteger((Long) o);
|
||||
else if (o instanceof Float) writeFloat((Float) o);
|
||||
else if (o instanceof Double) writeFloat((Double) o);
|
||||
else if (o instanceof String) writeString((String) o);
|
||||
else if (o instanceof byte[]) writeRaw((byte[]) o);
|
||||
else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes());
|
||||
else if (o instanceof List<?>) writeList((List<?>) o);
|
||||
else if (o instanceof Map<?, ?>) writeMap((Map<?, ?>) o);
|
||||
else if (o == null) writeNull();
|
||||
else throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ class WriterImpl implements Writer {
|
||||
|
||||
public void writeMap(Map<?, ?> m) throws IOException {
|
||||
write(MAP);
|
||||
for(Entry<?, ?> e : m.entrySet()) {
|
||||
for (Entry<?, ?> e : m.entrySet()) {
|
||||
writeObject(e.getKey());
|
||||
writeObject(e.getValue());
|
||||
}
|
||||
@@ -188,11 +188,11 @@ class WriterImpl implements Writer {
|
||||
|
||||
private void write(byte b) throws IOException {
|
||||
out.write(b);
|
||||
for(Consumer c : consumers) c.write(b);
|
||||
for (Consumer c : consumers) c.write(b);
|
||||
}
|
||||
|
||||
private void write(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
for(Consumer c : consumers) c.write(b, 0, b.length);
|
||||
for (Consumer c : consumers) c.write(b, 0, b.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,19 +35,19 @@ class DatabaseCleanerImpl extends TimerTask implements DatabaseCleaner {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if(callback == null) throw new IllegalStateException();
|
||||
if (callback == null) throw new IllegalStateException();
|
||||
try {
|
||||
if(callback.shouldCheckFreeSpace()) {
|
||||
if (callback.shouldCheckFreeSpace()) {
|
||||
LOG.info("Checking free space");
|
||||
callback.checkFreeSpaceAndClean();
|
||||
}
|
||||
} catch(DbClosedException e) {
|
||||
} catch (DbClosedException e) {
|
||||
LOG.info("Database closed, exiting");
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
throw new Error(e); // Kill the application
|
||||
} catch(RuntimeException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (RuntimeException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
throw new Error(e); // Kill the application
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,15 +12,15 @@ class ExponentialBackoff {
|
||||
* be greater than Long.MAX_VALUE, Long.MAX_VALUE is returned.
|
||||
*/
|
||||
static long calculateExpiry(long now, int maxLatency, int txCount) {
|
||||
if(now < 0) throw new IllegalArgumentException();
|
||||
if(maxLatency <= 0) throw new IllegalArgumentException();
|
||||
if(txCount < 0) throw new IllegalArgumentException();
|
||||
if (now < 0) throw new IllegalArgumentException();
|
||||
if (maxLatency <= 0) throw new IllegalArgumentException();
|
||||
if (txCount < 0) throw new IllegalArgumentException();
|
||||
// The maximum round-trip time is twice the maximum latency
|
||||
long roundTrip = maxLatency * 2L;
|
||||
// The interval between transmissions is roundTrip * 2 ^ txCount
|
||||
for(int i = 0; i < txCount; i++) {
|
||||
for (int i = 0; i < txCount; i++) {
|
||||
roundTrip <<= 1;
|
||||
if(roundTrip < 0) return Long.MAX_VALUE;
|
||||
if (roundTrip < 0) return Long.MAX_VALUE;
|
||||
}
|
||||
// The expiry time is the current time plus the interval
|
||||
long expiry = now + roundTrip;
|
||||
|
||||
@@ -41,7 +41,7 @@ class H2Database extends JdbcDatabase {
|
||||
|
||||
public boolean open() throws DbException, IOException {
|
||||
boolean reopen = config.databaseExists();
|
||||
if(!reopen) config.getDatabaseDirectory().mkdirs();
|
||||
if (!reopen) config.getDatabaseDirectory().mkdirs();
|
||||
super.open("org.h2.Driver", reopen);
|
||||
return reopen;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class H2Database extends JdbcDatabase {
|
||||
// H2 will close the database when the last connection closes
|
||||
try {
|
||||
super.closeAllConnections();
|
||||
} catch(SQLException e) {
|
||||
} catch (SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
@@ -64,17 +64,17 @@ class H2Database extends JdbcDatabase {
|
||||
long quota = maxSize - used;
|
||||
long min = Math.min(free, quota);
|
||||
return min;
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private long getDiskSpace(File f) {
|
||||
if(f.isDirectory()) {
|
||||
if (f.isDirectory()) {
|
||||
long total = 0;
|
||||
for(File child : f.listFiles()) total += getDiskSpace(child);
|
||||
for (File child : f.listFiles()) total += getDiskSpace(child);
|
||||
return total;
|
||||
} else if(f.isFile()) {
|
||||
} else if (f.isFile()) {
|
||||
return f.length();
|
||||
} else {
|
||||
return 0;
|
||||
@@ -84,7 +84,7 @@ class H2Database extends JdbcDatabase {
|
||||
@Override
|
||||
protected Connection createConnection() throws SQLException {
|
||||
byte[] key = config.getEncryptionKey().getBytes();
|
||||
if(key == null) throw new IllegalStateException();
|
||||
if (key == null) throw new IllegalStateException();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("user", "user");
|
||||
// Separate the file password from the user password with a space
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,6 @@ class EventBusImpl implements EventBus {
|
||||
}
|
||||
|
||||
public void broadcast(Event e) {
|
||||
for(EventListener l : listeners) l.eventOccurred(e);
|
||||
for (EventListener l : listeners) l.eventOccurred(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,11 +58,11 @@ class AliceConnector extends Connector {
|
||||
public void run() {
|
||||
// Create an incoming or outgoing connection
|
||||
DuplexTransportConnection conn = createInvitationConnection();
|
||||
if(conn == null) return;
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
|
||||
if (conn == null) return;
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
|
||||
// Don't proceed with more than one connection
|
||||
if(group.getAndSetConnected()) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant");
|
||||
if (group.getAndSetConnected()) {
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant");
|
||||
tryToClose(conn, false);
|
||||
return;
|
||||
}
|
||||
@@ -83,19 +83,19 @@ class AliceConnector extends Connector {
|
||||
sendPublicKey(w);
|
||||
byte[] key = receivePublicKey(r);
|
||||
secret = deriveMasterSecret(hash, key, true);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
}
|
||||
// The key agreement succeeded - derive the confirmation codes
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
int[] codes = crypto.deriveConfirmationCodes(secret);
|
||||
int aliceCode = codes[0], bobCode = codes[1];
|
||||
group.keyAgreementSucceeded(aliceCode, bobCode);
|
||||
@@ -105,22 +105,22 @@ class AliceConnector extends Connector {
|
||||
localMatched = group.waitForLocalConfirmationResult();
|
||||
sendConfirmation(w, localMatched);
|
||||
remoteMatched = receiveConfirmation(r);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.remoteConfirmationFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting for confirmation");
|
||||
group.remoteConfirmationFailed();
|
||||
tryToClose(conn, true);
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||
if (remoteMatched) group.remoteConfirmationSucceeded();
|
||||
else group.remoteConfirmationFailed();
|
||||
if(!(localMatched && remoteMatched)) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (!(localMatched && remoteMatched)) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " confirmation failed");
|
||||
tryToClose(conn, false);
|
||||
return;
|
||||
@@ -128,7 +128,7 @@ class AliceConnector extends Connector {
|
||||
// The timestamp is taken after exchanging confirmation results
|
||||
long localTimestamp = clock.currentTimeMillis();
|
||||
// Confirmation succeeded - upgrade to a secure connection
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " confirmation succeeded");
|
||||
// Create the readers
|
||||
InputStream streamReader =
|
||||
@@ -159,14 +159,14 @@ class AliceConnector extends Connector {
|
||||
remoteReuseConnection = receiveConfirmation(r);
|
||||
// Close the outgoing stream and expect EOF on the incoming stream
|
||||
w.close();
|
||||
if(!r.eof()) LOG.warning("Unexpected data at end of connection");
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (!r.eof()) LOG.warning("Unexpected data at end of connection");
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.pseudonymExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.pseudonymExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
@@ -176,17 +176,17 @@ class AliceConnector extends Connector {
|
||||
// Add the contact and store the transports
|
||||
try {
|
||||
addContact(remoteAuthor, remoteProps, secret, epoch, true);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
tryToClose(conn, true);
|
||||
group.pseudonymExchangeFailed();
|
||||
return;
|
||||
}
|
||||
// Reuse the connection as a transport connection if both peers agree
|
||||
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||
if (reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||
else tryToClose(conn, false);
|
||||
// Pseudonym exchange succeeded
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " pseudonym exchange succeeded");
|
||||
group.pseudonymExchangeSucceeded(remoteAuthor);
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ class BobConnector extends Connector {
|
||||
public void run() {
|
||||
// Create an incoming or outgoing connection
|
||||
DuplexTransportConnection conn = createInvitationConnection();
|
||||
if(conn == null) return;
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
|
||||
if (conn == null) return;
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
|
||||
// Carry out the key agreement protocol
|
||||
InputStream in;
|
||||
OutputStream out;
|
||||
@@ -74,8 +74,8 @@ class BobConnector extends Connector {
|
||||
// Alice goes first
|
||||
byte[] hash = receivePublicKeyHash(r);
|
||||
// Don't proceed with more than one connection
|
||||
if(group.getAndSetConnected()) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant");
|
||||
if (group.getAndSetConnected()) {
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " redundant");
|
||||
tryToClose(conn, false);
|
||||
return;
|
||||
}
|
||||
@@ -83,19 +83,19 @@ class BobConnector extends Connector {
|
||||
byte[] key = receivePublicKey(r);
|
||||
sendPublicKey(w);
|
||||
secret = deriveMasterSecret(hash, key, false);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.keyAgreementFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
}
|
||||
// The key agreement succeeded - derive the confirmation codes
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " agreement succeeded");
|
||||
int[] codes = crypto.deriveConfirmationCodes(secret);
|
||||
int aliceCode = codes[0], bobCode = codes[1];
|
||||
group.keyAgreementSucceeded(bobCode, aliceCode);
|
||||
@@ -105,22 +105,22 @@ class BobConnector extends Connector {
|
||||
remoteMatched = receiveConfirmation(r);
|
||||
localMatched = group.waitForLocalConfirmationResult();
|
||||
sendConfirmation(w, localMatched);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.remoteConfirmationFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting for confirmation");
|
||||
group.remoteConfirmationFailed();
|
||||
tryToClose(conn, true);
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||
if (remoteMatched) group.remoteConfirmationSucceeded();
|
||||
else group.remoteConfirmationFailed();
|
||||
if(!(localMatched && remoteMatched)) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (!(localMatched && remoteMatched)) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " confirmation failed");
|
||||
tryToClose(conn, false);
|
||||
return;
|
||||
@@ -128,7 +128,7 @@ class BobConnector extends Connector {
|
||||
// The timestamp is taken after exchanging confirmation results
|
||||
long localTimestamp = clock.currentTimeMillis();
|
||||
// Confirmation succeeded - upgrade to a secure connection
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " confirmation succeeded");
|
||||
// Create the readers
|
||||
InputStream streamReader =
|
||||
@@ -159,14 +159,14 @@ class BobConnector extends Connector {
|
||||
sendConfirmation(w, reuseConnection);
|
||||
// Close the outgoing stream and expect EOF on the incoming stream
|
||||
w.close();
|
||||
if(!r.eof()) LOG.warning("Unexpected data at end of connection");
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (!r.eof()) LOG.warning("Unexpected data at end of connection");
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.pseudonymExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
group.pseudonymExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
@@ -176,17 +176,17 @@ class BobConnector extends Connector {
|
||||
// Add the contact and store the transports
|
||||
try {
|
||||
addContact(remoteAuthor, remoteProps, secret, epoch, false);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
tryToClose(conn, true);
|
||||
group.pseudonymExchangeFailed();
|
||||
return;
|
||||
}
|
||||
// Reuse the connection as a transport connection if both peers agree
|
||||
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||
if (reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||
else tryToClose(conn, false);
|
||||
// Pseudonym exchange succeeded
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " pseudonym exchange succeeded");
|
||||
group.pseudonymExchangeSucceeded(remoteAuthor);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ abstract class Connector extends Thread {
|
||||
}
|
||||
|
||||
protected DuplexTransportConnection createInvitationConnection() {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " creating invitation connection");
|
||||
return plugin.createInvitationConnection(random, CONNECTION_TIMEOUT);
|
||||
}
|
||||
@@ -126,14 +126,14 @@ abstract class Connector extends Thread {
|
||||
protected void sendPublicKeyHash(Writer w) throws IOException {
|
||||
w.writeRaw(messageDigest.digest(keyPair.getPublic().getEncoded()));
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent hash");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent hash");
|
||||
}
|
||||
|
||||
protected byte[] receivePublicKeyHash(Reader r) throws IOException {
|
||||
int hashLength = messageDigest.getDigestLength();
|
||||
byte[] b = r.readRaw(hashLength);
|
||||
if(b.length < hashLength) throw new FormatException();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash");
|
||||
if (b.length < hashLength) throw new FormatException();
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -141,27 +141,27 @@ abstract class Connector extends Thread {
|
||||
byte[] key = keyPair.getPublic().getEncoded();
|
||||
w.writeRaw(key);
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent key");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent key");
|
||||
}
|
||||
|
||||
protected byte[] receivePublicKey(Reader r) throws GeneralSecurityException,
|
||||
IOException {
|
||||
byte[] b = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||
keyParser.parsePublicKey(b);
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received key");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received key");
|
||||
return b;
|
||||
}
|
||||
|
||||
protected byte[] deriveMasterSecret(byte[] hash, byte[] key, boolean alice)
|
||||
throws GeneralSecurityException {
|
||||
// Check that the hash matches the key
|
||||
if(!Arrays.equals(hash, messageDigest.digest(key))) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (!Arrays.equals(hash, messageDigest.digest(key))) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " hash does not match key");
|
||||
throw new GeneralSecurityException();
|
||||
}
|
||||
// Derive the master secret
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " deriving master secret");
|
||||
return crypto.deriveMasterSecret(key, keyPair, alice);
|
||||
}
|
||||
@@ -170,13 +170,13 @@ abstract class Connector extends Thread {
|
||||
throws IOException {
|
||||
w.writeBoolean(confirmed);
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " sent confirmation: " + confirmed);
|
||||
}
|
||||
|
||||
protected boolean receiveConfirmation(Reader r) throws IOException {
|
||||
boolean confirmed = r.readBoolean();
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " received confirmation: " + confirmed);
|
||||
return confirmed;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ abstract class Connector extends Thread {
|
||||
w.writeRaw(localAuthor.getPublicKey());
|
||||
w.writeRaw(sig);
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent pseudonym");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent pseudonym");
|
||||
}
|
||||
|
||||
protected Author receivePseudonym(Reader r, byte[] nonce)
|
||||
@@ -204,14 +204,14 @@ abstract class Connector extends Thread {
|
||||
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH);
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received pseudonym");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received pseudonym");
|
||||
// Verify the signature
|
||||
Signature signature = crypto.getSignature();
|
||||
KeyParser keyParser = crypto.getSignatureKeyParser();
|
||||
signature.initVerify(keyParser.parsePublicKey(publicKey));
|
||||
signature.update(nonce);
|
||||
if(!signature.verify(sig)) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (!signature.verify(sig)) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " invalid signature");
|
||||
throw new GeneralSecurityException();
|
||||
}
|
||||
@@ -221,25 +221,25 @@ abstract class Connector extends Thread {
|
||||
protected void sendTimestamp(Writer w, long timestamp) throws IOException {
|
||||
w.writeInteger(timestamp);
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " sent timestamp");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " sent timestamp");
|
||||
}
|
||||
|
||||
protected long receiveTimestamp(Reader r) throws IOException {
|
||||
long timestamp = r.readInteger();
|
||||
if(timestamp < 0) throw new FormatException();
|
||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received timestamp");
|
||||
if (timestamp < 0) throw new FormatException();
|
||||
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " received timestamp");
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
protected void sendTransportProperties(Writer w) throws IOException {
|
||||
w.writeListStart();
|
||||
for(Entry<TransportId, TransportProperties> e : localProps.entrySet()) {
|
||||
for (Entry<TransportId, TransportProperties> e : localProps.entrySet()) {
|
||||
w.writeString(e.getKey().getString());
|
||||
w.writeMap(e.getValue());
|
||||
}
|
||||
w.writeListEnd();
|
||||
w.flush();
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " sent transport properties");
|
||||
}
|
||||
|
||||
@@ -248,14 +248,14 @@ abstract class Connector extends Thread {
|
||||
Map<TransportId, TransportProperties> remoteProps =
|
||||
new HashMap<TransportId, TransportProperties>();
|
||||
r.readListStart();
|
||||
while(!r.hasListEnd()) {
|
||||
while (!r.hasListEnd()) {
|
||||
String idString = r.readString(MAX_TRANSPORT_ID_LENGTH);
|
||||
if(idString.length() == 0) throw new FormatException();
|
||||
if (idString.length() == 0) throw new FormatException();
|
||||
TransportId id = new TransportId(idString);
|
||||
Map<String, String> p = new HashMap<String, String>();
|
||||
r.readMapStart();
|
||||
for(int i = 0; !r.hasMapEnd(); i++) {
|
||||
if(i == MAX_PROPERTIES_PER_TRANSPORT)
|
||||
for (int i = 0; !r.hasMapEnd(); i++) {
|
||||
if (i == MAX_PROPERTIES_PER_TRANSPORT)
|
||||
throw new FormatException();
|
||||
String key = r.readString(MAX_PROPERTY_LENGTH);
|
||||
String value = r.readString(MAX_PROPERTY_LENGTH);
|
||||
@@ -265,7 +265,7 @@ abstract class Connector extends Thread {
|
||||
remoteProps.put(id, new TransportProperties(p));
|
||||
}
|
||||
r.readListEnd();
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(pluginName + " received transport properties");
|
||||
return remoteProps;
|
||||
}
|
||||
@@ -285,20 +285,20 @@ abstract class Connector extends Thread {
|
||||
// Create an endpoint for each transport shared with the contact
|
||||
List<TransportId> ids = new ArrayList<TransportId>();
|
||||
Map<TransportId, Integer> latencies = db.getTransportLatencies();
|
||||
for(TransportId id : localProps.keySet()) {
|
||||
if(latencies.containsKey(id) && remoteProps.containsKey(id))
|
||||
for (TransportId id : localProps.keySet()) {
|
||||
if (latencies.containsKey(id) && remoteProps.containsKey(id))
|
||||
ids.add(id);
|
||||
}
|
||||
// Assign indices to the transports deterministically and derive keys
|
||||
Collections.sort(ids, TransportIdComparator.INSTANCE);
|
||||
int size = ids.size();
|
||||
for(int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
TransportId id = ids.get(i);
|
||||
Endpoint ep = new Endpoint(contactId, id, epoch, alice);
|
||||
int maxLatency = latencies.get(id);
|
||||
try {
|
||||
db.addEndpoint(ep);
|
||||
} catch(NoSuchTransportException e) {
|
||||
} catch (NoSuchTransportException e) {
|
||||
continue;
|
||||
}
|
||||
byte[] initialSecret = crypto.deriveInitialSecret(secret, i);
|
||||
@@ -312,13 +312,13 @@ abstract class Connector extends Thread {
|
||||
LOG.info("Closing connection");
|
||||
conn.getReader().dispose(exception, true);
|
||||
conn.getWriter().dispose(exception);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void reuseConnection(DuplexTransportConnection conn) {
|
||||
if(contactId == null) throw new IllegalStateException();
|
||||
if (contactId == null) throw new IllegalStateException();
|
||||
TransportId t = plugin.getId();
|
||||
connectionManager.manageOutgoingConnection(contactId, t, conn);
|
||||
}
|
||||
|
||||
@@ -132,29 +132,29 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
try {
|
||||
localAuthor = db.getLocalAuthor(localAuthorId);
|
||||
localProps = db.getLocalProperties();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
synchLock.lock();
|
||||
try {
|
||||
connectionFailed = true;
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners) l.connectionFailed();
|
||||
for (InvitationListener l : listeners) l.connectionFailed();
|
||||
return;
|
||||
}
|
||||
// Start the connection threads
|
||||
Collection<Connector> connectors = new ArrayList<Connector>();
|
||||
// Alice is the party with the smaller invitation code
|
||||
if(localInvitationCode < remoteInvitationCode) {
|
||||
for(DuplexPlugin plugin : pluginManager.getInvitationPlugins()) {
|
||||
if (localInvitationCode < remoteInvitationCode) {
|
||||
for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) {
|
||||
Connector c = createAliceConnector(plugin, localAuthor,
|
||||
localProps);
|
||||
connectors.add(c);
|
||||
c.start();
|
||||
}
|
||||
} else {
|
||||
for(DuplexPlugin plugin: pluginManager.getInvitationPlugins()) {
|
||||
for (DuplexPlugin plugin: pluginManager.getInvitationPlugins()) {
|
||||
Connector c = createBobConnector(plugin, localAuthor,
|
||||
localProps);
|
||||
connectors.add(c);
|
||||
@@ -163,20 +163,20 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
}
|
||||
// Wait for the connection threads to finish
|
||||
try {
|
||||
for(Connector c : connectors) c.join();
|
||||
} catch(InterruptedException e) {
|
||||
for (Connector c : connectors) c.join();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting for connectors");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
// If none of the threads connected, inform the listeners
|
||||
if(!connected.get()) {
|
||||
if (!connected.get()) {
|
||||
synchLock.lock();
|
||||
try {
|
||||
connectionFailed = true;
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners) l.connectionFailed();
|
||||
for (InvitationListener l : listeners) l.connectionFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,8 +226,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
|
||||
boolean getAndSetConnected() {
|
||||
boolean redundant = connected.getAndSet(true);
|
||||
if(!redundant)
|
||||
for(InvitationListener l : listeners) l.connectionSucceeded();
|
||||
if (!redundant)
|
||||
for (InvitationListener l : listeners) l.connectionSucceeded();
|
||||
return redundant;
|
||||
}
|
||||
|
||||
@@ -239,12 +239,12 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners)
|
||||
for (InvitationListener l : listeners)
|
||||
l.keyAgreementSucceeded(localCode, remoteCode);
|
||||
}
|
||||
|
||||
void keyAgreementFailed() {
|
||||
for(InvitationListener l : listeners) l.keyAgreementFailed();
|
||||
for (InvitationListener l : listeners) l.keyAgreementFailed();
|
||||
}
|
||||
|
||||
boolean waitForLocalConfirmationResult() throws InterruptedException {
|
||||
@@ -265,7 +265,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners) l.remoteConfirmationSucceeded();
|
||||
for (InvitationListener l : listeners) l.remoteConfirmationSucceeded();
|
||||
}
|
||||
|
||||
void remoteConfirmationFailed() {
|
||||
@@ -276,7 +276,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners) l.remoteConfirmationFailed();
|
||||
for (InvitationListener l : listeners) l.remoteConfirmationFailed();
|
||||
}
|
||||
|
||||
void pseudonymExchangeSucceeded(Author remoteAuthor) {
|
||||
@@ -287,11 +287,11 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
for(InvitationListener l : listeners)
|
||||
for (InvitationListener l : listeners)
|
||||
l.pseudonymExchangeSucceeded(name);
|
||||
}
|
||||
|
||||
void pseudonymExchangeFailed() {
|
||||
for(InvitationListener l : listeners) l.pseudonymExchangeFailed();
|
||||
for (InvitationListener l : listeners) l.pseudonymExchangeFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,19 +50,19 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
}
|
||||
|
||||
public void register(Service s) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Registering service " + s.getClass().getName());
|
||||
services.add(s);
|
||||
}
|
||||
|
||||
public void registerForShutdown(ExecutorService e) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Registering executor " + e.getClass().getName());
|
||||
executors.add(e);
|
||||
}
|
||||
|
||||
public StartResult startServices() {
|
||||
if(!startStopSemaphore.tryAcquire()) {
|
||||
if (!startStopSemaphore.tryAcquire()) {
|
||||
LOG.info("Already starting or stopping");
|
||||
return ALREADY_RUNNING;
|
||||
}
|
||||
@@ -71,35 +71,35 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
long now = clock.currentTimeMillis();
|
||||
boolean reopened = db.open();
|
||||
long duration = clock.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if(reopened)
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
if (reopened)
|
||||
LOG.info("Reopening database took " + duration + " ms");
|
||||
else LOG.info("Creating database took " + duration + " ms");
|
||||
}
|
||||
dbLatch.countDown();
|
||||
for(Service s : services) {
|
||||
for (Service s : services) {
|
||||
now = clock.currentTimeMillis();
|
||||
boolean started = s.start();
|
||||
duration = clock.currentTimeMillis() - now;
|
||||
if(!started) {
|
||||
if(LOG.isLoggable(WARNING)) {
|
||||
if (!started) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
String name = s.getClass().getName();
|
||||
LOG.warning(name + " did not start");
|
||||
}
|
||||
return SERVICE_ERROR;
|
||||
}
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = s.getClass().getName();
|
||||
LOG.info("Starting " + name + " took " + duration + " ms");
|
||||
}
|
||||
}
|
||||
startupLatch.countDown();
|
||||
return SUCCESS;
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return DB_ERROR;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return DB_ERROR;
|
||||
} finally {
|
||||
startStopSemaphore.release();
|
||||
@@ -109,31 +109,31 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
public void stopServices() {
|
||||
try {
|
||||
startStopSemaphore.acquire();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting to stop services");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LOG.info("Stopping services");
|
||||
eventBus.broadcast(new ShutdownEvent());
|
||||
for(Service s : services) {
|
||||
for (Service s : services) {
|
||||
boolean stopped = s.stop();
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = s.getClass().getName();
|
||||
if(stopped) LOG.info("Service stopped: " + name);
|
||||
if (stopped) LOG.info("Service stopped: " + name);
|
||||
else LOG.warning("Service failed to stop: " + name);
|
||||
}
|
||||
}
|
||||
for(ExecutorService e : executors) e.shutdownNow();
|
||||
if(LOG.isLoggable(INFO))
|
||||
for (ExecutorService e : executors) e.shutdownNow();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(executors.size() + " executors shut down");
|
||||
db.close();
|
||||
LOG.info("Database closed");
|
||||
shutdownLatch.countDown();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} finally {
|
||||
startStopSemaphore.release();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ShutdownManagerImpl implements ShutdownManager {
|
||||
synchLock.lock();
|
||||
try {
|
||||
Thread hook = hooks.remove(handle);
|
||||
if(hook == null) return false;
|
||||
if (hook == null) return false;
|
||||
else return Runtime.getRuntime().removeShutdownHook(hook);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
|
||||
@@ -47,7 +47,7 @@ class AuthorFactoryImpl implements AuthorFactory {
|
||||
w.writeString(name);
|
||||
w.writeRaw(publicKey);
|
||||
w.writeListEnd();
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
// Shouldn't happen with ByteArrayOutputStream
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class AuthorReader implements ObjectReader<Author> {
|
||||
// Read and digest the data
|
||||
r.readListStart();
|
||||
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
||||
if(name.length() == 0) throw new FormatException();
|
||||
if (name.length() == 0) throw new FormatException();
|
||||
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||
r.readListEnd();
|
||||
// Reset the reader
|
||||
|
||||
@@ -24,11 +24,11 @@ class CountingConsumer implements Consumer {
|
||||
|
||||
public void write(byte b) throws IOException {
|
||||
count++;
|
||||
if(count > limit) throw new FormatException();
|
||||
if (count > limit) throw new FormatException();
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
count += len;
|
||||
if(count > limit) throw new FormatException();
|
||||
if (count > limit) throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,13 +114,13 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||
// Write packets until interrupted
|
||||
try {
|
||||
while(!interrupted) {
|
||||
while (!interrupted) {
|
||||
// Work out how long we should wait for a packet
|
||||
now = clock.currentTimeMillis();
|
||||
long wait = Math.min(nextKeepalive, nextRetxQuery) - now;
|
||||
if(wait < 0) wait = 0;
|
||||
if (wait < 0) wait = 0;
|
||||
// Flush any unflushed data if we're going to wait
|
||||
if(wait > 0 && dataToFlush && writerTasks.isEmpty()) {
|
||||
if (wait > 0 && dataToFlush && writerTasks.isEmpty()) {
|
||||
packetWriter.flush();
|
||||
dataToFlush = false;
|
||||
nextKeepalive = now + maxIdleTime;
|
||||
@@ -128,9 +128,9 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
// Wait for a packet
|
||||
ThrowingRunnable<IOException> task = writerTasks.poll(wait,
|
||||
MILLISECONDS);
|
||||
if(task == null) {
|
||||
if (task == null) {
|
||||
now = clock.currentTimeMillis();
|
||||
if(now >= nextRetxQuery) {
|
||||
if (now >= nextRetxQuery) {
|
||||
// Check for retransmittable packets
|
||||
dbExecutor.execute(new GenerateTransportUpdates());
|
||||
dbExecutor.execute(new GenerateSubscriptionUpdate());
|
||||
@@ -139,21 +139,21 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
nextRetxQuery = now + RETX_QUERY_INTERVAL;
|
||||
}
|
||||
if(now >= nextKeepalive) {
|
||||
if (now >= nextKeepalive) {
|
||||
// Flush the stream to keep it alive
|
||||
packetWriter.flush();
|
||||
dataToFlush = false;
|
||||
nextKeepalive = now + maxIdleTime;
|
||||
}
|
||||
} else if(task == CLOSE) {
|
||||
} else if (task == CLOSE) {
|
||||
break;
|
||||
} else {
|
||||
task.run();
|
||||
dataToFlush = true;
|
||||
}
|
||||
}
|
||||
if(dataToFlush) packetWriter.flush();
|
||||
} catch(InterruptedException e) {
|
||||
if (dataToFlush) packetWriter.flush();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.info("Interrupted while waiting for a packet to write");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
@@ -168,53 +168,53 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void eventOccurred(Event e) {
|
||||
if(e instanceof ContactRemovedEvent) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
if(c.getContactId().equals(contactId)) interrupt();
|
||||
} else if(e instanceof MessageAddedEvent) {
|
||||
if (c.getContactId().equals(contactId)) interrupt();
|
||||
} else if (e instanceof MessageAddedEvent) {
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
} else if(e instanceof MessageExpiredEvent) {
|
||||
} else if (e instanceof MessageExpiredEvent) {
|
||||
dbExecutor.execute(new GenerateRetentionUpdate());
|
||||
} else if(e instanceof LocalSubscriptionsUpdatedEvent) {
|
||||
} else if (e instanceof LocalSubscriptionsUpdatedEvent) {
|
||||
LocalSubscriptionsUpdatedEvent l =
|
||||
(LocalSubscriptionsUpdatedEvent) e;
|
||||
if(l.getAffectedContacts().contains(contactId)) {
|
||||
if (l.getAffectedContacts().contains(contactId)) {
|
||||
dbExecutor.execute(new GenerateSubscriptionUpdate());
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
}
|
||||
} else if(e instanceof LocalTransportsUpdatedEvent) {
|
||||
} else if (e instanceof LocalTransportsUpdatedEvent) {
|
||||
dbExecutor.execute(new GenerateTransportUpdates());
|
||||
} else if(e instanceof MessageRequestedEvent) {
|
||||
if(((MessageRequestedEvent) e).getContactId().equals(contactId))
|
||||
} else if (e instanceof MessageRequestedEvent) {
|
||||
if (((MessageRequestedEvent) e).getContactId().equals(contactId))
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
} else if(e instanceof MessageToAckEvent) {
|
||||
if(((MessageToAckEvent) e).getContactId().equals(contactId))
|
||||
} else if (e instanceof MessageToAckEvent) {
|
||||
if (((MessageToAckEvent) e).getContactId().equals(contactId))
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
} else if(e instanceof MessageToRequestEvent) {
|
||||
if(((MessageToRequestEvent) e).getContactId().equals(contactId))
|
||||
} else if (e instanceof MessageToRequestEvent) {
|
||||
if (((MessageToRequestEvent) e).getContactId().equals(contactId))
|
||||
dbExecutor.execute(new GenerateRequest());
|
||||
} else if(e instanceof RemoteRetentionTimeUpdatedEvent) {
|
||||
} else if (e instanceof RemoteRetentionTimeUpdatedEvent) {
|
||||
RemoteRetentionTimeUpdatedEvent r =
|
||||
(RemoteRetentionTimeUpdatedEvent) e;
|
||||
if(r.getContactId().equals(contactId))
|
||||
if (r.getContactId().equals(contactId))
|
||||
dbExecutor.execute(new GenerateRetentionAck());
|
||||
} else if(e instanceof RemoteSubscriptionsUpdatedEvent) {
|
||||
} else if (e instanceof RemoteSubscriptionsUpdatedEvent) {
|
||||
RemoteSubscriptionsUpdatedEvent r =
|
||||
(RemoteSubscriptionsUpdatedEvent) e;
|
||||
if(r.getContactId().equals(contactId)) {
|
||||
if (r.getContactId().equals(contactId)) {
|
||||
dbExecutor.execute(new GenerateSubscriptionAck());
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
}
|
||||
} else if(e instanceof RemoteTransportsUpdatedEvent) {
|
||||
} else if (e instanceof RemoteTransportsUpdatedEvent) {
|
||||
RemoteTransportsUpdatedEvent r =
|
||||
(RemoteTransportsUpdatedEvent) e;
|
||||
if(r.getContactId().equals(contactId))
|
||||
if (r.getContactId().equals(contactId))
|
||||
dbExecutor.execute(new GenerateTransportAcks());
|
||||
} else if(e instanceof ShutdownEvent) {
|
||||
} else if (e instanceof ShutdownEvent) {
|
||||
interrupt();
|
||||
} else if(e instanceof TransportRemovedEvent) {
|
||||
} else if (e instanceof TransportRemovedEvent) {
|
||||
TransportRemovedEvent t = (TransportRemovedEvent) e;
|
||||
if(t.getTransportId().equals(transportId)) interrupt();
|
||||
if (t.getTransportId().equals(transportId)) interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,15 +222,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
int maxMessages = packetWriter.getMaxMessagesForAck(Long.MAX_VALUE);
|
||||
try {
|
||||
Ack a = db.generateAck(contactId, maxMessages);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated ack: " + (a != null));
|
||||
if(a != null) writerTasks.add(new WriteAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (a != null) writerTasks.add(new WriteAck(a));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeAck(ack);
|
||||
LOG.info("Sent ack");
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
@@ -257,15 +257,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateBatch implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<byte[]> b = db.generateRequestedBatch(contactId,
|
||||
MAX_PAYLOAD_LENGTH, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated batch: " + (b != null));
|
||||
if(b != null) writerTasks.add(new WriteBatch(b));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (b != null) writerTasks.add(new WriteBatch(b));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -281,8 +281,8 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
if (interrupted) return;
|
||||
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
LOG.info("Sent batch");
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
}
|
||||
@@ -292,16 +292,16 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateOffer implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
int maxMessages = packetWriter.getMaxMessagesForOffer(
|
||||
Long.MAX_VALUE);
|
||||
try {
|
||||
Offer o = db.generateOffer(contactId, maxMessages, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated offer: " + (o != null));
|
||||
if(o != null) writerTasks.add(new WriteOffer(o));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (o != null) writerTasks.add(new WriteOffer(o));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -317,7 +317,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeOffer(offer);
|
||||
LOG.info("Sent offer");
|
||||
dbExecutor.execute(new GenerateOffer());
|
||||
@@ -328,16 +328,16 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateRequest implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
int maxMessages = packetWriter.getMaxMessagesForRequest(
|
||||
Long.MAX_VALUE);
|
||||
try {
|
||||
Request r = db.generateRequest(contactId, maxMessages);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated request: " + (r != null));
|
||||
if(r != null) writerTasks.add(new WriteRequest(r));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (r != null) writerTasks.add(new WriteRequest(r));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -353,7 +353,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRequest(request);
|
||||
LOG.info("Sent request");
|
||||
dbExecutor.execute(new GenerateRequest());
|
||||
@@ -364,14 +364,14 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateRetentionAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
RetentionAck a = db.generateRetentionAck(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated retention ack: " + (a != null));
|
||||
if(a != null) writerTasks.add(new WriteRetentionAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (a != null) writerTasks.add(new WriteRetentionAck(a));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -388,7 +388,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRetentionAck(ack);
|
||||
LOG.info("Sent retention ack");
|
||||
dbExecutor.execute(new GenerateRetentionAck());
|
||||
@@ -399,15 +399,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateRetentionUpdate implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
RetentionUpdate u =
|
||||
db.generateRetentionUpdate(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated retention update: " + (u != null));
|
||||
if(u != null) writerTasks.add(new WriteRetentionUpdate(u));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (u != null) writerTasks.add(new WriteRetentionUpdate(u));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -424,7 +424,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRetentionUpdate(update);
|
||||
LOG.info("Sent retention update");
|
||||
dbExecutor.execute(new GenerateRetentionUpdate());
|
||||
@@ -435,14 +435,14 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateSubscriptionAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
SubscriptionAck a = db.generateSubscriptionAck(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated subscription ack: " + (a != null));
|
||||
if(a != null) writerTasks.add(new WriteSubscriptionAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (a != null) writerTasks.add(new WriteSubscriptionAck(a));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeSubscriptionAck(ack);
|
||||
LOG.info("Sent subscription ack");
|
||||
dbExecutor.execute(new GenerateSubscriptionAck());
|
||||
@@ -470,15 +470,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateSubscriptionUpdate implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
SubscriptionUpdate u =
|
||||
db.generateSubscriptionUpdate(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated subscription update: " + (u != null));
|
||||
if(u != null) writerTasks.add(new WriteSubscriptionUpdate(u));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (u != null) writerTasks.add(new WriteSubscriptionUpdate(u));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -495,7 +495,7 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeSubscriptionUpdate(update);
|
||||
LOG.info("Sent subscription update");
|
||||
dbExecutor.execute(new GenerateSubscriptionUpdate());
|
||||
@@ -506,15 +506,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateTransportAcks implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<TransportAck> acks =
|
||||
db.generateTransportAcks(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated transport acks: " + (acks != null));
|
||||
if(acks != null) writerTasks.add(new WriteTransportAcks(acks));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (acks != null) writerTasks.add(new WriteTransportAcks(acks));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -530,8 +530,8 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(TransportAck a : acks) packetWriter.writeTransportAck(a);
|
||||
if (interrupted) return;
|
||||
for (TransportAck a : acks) packetWriter.writeTransportAck(a);
|
||||
LOG.info("Sent transport acks");
|
||||
dbExecutor.execute(new GenerateTransportAcks());
|
||||
}
|
||||
@@ -541,15 +541,15 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateTransportUpdates implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<TransportUpdate> t =
|
||||
db.generateTransportUpdates(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated transport updates: " + (t != null));
|
||||
if(t != null) writerTasks.add(new WriteTransportUpdates(t));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (t != null) writerTasks.add(new WriteTransportUpdates(t));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -566,8 +566,8 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(TransportUpdate u : updates)
|
||||
if (interrupted) return;
|
||||
for (TransportUpdate u : updates)
|
||||
packetWriter.writeTransportUpdate(u);
|
||||
LOG.info("Sent transport updates");
|
||||
dbExecutor.execute(new GenerateTransportUpdates());
|
||||
|
||||
@@ -40,7 +40,7 @@ class GroupFactoryImpl implements GroupFactory {
|
||||
w.writeString(name);
|
||||
w.writeRaw(salt);
|
||||
w.writeListEnd();
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
// Shouldn't happen with ByteArrayOutputStream
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ class GroupReader implements ObjectReader<Group> {
|
||||
r.addConsumer(digesting);
|
||||
r.readListStart();
|
||||
String name = r.readString(MAX_GROUP_NAME_LENGTH);
|
||||
if(name.length() == 0) throw new FormatException();
|
||||
if (name.length() == 0) throw new FormatException();
|
||||
byte[] salt = r.readRaw(GROUP_SALT_LENGTH);
|
||||
if(salt.length != GROUP_SALT_LENGTH) throw new FormatException();
|
||||
if (salt.length != GROUP_SALT_LENGTH) throw new FormatException();
|
||||
r.readListEnd();
|
||||
r.removeConsumer(digesting);
|
||||
// Build and return the group
|
||||
|
||||
@@ -70,35 +70,35 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
eventBus.addListener(this);
|
||||
try {
|
||||
// Read packets until interrupted or EOF
|
||||
while(!interrupted && !packetReader.eof()) {
|
||||
if(packetReader.hasAck()) {
|
||||
while (!interrupted && !packetReader.eof()) {
|
||||
if (packetReader.hasAck()) {
|
||||
Ack a = packetReader.readAck();
|
||||
dbExecutor.execute(new ReceiveAck(a));
|
||||
} else if(packetReader.hasMessage()) {
|
||||
} else if (packetReader.hasMessage()) {
|
||||
UnverifiedMessage m = packetReader.readMessage();
|
||||
cryptoExecutor.execute(new VerifyMessage(m));
|
||||
} else if(packetReader.hasOffer()) {
|
||||
} else if (packetReader.hasOffer()) {
|
||||
Offer o = packetReader.readOffer();
|
||||
dbExecutor.execute(new ReceiveOffer(o));
|
||||
} else if(packetReader.hasRequest()) {
|
||||
} else if (packetReader.hasRequest()) {
|
||||
Request r = packetReader.readRequest();
|
||||
dbExecutor.execute(new ReceiveRequest(r));
|
||||
} else if(packetReader.hasRetentionAck()) {
|
||||
} else if (packetReader.hasRetentionAck()) {
|
||||
RetentionAck a = packetReader.readRetentionAck();
|
||||
dbExecutor.execute(new ReceiveRetentionAck(a));
|
||||
} else if(packetReader.hasRetentionUpdate()) {
|
||||
} else if (packetReader.hasRetentionUpdate()) {
|
||||
RetentionUpdate u = packetReader.readRetentionUpdate();
|
||||
dbExecutor.execute(new ReceiveRetentionUpdate(u));
|
||||
} else if(packetReader.hasSubscriptionAck()) {
|
||||
} else if (packetReader.hasSubscriptionAck()) {
|
||||
SubscriptionAck a = packetReader.readSubscriptionAck();
|
||||
dbExecutor.execute(new ReceiveSubscriptionAck(a));
|
||||
} else if(packetReader.hasSubscriptionUpdate()) {
|
||||
} else if (packetReader.hasSubscriptionUpdate()) {
|
||||
SubscriptionUpdate u = packetReader.readSubscriptionUpdate();
|
||||
dbExecutor.execute(new ReceiveSubscriptionUpdate(u));
|
||||
} else if(packetReader.hasTransportAck()) {
|
||||
} else if (packetReader.hasTransportAck()) {
|
||||
TransportAck a = packetReader.readTransportAck();
|
||||
dbExecutor.execute(new ReceiveTransportAck(a));
|
||||
} else if(packetReader.hasTransportUpdate()) {
|
||||
} else if (packetReader.hasTransportUpdate()) {
|
||||
TransportUpdate u = packetReader.readTransportUpdate();
|
||||
dbExecutor.execute(new ReceiveTransportUpdate(u));
|
||||
} else {
|
||||
@@ -116,14 +116,14 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void eventOccurred(Event e) {
|
||||
if(e instanceof ContactRemovedEvent) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
if(c.getContactId().equals(contactId)) interrupt();
|
||||
} else if(e instanceof ShutdownEvent) {
|
||||
if (c.getContactId().equals(contactId)) interrupt();
|
||||
} else if (e instanceof ShutdownEvent) {
|
||||
interrupt();
|
||||
} else if(e instanceof TransportRemovedEvent) {
|
||||
} else if (e instanceof TransportRemovedEvent) {
|
||||
TransportRemovedEvent t = (TransportRemovedEvent) e;
|
||||
if(t.getTransportId().equals(transportId)) interrupt();
|
||||
if (t.getTransportId().equals(transportId)) interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveAck(contactId, ack);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -157,8 +157,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
try {
|
||||
Message m = messageVerifier.verifyMessage(message);
|
||||
dbExecutor.execute(new ReceiveMessage(m));
|
||||
} catch(GeneralSecurityException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -175,8 +175,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveMessage(contactId, message);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -193,8 +193,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveOffer(contactId, offer);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -211,8 +211,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveRequest(contactId, request);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -229,8 +229,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveRetentionAck(contactId, ack);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -247,8 +247,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveRetentionUpdate(contactId, update);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -265,8 +265,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveSubscriptionAck(contactId, ack);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -283,8 +283,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveSubscriptionUpdate(contactId, update);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -301,8 +301,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveTransportAck(contactId, ack);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -319,8 +319,8 @@ class IncomingSession implements MessagingSession, EventListener {
|
||||
public void run() {
|
||||
try {
|
||||
db.receiveTransportUpdate(contactId, update);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,11 +61,11 @@ class MessageFactoryImpl implements MessageFactory {
|
||||
PrivateKey privateKey, String contentType, long timestamp,
|
||||
byte[] body) throws IOException, GeneralSecurityException {
|
||||
// Validate the arguments
|
||||
if((author == null) != (privateKey == null))
|
||||
if ((author == null) != (privateKey == null))
|
||||
throw new IllegalArgumentException();
|
||||
if(StringUtils.toUtf8(contentType).length > MAX_CONTENT_TYPE_LENGTH)
|
||||
if (StringUtils.toUtf8(contentType).length > MAX_CONTENT_TYPE_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if(body.length > MAX_BODY_LENGTH)
|
||||
if (body.length > MAX_BODY_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
// Serialise the message to a buffer
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
@@ -76,17 +76,17 @@ class MessageFactoryImpl implements MessageFactory {
|
||||
Consumer digestingConsumer = new DigestingConsumer(messageDigest);
|
||||
w.addConsumer(digestingConsumer);
|
||||
Consumer signingConsumer = null;
|
||||
if(privateKey != null) {
|
||||
if (privateKey != null) {
|
||||
signature.initSign(privateKey);
|
||||
signingConsumer = new SigningConsumer(signature);
|
||||
w.addConsumer(signingConsumer);
|
||||
}
|
||||
// Write the message
|
||||
w.writeListStart();
|
||||
if(parent == null) w.writeNull();
|
||||
if (parent == null) w.writeNull();
|
||||
else w.writeRaw(parent.getBytes());
|
||||
writeGroup(w, group);
|
||||
if(author == null) w.writeNull();
|
||||
if (author == null) w.writeNull();
|
||||
else writeAuthor(w, author);
|
||||
w.writeString(contentType);
|
||||
w.writeInteger(timestamp);
|
||||
@@ -96,12 +96,12 @@ class MessageFactoryImpl implements MessageFactory {
|
||||
w.writeRaw(body);
|
||||
int bodyStart = (int) counting.getCount() - body.length;
|
||||
// Sign the message with the author's private key, if there is one
|
||||
if(privateKey == null) {
|
||||
if (privateKey == null) {
|
||||
w.writeNull();
|
||||
} else {
|
||||
w.removeConsumer(signingConsumer);
|
||||
byte[] sig = signature.sign();
|
||||
if(sig.length > MAX_SIGNATURE_LENGTH)
|
||||
if (sig.length > MAX_SIGNATURE_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
w.writeRaw(sig);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ class MessageImpl implements Message {
|
||||
public MessageImpl(MessageId id, MessageId parent, Group group,
|
||||
Author author, String contentType, long timestamp,
|
||||
byte[] raw, int bodyStart, int bodyLength) {
|
||||
if(bodyStart + bodyLength > raw.length)
|
||||
if (bodyStart + bodyLength > raw.length)
|
||||
throw new IllegalArgumentException();
|
||||
if(bodyLength > MAX_BODY_LENGTH)
|
||||
if (bodyLength > MAX_BODY_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
|
||||
@@ -37,27 +37,27 @@ class MessageReader implements ObjectReader<UnverifiedMessage> {
|
||||
r.readListStart();
|
||||
// Read the parent's message ID, if there is one
|
||||
MessageId parent = null;
|
||||
if(r.hasNull()) {
|
||||
if (r.hasNull()) {
|
||||
r.readNull();
|
||||
} else {
|
||||
byte[] b = r.readRaw(UniqueId.LENGTH);
|
||||
if(b.length < UniqueId.LENGTH) throw new FormatException();
|
||||
if (b.length < UniqueId.LENGTH) throw new FormatException();
|
||||
parent = new MessageId(b);
|
||||
}
|
||||
// Read the group
|
||||
Group group = groupReader.readObject(r);
|
||||
// Read the author, if there is one
|
||||
Author author = null;
|
||||
if(r.hasNull()) r.readNull();
|
||||
if (r.hasNull()) r.readNull();
|
||||
else author = authorReader.readObject(r);
|
||||
// Read the content type
|
||||
String contentType = r.readString(MAX_CONTENT_TYPE_LENGTH);
|
||||
// Read the timestamp
|
||||
long timestamp = r.readInteger();
|
||||
if(timestamp < 0) throw new FormatException();
|
||||
if (timestamp < 0) throw new FormatException();
|
||||
// Read the salt
|
||||
byte[] salt = r.readRaw(MESSAGE_SALT_LENGTH);
|
||||
if(salt.length < MESSAGE_SALT_LENGTH) throw new FormatException();
|
||||
if (salt.length < MESSAGE_SALT_LENGTH) throw new FormatException();
|
||||
// Read the message body
|
||||
byte[] body = r.readRaw(MAX_BODY_LENGTH);
|
||||
// Record the offset of the body within the message
|
||||
@@ -66,7 +66,7 @@ class MessageReader implements ObjectReader<UnverifiedMessage> {
|
||||
int signedLength = (int) counting.getCount();
|
||||
// Read the author's signature, if there is one
|
||||
byte[] signature = null;
|
||||
if(author == null) r.readNull();
|
||||
if (author == null) r.readNull();
|
||||
else signature = r.readRaw(MAX_SIGNATURE_LENGTH);
|
||||
// Read the end of the message
|
||||
r.readListEnd();
|
||||
|
||||
@@ -42,7 +42,7 @@ class MessageVerifierImpl implements MessageVerifier {
|
||||
MessageDigest messageDigest = crypto.getMessageDigest();
|
||||
Signature signature = crypto.getSignature();
|
||||
// Reject the message if it's too far in the future
|
||||
if(m.getTimestamp() > clock.currentTimeMillis() + MAX_CLOCK_DIFFERENCE)
|
||||
if (m.getTimestamp() > clock.currentTimeMillis() + MAX_CLOCK_DIFFERENCE)
|
||||
throw new GeneralSecurityException();
|
||||
// Hash the message to get the message ID
|
||||
byte[] raw = m.getSerialised();
|
||||
@@ -50,18 +50,18 @@ class MessageVerifierImpl implements MessageVerifier {
|
||||
MessageId id = new MessageId(messageDigest.digest());
|
||||
// Verify the author's signature, if there is one
|
||||
Author author = m.getAuthor();
|
||||
if(author != null) {
|
||||
if (author != null) {
|
||||
PublicKey k = keyParser.parsePublicKey(author.getPublicKey());
|
||||
signature.initVerify(k);
|
||||
signature.update(raw, 0, m.getSignedLength());
|
||||
if(!signature.verify(m.getSignature()))
|
||||
if (!signature.verify(m.getSignature()))
|
||||
throw new GeneralSecurityException();
|
||||
}
|
||||
Message verified = new MessageImpl(id, m.getParent(), m.getGroup(),
|
||||
author, m.getContentType(), m.getTimestamp(), raw,
|
||||
m.getBodyStart(), m.getBodyLength());
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Verifying message took " + duration + " ms");
|
||||
return verified;
|
||||
}
|
||||
|
||||
@@ -77,32 +77,32 @@ class PacketReaderImpl implements PacketReader {
|
||||
assert state == State.BUFFER_EMPTY;
|
||||
// Read the header
|
||||
int offset = 0;
|
||||
while(offset < HEADER_LENGTH) {
|
||||
while (offset < HEADER_LENGTH) {
|
||||
int read = in.read(header, offset, HEADER_LENGTH - offset);
|
||||
if(read == -1) {
|
||||
if(offset > 0) throw new FormatException();
|
||||
if (read == -1) {
|
||||
if (offset > 0) throw new FormatException();
|
||||
state = State.EOF;
|
||||
return;
|
||||
}
|
||||
offset += read;
|
||||
}
|
||||
// Check the protocol version
|
||||
if(header[0] != PROTOCOL_VERSION) throw new FormatException();
|
||||
if (header[0] != PROTOCOL_VERSION) throw new FormatException();
|
||||
// Read the payload length
|
||||
payloadLength = ByteUtils.readUint16(header, 2);
|
||||
if(payloadLength > MAX_PAYLOAD_LENGTH) throw new FormatException();
|
||||
if (payloadLength > MAX_PAYLOAD_LENGTH) throw new FormatException();
|
||||
// Read the payload
|
||||
offset = 0;
|
||||
while(offset < payloadLength) {
|
||||
while (offset < payloadLength) {
|
||||
int read = in.read(payload, offset, payloadLength - offset);
|
||||
if(read == -1) throw new FormatException();
|
||||
if (read == -1) throw new FormatException();
|
||||
offset += read;
|
||||
}
|
||||
state = State.BUFFER_FULL;
|
||||
}
|
||||
|
||||
public boolean eof() throws IOException {
|
||||
if(state == State.BUFFER_EMPTY) readPacket();
|
||||
if (state == State.BUFFER_EMPTY) readPacket();
|
||||
assert state != State.BUFFER_EMPTY;
|
||||
return state == State.EOF;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public Ack readAck() throws IOException {
|
||||
if(!hasAck()) throw new FormatException();
|
||||
if (!hasAck()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -121,17 +121,17 @@ class PacketReaderImpl implements PacketReader {
|
||||
// Read the message IDs
|
||||
List<MessageId> acked = new ArrayList<MessageId>();
|
||||
r.readListStart();
|
||||
while(!r.hasListEnd()) {
|
||||
while (!r.hasListEnd()) {
|
||||
byte[] b = r.readRaw(UniqueId.LENGTH);
|
||||
if(b.length != UniqueId.LENGTH)
|
||||
if (b.length != UniqueId.LENGTH)
|
||||
throw new FormatException();
|
||||
acked.add(new MessageId(b));
|
||||
}
|
||||
if(acked.isEmpty()) throw new FormatException();
|
||||
if (acked.isEmpty()) throw new FormatException();
|
||||
r.readListEnd();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the ack
|
||||
return new Ack(Collections.unmodifiableList(acked));
|
||||
@@ -142,13 +142,13 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public UnverifiedMessage readMessage() throws IOException {
|
||||
if(!hasMessage()) throw new FormatException();
|
||||
if (!hasMessage()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
// Read and build the message
|
||||
UnverifiedMessage m = messageReader.readObject(r);
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
return m;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public Offer readOffer() throws IOException {
|
||||
if(!hasOffer()) throw new FormatException();
|
||||
if (!hasOffer()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -167,17 +167,17 @@ class PacketReaderImpl implements PacketReader {
|
||||
// Read the message IDs
|
||||
List<MessageId> offered = new ArrayList<MessageId>();
|
||||
r.readListStart();
|
||||
while(!r.hasListEnd()) {
|
||||
while (!r.hasListEnd()) {
|
||||
byte[] b = r.readRaw(UniqueId.LENGTH);
|
||||
if(b.length != UniqueId.LENGTH)
|
||||
if (b.length != UniqueId.LENGTH)
|
||||
throw new FormatException();
|
||||
offered.add(new MessageId(b));
|
||||
}
|
||||
if(offered.isEmpty()) throw new FormatException();
|
||||
if (offered.isEmpty()) throw new FormatException();
|
||||
r.readListEnd();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the offer
|
||||
return new Offer(Collections.unmodifiableList(offered));
|
||||
@@ -188,7 +188,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public Request readRequest() throws IOException {
|
||||
if(!hasRequest()) throw new FormatException();
|
||||
if (!hasRequest()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -197,17 +197,17 @@ class PacketReaderImpl implements PacketReader {
|
||||
// Read the message IDs
|
||||
r.readListStart();
|
||||
List<MessageId> requested = new ArrayList<MessageId>();
|
||||
while(!r.hasListEnd()) {
|
||||
while (!r.hasListEnd()) {
|
||||
byte[] b = r.readRaw(UniqueId.LENGTH);
|
||||
if(b.length != UniqueId.LENGTH)
|
||||
if (b.length != UniqueId.LENGTH)
|
||||
throw new FormatException();
|
||||
requested.add(new MessageId(b));
|
||||
}
|
||||
if(requested.isEmpty()) throw new FormatException();
|
||||
if (requested.isEmpty()) throw new FormatException();
|
||||
r.readListEnd();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the request
|
||||
return new Request(Collections.unmodifiableList(requested));
|
||||
@@ -218,7 +218,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public RetentionAck readRetentionAck() throws IOException {
|
||||
if(!hasRetentionAck()) throw new FormatException();
|
||||
if (!hasRetentionAck()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -226,10 +226,10 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readListStart();
|
||||
// Read the version
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the retention ack
|
||||
return new RetentionAck(version);
|
||||
@@ -240,7 +240,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public RetentionUpdate readRetentionUpdate() throws IOException {
|
||||
if(!hasRetentionUpdate()) throw new FormatException();
|
||||
if (!hasRetentionUpdate()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -248,12 +248,12 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readListStart();
|
||||
// Read the retention time and version
|
||||
long retention = r.readInteger();
|
||||
if(retention < 0) throw new FormatException();
|
||||
if (retention < 0) throw new FormatException();
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the retention update
|
||||
return new RetentionUpdate(retention, version);
|
||||
@@ -264,7 +264,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public SubscriptionAck readSubscriptionAck() throws IOException {
|
||||
if(!hasSubscriptionAck()) throw new FormatException();
|
||||
if (!hasSubscriptionAck()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -272,10 +272,10 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readListStart();
|
||||
// Read the version
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the subscription ack
|
||||
return new SubscriptionAck(version);
|
||||
@@ -286,13 +286,13 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public SubscriptionUpdate readSubscriptionUpdate() throws IOException {
|
||||
if(!hasSubscriptionUpdate()) throw new FormatException();
|
||||
if (!hasSubscriptionUpdate()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
// Read and build the subscription update
|
||||
SubscriptionUpdate u = subscriptionUpdateReader.readObject(r);
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
return u;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public TransportAck readTransportAck() throws IOException {
|
||||
if(!hasTransportAck()) throw new FormatException();
|
||||
if (!hasTransportAck()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -310,13 +310,13 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readListStart();
|
||||
// Read the transport ID and version
|
||||
String idString = r.readString(MAX_TRANSPORT_ID_LENGTH);
|
||||
if(idString.length() == 0) throw new FormatException();
|
||||
if (idString.length() == 0) throw new FormatException();
|
||||
TransportId id = new TransportId(idString);
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the transport ack
|
||||
return new TransportAck(id, version);
|
||||
@@ -327,7 +327,7 @@ class PacketReaderImpl implements PacketReader {
|
||||
}
|
||||
|
||||
public TransportUpdate readTransportUpdate() throws IOException {
|
||||
if(!hasTransportUpdate()) throw new FormatException();
|
||||
if (!hasTransportUpdate()) throw new FormatException();
|
||||
// Set up the reader
|
||||
InputStream bais = new ByteArrayInputStream(payload, 0, payloadLength);
|
||||
Reader r = readerFactory.createReader(bais);
|
||||
@@ -335,13 +335,13 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readListStart();
|
||||
// Read the transport ID
|
||||
String idString = r.readString(MAX_TRANSPORT_ID_LENGTH);
|
||||
if(idString.length() == 0) throw new FormatException();
|
||||
if (idString.length() == 0) throw new FormatException();
|
||||
TransportId id = new TransportId(idString);
|
||||
// Read the transport properties
|
||||
Map<String, String> p = new HashMap<String, String>();
|
||||
r.readMapStart();
|
||||
for(int i = 0; !r.hasMapEnd(); i++) {
|
||||
if(i == MAX_PROPERTIES_PER_TRANSPORT)
|
||||
for (int i = 0; !r.hasMapEnd(); i++) {
|
||||
if (i == MAX_PROPERTIES_PER_TRANSPORT)
|
||||
throw new FormatException();
|
||||
String key = r.readString(MAX_PROPERTY_LENGTH);
|
||||
String value = r.readString(MAX_PROPERTY_LENGTH);
|
||||
@@ -350,10 +350,10 @@ class PacketReaderImpl implements PacketReader {
|
||||
r.readMapEnd();
|
||||
// Read the version number
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the payload
|
||||
r.readListEnd();
|
||||
if(!r.eof()) throw new FormatException();
|
||||
if (!r.eof()) throw new FormatException();
|
||||
state = State.BUFFER_EMPTY;
|
||||
// Build and return the transport update
|
||||
return new TransportUpdate(id, new TransportProperties(p), version);
|
||||
|
||||
@@ -85,7 +85,7 @@ class PacketWriterImpl implements PacketWriter {
|
||||
Writer w = writerFactory.createWriter(payload);
|
||||
w.writeListStart();
|
||||
w.writeListStart();
|
||||
for(MessageId m : a.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
for (MessageId m : a.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
w.writeListEnd();
|
||||
w.writeListEnd();
|
||||
writePacket(ACK);
|
||||
@@ -103,7 +103,7 @@ class PacketWriterImpl implements PacketWriter {
|
||||
Writer w = writerFactory.createWriter(payload);
|
||||
w.writeListStart();
|
||||
w.writeListStart();
|
||||
for(MessageId m : o.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
for (MessageId m : o.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
w.writeListEnd();
|
||||
w.writeListEnd();
|
||||
writePacket(OFFER);
|
||||
@@ -114,7 +114,7 @@ class PacketWriterImpl implements PacketWriter {
|
||||
Writer w = writerFactory.createWriter(payload);
|
||||
w.writeListStart();
|
||||
w.writeListStart();
|
||||
for(MessageId m : r.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
for (MessageId m : r.getMessageIds()) w.writeRaw(m.getBytes());
|
||||
w.writeListEnd();
|
||||
w.writeListEnd();
|
||||
writePacket(REQUEST);
|
||||
@@ -154,7 +154,7 @@ class PacketWriterImpl implements PacketWriter {
|
||||
Writer w = writerFactory.createWriter(payload);
|
||||
w.writeListStart();
|
||||
w.writeListStart();
|
||||
for(Group g : u.getGroups()) {
|
||||
for (Group g : u.getGroups()) {
|
||||
w.writeListStart();
|
||||
w.writeString(g.getName());
|
||||
w.writeRaw(g.getSalt());
|
||||
|
||||
@@ -88,13 +88,13 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
// Write packets until interrupted or no more packets to write
|
||||
try {
|
||||
while(!interrupted) {
|
||||
while (!interrupted) {
|
||||
ThrowingRunnable<IOException> task = writerTasks.take();
|
||||
if(task == CLOSE) break;
|
||||
if (task == CLOSE) break;
|
||||
task.run();
|
||||
}
|
||||
packetWriter.flush();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.info("Interrupted while waiting for a packet to write");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
@@ -109,18 +109,18 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
private void decrementOutstandingQueries() {
|
||||
if(outstandingQueries.decrementAndGet() == 0) writerTasks.add(CLOSE);
|
||||
if (outstandingQueries.decrementAndGet() == 0) writerTasks.add(CLOSE);
|
||||
}
|
||||
|
||||
public void eventOccurred(Event e) {
|
||||
if(e instanceof ContactRemovedEvent) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
if(c.getContactId().equals(contactId)) interrupt();
|
||||
} else if(e instanceof ShutdownEvent) {
|
||||
if (c.getContactId().equals(contactId)) interrupt();
|
||||
} else if (e instanceof ShutdownEvent) {
|
||||
interrupt();
|
||||
} else if(e instanceof TransportRemovedEvent) {
|
||||
} else if (e instanceof TransportRemovedEvent) {
|
||||
TransportRemovedEvent t = (TransportRemovedEvent) e;
|
||||
if(t.getTransportId().equals(transportId)) interrupt();
|
||||
if (t.getTransportId().equals(transportId)) interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,16 +128,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
int maxMessages = packetWriter.getMaxMessagesForAck(Long.MAX_VALUE);
|
||||
try {
|
||||
Ack a = db.generateAck(contactId, maxMessages);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated ack: " + (a != null));
|
||||
if(a == null) decrementOutstandingQueries();
|
||||
if (a == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeAck(ack);
|
||||
LOG.info("Sent ack");
|
||||
dbExecutor.execute(new GenerateAck());
|
||||
@@ -164,16 +164,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateBatch implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<byte[]> b = db.generateBatch(contactId,
|
||||
MAX_PAYLOAD_LENGTH, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated batch: " + (b != null));
|
||||
if(b == null) decrementOutstandingQueries();
|
||||
if (b == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteBatch(b));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -189,8 +189,8 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
if (interrupted) return;
|
||||
for (byte[] raw : batch) packetWriter.writeMessage(raw);
|
||||
LOG.info("Sent batch");
|
||||
dbExecutor.execute(new GenerateBatch());
|
||||
}
|
||||
@@ -200,15 +200,15 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateRetentionAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
RetentionAck a = db.generateRetentionAck(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated retention ack: " + (a != null));
|
||||
if(a == null) decrementOutstandingQueries();
|
||||
if (a == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteRetentionAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -225,7 +225,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRetentionAck(ack);
|
||||
LOG.info("Sent retention ack");
|
||||
dbExecutor.execute(new GenerateRetentionAck());
|
||||
@@ -236,16 +236,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateRetentionUpdate implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
RetentionUpdate u =
|
||||
db.generateRetentionUpdate(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated retention update: " + (u != null));
|
||||
if(u == null) decrementOutstandingQueries();
|
||||
if (u == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteRetentionUpdate(u));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeRetentionUpdate(update);
|
||||
LOG.info("Sent retention update");
|
||||
dbExecutor.execute(new GenerateRetentionUpdate());
|
||||
@@ -273,15 +273,15 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateSubscriptionAck implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
SubscriptionAck a = db.generateSubscriptionAck(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated subscription ack: " + (a != null));
|
||||
if(a == null) decrementOutstandingQueries();
|
||||
if (a == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteSubscriptionAck(a));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -298,7 +298,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeSubscriptionAck(ack);
|
||||
LOG.info("Sent subscription ack");
|
||||
dbExecutor.execute(new GenerateSubscriptionAck());
|
||||
@@ -309,16 +309,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateSubscriptionUpdate implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
SubscriptionUpdate u =
|
||||
db.generateSubscriptionUpdate(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated subscription update: " + (u != null));
|
||||
if(u == null) decrementOutstandingQueries();
|
||||
if (u == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteSubscriptionUpdate(u));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -335,7 +335,7 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
packetWriter.writeSubscriptionUpdate(update);
|
||||
LOG.info("Sent subscription update");
|
||||
dbExecutor.execute(new GenerateSubscriptionUpdate());
|
||||
@@ -346,16 +346,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateTransportAcks implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<TransportAck> acks =
|
||||
db.generateTransportAcks(contactId);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated transport acks: " + (acks != null));
|
||||
if(acks == null) decrementOutstandingQueries();
|
||||
if (acks == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteTransportAcks(acks));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -371,8 +371,8 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(TransportAck a : acks) packetWriter.writeTransportAck(a);
|
||||
if (interrupted) return;
|
||||
for (TransportAck a : acks) packetWriter.writeTransportAck(a);
|
||||
LOG.info("Sent transport acks");
|
||||
dbExecutor.execute(new GenerateTransportAcks());
|
||||
}
|
||||
@@ -382,16 +382,16 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
private class GenerateTransportUpdates implements Runnable {
|
||||
|
||||
public void run() {
|
||||
if(interrupted) return;
|
||||
if (interrupted) return;
|
||||
try {
|
||||
Collection<TransportUpdate> t =
|
||||
db.generateTransportUpdates(contactId, maxLatency);
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Generated transport updates: " + (t != null));
|
||||
if(t == null) decrementOutstandingQueries();
|
||||
if (t == null) decrementOutstandingQueries();
|
||||
else writerTasks.add(new WriteTransportUpdates(t));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
@@ -408,8 +408,8 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if(interrupted) return;
|
||||
for(TransportUpdate u : updates)
|
||||
if (interrupted) return;
|
||||
for (TransportUpdate u : updates)
|
||||
packetWriter.writeTransportUpdate(u);
|
||||
LOG.info("Sent transport updates");
|
||||
dbExecutor.execute(new GenerateTransportUpdates());
|
||||
|
||||
@@ -36,15 +36,15 @@ class SubscriptionUpdateReader implements ObjectReader<SubscriptionUpdate> {
|
||||
List<Group> groups = new ArrayList<Group>();
|
||||
Set<GroupId> ids = new HashSet<GroupId>();
|
||||
r.readListStart();
|
||||
for(int i = 0; i < MAX_SUBSCRIPTIONS && !r.hasListEnd(); i++) {
|
||||
for (int i = 0; i < MAX_SUBSCRIPTIONS && !r.hasListEnd(); i++) {
|
||||
Group g = groupReader.readObject(r);
|
||||
if(!ids.add(g.getId())) throw new FormatException(); // Duplicate
|
||||
if (!ids.add(g.getId())) throw new FormatException(); // Duplicate
|
||||
groups.add(g);
|
||||
}
|
||||
r.readListEnd();
|
||||
// Read the version number
|
||||
long version = r.readInteger();
|
||||
if(version < 0) throw new FormatException();
|
||||
if (version < 0) throw new FormatException();
|
||||
// Read the end of the update
|
||||
r.readListEnd();
|
||||
// Reset the reader
|
||||
|
||||
@@ -84,9 +84,9 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
InputStream in = r.getInputStream();
|
||||
int offset = 0;
|
||||
while(offset < tag.length) {
|
||||
while (offset < tag.length) {
|
||||
int read = in.read(tag, offset, tag.length - offset);
|
||||
if(read == -1) throw new EOFException();
|
||||
if (read == -1) throw new EOFException();
|
||||
offset += read;
|
||||
}
|
||||
return tag;
|
||||
@@ -135,16 +135,16 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(transportId, reader);
|
||||
ctx = tagRecogniser.recogniseTag(transportId, tag);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
}
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.info("Unrecognised tag");
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
@@ -155,8 +155,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
// Create and run the incoming session
|
||||
createIncomingSession(ctx, reader).run();
|
||||
disposeReader(false, true);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, true);
|
||||
} finally {
|
||||
connectionRegistry.unregisterConnection(contactId, transportId);
|
||||
@@ -166,8 +166,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
private void disposeReader(boolean exception, boolean recognised) {
|
||||
try {
|
||||
reader.dispose(exception, recognised);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
// Allocate a stream context
|
||||
StreamContext ctx = keyManager.getStreamContext(contactId,
|
||||
transportId);
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
disposeWriter(true);
|
||||
return;
|
||||
@@ -199,8 +199,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
// Create and run the outgoing session
|
||||
createSimplexOutgoingSession(ctx, writer).run();
|
||||
disposeWriter(false);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeWriter(true);
|
||||
} finally {
|
||||
connectionRegistry.unregisterConnection(contactId, transportId);
|
||||
@@ -210,8 +210,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
private void disposeWriter(boolean exception) {
|
||||
try {
|
||||
writer.dispose(exception);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,16 +239,16 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(transportId, reader);
|
||||
ctx = tagRecogniser.recogniseTag(transportId, tag);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
}
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.info("Unrecognised tag");
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
@@ -266,8 +266,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
incomingSession = createIncomingSession(ctx, reader);
|
||||
incomingSession.run();
|
||||
disposeReader(false, true);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, true);
|
||||
} finally {
|
||||
connectionRegistry.unregisterConnection(contactId, transportId);
|
||||
@@ -278,7 +278,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
// Allocate a stream context
|
||||
StreamContext ctx = keyManager.getStreamContext(contactId,
|
||||
transportId);
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
disposeWriter(true);
|
||||
return;
|
||||
@@ -288,29 +288,29 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
outgoingSession = createDuplexOutgoingSession(ctx, writer);
|
||||
outgoingSession.run();
|
||||
disposeWriter(false);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeWriter(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeReader(boolean exception, boolean recognised) {
|
||||
if(exception && outgoingSession != null)
|
||||
if (exception && outgoingSession != null)
|
||||
outgoingSession.interrupt();
|
||||
try {
|
||||
reader.dispose(exception, recognised);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeWriter(boolean exception) {
|
||||
if(exception && incomingSession != null)
|
||||
if (exception && incomingSession != null)
|
||||
incomingSession.interrupt();
|
||||
try {
|
||||
writer.dispose(exception);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,7 +337,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
// Allocate a stream context
|
||||
StreamContext ctx = keyManager.getStreamContext(contactId,
|
||||
transportId);
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.warning("Could not allocate stream context");
|
||||
disposeWriter(true);
|
||||
return;
|
||||
@@ -354,8 +354,8 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
outgoingSession = createDuplexOutgoingSession(ctx, writer);
|
||||
outgoingSession.run();
|
||||
disposeWriter(false);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeWriter(true);
|
||||
} finally {
|
||||
connectionRegistry.unregisterConnection(contactId, transportId);
|
||||
@@ -368,23 +368,23 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(transportId, reader);
|
||||
ctx = tagRecogniser.recogniseTag(transportId, tag);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, true);
|
||||
return;
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, true);
|
||||
return;
|
||||
}
|
||||
// Unrecognised tags are suspicious in this case
|
||||
if(ctx == null) {
|
||||
if (ctx == null) {
|
||||
LOG.warning("Unrecognised tag for returning stream");
|
||||
disposeReader(true, true);
|
||||
return;
|
||||
}
|
||||
// Check that the stream comes from the expected contact
|
||||
if(!ctx.getContactId().equals(contactId)) {
|
||||
if (!ctx.getContactId().equals(contactId)) {
|
||||
LOG.warning("Wrong contact ID for returning stream");
|
||||
disposeReader(true, true);
|
||||
return;
|
||||
@@ -394,29 +394,29 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
incomingSession = createIncomingSession(ctx, reader);
|
||||
incomingSession.run();
|
||||
disposeReader(false, true);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeReader(boolean exception, boolean recognised) {
|
||||
if(exception && outgoingSession != null)
|
||||
if (exception && outgoingSession != null)
|
||||
outgoingSession.interrupt();
|
||||
try {
|
||||
reader.dispose(exception, recognised);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeWriter(boolean exception) {
|
||||
if(exception && incomingSession != null)
|
||||
if (exception && incomingSession != null)
|
||||
incomingSession.interrupt();
|
||||
try {
|
||||
writer.dispose(exception);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,15 +46,15 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
synchLock.lock();
|
||||
try {
|
||||
Map<ContactId, Integer> m = connections.get(t);
|
||||
if(m == null) {
|
||||
if (m == null) {
|
||||
m = new HashMap<ContactId, Integer>();
|
||||
connections.put(t, m);
|
||||
}
|
||||
Integer count = m.get(c);
|
||||
if(count == null) m.put(c, 1);
|
||||
if (count == null) m.put(c, 1);
|
||||
else m.put(c, count + 1);
|
||||
count = contactCounts.get(c);
|
||||
if(count == null) {
|
||||
if (count == null) {
|
||||
firstConnection = true;
|
||||
contactCounts.put(c, 1);
|
||||
} else {
|
||||
@@ -64,7 +64,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
synchLock.unlock();
|
||||
}
|
||||
|
||||
if(firstConnection) {
|
||||
if (firstConnection) {
|
||||
LOG.info("Contact connected");
|
||||
eventBus.broadcast(new ContactConnectedEvent(c));
|
||||
}
|
||||
@@ -76,17 +76,17 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
synchLock.lock();
|
||||
try {
|
||||
Map<ContactId, Integer> m = connections.get(t);
|
||||
if(m == null) throw new IllegalArgumentException();
|
||||
if (m == null) throw new IllegalArgumentException();
|
||||
Integer count = m.remove(c);
|
||||
if(count == null) throw new IllegalArgumentException();
|
||||
if(count == 1) {
|
||||
if(m.isEmpty()) connections.remove(t);
|
||||
if (count == null) throw new IllegalArgumentException();
|
||||
if (count == 1) {
|
||||
if (m.isEmpty()) connections.remove(t);
|
||||
} else {
|
||||
m.put(c, count - 1);
|
||||
}
|
||||
count = contactCounts.get(c);
|
||||
if(count == null) throw new IllegalArgumentException();
|
||||
if(count == 1) {
|
||||
if (count == null) throw new IllegalArgumentException();
|
||||
if (count == 1) {
|
||||
lastConnection = true;
|
||||
contactCounts.remove(c);
|
||||
} else {
|
||||
@@ -96,7 +96,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
synchLock.unlock();
|
||||
}
|
||||
|
||||
if(lastConnection) {
|
||||
if (lastConnection) {
|
||||
LOG.info("Contact disconnected");
|
||||
eventBus.broadcast(new ContactDisconnectedEvent(c));
|
||||
}
|
||||
@@ -107,9 +107,9 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
synchLock.lock();
|
||||
try {
|
||||
Map<ContactId, Integer> m = connections.get(t);
|
||||
if(m == null) return Collections.emptyList();
|
||||
if (m == null) return Collections.emptyList();
|
||||
List<ContactId> ids = new ArrayList<ContactId>(m.keySet());
|
||||
if(LOG.isLoggable(INFO)) LOG.info(ids.size() + " contacts connected");
|
||||
if (LOG.isLoggable(INFO)) LOG.info(ids.size() + " contacts connected");
|
||||
return Collections.unmodifiableList(ids);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
|
||||
@@ -84,20 +84,20 @@ class PluginManagerImpl implements PluginManager {
|
||||
Collection<SimplexPluginFactory> sFactories =
|
||||
simplexPluginConfig.getFactories();
|
||||
final CountDownLatch sLatch = new CountDownLatch(sFactories.size());
|
||||
for(SimplexPluginFactory factory : sFactories)
|
||||
for (SimplexPluginFactory factory : sFactories)
|
||||
ioExecutor.execute(new SimplexPluginStarter(factory, sLatch));
|
||||
// Instantiate and start the duplex plugins
|
||||
LOG.info("Starting duplex plugins");
|
||||
Collection<DuplexPluginFactory> dFactories =
|
||||
duplexPluginConfig.getFactories();
|
||||
final CountDownLatch dLatch = new CountDownLatch(dFactories.size());
|
||||
for(DuplexPluginFactory factory : dFactories)
|
||||
for (DuplexPluginFactory factory : dFactories)
|
||||
ioExecutor.execute(new DuplexPluginStarter(factory, dLatch));
|
||||
// Wait for the plugins to start
|
||||
try {
|
||||
sLatch.await();
|
||||
dLatch.await();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while starting plugins");
|
||||
Thread.currentThread().interrupt();
|
||||
return false;
|
||||
@@ -112,11 +112,11 @@ class PluginManagerImpl implements PluginManager {
|
||||
final CountDownLatch latch = new CountDownLatch(plugins.size());
|
||||
// Stop the simplex plugins
|
||||
LOG.info("Stopping simplex plugins");
|
||||
for(SimplexPlugin plugin : simplexPlugins)
|
||||
for (SimplexPlugin plugin : simplexPlugins)
|
||||
ioExecutor.execute(new PluginStopper(plugin, latch));
|
||||
// Stop the duplex plugins
|
||||
LOG.info("Stopping duplex plugins");
|
||||
for(DuplexPlugin plugin : duplexPlugins)
|
||||
for (DuplexPlugin plugin : duplexPlugins)
|
||||
ioExecutor.execute(new PluginStopper(plugin, latch));
|
||||
plugins.clear();
|
||||
simplexPlugins.clear();
|
||||
@@ -124,7 +124,7 @@ class PluginManagerImpl implements PluginManager {
|
||||
// Wait for all the plugins to stop
|
||||
try {
|
||||
latch.await();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while stopping plugins");
|
||||
Thread.currentThread().interrupt();
|
||||
return false;
|
||||
@@ -138,8 +138,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
|
||||
public Collection<DuplexPlugin> getInvitationPlugins() {
|
||||
List<DuplexPlugin> supported = new ArrayList<DuplexPlugin>();
|
||||
for(DuplexPlugin d : duplexPlugins)
|
||||
if(d.supportsInvitations()) supported.add(d);
|
||||
for (DuplexPlugin d : duplexPlugins)
|
||||
if (d.supportsInvitations()) supported.add(d);
|
||||
return Collections.unmodifiableList(supported);
|
||||
}
|
||||
|
||||
@@ -159,8 +159,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
TransportId id = factory.getId();
|
||||
SimplexCallback callback = new SimplexCallback(id);
|
||||
SimplexPlugin plugin = factory.createPlugin(callback);
|
||||
if(plugin == null) {
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (plugin == null) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = factory.getClass().getSimpleName();
|
||||
LOG.info(name + " did not create a plugin");
|
||||
}
|
||||
@@ -170,10 +170,10 @@ class PluginManagerImpl implements PluginManager {
|
||||
long start = clock.currentTimeMillis();
|
||||
db.addTransport(id, plugin.getMaxLatency());
|
||||
long duration = clock.currentTimeMillis() - start;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Adding transport took " + duration + " ms");
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
return;
|
||||
}
|
||||
@@ -181,23 +181,23 @@ class PluginManagerImpl implements PluginManager {
|
||||
long start = clock.currentTimeMillis();
|
||||
boolean started = plugin.start();
|
||||
long duration = clock.currentTimeMillis() - start;
|
||||
if(started) {
|
||||
if (started) {
|
||||
plugins.put(id, plugin);
|
||||
simplexPlugins.add(plugin);
|
||||
if(plugin.shouldPoll()) poller.addPlugin(plugin);
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (plugin.shouldPoll()) poller.addPlugin(plugin);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = plugin.getClass().getSimpleName();
|
||||
LOG.info("Starting " + name + " took " +
|
||||
duration + " ms");
|
||||
}
|
||||
} else {
|
||||
if(LOG.isLoggable(WARNING)) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
String name = plugin.getClass().getSimpleName();
|
||||
LOG.warning(name + " did not start");
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
} finally {
|
||||
@@ -222,8 +222,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
TransportId id = factory.getId();
|
||||
DuplexCallback callback = new DuplexCallback(id);
|
||||
DuplexPlugin plugin = factory.createPlugin(callback);
|
||||
if(plugin == null) {
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (plugin == null) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = factory.getClass().getSimpleName();
|
||||
LOG.info(name + " did not create a plugin");
|
||||
}
|
||||
@@ -233,10 +233,10 @@ class PluginManagerImpl implements PluginManager {
|
||||
long start = clock.currentTimeMillis();
|
||||
db.addTransport(id, plugin.getMaxLatency());
|
||||
long duration = clock.currentTimeMillis() - start;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Adding transport took " + duration + " ms");
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
return;
|
||||
}
|
||||
@@ -244,23 +244,23 @@ class PluginManagerImpl implements PluginManager {
|
||||
long start = clock.currentTimeMillis();
|
||||
boolean started = plugin.start();
|
||||
long duration = clock.currentTimeMillis() - start;
|
||||
if(started) {
|
||||
if (started) {
|
||||
plugins.put(id, plugin);
|
||||
duplexPlugins.add(plugin);
|
||||
if(plugin.shouldPoll()) poller.addPlugin(plugin);
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (plugin.shouldPoll()) poller.addPlugin(plugin);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = plugin.getClass().getSimpleName();
|
||||
LOG.info("Starting " + name + " took " +
|
||||
duration + " ms");
|
||||
}
|
||||
} else {
|
||||
if(LOG.isLoggable(WARNING)) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
String name = plugin.getClass().getSimpleName();
|
||||
LOG.warning(name + " did not start");
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
} finally {
|
||||
@@ -284,12 +284,12 @@ class PluginManagerImpl implements PluginManager {
|
||||
long start = clock.currentTimeMillis();
|
||||
plugin.stop();
|
||||
long duration = clock.currentTimeMillis() - start;
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
String name = plugin.getClass().getSimpleName();
|
||||
LOG.info("Stopping " + name + " took " + duration + " ms");
|
||||
}
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
@@ -307,8 +307,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
public TransportConfig getConfig() {
|
||||
try {
|
||||
return db.getConfig(id);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return new TransportConfig();
|
||||
}
|
||||
}
|
||||
@@ -317,8 +317,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
try {
|
||||
TransportProperties p = db.getLocalProperties(id);
|
||||
return p == null ? new TransportProperties() : p;
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return new TransportProperties();
|
||||
}
|
||||
}
|
||||
@@ -326,8 +326,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
public Map<ContactId, TransportProperties> getRemoteProperties() {
|
||||
try {
|
||||
return db.getRemoteProperties(id);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
@@ -335,16 +335,16 @@ class PluginManagerImpl implements PluginManager {
|
||||
public void mergeConfig(TransportConfig c) {
|
||||
try {
|
||||
db.mergeConfig(id, c);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void mergeLocalProperties(TransportProperties p) {
|
||||
try {
|
||||
db.mergeLocalProperties(id, p);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ class PluginManagerImpl implements PluginManager {
|
||||
|
||||
public void pollNow() {
|
||||
Plugin p = plugins.get(id);
|
||||
if(p != null) poller.pollNow(p);
|
||||
if (p != null) poller.pollNow(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,14 +41,14 @@ class PollerImpl implements Poller {
|
||||
private void schedule(Plugin plugin, boolean randomise) {
|
||||
long interval = plugin.getPollingInterval();
|
||||
// Randomise intervals at startup to spread out connection attempts
|
||||
if(randomise) interval = (long) (interval * Math.random());
|
||||
if (randomise) interval = (long) (interval * Math.random());
|
||||
timer.schedule(new PollTask(plugin), interval);
|
||||
}
|
||||
|
||||
public void pollNow(final Plugin p) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Polling " + p.getClass().getSimpleName());
|
||||
p.poll(connectionRegistry.getConnectedContacts(p.getId()));
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ public abstract class FilePlugin implements SimplexPlugin {
|
||||
}
|
||||
|
||||
public TransportConnectionWriter createWriter(ContactId c) {
|
||||
if(!running) return null;
|
||||
if (!running) return null;
|
||||
return createWriter(createConnectionFilename());
|
||||
}
|
||||
|
||||
private String createConnectionFilename() {
|
||||
StringBuilder s = new StringBuilder(12);
|
||||
for(int i = 0; i < 8; i++) s.append((char) ('a' + Math.random() * 26));
|
||||
for (int i = 0; i < 8; i++) s.append((char) ('a' + Math.random() * 26));
|
||||
s.append(".dat");
|
||||
return s.toString();
|
||||
}
|
||||
@@ -79,24 +79,24 @@ public abstract class FilePlugin implements SimplexPlugin {
|
||||
}
|
||||
|
||||
private TransportConnectionWriter createWriter(String filename) {
|
||||
if(!running) return null;
|
||||
if (!running) return null;
|
||||
File dir = chooseOutputDirectory();
|
||||
if(dir == null || !dir.exists() || !dir.isDirectory()) return null;
|
||||
if (dir == null || !dir.exists() || !dir.isDirectory()) return null;
|
||||
File f = new File(dir, filename);
|
||||
try {
|
||||
long capacity = fileUtils.getFreeSpace(dir);
|
||||
if(capacity < MIN_STREAM_LENGTH) return null;
|
||||
if (capacity < MIN_STREAM_LENGTH) return null;
|
||||
OutputStream out = new FileOutputStream(f);
|
||||
return new FileTransportWriter(f, out, capacity, this);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
f.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void createReaderFromFile(final File f) {
|
||||
if(!running) return;
|
||||
if (!running) return;
|
||||
ioExecutor.execute(new ReaderCreator(f));
|
||||
}
|
||||
|
||||
@@ -109,13 +109,13 @@ public abstract class FilePlugin implements SimplexPlugin {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if(isPossibleConnectionFilename(file.getName())) {
|
||||
if (isPossibleConnectionFilename(file.getName())) {
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
callback.readerCreated(new FileTransportReader(file, in,
|
||||
FilePlugin.this));
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ class FileTransportReader implements TransportConnectionReader {
|
||||
public void dispose(boolean exception, boolean recognised) {
|
||||
try {
|
||||
in.close();
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
if(recognised) {
|
||||
if (recognised) {
|
||||
file.delete();
|
||||
plugin.readerFinished(file);
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ class FileTransportWriter implements TransportConnectionWriter {
|
||||
public void dispose(boolean exception) {
|
||||
try {
|
||||
out.close();
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
if(exception) file.delete();
|
||||
if (exception) file.delete();
|
||||
else plugin.writerFinished(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
String oldAddress = p.get("address"), oldPort = p.get("port");
|
||||
InetSocketAddress old = parseSocketAddress(oldAddress, oldPort);
|
||||
List<SocketAddress> addrs = new LinkedList<SocketAddress>();
|
||||
for(InetAddress a : getLocalIpAddresses()) {
|
||||
if(isAcceptableAddress(a)) {
|
||||
for (InetAddress a : getLocalIpAddresses()) {
|
||||
if (isAcceptableAddress(a)) {
|
||||
// If this is the old address, try to use the same port
|
||||
if(old != null && old.getAddress().equals(a))
|
||||
if (old != null && old.getAddress().equals(a))
|
||||
addrs.add(0, new InetSocketAddress(a, old.getPort()));
|
||||
addrs.add(new InetSocketAddress(a, 0));
|
||||
}
|
||||
@@ -54,10 +54,10 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
|
||||
@Override
|
||||
protected boolean isConnectable(InetSocketAddress remote) {
|
||||
if(remote.getPort() == 0) return false;
|
||||
if(!isAcceptableAddress(remote.getAddress())) return false;
|
||||
if (remote.getPort() == 0) return false;
|
||||
if (!isAcceptableAddress(remote.getAddress())) return false;
|
||||
// Try to determine whether the address is on the same LAN as us
|
||||
if(socket == null) return false;
|
||||
if (socket == null) return false;
|
||||
byte[] localIp = socket.getInetAddress().getAddress();
|
||||
byte[] remoteIp = remote.getAddress().getAddress();
|
||||
return addressesAreOnSameLan(localIp, remoteIp);
|
||||
@@ -66,12 +66,12 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
// Package access for testing
|
||||
boolean addressesAreOnSameLan(byte[] localIp, byte[] remoteIp) {
|
||||
// 10.0.0.0/8
|
||||
if(localIp[0] == 10) return remoteIp[0] == 10;
|
||||
if (localIp[0] == 10) return remoteIp[0] == 10;
|
||||
// 172.16.0.0/12
|
||||
if(localIp[0] == (byte) 172 && (localIp[1] & 0xF0) == 16)
|
||||
if (localIp[0] == (byte) 172 && (localIp[1] & 0xF0) == 16)
|
||||
return remoteIp[0] == (byte) 172 && (remoteIp[1] & 0xF0) == 16;
|
||||
// 192.168.0.0/16
|
||||
if(localIp[0] == (byte) 192 && localIp[1] == (byte) 168)
|
||||
if (localIp[0] == (byte) 192 && localIp[1] == (byte) 168)
|
||||
return remoteIp[0] == (byte) 192 && remoteIp[1] == (byte) 168;
|
||||
// Unrecognised prefix - may be compatible
|
||||
return true;
|
||||
|
||||
@@ -30,18 +30,18 @@ class PortMapperImpl implements PortMapper {
|
||||
}
|
||||
|
||||
public MappingResult map(final int port) {
|
||||
if(!started.getAndSet(true)) start();
|
||||
if(gateway == null) return null;
|
||||
if (!started.getAndSet(true)) start();
|
||||
if (gateway == null) return null;
|
||||
InetAddress internal = gateway.getLocalAddress();
|
||||
if(internal == null) return null;
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (internal == null) return null;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Internal address " + getHostAddress(internal));
|
||||
boolean succeeded = false;
|
||||
InetAddress external = null;
|
||||
try {
|
||||
succeeded = gateway.addPortMapping(port, port,
|
||||
getHostAddress(internal), "TCP", "TCP");
|
||||
if(succeeded) {
|
||||
if (succeeded) {
|
||||
shutdownManager.addShutdownHook(new Runnable() {
|
||||
public void run() {
|
||||
deleteMapping(port);
|
||||
@@ -49,14 +49,14 @@ class PortMapperImpl implements PortMapper {
|
||||
});
|
||||
}
|
||||
String externalString = gateway.getExternalIPAddress();
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("External address " + externalString);
|
||||
if(externalString != null)
|
||||
if (externalString != null)
|
||||
external = InetAddress.getByName(externalString);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch(SAXException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
return new MappingResult(internal, external, port, succeeded);
|
||||
}
|
||||
@@ -64,7 +64,7 @@ class PortMapperImpl implements PortMapper {
|
||||
private String getHostAddress(InetAddress a) {
|
||||
String addr = a.getHostAddress();
|
||||
int percent = addr.indexOf('%');
|
||||
if(percent == -1) return addr;
|
||||
if (percent == -1) return addr;
|
||||
return addr.substring(0, percent);
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ class PortMapperImpl implements PortMapper {
|
||||
GatewayDiscover d = new GatewayDiscover();
|
||||
try {
|
||||
d.discover();
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch(SAXException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch(ParserConfigurationException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (ParserConfigurationException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
gateway = d.getValidGateway();
|
||||
}
|
||||
@@ -85,12 +85,12 @@ class PortMapperImpl implements PortMapper {
|
||||
private void deleteMapping(int port) {
|
||||
try {
|
||||
gateway.deletePortMapping(port, "TCP");
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Deleted mapping for port " + port);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch(SAXException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
this.maxLatency = maxLatency;
|
||||
this.maxIdleTime = maxIdleTime;
|
||||
this.pollingInterval = pollingInterval;
|
||||
if(maxIdleTime > Integer.MAX_VALUE / 2)
|
||||
if (maxIdleTime > Integer.MAX_VALUE / 2)
|
||||
socketTimeout = Integer.MAX_VALUE;
|
||||
else socketTimeout = maxIdleTime * 2;
|
||||
}
|
||||
@@ -80,32 +80,32 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
protected void bind() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
if(!running) return;
|
||||
if (!running) return;
|
||||
ServerSocket ss = null;
|
||||
for(SocketAddress addr : getLocalSocketAddresses()) {
|
||||
for (SocketAddress addr : getLocalSocketAddresses()) {
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.bind(addr);
|
||||
break;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Failed to bind " + addr);
|
||||
tryToClose(ss);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(ss == null || !ss.isBound()) {
|
||||
if (ss == null || !ss.isBound()) {
|
||||
LOG.info("Could not bind server socket");
|
||||
return;
|
||||
}
|
||||
if(!running) {
|
||||
if (!running) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
socket = ss;
|
||||
SocketAddress local = ss.getLocalSocketAddress();
|
||||
setLocalSocketAddress((InetSocketAddress) local);
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Listening on " + local);
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Listening on " + local);
|
||||
callback.pollNow();
|
||||
acceptContactConnections();
|
||||
}
|
||||
@@ -114,9 +114,9 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
|
||||
protected void tryToClose(ServerSocket ss) {
|
||||
try {
|
||||
if(ss != null) ss.close();
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (ss != null) ss.close();
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,17 +134,17 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
}
|
||||
|
||||
private void acceptContactConnections() {
|
||||
while(isRunning()) {
|
||||
while (isRunning()) {
|
||||
Socket s;
|
||||
try {
|
||||
s = socket.accept();
|
||||
s.setSoTimeout(socketTimeout);
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
// This is expected when the socket is closed
|
||||
if(LOG.isLoggable(INFO)) LOG.info(e.toString());
|
||||
if (LOG.isLoggable(INFO)) LOG.info(e.toString());
|
||||
return;
|
||||
}
|
||||
if(LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Connection from " + s.getRemoteSocketAddress());
|
||||
TcpTransportConnection conn = new TcpTransportConnection(this, s);
|
||||
callback.incomingConnectionCreated(conn);
|
||||
@@ -169,26 +169,26 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
}
|
||||
|
||||
public void poll(Collection<ContactId> connected) {
|
||||
if(!isRunning()) return;
|
||||
for(ContactId c : callback.getRemoteProperties().keySet())
|
||||
if(!connected.contains(c)) connectAndCallBack(c);
|
||||
if (!isRunning()) return;
|
||||
for (ContactId c : callback.getRemoteProperties().keySet())
|
||||
if (!connected.contains(c)) connectAndCallBack(c);
|
||||
}
|
||||
|
||||
private void connectAndCallBack(final ContactId c) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
DuplexTransportConnection d = createConnection(c);
|
||||
if(d != null) callback.outgoingConnectionCreated(c, d);
|
||||
if (d != null) callback.outgoingConnectionCreated(c, d);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DuplexTransportConnection createConnection(ContactId c) {
|
||||
if(!isRunning()) return null;
|
||||
if (!isRunning()) return null;
|
||||
InetSocketAddress remote = getRemoteSocketAddress(c);
|
||||
if(remote == null) return null;
|
||||
if(!isConnectable(remote)) {
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
if (remote == null) return null;
|
||||
if (!isConnectable(remote)) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
SocketAddress local = socket.getLocalSocketAddress();
|
||||
LOG.info(remote + " is not connectable from " + local);
|
||||
}
|
||||
@@ -196,37 +196,37 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
}
|
||||
Socket s = new Socket();
|
||||
try {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Connecting to " + remote);
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Connecting to " + remote);
|
||||
s.connect(remote);
|
||||
s.setSoTimeout(socketTimeout);
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Connected to " + remote);
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Connected to " + remote);
|
||||
return new TcpTransportConnection(this, s);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Could not connect to " + remote);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Could not connect to " + remote);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InetSocketAddress getRemoteSocketAddress(ContactId c) {
|
||||
TransportProperties p = callback.getRemoteProperties().get(c);
|
||||
if(p == null) return null;
|
||||
if (p == null) return null;
|
||||
return parseSocketAddress(p.get("address"), p.get("port"));
|
||||
}
|
||||
|
||||
protected InetSocketAddress parseSocketAddress(String addr, String port) {
|
||||
if(StringUtils.isNullOrEmpty(addr)) return null;
|
||||
if(StringUtils.isNullOrEmpty(port)) return null;
|
||||
if (StringUtils.isNullOrEmpty(addr)) return null;
|
||||
if (StringUtils.isNullOrEmpty(port)) return null;
|
||||
// Ensure getByName() won't perform a DNS lookup
|
||||
if(!DOTTED_QUAD.matcher(addr).matches()) return null;
|
||||
if (!DOTTED_QUAD.matcher(addr).matches()) return null;
|
||||
try {
|
||||
InetAddress a = InetAddress.getByName(addr);
|
||||
int p = Integer.parseInt(port);
|
||||
return new InetSocketAddress(a, p);
|
||||
} catch(UnknownHostException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning("Invalid address: " + addr);
|
||||
} catch (UnknownHostException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.warning("Invalid address: " + addr);
|
||||
return null;
|
||||
} catch(NumberFormatException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning("Invalid port: " + port);
|
||||
} catch (NumberFormatException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.warning("Invalid port: " + port);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -244,12 +244,12 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
List<NetworkInterface> ifaces;
|
||||
try {
|
||||
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
} catch(SocketException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SocketException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<InetAddress> addrs = new ArrayList<InetAddress>();
|
||||
for(NetworkInterface iface : ifaces)
|
||||
for (NetworkInterface iface : ifaces)
|
||||
addrs.addAll(Collections.list(iface.getInetAddresses()));
|
||||
return addrs;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ class TcpTransportConnection implements DuplexTransportConnection {
|
||||
|
||||
public void dispose(boolean exception, boolean recognised)
|
||||
throws IOException {
|
||||
if(halfClosed.getAndSet(true) || exception)
|
||||
if(!closed.getAndSet(true)) socket.close();
|
||||
if (halfClosed.getAndSet(true) || exception)
|
||||
if (!closed.getAndSet(true)) socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ class TcpTransportConnection implements DuplexTransportConnection {
|
||||
}
|
||||
|
||||
public void dispose(boolean exception) throws IOException {
|
||||
if(halfClosed.getAndSet(true) || exception)
|
||||
if(!closed.getAndSet(true)) socket.close();
|
||||
if (halfClosed.getAndSet(true) || exception)
|
||||
if (!closed.getAndSet(true)) socket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@ class WanTcpPlugin extends TcpPlugin {
|
||||
String oldAddress = p.get("address"), oldPort = p.get("port");
|
||||
InetSocketAddress old = parseSocketAddress(oldAddress, oldPort);
|
||||
List<SocketAddress> addrs = new LinkedList<SocketAddress>();
|
||||
for(InetAddress a : getLocalIpAddresses()) {
|
||||
if(isAcceptableAddress(a)) {
|
||||
for (InetAddress a : getLocalIpAddresses()) {
|
||||
if (isAcceptableAddress(a)) {
|
||||
// If this is the old address, try to use the same port
|
||||
if(old != null && old.getAddress().equals(a))
|
||||
if (old != null && old.getAddress().equals(a))
|
||||
addrs.add(0, new InetSocketAddress(a, old.getPort()));
|
||||
addrs.add(new InetSocketAddress(a, 0));
|
||||
}
|
||||
@@ -49,9 +49,9 @@ class WanTcpPlugin extends TcpPlugin {
|
||||
// Accept interfaces with local addresses that can be port-mapped
|
||||
int port = old == null ? chooseEphemeralPort() : old.getPort();
|
||||
mappingResult = portMapper.map(port);
|
||||
if(mappingResult != null && mappingResult.isUsable()) {
|
||||
if (mappingResult != null && mappingResult.isUsable()) {
|
||||
InetSocketAddress a = mappingResult.getInternal();
|
||||
if(a.getAddress() instanceof Inet4Address) addrs.add(a);
|
||||
if (a.getAddress() instanceof Inet4Address) addrs.add(a);
|
||||
}
|
||||
return addrs;
|
||||
}
|
||||
@@ -71,15 +71,15 @@ class WanTcpPlugin extends TcpPlugin {
|
||||
|
||||
@Override
|
||||
protected boolean isConnectable(InetSocketAddress remote) {
|
||||
if(remote.getPort() == 0) return false;
|
||||
if (remote.getPort() == 0) return false;
|
||||
return isAcceptableAddress(remote.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setLocalSocketAddress(InetSocketAddress a) {
|
||||
if(mappingResult != null && mappingResult.isUsable()) {
|
||||
if (mappingResult != null && mappingResult.isUsable()) {
|
||||
// Advertise the external address to contacts
|
||||
if(a.equals(mappingResult.getInternal()))
|
||||
if (a.equals(mappingResult.getInternal()))
|
||||
a = mappingResult.getExternal();
|
||||
}
|
||||
TransportProperties p = new TransportProperties();
|
||||
|
||||
@@ -13,7 +13,7 @@ class Ack extends Frame {
|
||||
|
||||
Ack(byte[] buf) {
|
||||
super(buf);
|
||||
if(buf.length != LENGTH) throw new IllegalArgumentException();
|
||||
if (buf.length != LENGTH) throw new IllegalArgumentException();
|
||||
buf[0] = (byte) Frame.ACK_FLAG;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ class Crc32 {
|
||||
private static final long[] TABLE = new long[256];
|
||||
|
||||
static {
|
||||
for(int i = 0; i < 256; i++) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
long c = i;
|
||||
for(int j = 0; j < 8; j++) {
|
||||
if((c & 1) != 0) c = 0xedb88320L ^ (c >> 1);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if ((c & 1) != 0) c = 0xedb88320L ^ (c >> 1);
|
||||
else c >>= 1;
|
||||
}
|
||||
TABLE[i] = c;
|
||||
@@ -16,7 +16,7 @@ class Crc32 {
|
||||
}
|
||||
|
||||
private static long update(long c, byte[] b, int off, int len) {
|
||||
for(int i = off; i < off + len; i++)
|
||||
for (int i = off; i < off + len; i++)
|
||||
c = TABLE[(int) ((c ^ b[i]) & 0xff)] ^ (c >> 8);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class Data extends Frame {
|
||||
|
||||
Data(byte[] buf) {
|
||||
super(buf);
|
||||
if(buf.length < MIN_LENGTH || buf.length > MAX_LENGTH)
|
||||
if (buf.length < MIN_LENGTH || buf.length > MAX_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class Data extends Frame {
|
||||
}
|
||||
|
||||
void setLastFrame(boolean lastFrame) {
|
||||
if(lastFrame) buf[0] = (byte) Frame.FIN_FLAG;
|
||||
if (lastFrame) buf[0] = (byte) Frame.FIN_FLAG;
|
||||
}
|
||||
|
||||
int getPayloadLength() {
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract class Frame {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Frame) {
|
||||
if (o instanceof Frame) {
|
||||
Frame f = (Frame) o;
|
||||
return buf[0] == f.buf[0] &&
|
||||
getSequenceNumber() == f.getSequenceNumber();
|
||||
|
||||
@@ -43,13 +43,13 @@ class Receiver implements ReadHandler {
|
||||
windowLock.lock();
|
||||
try {
|
||||
long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT;
|
||||
while(now < end && valid) {
|
||||
if(dataFrames.isEmpty()) {
|
||||
while (now < end && valid) {
|
||||
if (dataFrames.isEmpty()) {
|
||||
// Wait for a data frame
|
||||
dataFrameAvailable.await(end - now, MILLISECONDS);
|
||||
} else {
|
||||
Data d = dataFrames.first();
|
||||
if(d.getSequenceNumber() == nextSequenceNumber) {
|
||||
if (d.getSequenceNumber() == nextSequenceNumber) {
|
||||
dataFrames.remove(d);
|
||||
// Update the window
|
||||
windowSize += d.getPayloadLength();
|
||||
@@ -63,7 +63,7 @@ class Receiver implements ReadHandler {
|
||||
}
|
||||
now = clock.currentTimeMillis();
|
||||
}
|
||||
if(valid) throw new IOException("Read timed out");
|
||||
if (valid) throw new IOException("Read timed out");
|
||||
throw new IOException("Connection closed");
|
||||
} finally {
|
||||
windowLock.unlock();
|
||||
@@ -81,7 +81,7 @@ class Receiver implements ReadHandler {
|
||||
}
|
||||
|
||||
public void handleRead(byte[] b) throws IOException {
|
||||
if(!valid) throw new IOException("Connection closed");
|
||||
if (!valid) throw new IOException("Connection closed");
|
||||
switch(b[0]) {
|
||||
case 0:
|
||||
case Frame.FIN_FLAG:
|
||||
@@ -99,36 +99,36 @@ class Receiver implements ReadHandler {
|
||||
private void handleData(byte[] b) throws IOException {
|
||||
windowLock.lock();
|
||||
try {
|
||||
if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
|
||||
if (b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
|
||||
// Ignore data frame with invalid length
|
||||
return;
|
||||
}
|
||||
Data d = new Data(b);
|
||||
int payloadLength = d.getPayloadLength();
|
||||
if(payloadLength > windowSize) return; // No space in the window
|
||||
if(d.getChecksum() != d.calculateChecksum()) {
|
||||
if (payloadLength > windowSize) return; // No space in the window
|
||||
if (d.getChecksum() != d.calculateChecksum()) {
|
||||
// Ignore data frame with invalid checksum
|
||||
return;
|
||||
}
|
||||
long sequenceNumber = d.getSequenceNumber();
|
||||
if(sequenceNumber == 0) {
|
||||
if (sequenceNumber == 0) {
|
||||
// Window probe
|
||||
} else if(sequenceNumber < nextSequenceNumber) {
|
||||
} else if (sequenceNumber < nextSequenceNumber) {
|
||||
// Duplicate data frame
|
||||
} else if(d.isLastFrame()) {
|
||||
} else if (d.isLastFrame()) {
|
||||
finalSequenceNumber = sequenceNumber;
|
||||
// Remove any data frames with higher sequence numbers
|
||||
Iterator<Data> it = dataFrames.iterator();
|
||||
while(it.hasNext()) {
|
||||
while (it.hasNext()) {
|
||||
Data d1 = it.next();
|
||||
if(d1.getSequenceNumber() >= finalSequenceNumber) it.remove();
|
||||
if (d1.getSequenceNumber() >= finalSequenceNumber) it.remove();
|
||||
}
|
||||
if(dataFrames.add(d)) {
|
||||
if (dataFrames.add(d)) {
|
||||
windowSize -= payloadLength;
|
||||
dataFrameAvailable.signalAll();
|
||||
}
|
||||
} else if(sequenceNumber < finalSequenceNumber) {
|
||||
if(dataFrames.add(d)) {
|
||||
} else if (sequenceNumber < finalSequenceNumber) {
|
||||
if (dataFrames.add(d)) {
|
||||
windowSize -= payloadLength;
|
||||
dataFrameAvailable.signalAll();
|
||||
}
|
||||
@@ -144,8 +144,8 @@ class Receiver implements ReadHandler {
|
||||
|
||||
public int compare(Data d1, Data d2) {
|
||||
long s1 = d1.getSequenceNumber(), s2 = d2.getSequenceNumber();
|
||||
if(s1 < s2) return -1;
|
||||
if(s1 > s2) return 1;
|
||||
if (s1 < s2) return -1;
|
||||
if (s1 > s2) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ class ReceiverInputStream extends InputStream {
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if(length == -1) return -1;
|
||||
while(length == 0) if(!receive()) return -1;
|
||||
if (length == -1) return -1;
|
||||
while (length == 0) if (!receive()) return -1;
|
||||
int b = data.getBuffer()[offset] & 0xff;
|
||||
offset++;
|
||||
length--;
|
||||
@@ -31,8 +31,8 @@ class ReceiverInputStream extends InputStream {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if(length == -1) return -1;
|
||||
while(length == 0) if(!receive()) return -1;
|
||||
if (length == -1) return -1;
|
||||
while (length == 0) if (!receive()) return -1;
|
||||
len = Math.min(len, length);
|
||||
System.arraycopy(data.getBuffer(), offset, b, off, len);
|
||||
offset += len;
|
||||
@@ -42,13 +42,13 @@ class ReceiverInputStream extends InputStream {
|
||||
|
||||
private boolean receive() throws IOException {
|
||||
assert length == 0;
|
||||
if(data != null && data.isLastFrame()) {
|
||||
if (data != null && data.isLastFrame()) {
|
||||
length = -1;
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
data = receiver.read();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted while reading");
|
||||
}
|
||||
|
||||
@@ -54,27 +54,27 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
|
||||
long now = clock.currentTimeMillis();
|
||||
long next = now + TICK_INTERVAL;
|
||||
try {
|
||||
while(running) {
|
||||
while (running) {
|
||||
byte[] b = null;
|
||||
while(now < next && b == null) {
|
||||
while (now < next && b == null) {
|
||||
b = writes.poll(next - now, MILLISECONDS);
|
||||
if(!running) return;
|
||||
if (!running) return;
|
||||
now = clock.currentTimeMillis();
|
||||
}
|
||||
if(b == null) {
|
||||
if (b == null) {
|
||||
sender.tick();
|
||||
while(next <= now) next += TICK_INTERVAL;
|
||||
while (next <= now) next += TICK_INTERVAL;
|
||||
} else {
|
||||
if(b.length == 0) return; // Poison pill
|
||||
if (b.length == 0) return; // Poison pill
|
||||
writeHandler.handleWrite(b);
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting to write");
|
||||
Thread.currentThread().interrupt();
|
||||
running = false;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
running = false;
|
||||
}
|
||||
@@ -98,11 +98,11 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
|
||||
|
||||
// The lower layer calls this method to pass data up to the SLIP decoder
|
||||
public void handleRead(byte[] b) throws IOException {
|
||||
if(running) decoder.handleRead(b);
|
||||
if (running) decoder.handleRead(b);
|
||||
}
|
||||
|
||||
// The SLIP encoder calls this method to pass data down to the lower layer
|
||||
public void handleWrite(byte[] b) {
|
||||
if(running && b.length > 0) writes.add(b);
|
||||
if (running && b.length > 0) writes.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ class Sender {
|
||||
}
|
||||
|
||||
void handleAck(byte[] b) throws IOException {
|
||||
if(b.length != Ack.LENGTH) {
|
||||
if (b.length != Ack.LENGTH) {
|
||||
// Ignore ack frame with invalid length
|
||||
return;
|
||||
}
|
||||
Ack a = new Ack(b);
|
||||
if(a.getChecksum() != a.calculateChecksum()) {
|
||||
if (a.getChecksum() != a.calculateChecksum()) {
|
||||
// Ignore ack frame with invalid checksum
|
||||
return;
|
||||
}
|
||||
@@ -70,27 +70,27 @@ class Sender {
|
||||
// Remove the acked data frame if it's outstanding
|
||||
int foundIndex = -1;
|
||||
Iterator<Outstanding> it = outstanding.iterator();
|
||||
for(int i = 0; it.hasNext(); i++) {
|
||||
for (int i = 0; it.hasNext(); i++) {
|
||||
Outstanding o = it.next();
|
||||
if(o.data.getSequenceNumber() == sequenceNumber) {
|
||||
if (o.data.getSequenceNumber() == sequenceNumber) {
|
||||
it.remove();
|
||||
outstandingBytes -= o.data.getPayloadLength();
|
||||
foundIndex = i;
|
||||
// Update the round-trip time and retransmission timeout
|
||||
if(!o.retransmitted) {
|
||||
if (!o.retransmitted) {
|
||||
int sample = (int) (now - o.lastTransmitted);
|
||||
int error = sample - rtt;
|
||||
rtt += (error >> 3);
|
||||
rttVar += (Math.abs(error) - rttVar) >> 2;
|
||||
rto = rtt + (rttVar << 2);
|
||||
if(rto < MIN_RTO) rto = MIN_RTO;
|
||||
else if(rto > MAX_RTO) rto = MAX_RTO;
|
||||
if (rto < MIN_RTO) rto = MIN_RTO;
|
||||
else if (rto > MAX_RTO) rto = MAX_RTO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If any older data frames are outstanding, retransmit the oldest
|
||||
if(foundIndex > 0) {
|
||||
if (foundIndex > 0) {
|
||||
fastRetransmit = outstanding.poll();
|
||||
fastRetransmit.lastTransmitted = now;
|
||||
fastRetransmit.retransmitted = true;
|
||||
@@ -102,13 +102,13 @@ class Sender {
|
||||
// Don't accept an unreasonably large window size
|
||||
windowSize = Math.min(a.getWindowSize(), MAX_WINDOW_SIZE);
|
||||
// If space has become available, notify any waiting writers
|
||||
if(windowSize > oldWindowSize || foundIndex != -1)
|
||||
if (windowSize > oldWindowSize || foundIndex != -1)
|
||||
sendWindowAvailable.signalAll();
|
||||
} finally {
|
||||
windowLock.unlock();
|
||||
}
|
||||
// Fast retransmission
|
||||
if(fastRetransmit != null)
|
||||
if (fastRetransmit != null)
|
||||
writeHandler.handleWrite(fastRetransmit.data.getBuffer());
|
||||
}
|
||||
|
||||
@@ -118,28 +118,28 @@ class Sender {
|
||||
boolean sendProbe = false;
|
||||
windowLock.lock();
|
||||
try {
|
||||
if(outstanding.isEmpty()) {
|
||||
if(dataWaiting && now - lastWindowUpdateOrProbe > rto) {
|
||||
if (outstanding.isEmpty()) {
|
||||
if (dataWaiting && now - lastWindowUpdateOrProbe > rto) {
|
||||
sendProbe = true;
|
||||
rto <<= 1;
|
||||
if(rto > MAX_RTO) rto = MAX_RTO;
|
||||
if (rto > MAX_RTO) rto = MAX_RTO;
|
||||
}
|
||||
} else {
|
||||
Iterator<Outstanding> it = outstanding.iterator();
|
||||
while(it.hasNext()) {
|
||||
while (it.hasNext()) {
|
||||
Outstanding o = it.next();
|
||||
if(now - o.lastTransmitted > rto) {
|
||||
if (now - o.lastTransmitted > rto) {
|
||||
it.remove();
|
||||
if(retransmit == null)
|
||||
if (retransmit == null)
|
||||
retransmit = new ArrayList<Outstanding>();
|
||||
retransmit.add(o);
|
||||
// Update the retransmission timeout
|
||||
rto <<= 1;
|
||||
if(rto > MAX_RTO) rto = MAX_RTO;
|
||||
if (rto > MAX_RTO) rto = MAX_RTO;
|
||||
}
|
||||
}
|
||||
if(retransmit != null) {
|
||||
for(Outstanding o : retransmit) {
|
||||
if (retransmit != null) {
|
||||
for (Outstanding o : retransmit) {
|
||||
o.lastTransmitted = now;
|
||||
o.retransmitted = true;
|
||||
outstanding.add(o);
|
||||
@@ -150,15 +150,15 @@ class Sender {
|
||||
windowLock.unlock();
|
||||
}
|
||||
// Send a window probe if necessary
|
||||
if(sendProbe) {
|
||||
if (sendProbe) {
|
||||
byte[] buf = new byte[Data.MIN_LENGTH];
|
||||
Data probe = new Data(buf);
|
||||
probe.setChecksum(probe.calculateChecksum());
|
||||
writeHandler.handleWrite(buf);
|
||||
}
|
||||
// Retransmit any lost data frames
|
||||
if(retransmit != null) {
|
||||
for(Outstanding o : retransmit)
|
||||
if (retransmit != null) {
|
||||
for (Outstanding o : retransmit)
|
||||
writeHandler.handleWrite(o.data.getBuffer());
|
||||
}
|
||||
}
|
||||
@@ -169,12 +169,12 @@ class Sender {
|
||||
try {
|
||||
// Wait for space in the window
|
||||
long now = clock.currentTimeMillis(), end = now + WRITE_TIMEOUT;
|
||||
while(now < end && outstandingBytes + payloadLength >= windowSize) {
|
||||
while (now < end && outstandingBytes + payloadLength >= windowSize) {
|
||||
dataWaiting = true;
|
||||
sendWindowAvailable.await(end - now, MILLISECONDS);
|
||||
now = clock.currentTimeMillis();
|
||||
}
|
||||
if(outstandingBytes + payloadLength >= windowSize)
|
||||
if (outstandingBytes + payloadLength >= windowSize)
|
||||
throw new IOException("Write timed out");
|
||||
outstanding.add(new Outstanding(d, now));
|
||||
outstandingBytes += payloadLength;
|
||||
@@ -188,7 +188,7 @@ class Sender {
|
||||
void flush() throws IOException, InterruptedException {
|
||||
windowLock.lock();
|
||||
try {
|
||||
while(dataWaiting || !outstanding.isEmpty())
|
||||
while (dataWaiting || !outstanding.isEmpty())
|
||||
sendWindowAvailable.await();
|
||||
} finally {
|
||||
windowLock.unlock();
|
||||
|
||||
@@ -20,7 +20,7 @@ class SenderOutputStream extends OutputStream {
|
||||
send(true);
|
||||
try {
|
||||
sender.flush();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted while closing");
|
||||
}
|
||||
@@ -28,10 +28,10 @@ class SenderOutputStream extends OutputStream {
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if(offset > Data.HEADER_LENGTH) send(false);
|
||||
if (offset > Data.HEADER_LENGTH) send(false);
|
||||
try {
|
||||
sender.flush();
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted while flushing");
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class SenderOutputStream extends OutputStream {
|
||||
public void write(int b) throws IOException {
|
||||
buf[offset] = (byte) b;
|
||||
offset++;
|
||||
if(offset == Data.HEADER_LENGTH + Data.MAX_PAYLOAD_LENGTH) send(false);
|
||||
if (offset == Data.HEADER_LENGTH + Data.MAX_PAYLOAD_LENGTH) send(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,7 +52,7 @@ class SenderOutputStream extends OutputStream {
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
||||
while(available <= len) {
|
||||
while (available <= len) {
|
||||
System.arraycopy(b, off, buf, offset, available);
|
||||
offset += available;
|
||||
send(false);
|
||||
@@ -73,7 +73,7 @@ class SenderOutputStream extends OutputStream {
|
||||
d.setChecksum(d.calculateChecksum());
|
||||
try {
|
||||
sender.write(d);
|
||||
} catch(InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Interrupted while writing");
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ class SlipDecoder implements ReadHandler {
|
||||
}
|
||||
|
||||
public void handleRead(byte[] b) throws IOException {
|
||||
for(int i = 0; i < b.length; i++) {
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
switch(b[i]) {
|
||||
case END:
|
||||
if(escape) {
|
||||
if (escape) {
|
||||
reset(true);
|
||||
} else {
|
||||
if(decodedLength > 0) {
|
||||
if (decodedLength > 0) {
|
||||
byte[] decoded = new byte[decodedLength];
|
||||
System.arraycopy(buf, 0, decoded, 0, decodedLength);
|
||||
readHandler.handleRead(decoded);
|
||||
@@ -37,31 +37,31 @@ class SlipDecoder implements ReadHandler {
|
||||
}
|
||||
break;
|
||||
case ESC:
|
||||
if(escape) reset(true);
|
||||
if (escape) reset(true);
|
||||
else escape = true;
|
||||
break;
|
||||
case TEND:
|
||||
if(escape) {
|
||||
if (escape) {
|
||||
escape = false;
|
||||
if(decodedLength == buf.length) reset(true);
|
||||
if (decodedLength == buf.length) reset(true);
|
||||
else buf[decodedLength++] = END;
|
||||
} else {
|
||||
if(decodedLength == buf.length) reset(true);
|
||||
if (decodedLength == buf.length) reset(true);
|
||||
else buf[decodedLength++] = TEND;
|
||||
}
|
||||
break;
|
||||
case TESC:
|
||||
if(escape) {
|
||||
if (escape) {
|
||||
escape = false;
|
||||
if(decodedLength == buf.length) reset(true);
|
||||
if (decodedLength == buf.length) reset(true);
|
||||
else buf[decodedLength++] = ESC;
|
||||
} else {
|
||||
if(decodedLength == buf.length) reset(true);
|
||||
if (decodedLength == buf.length) reset(true);
|
||||
else buf[decodedLength++] = TESC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(escape || decodedLength == buf.length) reset(true);
|
||||
if (escape || decodedLength == buf.length) reset(true);
|
||||
else buf[decodedLength++] = b[i];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ class SlipEncoder implements WriteHandler {
|
||||
|
||||
public void handleWrite(byte[] b) throws IOException {
|
||||
int encodedLength = b.length + 2;
|
||||
for(int i = 0; i < b.length; i++)
|
||||
if(b[i] == END || b[i] == ESC) encodedLength++;
|
||||
for (int i = 0; i < b.length; i++)
|
||||
if (b[i] == END || b[i] == ESC) encodedLength++;
|
||||
byte[] encoded = new byte[encodedLength];
|
||||
encoded[0] = END;
|
||||
for(int i = 0, j = 1; i < b.length; i++) {
|
||||
if(b[i] == END) {
|
||||
for (int i = 0, j = 1; i < b.length; i++) {
|
||||
if (b[i] == END) {
|
||||
encoded[j++] = ESC;
|
||||
encoded[j++] = TEND;
|
||||
} else if(b[i] == ESC) {
|
||||
} else if (b[i] == ESC) {
|
||||
encoded[j++] = ESC;
|
||||
encoded[j++] = TESC;
|
||||
} else {
|
||||
|
||||
@@ -40,9 +40,9 @@ class LinuxSeedProvider implements SeedProvider {
|
||||
writeToEntropyPool(out);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
// On some devices /dev/urandom isn't writable - this isn't fatal
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
// Read the seed from the pool
|
||||
try {
|
||||
@@ -50,7 +50,7 @@ class LinuxSeedProvider implements SeedProvider {
|
||||
new FileInputStream(inputFile));
|
||||
in.readFully(seed);
|
||||
in.close();
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return seed;
|
||||
@@ -61,9 +61,9 @@ class LinuxSeedProvider implements SeedProvider {
|
||||
out.writeLong(System.nanoTime());
|
||||
List<NetworkInterface> ifaces =
|
||||
Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
for(NetworkInterface i : ifaces) {
|
||||
for (NetworkInterface i : ifaces) {
|
||||
List<InetAddress> addrs = Collections.list(i.getInetAddresses());
|
||||
for(InetAddress a : addrs) out.write(a.getAddress());
|
||||
for (InetAddress a : addrs) out.write(a.getAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
try {
|
||||
secrets = db.getSecrets();
|
||||
maxLatencies.putAll(db.getTransportLatencies());
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return false;
|
||||
}
|
||||
// Work out what phase of its lifecycle each secret is in
|
||||
@@ -93,23 +93,23 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
assignSecretsToMaps(now, secrets);
|
||||
// Replace any dead secrets
|
||||
Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
|
||||
if(!created.isEmpty()) {
|
||||
if (!created.isEmpty()) {
|
||||
// Store any secrets that have been created,
|
||||
// removing any dead ones
|
||||
try {
|
||||
db.addSecrets(created);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Pass the old, current and new secrets to the recogniser
|
||||
for(TemporarySecret s : oldSecrets.values())
|
||||
for (TemporarySecret s : oldSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
for(TemporarySecret s : currentSecrets.values())
|
||||
for (TemporarySecret s : currentSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
for(TemporarySecret s : newSecrets.values())
|
||||
for (TemporarySecret s : newSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
// Schedule periodic key rotation
|
||||
timer.scheduleAtFixedRate(this, MS_BETWEEN_CHECKS,
|
||||
@@ -125,10 +125,10 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
private Collection<TemporarySecret> assignSecretsToMaps(long now,
|
||||
Collection<TemporarySecret> secrets) {
|
||||
Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
|
||||
for(TemporarySecret s : secrets) {
|
||||
for (TemporarySecret s : secrets) {
|
||||
// Discard the secret if the transport has been removed
|
||||
Integer maxLatency = maxLatencies.get(s.getTransportId());
|
||||
if(maxLatency == null) {
|
||||
if (maxLatency == null) {
|
||||
LOG.info("Discarding obsolete secret");
|
||||
continue;
|
||||
}
|
||||
@@ -137,13 +137,13 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
long activationTime = creationTime + rotation;
|
||||
long deactivationTime = activationTime + rotation;
|
||||
long destructionTime = deactivationTime + rotation;
|
||||
if(now >= destructionTime) {
|
||||
if (now >= destructionTime) {
|
||||
dead.add(s);
|
||||
} else if(now >= deactivationTime) {
|
||||
} else if (now >= deactivationTime) {
|
||||
oldSecrets.put(new EndpointKey(s), s);
|
||||
} else if(now >= activationTime) {
|
||||
} else if (now >= activationTime) {
|
||||
currentSecrets.put(new EndpointKey(s), s);
|
||||
} else if(now >= creationTime) {
|
||||
} else if (now >= creationTime) {
|
||||
newSecrets.put(new EndpointKey(s), s);
|
||||
} else {
|
||||
// FIXME: Work out what to do here
|
||||
@@ -160,13 +160,13 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
// If there are several dead secrets for an endpoint, use the newest
|
||||
Map<EndpointKey, TemporarySecret> newest =
|
||||
new HashMap<EndpointKey, TemporarySecret>();
|
||||
for(TemporarySecret s : dead) {
|
||||
for (TemporarySecret s : dead) {
|
||||
EndpointKey k = new EndpointKey(s);
|
||||
TemporarySecret exists = newest.get(k);
|
||||
if(exists == null) {
|
||||
if (exists == null) {
|
||||
// There's no other secret for this endpoint
|
||||
newest.put(k, s);
|
||||
} else if(exists.getPeriod() < s.getPeriod()) {
|
||||
} else if (exists.getPeriod() < s.getPeriod()) {
|
||||
// There's an older secret - use this one instead
|
||||
newest.put(k, s);
|
||||
} else {
|
||||
@@ -174,36 +174,36 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
}
|
||||
Collection<TemporarySecret> created = new ArrayList<TemporarySecret>();
|
||||
for(Entry<EndpointKey, TemporarySecret> e : newest.entrySet()) {
|
||||
for (Entry<EndpointKey, TemporarySecret> e : newest.entrySet()) {
|
||||
TemporarySecret s = e.getValue();
|
||||
Integer maxLatency = maxLatencies.get(s.getTransportId());
|
||||
if(maxLatency == null) throw new IllegalStateException();
|
||||
if (maxLatency == null) throw new IllegalStateException();
|
||||
// Work out which rotation period we're in
|
||||
long elapsed = now - s.getEpoch();
|
||||
long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
long period = (elapsed / rotation) + 1;
|
||||
if(period < 1) throw new IllegalStateException();
|
||||
if(period - s.getPeriod() < 2)
|
||||
if (period < 1) throw new IllegalStateException();
|
||||
if (period - s.getPeriod() < 2)
|
||||
throw new IllegalStateException();
|
||||
// Derive the old, current and new secrets
|
||||
byte[] b1 = s.getSecret();
|
||||
for(long p = s.getPeriod() + 1; p < period; p++)
|
||||
for (long p = s.getPeriod() + 1; p < period; p++)
|
||||
b1 = crypto.deriveNextSecret(b1, p);
|
||||
byte[] b2 = crypto.deriveNextSecret(b1, period);
|
||||
byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
|
||||
// Add the secrets to their respective maps if not already present
|
||||
EndpointKey k = e.getKey();
|
||||
if(!oldSecrets.containsKey(k)) {
|
||||
if (!oldSecrets.containsKey(k)) {
|
||||
TemporarySecret s1 = new TemporarySecret(s, period - 1, b1);
|
||||
oldSecrets.put(k, s1);
|
||||
created.add(s1);
|
||||
}
|
||||
if(!currentSecrets.containsKey(k)) {
|
||||
if (!currentSecrets.containsKey(k)) {
|
||||
TemporarySecret s2 = new TemporarySecret(s, period, b2);
|
||||
currentSecrets.put(k, s2);
|
||||
created.add(s2);
|
||||
}
|
||||
if(!newSecrets.containsKey(k)) {
|
||||
if (!newSecrets.containsKey(k)) {
|
||||
TemporarySecret s3 = new TemporarySecret(s, period + 1, b3);
|
||||
newSecrets.put(k, s3);
|
||||
created.add(s3);
|
||||
@@ -233,19 +233,19 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
synchLock.lock();
|
||||
try {
|
||||
TemporarySecret s = currentSecrets.get(new EndpointKey(c, t));
|
||||
if(s == null) {
|
||||
if (s == null) {
|
||||
LOG.info("No secret for endpoint");
|
||||
return null;
|
||||
}
|
||||
long streamNumber;
|
||||
try {
|
||||
streamNumber = db.incrementStreamCounter(c, t, s.getPeriod());
|
||||
if(streamNumber == -1) {
|
||||
if (streamNumber == -1) {
|
||||
LOG.info("No counter for period");
|
||||
return null;
|
||||
}
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
byte[] secret = s.getSecret();
|
||||
@@ -264,10 +264,10 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
long elapsed = clock.currentTimeMillis() - ep.getEpoch();
|
||||
long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
long period = (elapsed / rotation) + 1;
|
||||
if(period < 1) throw new IllegalStateException();
|
||||
if (period < 1) throw new IllegalStateException();
|
||||
// Derive the old, current and new secrets
|
||||
byte[] b1 = initialSecret;
|
||||
for(long p = 0; p < period; p++)
|
||||
for (long p = 0; p < period; p++)
|
||||
b1 = crypto.deriveNextSecret(b1, p);
|
||||
byte[] b2 = crypto.deriveNextSecret(b1, period);
|
||||
byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
|
||||
@@ -282,8 +282,8 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
// Store the new secrets
|
||||
try {
|
||||
db.addSecrets(Arrays.asList(s1, s2, s3));
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return;
|
||||
}
|
||||
// Pass the new secrets to the recogniser
|
||||
@@ -311,7 +311,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
long now = clock.currentTimeMillis();
|
||||
Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
|
||||
// Remove any dead secrets from the recogniser
|
||||
for(TemporarySecret s : dead) {
|
||||
for (TemporarySecret s : dead) {
|
||||
ContactId c = s.getContactId();
|
||||
TransportId t = s.getTransportId();
|
||||
long period = s.getPeriod();
|
||||
@@ -319,15 +319,15 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
// Replace any dead secrets
|
||||
Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
|
||||
if(!created.isEmpty()) {
|
||||
if (!created.isEmpty()) {
|
||||
// Store any secrets that have been created
|
||||
try {
|
||||
db.addSecrets(created);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
// Pass any secrets that have been created to the recogniser
|
||||
for(TemporarySecret s : created) tagRecogniser.addSecret(s);
|
||||
for (TemporarySecret s : created) tagRecogniser.addSecret(s);
|
||||
}
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
@@ -335,13 +335,13 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
|
||||
public void eventOccurred(Event e) {
|
||||
if(e instanceof ContactRemovedEvent) {
|
||||
if (e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
timer.schedule(new ContactRemovedTask(c), 0);
|
||||
} else if(e instanceof TransportAddedEvent) {
|
||||
} else if (e instanceof TransportAddedEvent) {
|
||||
TransportAddedEvent t = (TransportAddedEvent) e;
|
||||
timer.schedule(new TransportAddedTask(t), 0);
|
||||
} else if(e instanceof TransportRemovedEvent) {
|
||||
} else if (e instanceof TransportRemovedEvent) {
|
||||
TransportRemovedEvent t = (TransportRemovedEvent) e;
|
||||
timer.schedule(new TransportRemovedTask(t), 0);
|
||||
}
|
||||
@@ -350,15 +350,15 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
// Locking: synchLock
|
||||
private void removeSecrets(ContactId c, Map<?, TemporarySecret> m) {
|
||||
Iterator<TemporarySecret> it = m.values().iterator();
|
||||
while(it.hasNext())
|
||||
if(it.next().getContactId().equals(c)) it.remove();
|
||||
while (it.hasNext())
|
||||
if (it.next().getContactId().equals(c)) it.remove();
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void removeSecrets(TransportId t, Map<?, TemporarySecret> m) {
|
||||
Iterator<TemporarySecret> it = m.values().iterator();
|
||||
while(it.hasNext())
|
||||
if(it.next().getTransportId().equals(t)) it.remove();
|
||||
while (it.hasNext())
|
||||
if (it.next().getTransportId().equals(t)) it.remove();
|
||||
}
|
||||
|
||||
private static class EndpointKey {
|
||||
@@ -382,7 +382,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof EndpointKey) {
|
||||
if (o instanceof EndpointKey) {
|
||||
EndpointKey k = (EndpointKey) o;
|
||||
return contactId.equals(k.contactId) &&
|
||||
transportId.equals(k.transportId);
|
||||
|
||||
@@ -17,23 +17,23 @@ class ReorderingWindow {
|
||||
|
||||
ReorderingWindow() {
|
||||
unseen = new HashSet<Long>();
|
||||
for(long l = 0; l < REORDERING_WINDOW_SIZE / 2; l++) unseen.add(l);
|
||||
for (long l = 0; l < REORDERING_WINDOW_SIZE / 2; l++) unseen.add(l);
|
||||
centre = 0;
|
||||
}
|
||||
|
||||
ReorderingWindow(long centre, byte[] bitmap) {
|
||||
if(centre < 0 || centre > MAX_32_BIT_UNSIGNED + 1)
|
||||
if (centre < 0 || centre > MAX_32_BIT_UNSIGNED + 1)
|
||||
throw new IllegalArgumentException();
|
||||
if(bitmap.length != REORDERING_WINDOW_SIZE / 8)
|
||||
if (bitmap.length != REORDERING_WINDOW_SIZE / 8)
|
||||
throw new IllegalArgumentException();
|
||||
this.centre = centre;
|
||||
unseen = new HashSet<Long>();
|
||||
long bitmapBottom = centre - REORDERING_WINDOW_SIZE / 2;
|
||||
for(int bytes = 0; bytes < bitmap.length; bytes++) {
|
||||
for(int bits = 0; bits < 8; bits++) {
|
||||
for (int bytes = 0; bytes < bitmap.length; bytes++) {
|
||||
for (int bits = 0; bits < 8; bits++) {
|
||||
long streamNumber = bitmapBottom + bytes * 8 + bits;
|
||||
if(streamNumber >= 0 && streamNumber <= MAX_32_BIT_UNSIGNED) {
|
||||
if((bitmap[bytes] & (128 >> bits)) == 0)
|
||||
if (streamNumber >= 0 && streamNumber <= MAX_32_BIT_UNSIGNED) {
|
||||
if ((bitmap[bytes] & (128 >> bits)) == 0)
|
||||
unseen.add(streamNumber);
|
||||
}
|
||||
}
|
||||
@@ -47,20 +47,20 @@ class ReorderingWindow {
|
||||
Collection<Long> setSeen(long streamNumber) {
|
||||
long bottom = getBottom(centre);
|
||||
long top = getTop(centre);
|
||||
if(streamNumber < bottom || streamNumber > top)
|
||||
if (streamNumber < bottom || streamNumber > top)
|
||||
throw new IllegalArgumentException();
|
||||
if(!unseen.remove(streamNumber))
|
||||
if (!unseen.remove(streamNumber))
|
||||
throw new IllegalArgumentException();
|
||||
Collection<Long> changed = new ArrayList<Long>();
|
||||
if(streamNumber >= centre) {
|
||||
if (streamNumber >= centre) {
|
||||
centre = streamNumber + 1;
|
||||
long newBottom = getBottom(centre);
|
||||
long newTop = getTop(centre);
|
||||
for(long l = bottom; l < newBottom; l++) {
|
||||
if(unseen.remove(l)) changed.add(l);
|
||||
for (long l = bottom; l < newBottom; l++) {
|
||||
if (unseen.remove(l)) changed.add(l);
|
||||
}
|
||||
for(long l = top + 1; l <= newTop; l++) {
|
||||
if(unseen.add(l)) changed.add(l);
|
||||
for (long l = top + 1; l <= newTop; l++) {
|
||||
if (unseen.add(l)) changed.add(l);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
@@ -73,11 +73,11 @@ class ReorderingWindow {
|
||||
byte[] getBitmap() {
|
||||
byte[] bitmap = new byte[REORDERING_WINDOW_SIZE / 8];
|
||||
long bitmapBottom = centre - REORDERING_WINDOW_SIZE / 2;
|
||||
for(int bytes = 0; bytes < bitmap.length; bytes++) {
|
||||
for(int bits = 0; bits < 8; bits++) {
|
||||
for (int bytes = 0; bytes < bitmap.length; bytes++) {
|
||||
for (int bits = 0; bits < 8; bits++) {
|
||||
long streamNumber = bitmapBottom + bytes * 8 + bits;
|
||||
if(streamNumber >= 0 && streamNumber <= MAX_32_BIT_UNSIGNED) {
|
||||
if(!unseen.contains(streamNumber))
|
||||
if (streamNumber >= 0 && streamNumber <= MAX_32_BIT_UNSIGNED) {
|
||||
if (!unseen.contains(streamNumber))
|
||||
bitmap[bytes] |= 128 >> bits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ class StreamReaderImpl extends InputStream {
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
while(length <= 0) {
|
||||
if(length == -1) return -1;
|
||||
while (length <= 0) {
|
||||
if (length == -1) return -1;
|
||||
readFrame();
|
||||
}
|
||||
int b = payload[offset] & 0xff;
|
||||
@@ -38,8 +38,8 @@ class StreamReaderImpl extends InputStream {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
while(length <= 0) {
|
||||
if(length == -1) return -1;
|
||||
while (length <= 0) {
|
||||
if (length == -1) return -1;
|
||||
readFrame();
|
||||
}
|
||||
len = Math.min(len, length);
|
||||
|
||||
@@ -43,7 +43,7 @@ class StreamWriterImpl extends OutputStream {
|
||||
public void write(int b) throws IOException {
|
||||
payload[length] = (byte) b;
|
||||
length++;
|
||||
if(length == payload.length) writeFrame(false);
|
||||
if (length == payload.length) writeFrame(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +54,7 @@ class StreamWriterImpl extends OutputStream {
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
int available = payload.length - length;
|
||||
while(available <= len) {
|
||||
while (available <= len) {
|
||||
System.arraycopy(b, off, payload, length, available);
|
||||
length += available;
|
||||
writeFrame(false);
|
||||
|
||||
@@ -41,7 +41,7 @@ class TagRecogniserImpl implements TagRecogniser {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
if(r == null) return null;
|
||||
if (r == null) return null;
|
||||
return r.recogniseTag(tag);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class TagRecogniserImpl implements TagRecogniser {
|
||||
synchLock.lock();
|
||||
try {
|
||||
r = recognisers.get(t);
|
||||
if(r == null) {
|
||||
if (r == null) {
|
||||
r = new TransportTagRecogniser(crypto, db, t);
|
||||
recognisers.put(t, r);
|
||||
}
|
||||
@@ -69,13 +69,13 @@ class TagRecogniserImpl implements TagRecogniser {
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
}
|
||||
if(r != null) r.removeSecret(c, period);
|
||||
if (r != null) r.removeSecret(c, period);
|
||||
}
|
||||
|
||||
public void removeSecrets(ContactId c) {
|
||||
synchLock.lock();
|
||||
try {
|
||||
for(TransportTagRecogniser r : recognisers.values())
|
||||
for (TransportTagRecogniser r : recognisers.values())
|
||||
r.removeSecrets(c);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
@@ -95,7 +95,7 @@ class TagRecogniserImpl implements TagRecogniser {
|
||||
public void removeSecrets() {
|
||||
synchLock.lock();
|
||||
try {
|
||||
for(TransportTagRecogniser r : recognisers.values())
|
||||
for (TransportTagRecogniser r : recognisers.values())
|
||||
r.removeSecrets();
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
|
||||
@@ -48,13 +48,13 @@ class TransportTagRecogniser {
|
||||
synchLock.lock();
|
||||
try {
|
||||
TagContext t = tagMap.remove(new Bytes(tag));
|
||||
if(t == null) return null; // The tag was not expected
|
||||
if (t == null) return null; // The tag was not expected
|
||||
// Update the reordering window and the expected tags
|
||||
SecretKey key = crypto.deriveTagKey(t.secret, !t.alice);
|
||||
for(long streamNumber : t.window.setSeen(t.streamNumber)) {
|
||||
for (long streamNumber : t.window.setSeen(t.streamNumber)) {
|
||||
byte[] tag1 = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag1, key, streamNumber);
|
||||
if(streamNumber < t.streamNumber) {
|
||||
if (streamNumber < t.streamNumber) {
|
||||
TagContext removed = tagMap.remove(new Bytes(tag1));
|
||||
assert removed != null;
|
||||
} else {
|
||||
@@ -85,7 +85,7 @@ class TransportTagRecogniser {
|
||||
// Create the reordering window and the expected tags
|
||||
SecretKey key = crypto.deriveTagKey(secret, !alice);
|
||||
ReorderingWindow window = new ReorderingWindow(centre, bitmap);
|
||||
for(long streamNumber : window.getUnseen()) {
|
||||
for (long streamNumber : window.getUnseen()) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, key, streamNumber);
|
||||
TagContext added = new TagContext(contactId, alice, period,
|
||||
@@ -106,7 +106,7 @@ class TransportTagRecogniser {
|
||||
try {
|
||||
RemovalKey k = new RemovalKey(contactId, period);
|
||||
RemovalContext removed = removalMap.remove(k);
|
||||
if(removed == null) throw new IllegalArgumentException();
|
||||
if (removed == null) throw new IllegalArgumentException();
|
||||
removeSecret(removed);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
@@ -118,7 +118,7 @@ class TransportTagRecogniser {
|
||||
// Remove the expected tags
|
||||
SecretKey key = crypto.deriveTagKey(r.secret, !r.alice);
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
for(long streamNumber : r.window.getUnseen()) {
|
||||
for (long streamNumber : r.window.getUnseen()) {
|
||||
crypto.encodeTag(tag, key, streamNumber);
|
||||
TagContext removed = tagMap.remove(new Bytes(tag));
|
||||
assert removed != null;
|
||||
@@ -129,9 +129,9 @@ class TransportTagRecogniser {
|
||||
synchLock.lock();
|
||||
try {
|
||||
Collection<RemovalKey> keysToRemove = new ArrayList<RemovalKey>();
|
||||
for(RemovalKey k : removalMap.keySet())
|
||||
if(k.contactId.equals(c)) keysToRemove.add(k);
|
||||
for(RemovalKey k : keysToRemove)
|
||||
for (RemovalKey k : removalMap.keySet())
|
||||
if (k.contactId.equals(c)) keysToRemove.add(k);
|
||||
for (RemovalKey k : keysToRemove)
|
||||
removeSecret(k.contactId, k.period);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
@@ -141,7 +141,7 @@ class TransportTagRecogniser {
|
||||
void removeSecrets() {
|
||||
synchLock.lock();
|
||||
try {
|
||||
for(RemovalContext r : removalMap.values()) removeSecret(r);
|
||||
for (RemovalContext r : removalMap.values()) removeSecret(r);
|
||||
assert tagMap.isEmpty();
|
||||
removalMap.clear();
|
||||
} finally {
|
||||
@@ -191,7 +191,7 @@ class TransportTagRecogniser {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof RemovalKey) {
|
||||
if (o instanceof RemovalKey) {
|
||||
RemovalKey k = (RemovalKey) o;
|
||||
return contactId.equals(k.contactId) && period == k.period;
|
||||
}
|
||||
|
||||
@@ -13,24 +13,24 @@ public class ByteUtils {
|
||||
public static final long MAX_32_BIT_UNSIGNED = 4294967295L; // 2^32 - 1
|
||||
|
||||
public static void writeUint8(int i, byte[] b, int offset) {
|
||||
if(i < 0) throw new IllegalArgumentException();
|
||||
if(i > 255) throw new IllegalArgumentException();
|
||||
if(b.length < offset) throw new IllegalArgumentException();
|
||||
if (i < 0) throw new IllegalArgumentException();
|
||||
if (i > 255) throw new IllegalArgumentException();
|
||||
if (b.length < offset) throw new IllegalArgumentException();
|
||||
b[offset] = (byte) i;
|
||||
}
|
||||
|
||||
public static void writeUint16(int i, byte[] b, int offset) {
|
||||
if(i < 0) throw new IllegalArgumentException();
|
||||
if(i > MAX_16_BIT_UNSIGNED) throw new IllegalArgumentException();
|
||||
if(b.length < offset + 2) throw new IllegalArgumentException();
|
||||
if (i < 0) throw new IllegalArgumentException();
|
||||
if (i > MAX_16_BIT_UNSIGNED) throw new IllegalArgumentException();
|
||||
if (b.length < offset + 2) throw new IllegalArgumentException();
|
||||
b[offset] = (byte) (i >> 8);
|
||||
b[offset + 1] = (byte) (i & 0xFF);
|
||||
}
|
||||
|
||||
public static void writeUint32(long i, byte[] b, int offset) {
|
||||
if(i < 0) throw new IllegalArgumentException();
|
||||
if(i > MAX_32_BIT_UNSIGNED) throw new IllegalArgumentException();
|
||||
if(b.length < offset + 4) throw new IllegalArgumentException();
|
||||
if (i < 0) throw new IllegalArgumentException();
|
||||
if (i > MAX_32_BIT_UNSIGNED) throw new IllegalArgumentException();
|
||||
if (b.length < offset + 4) throw new IllegalArgumentException();
|
||||
b[offset] = (byte) (i >> 24);
|
||||
b[offset + 1] = (byte) (i >> 16 & 0xFF);
|
||||
b[offset + 2] = (byte) (i >> 8 & 0xFF);
|
||||
@@ -38,21 +38,21 @@ public class ByteUtils {
|
||||
}
|
||||
|
||||
public static int readUint16(byte[] b, int offset) {
|
||||
if(b.length < offset + 2) throw new IllegalArgumentException();
|
||||
if (b.length < offset + 2) throw new IllegalArgumentException();
|
||||
return ((b[offset] & 0xFF) << 8) | (b[offset + 1] & 0xFF);
|
||||
}
|
||||
|
||||
public static long readUint32(byte[] b, int offset) {
|
||||
if(b.length < offset + 4) throw new IllegalArgumentException();
|
||||
if (b.length < offset + 4) throw new IllegalArgumentException();
|
||||
return ((b[offset] & 0xFFL) << 24) | ((b[offset + 1] & 0xFFL) << 16)
|
||||
| ((b[offset + 2] & 0xFFL) << 8) | (b[offset + 3] & 0xFFL);
|
||||
}
|
||||
|
||||
public static int readUint(byte[] b, int bits) {
|
||||
if(b.length << 3 < bits) throw new IllegalArgumentException();
|
||||
if (b.length << 3 < bits) throw new IllegalArgumentException();
|
||||
int result = 0;
|
||||
for(int i = 0; i < bits; i++) {
|
||||
if((b[i >> 3] & 128 >> (i & 7)) != 0) result |= 1 << bits - i - 1;
|
||||
for (int i = 0; i < bits; i++) {
|
||||
if ((b[i >> 3] & 128 >> (i & 7)) != 0) result |= 1 << bits - i - 1;
|
||||
}
|
||||
assert result >= 0;
|
||||
assert result < 1 << bits;
|
||||
|
||||
@@ -15,8 +15,8 @@ public class LatchedReference<T> {
|
||||
}
|
||||
|
||||
public boolean set(T t) {
|
||||
if(t == null) throw new IllegalArgumentException();
|
||||
if(reference.compareAndSet(null, t)) {
|
||||
if (t == null) throw new IllegalArgumentException();
|
||||
if (reference.compareAndSet(null, t)) {
|
||||
latch.countDown();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@ public class OsUtils {
|
||||
}
|
||||
|
||||
public static boolean isMacLeopardOrNewer() {
|
||||
if(!isMac() || version == null) return false;
|
||||
if (!isMac() || version == null) return false;
|
||||
try {
|
||||
String[] v = version.split("\\.");
|
||||
if(v.length != 3) return false;
|
||||
if (v.length != 3) return false;
|
||||
int major = Integer.parseInt(v[0]);
|
||||
int minor = Integer.parseInt(v[1]);
|
||||
return major >= 10 && minor >= 5;
|
||||
} catch(NumberFormatException e) {
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ public class StringUtils {
|
||||
|
||||
public static String join(Collection<String> strings, String separator) {
|
||||
StringBuilder joined = new StringBuilder();
|
||||
for(String s : strings) {
|
||||
if(joined.length() > 0) joined.append(separator);
|
||||
for (String s : strings) {
|
||||
if (joined.length() > 0) joined.append(separator);
|
||||
joined.append(s);
|
||||
}
|
||||
return joined.toString();
|
||||
@@ -26,7 +26,7 @@ public class StringUtils {
|
||||
public static byte[] toUtf8(String s) {
|
||||
try {
|
||||
return s.getBytes("UTF-8");
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class StringUtils {
|
||||
public static String fromUtf8(byte[] bytes) {
|
||||
try {
|
||||
return new String(bytes, "UTF-8");
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class StringUtils {
|
||||
/** Converts the given byte array to a hex character array. */
|
||||
public static char[] toHexChars(byte[] bytes) {
|
||||
char[] hex = new char[bytes.length * 2];
|
||||
for(int i = 0, j = 0; i < bytes.length; i++) {
|
||||
for (int i = 0, j = 0; i < bytes.length; i++) {
|
||||
hex[j++] = HEX[(bytes[i] >> 4) & 0xF];
|
||||
hex[j++] = HEX[bytes[i] & 0xF];
|
||||
}
|
||||
@@ -57,9 +57,9 @@ public class StringUtils {
|
||||
/** Converts the given hex string to a byte array. */
|
||||
public static byte[] fromHexString(String hex) {
|
||||
int len = hex.length();
|
||||
if(len % 2 != 0) throw new IllegalArgumentException("Not a hex string");
|
||||
if (len % 2 != 0) throw new IllegalArgumentException("Not a hex string");
|
||||
byte[] bytes = new byte[len / 2];
|
||||
for(int i = 0, j = 0; i < len; i += 2, j++) {
|
||||
for (int i = 0, j = 0; i < len; i += 2, j++) {
|
||||
int high = hexDigitToInt(hex.charAt(i));
|
||||
int low = hexDigitToInt(hex.charAt(i + 1));
|
||||
bytes[j] = (byte) ((high << 4) + low);
|
||||
@@ -68,9 +68,9 @@ public class StringUtils {
|
||||
}
|
||||
|
||||
private static int hexDigitToInt(char c) {
|
||||
if(c >= '0' && c <= '9') return c - '0';
|
||||
if(c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
if(c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
throw new IllegalArgumentException("Not a hex digit: " + c);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user