mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Comments to indicate which locks guard which variables.
This commit is contained in:
@@ -61,18 +61,18 @@ Service, EventListener {
|
||||
private final Executor dbExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final Context appContext;
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final Map<ContactId, Integer> contactCounts =
|
||||
new HashMap<ContactId, Integer>();
|
||||
private final Map<GroupId, Integer> groupCounts =
|
||||
new HashMap<GroupId, Integer>();
|
||||
|
||||
private int privateTotal = 0, groupTotal = 0;
|
||||
private int nextRequestId = 0;
|
||||
|
||||
private volatile Settings settings = new Settings();
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
@Inject
|
||||
public AndroidNotificationManagerImpl(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||
@@ -136,6 +136,7 @@ Service, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void updatePrivateMessageNotification() {
|
||||
if(privateTotal == 0) {
|
||||
clearPrivateMessageNotification();
|
||||
@@ -180,6 +181,7 @@ Service, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void clearPrivateMessageNotification() {
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
@@ -222,6 +224,7 @@ Service, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void updateGroupPostNotification() {
|
||||
if(groupTotal == 0) {
|
||||
clearGroupPostNotification();
|
||||
@@ -266,6 +269,7 @@ Service, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void clearGroupPostNotification() {
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
|
||||
@@ -15,13 +15,13 @@ class ReferenceManagerImpl implements ReferenceManager {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ReferenceManagerImpl.class.getName());
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final Map<Class<?>, Map<Long, Object>> outerMap =
|
||||
new HashMap<Class<?>, Map<Long, Object>>();
|
||||
|
||||
private long nextHandle = 0;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
public <T> T getReference(long handle, Class<T> c) {
|
||||
synchLock.lock();
|
||||
try {
|
||||
|
||||
@@ -19,6 +19,9 @@ class FortunaGenerator {
|
||||
private static final int KEY_BYTES = 32;
|
||||
private static final int BLOCK_BYTES = 16;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final MessageDigest digest = new DoubleDigest(new SHA256Digest());
|
||||
private final BlockCipher cipher = new AESLightEngine();
|
||||
private final byte[] key = new byte[KEY_BYTES];
|
||||
@@ -26,8 +29,6 @@ class FortunaGenerator {
|
||||
private final byte[] buffer = new byte[BLOCK_BYTES];
|
||||
private final byte[] newKey = new byte[KEY_BYTES];
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
FortunaGenerator(byte[] seed) {
|
||||
reseed(seed);
|
||||
}
|
||||
|
||||
@@ -316,12 +316,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private final Clock clock;
|
||||
|
||||
private final LinkedList<Connection> connections =
|
||||
new LinkedList<Connection>();
|
||||
new LinkedList<Connection>(); // Locking: connectionsLock
|
||||
|
||||
private final AtomicInteger transactionCount = new AtomicInteger(0);
|
||||
|
||||
private int openConnections = 0;
|
||||
private boolean closed = false;
|
||||
private int openConnections = 0; // Locking: connectionsLock
|
||||
private boolean closed = false; // Locking: connectionsLock
|
||||
|
||||
protected abstract Connection createConnection() throws SQLException;
|
||||
protected abstract void flushBuffersToDisk(Statement s) throws SQLException;
|
||||
@@ -444,7 +444,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
} finally {
|
||||
connectionsLock.unlock();
|
||||
}
|
||||
|
||||
try {
|
||||
if(txn == null) {
|
||||
// Open a new connection
|
||||
|
||||
@@ -62,12 +62,9 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
private final Collection<InvitationListener> listeners;
|
||||
private final AtomicBoolean connected;
|
||||
private final CountDownLatch localConfirmationLatch;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
/*The state that's accessed in addListener() after
|
||||
* calling listeners.add() must be guarded by a lock.
|
||||
*/
|
||||
// The following are locking: synchLock
|
||||
private int localConfirmationCode = -1, remoteConfirmationCode = -1;
|
||||
private boolean connectionFailed = false;
|
||||
private boolean localCompared = false, remoteCompared = false;
|
||||
|
||||
@@ -9,12 +9,12 @@ import org.briarproject.api.lifecycle.ShutdownManager;
|
||||
|
||||
class ShutdownManagerImpl implements ShutdownManager {
|
||||
|
||||
protected final Map<Integer, Thread> hooks;
|
||||
|
||||
private int nextHandle = 0;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
protected final Map<Integer, Thread> hooks;
|
||||
private int nextHandle = 0;
|
||||
|
||||
ShutdownManagerImpl() {
|
||||
hooks = new HashMap<Integer, Thread>();
|
||||
}
|
||||
|
||||
@@ -27,13 +27,12 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
Logger.getLogger(ConnectionRegistryImpl.class.getName());
|
||||
|
||||
private final EventBus eventBus;
|
||||
// Locking: this
|
||||
private final Map<TransportId, Map<ContactId, Integer>> connections;
|
||||
// Locking: this
|
||||
private final Map<ContactId, Integer> contactCounts;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final Map<TransportId, Map<ContactId, Integer>> connections;
|
||||
private final Map<ContactId, Integer> contactCounts;
|
||||
|
||||
@Inject
|
||||
ConnectionRegistryImpl(EventBus eventBus) {
|
||||
this.eventBus = eventBus;
|
||||
|
||||
@@ -21,15 +21,17 @@ class Receiver implements ReadHandler {
|
||||
|
||||
private final Clock clock;
|
||||
private final Sender sender;
|
||||
private final SortedSet<Data> dataFrames;
|
||||
private final Lock windowLock = new ReentrantLock();
|
||||
private final Condition dataFrameAvailable = windowLock.newCondition();
|
||||
|
||||
// The following are locking: windowLock
|
||||
private final SortedSet<Data> dataFrames;
|
||||
private int windowSize = MAX_WINDOW_SIZE;
|
||||
|
||||
private long finalSequenceNumber = Long.MAX_VALUE;
|
||||
private long nextSequenceNumber = 1;
|
||||
|
||||
private volatile boolean valid = true;
|
||||
private Lock synchLock = new ReentrantLock();
|
||||
private Condition dataFrameAvailable = synchLock.newCondition();
|
||||
|
||||
Receiver(Clock clock, Sender sender) {
|
||||
this.sender = sender;
|
||||
@@ -38,7 +40,7 @@ class Receiver implements ReadHandler {
|
||||
}
|
||||
|
||||
Data read() throws IOException, InterruptedException {
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT;
|
||||
while(now < end && valid) {
|
||||
@@ -64,17 +66,17 @@ class Receiver implements ReadHandler {
|
||||
if(valid) throw new IOException("Read timed out");
|
||||
throw new IOException("Connection closed");
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate() {
|
||||
valid = false;
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
dataFrameAvailable.signalAll();
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ class Receiver implements ReadHandler {
|
||||
}
|
||||
|
||||
private void handleData(byte[] b) throws IOException {
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
|
||||
// Ignore data frame with invalid length
|
||||
@@ -134,7 +136,7 @@ class Receiver implements ReadHandler {
|
||||
// Acknowledge the data frame even if it's a duplicate
|
||||
sender.sendAck(sequenceNumber, windowSize);
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,11 @@ class Sender {
|
||||
|
||||
private final Clock clock;
|
||||
private final WriteHandler writeHandler;
|
||||
private final LinkedList<Outstanding> outstanding;
|
||||
private final Lock windowLock = new ReentrantLock();
|
||||
private final Condition sendWindowAvailable = windowLock.newCondition();
|
||||
|
||||
// The following are locking: windowLock
|
||||
private final LinkedList<Outstanding> outstanding;
|
||||
private int outstandingBytes = 0;
|
||||
private int windowSize = Data.MAX_PAYLOAD_LENGTH;
|
||||
private int rtt = INITIAL_RTT, rttVar = INITIAL_RTT_VAR;
|
||||
@@ -35,9 +38,6 @@ class Sender {
|
||||
private long lastWindowUpdateOrProbe = Long.MAX_VALUE;
|
||||
private boolean dataWaiting = false;
|
||||
|
||||
private Lock synchLock = new ReentrantLock();
|
||||
private Condition sendWindowAvailable = synchLock.newCondition();
|
||||
|
||||
Sender(Clock clock, WriteHandler writeHandler) {
|
||||
this.clock = clock;
|
||||
this.writeHandler = writeHandler;
|
||||
@@ -65,7 +65,7 @@ class Sender {
|
||||
long sequenceNumber = a.getSequenceNumber();
|
||||
long now = clock.currentTimeMillis();
|
||||
Outstanding fastRetransmit = null;
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
// Remove the acked data frame if it's outstanding
|
||||
int foundIndex = -1;
|
||||
@@ -105,7 +105,7 @@ class Sender {
|
||||
if(windowSize > oldWindowSize || foundIndex != -1)
|
||||
sendWindowAvailable.signalAll();
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
// Fast retransmission
|
||||
if(fastRetransmit != null)
|
||||
@@ -116,7 +116,7 @@ class Sender {
|
||||
long now = clock.currentTimeMillis();
|
||||
List<Outstanding> retransmit = null;
|
||||
boolean sendProbe = false;
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
if(outstanding.isEmpty()) {
|
||||
if(dataWaiting && now - lastWindowUpdateOrProbe > rto) {
|
||||
@@ -147,7 +147,7 @@ class Sender {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
// Send a window probe if necessary
|
||||
if(sendProbe) {
|
||||
@@ -165,7 +165,7 @@ class Sender {
|
||||
|
||||
void write(Data d) throws IOException, InterruptedException {
|
||||
int payloadLength = d.getPayloadLength();
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
// Wait for space in the window
|
||||
long now = clock.currentTimeMillis(), end = now + WRITE_TIMEOUT;
|
||||
@@ -180,18 +180,18 @@ class Sender {
|
||||
outstandingBytes += payloadLength;
|
||||
dataWaiting = false;
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
writeHandler.handleWrite(d.getBuffer());
|
||||
}
|
||||
|
||||
void flush() throws IOException, InterruptedException {
|
||||
synchLock.lock();
|
||||
windowLock.lock();
|
||||
try {
|
||||
while(dataWaiting || !outstanding.isEmpty())
|
||||
sendWindowAvailable.await();
|
||||
} finally {
|
||||
synchLock.unlock();
|
||||
windowLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,14 +50,14 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
private final TagRecogniser tagRecogniser;
|
||||
private final Clock clock;
|
||||
private final Timer timer;
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final Map<TransportId, Integer> maxLatencies;
|
||||
private final Map<EndpointKey, TemporarySecret> oldSecrets;
|
||||
private final Map<EndpointKey, TemporarySecret> currentSecrets;
|
||||
private final Map<EndpointKey, TemporarySecret> newSecrets;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
@Inject
|
||||
KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
|
||||
EventBus eventBus, TagRecogniser tagRecogniser, Clock clock,
|
||||
@@ -121,6 +121,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
|
||||
// Assigns secrets to the appropriate maps and returns any dead secrets
|
||||
// Locking: synchLock
|
||||
private Collection<TemporarySecret> assignSecretsToMaps(long now,
|
||||
Collection<TemporarySecret> secrets) {
|
||||
Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
|
||||
@@ -153,6 +154,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
|
||||
// Replaces the given secrets and returns any secrets created
|
||||
// Locking: synchLock
|
||||
private Collection<TemporarySecret> replaceDeadSecrets(long now,
|
||||
Collection<TemporarySecret> dead) {
|
||||
// If there are several dead secrets for an endpoint, use the newest
|
||||
@@ -253,7 +255,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void endpointAdded(Endpoint ep, int maxLatency,
|
||||
public void endpointAdded(Endpoint ep, int maxLatency,
|
||||
byte[] initialSecret) {
|
||||
synchLock.lock();
|
||||
try {
|
||||
@@ -345,12 +347,14 @@ 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();
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void removeSecrets(TransportId t, Map<?, TemporarySecret> m) {
|
||||
Iterator<TemporarySecret> it = m.values().iterator();
|
||||
while(it.hasNext())
|
||||
|
||||
@@ -1,546 +0,0 @@
|
||||
package org.briarproject.transport;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.crypto.KeyManager;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.TransportAddedEvent;
|
||||
import org.briarproject.api.event.TransportRemovedEvent;
|
||||
import org.briarproject.api.system.Clock;
|
||||
import org.briarproject.api.system.Timer;
|
||||
import org.briarproject.api.transport.Endpoint;
|
||||
import org.briarproject.api.transport.StreamContext;
|
||||
import org.briarproject.api.transport.TagRecogniser;
|
||||
import org.briarproject.api.transport.TemporarySecret;
|
||||
|
||||
// FIXME: Don't make alien calls with a lock held
|
||||
class KeyManagerImpl extends TimerTask implements KeyManager, EventListener {
|
||||
|
||||
private static final int MS_BETWEEN_CHECKS = 60 * 1000;
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(KeyManagerImpl.class.getName());
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final DatabaseComponent db;
|
||||
private final EventBus eventBus;
|
||||
private final TagRecogniser tagRecogniser;
|
||||
private final Clock clock;
|
||||
private final Timer timer;
|
||||
|
||||
<<<<<<< HEAD
|
||||
private final Map<TransportId, Long> maxLatencies;
|
||||
=======
|
||||
// All of the following are locking: this
|
||||
private final Map<TransportId, Integer> maxLatencies;
|
||||
>>>>>>> theSource
|
||||
private final Map<EndpointKey, TemporarySecret> oldSecrets;
|
||||
private final Map<EndpointKey, TemporarySecret> currentSecrets;
|
||||
private final Map<EndpointKey, TemporarySecret> newSecrets;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
@Inject
|
||||
KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
|
||||
EventBus eventBus, TagRecogniser tagRecogniser, Clock clock,
|
||||
Timer timer) {
|
||||
this.crypto = crypto;
|
||||
this.db = db;
|
||||
this.eventBus = eventBus;
|
||||
this.tagRecogniser = tagRecogniser;
|
||||
this.clock = clock;
|
||||
this.timer = timer;
|
||||
maxLatencies = new HashMap<TransportId, Integer>();
|
||||
oldSecrets = new HashMap<EndpointKey, TemporarySecret>();
|
||||
currentSecrets = new HashMap<EndpointKey, TemporarySecret>();
|
||||
newSecrets = new HashMap<EndpointKey, TemporarySecret>();
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
synchLock.lock();
|
||||
try {
|
||||
eventBus.addListener(this);
|
||||
// Load the temporary secrets and transport latencies from the database
|
||||
Collection<TemporarySecret> secrets;
|
||||
try {
|
||||
secrets = db.getSecrets();
|
||||
maxLatencies.putAll(db.getTransportLatencies());
|
||||
} 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
|
||||
long now = clock.currentTimeMillis();
|
||||
Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
|
||||
// Replace any dead secrets
|
||||
Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
|
||||
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)) LOG.log(WARNING, e.toString(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Pass the old, current and new secrets to the recogniser
|
||||
for(TemporarySecret s : oldSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
for(TemporarySecret s : currentSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
for(TemporarySecret s : newSecrets.values())
|
||||
tagRecogniser.addSecret(s);
|
||||
// Schedule periodic key rotation
|
||||
timer.scheduleAtFixedRate(this, MS_BETWEEN_CHECKS, MS_BETWEEN_CHECKS);
|
||||
return true;
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Assigns secrets to the appropriate maps and returns any dead secrets
|
||||
private Collection<TemporarySecret> assignSecretsToMaps(long now,
|
||||
Collection<TemporarySecret> secrets) {
|
||||
Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
|
||||
for(TemporarySecret s : secrets) {
|
||||
// Discard the secret if the transport has been removed
|
||||
Integer maxLatency = maxLatencies.get(s.getTransportId());
|
||||
if(maxLatency == null) {
|
||||
LOG.info("Discarding obsolete secret");
|
||||
continue;
|
||||
}
|
||||
long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
long creationTime = s.getEpoch() + rotation * (s.getPeriod() - 2);
|
||||
long activationTime = creationTime + rotation;
|
||||
long deactivationTime = activationTime + rotation;
|
||||
long destructionTime = deactivationTime + rotation;
|
||||
if(now >= destructionTime) {
|
||||
dead.add(s);
|
||||
} else if(now >= deactivationTime) {
|
||||
oldSecrets.put(new EndpointKey(s), s);
|
||||
} else if(now >= activationTime) {
|
||||
currentSecrets.put(new EndpointKey(s), s);
|
||||
} else if(now >= creationTime) {
|
||||
newSecrets.put(new EndpointKey(s), s);
|
||||
} else {
|
||||
// FIXME: Work out what to do here
|
||||
throw new Error("Clock has moved backwards");
|
||||
}
|
||||
}
|
||||
return dead;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// Replaces and erases the given secrets and returns any secrets created
|
||||
=======
|
||||
// Replaces the given secrets and returns any secrets created
|
||||
// Locking: this
|
||||
>>>>>>> theSource
|
||||
private Collection<TemporarySecret> replaceDeadSecrets(long now,
|
||||
Collection<TemporarySecret> dead) {
|
||||
// If there are several dead secrets for an endpoint, use the newest
|
||||
Map<EndpointKey, TemporarySecret> newest =
|
||||
new HashMap<EndpointKey, TemporarySecret>();
|
||||
for(TemporarySecret s : dead) {
|
||||
EndpointKey k = new EndpointKey(s);
|
||||
TemporarySecret exists = newest.get(k);
|
||||
if(exists == null) {
|
||||
// There's no other secret for this endpoint
|
||||
newest.put(k, s);
|
||||
} else if(exists.getPeriod() < s.getPeriod()) {
|
||||
// There's an older secret - use this one instead
|
||||
newest.put(k, s);
|
||||
} else {
|
||||
// There's a newer secret - keep using it
|
||||
}
|
||||
}
|
||||
Collection<TemporarySecret> created = new ArrayList<TemporarySecret>();
|
||||
for(Entry<EndpointKey, TemporarySecret> e : newest.entrySet()) {
|
||||
TemporarySecret s = e.getValue();
|
||||
Integer maxLatency = maxLatencies.get(s.getTransportId());
|
||||
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)
|
||||
throw new IllegalStateException();
|
||||
// Derive the old, current and new secrets
|
||||
byte[] b1 = s.getSecret();
|
||||
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)) {
|
||||
TemporarySecret s1 = new TemporarySecret(s, period - 1, b1);
|
||||
oldSecrets.put(k, s1);
|
||||
created.add(s1);
|
||||
}
|
||||
if(!currentSecrets.containsKey(k)) {
|
||||
TemporarySecret s2 = new TemporarySecret(s, period, b2);
|
||||
currentSecrets.put(k, s2);
|
||||
created.add(s2);
|
||||
}
|
||||
if(!newSecrets.containsKey(k)) {
|
||||
TemporarySecret s3 = new TemporarySecret(s, period + 1, b3);
|
||||
newSecrets.put(k, s3);
|
||||
created.add(s3);
|
||||
}
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
public boolean stop() {
|
||||
synchLock.lock();
|
||||
try{
|
||||
eventBus.removeListener(this);
|
||||
timer.cancel();
|
||||
tagRecogniser.removeSecrets();
|
||||
maxLatencies.clear();
|
||||
removeAndEraseSecrets(oldSecrets);
|
||||
removeAndEraseSecrets(currentSecrets);
|
||||
removeAndEraseSecrets(newSecrets);
|
||||
return true;
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAndEraseSecrets(Map<?, TemporarySecret> m) {
|
||||
for(TemporarySecret s : m.values()) ByteUtils.erase(s.getSecret());
|
||||
m.clear();
|
||||
}
|
||||
|
||||
public StreamContext getStreamContext(ContactId c,
|
||||
=======
|
||||
public synchronized boolean stop() {
|
||||
eventBus.removeListener(this);
|
||||
timer.cancel();
|
||||
tagRecogniser.removeSecrets();
|
||||
maxLatencies.clear();
|
||||
oldSecrets.clear();
|
||||
currentSecrets.clear();
|
||||
newSecrets.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized StreamContext getStreamContext(ContactId c,
|
||||
>>>>>>> theSource
|
||||
TransportId t) {
|
||||
synchLock.lock();
|
||||
try{
|
||||
TemporarySecret s = currentSecrets.get(new EndpointKey(c, t));
|
||||
if(s == null) {
|
||||
LOG.info("No secret for endpoint");
|
||||
return null;
|
||||
}
|
||||
long streamNumber;
|
||||
try {
|
||||
streamNumber = db.incrementStreamCounter(c, t, s.getPeriod());
|
||||
if(streamNumber == -1) {
|
||||
LOG.info("No counter for period");
|
||||
return null;
|
||||
}
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
// Clone the secret - the original will be erased
|
||||
byte[] secret = s.getSecret().clone();
|
||||
return new StreamContext(c, t, secret, streamNumber, s.getAlice());
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
}
|
||||
|
||||
public void endpointAdded(Endpoint ep, long maxLatency,
|
||||
byte[] initialSecret) {
|
||||
synchLock.lock();
|
||||
try{
|
||||
maxLatencies.put(ep.getTransportId(), maxLatency);
|
||||
// Work out which rotation period we're in
|
||||
long elapsed = clock.currentTimeMillis() - ep.getEpoch();
|
||||
long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
long period = (elapsed / rotation) + 1;
|
||||
if(period < 1) throw new IllegalStateException();
|
||||
// Derive the old, current and new secrets
|
||||
byte[] b1 = initialSecret;
|
||||
for(long p = 0; p < period; p++) {
|
||||
byte[] temp = crypto.deriveNextSecret(b1, p);
|
||||
ByteUtils.erase(b1);
|
||||
b1 = temp;
|
||||
}
|
||||
byte[] b2 = crypto.deriveNextSecret(b1, period);
|
||||
byte[] b3 = crypto.deriveNextSecret(b2, period + 1);
|
||||
TemporarySecret s1 = new TemporarySecret(ep, period - 1, b1);
|
||||
TemporarySecret s2 = new TemporarySecret(ep, period, b2);
|
||||
TemporarySecret s3 = new TemporarySecret(ep, period + 1, b3);
|
||||
// Add the incoming secrets to their respective maps
|
||||
EndpointKey k = new EndpointKey(ep);
|
||||
oldSecrets.put(k, s1);
|
||||
currentSecrets.put(k, s2);
|
||||
newSecrets.put(k, s3);
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
// Pass the new secrets to the recogniser
|
||||
tagRecogniser.addSecret(s1);
|
||||
tagRecogniser.addSecret(s2);
|
||||
tagRecogniser.addSecret(s3);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
=======
|
||||
byte[] secret = s.getSecret();
|
||||
return new StreamContext(c, t, secret, streamNumber, s.getAlice());
|
||||
}
|
||||
|
||||
public synchronized void endpointAdded(Endpoint ep, int maxLatency,
|
||||
byte[] initialSecret) {
|
||||
maxLatencies.put(ep.getTransportId(), maxLatency);
|
||||
// Work out which rotation period we're in
|
||||
long elapsed = clock.currentTimeMillis() - ep.getEpoch();
|
||||
long rotation = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
long period = (elapsed / rotation) + 1;
|
||||
if(period < 1) throw new IllegalStateException();
|
||||
// Derive the old, current and new secrets
|
||||
byte[] b1 = initialSecret;
|
||||
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);
|
||||
TemporarySecret s1 = new TemporarySecret(ep, period - 1, b1);
|
||||
TemporarySecret s2 = new TemporarySecret(ep, period, b2);
|
||||
TemporarySecret s3 = new TemporarySecret(ep, period + 1, b3);
|
||||
// Add the incoming secrets to their respective maps
|
||||
EndpointKey k = new EndpointKey(ep);
|
||||
oldSecrets.put(k, s1);
|
||||
currentSecrets.put(k, s2);
|
||||
newSecrets.put(k, s3);
|
||||
// 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);
|
||||
return;
|
||||
>>>>>>> theSource
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchLock.lock();
|
||||
try{
|
||||
// Rebuild the maps because we may be running a whole period late
|
||||
Collection<TemporarySecret> secrets = new ArrayList<TemporarySecret>();
|
||||
secrets.addAll(oldSecrets.values());
|
||||
secrets.addAll(currentSecrets.values());
|
||||
secrets.addAll(newSecrets.values());
|
||||
oldSecrets.clear();
|
||||
currentSecrets.clear();
|
||||
newSecrets.clear();
|
||||
// Work out what phase of its lifecycle each secret is in
|
||||
long now = clock.currentTimeMillis();
|
||||
Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
|
||||
// Remove any dead secrets from the recogniser
|
||||
for(TemporarySecret s : dead) {
|
||||
ContactId c = s.getContactId();
|
||||
TransportId t = s.getTransportId();
|
||||
long period = s.getPeriod();
|
||||
tagRecogniser.removeSecret(c, t, period);
|
||||
}
|
||||
// Replace any dead secrets
|
||||
Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
|
||||
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);
|
||||
}
|
||||
// Pass any secrets that have been created to the recogniser
|
||||
for(TemporarySecret s : created) tagRecogniser.addSecret(s);
|
||||
}
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void eventOccurred(Event e) {
|
||||
if(e instanceof ContactRemovedEvent) {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
timer.schedule(new ContactRemovedTask(c), 0);
|
||||
} else if(e instanceof TransportAddedEvent) {
|
||||
TransportAddedEvent t = (TransportAddedEvent) e;
|
||||
timer.schedule(new TransportAddedTask(t), 0);
|
||||
} else if(e instanceof TransportRemovedEvent) {
|
||||
TransportRemovedEvent t = (TransportRemovedEvent) e;
|
||||
timer.schedule(new TransportRemovedTask(t), 0);
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
private void removeAndEraseSecrets(ContactId c, Map<?, TemporarySecret> m) {
|
||||
=======
|
||||
// Locking: this
|
||||
private void removeSecrets(ContactId c, Map<?, TemporarySecret> m) {
|
||||
>>>>>>> theSource
|
||||
Iterator<TemporarySecret> it = m.values().iterator();
|
||||
while(it.hasNext())
|
||||
if(it.next().getContactId().equals(c)) it.remove();
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
private void removeAndEraseSecrets(TransportId t,
|
||||
Map<?, TemporarySecret> m) {
|
||||
=======
|
||||
// Locking: this
|
||||
private void removeSecrets(TransportId t, Map<?, TemporarySecret> m) {
|
||||
>>>>>>> theSource
|
||||
Iterator<TemporarySecret> it = m.values().iterator();
|
||||
while(it.hasNext())
|
||||
if(it.next().getTransportId().equals(t)) it.remove();
|
||||
}
|
||||
|
||||
private static class EndpointKey {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final TransportId transportId;
|
||||
|
||||
private EndpointKey(ContactId contactId, TransportId transportId) {
|
||||
this.contactId = contactId;
|
||||
this.transportId = transportId;
|
||||
}
|
||||
|
||||
private EndpointKey(Endpoint ep) {
|
||||
this(ep.getContactId(), ep.getTransportId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return contactId.hashCode() ^ transportId.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof EndpointKey) {
|
||||
EndpointKey k = (EndpointKey) o;
|
||||
return contactId.equals(k.contactId) &&
|
||||
transportId.equals(k.transportId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class ContactRemovedTask extends TimerTask {
|
||||
|
||||
private final ContactRemovedEvent event;
|
||||
|
||||
private ContactRemovedTask(ContactRemovedEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ContactId c = event.getContactId();
|
||||
tagRecogniser.removeSecrets(c);
|
||||
<<<<<<< HEAD
|
||||
synchLock.lock();
|
||||
try {
|
||||
removeAndEraseSecrets(c, oldSecrets);
|
||||
removeAndEraseSecrets(c, currentSecrets);
|
||||
removeAndEraseSecrets(c, newSecrets);
|
||||
=======
|
||||
synchronized(KeyManagerImpl.this) {
|
||||
removeSecrets(c, oldSecrets);
|
||||
removeSecrets(c, currentSecrets);
|
||||
removeSecrets(c, newSecrets);
|
||||
>>>>>>> theSource
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TransportAddedTask extends TimerTask {
|
||||
|
||||
private final TransportAddedEvent event;
|
||||
|
||||
private TransportAddedTask(TransportAddedEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchLock.lock();
|
||||
try {
|
||||
maxLatencies.put(event.getTransportId(), event.getMaxLatency());
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TransportRemovedTask extends TimerTask {
|
||||
|
||||
private TransportRemovedEvent event;
|
||||
|
||||
private TransportRemovedTask(TransportRemovedEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
TransportId t = event.getTransportId();
|
||||
tagRecogniser.removeSecrets(t);
|
||||
synchLock.lock();
|
||||
try {
|
||||
maxLatencies.remove(t);
|
||||
removeSecrets(t, oldSecrets);
|
||||
removeSecrets(t, currentSecrets);
|
||||
removeSecrets(t, newSecrets);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,10 @@ class TagRecogniserImpl implements TagRecogniser {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final DatabaseComponent db;
|
||||
|
||||
private final Map<TransportId, TransportTagRecogniser> recognisers;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// Locking: synchLock
|
||||
private final Map<TransportId, TransportTagRecogniser> recognisers;
|
||||
|
||||
@Inject
|
||||
TagRecogniserImpl(CryptoComponent crypto, DatabaseComponent db) {
|
||||
|
||||
@@ -29,11 +29,12 @@ class TransportTagRecogniser {
|
||||
private final CryptoComponent crypto;
|
||||
private final DatabaseComponent db;
|
||||
private final TransportId transportId;
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final Map<Bytes, TagContext> tagMap;
|
||||
private final Map<RemovalKey, RemovalContext> removalMap;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
TransportTagRecogniser(CryptoComponent crypto, DatabaseComponent db,
|
||||
TransportId transportId) {
|
||||
this.crypto = crypto;
|
||||
@@ -112,6 +113,7 @@ class TransportTagRecogniser {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void removeSecret(RemovalContext r) {
|
||||
// Remove the expected tags
|
||||
SecretKey key = crypto.deriveTagKey(r.secret, !r.alice);
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
package org.briarproject.transport;
|
||||
|
||||
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.briarproject.api.Bytes;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.crypto.SecretKey;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.transport.StreamContext;
|
||||
import org.briarproject.api.transport.TemporarySecret;
|
||||
|
||||
// FIXME: Don't make alien calls with a lock held
|
||||
/**
|
||||
* A {@link org.briarproject.api.transport.TagRecogniser TagRecogniser} for a
|
||||
* specific transport.
|
||||
*/
|
||||
class TransportTagRecogniser {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final DatabaseComponent db;
|
||||
private final TransportId transportId;
|
||||
private final Map<Bytes, TagContext> tagMap;
|
||||
private final Map<RemovalKey, RemovalContext> removalMap;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
TransportTagRecogniser(CryptoComponent crypto, DatabaseComponent db,
|
||||
TransportId transportId) {
|
||||
this.crypto = crypto;
|
||||
this.db = db;
|
||||
this.transportId = transportId;
|
||||
tagMap = new HashMap<Bytes, TagContext>();
|
||||
removalMap = new HashMap<RemovalKey, RemovalContext>();
|
||||
}
|
||||
|
||||
StreamContext recogniseTag(byte[] tag) throws DbException {
|
||||
synchLock.lock();
|
||||
try{
|
||||
TagContext t = tagMap.remove(new Bytes(tag));
|
||||
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)) {
|
||||
byte[] tag1 = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag1, key, streamNumber);
|
||||
if(streamNumber < t.streamNumber) {
|
||||
TagContext removed = tagMap.remove(new Bytes(tag1));
|
||||
assert removed != null;
|
||||
} else {
|
||||
TagContext added = new TagContext(t, streamNumber);
|
||||
TagContext duplicate = tagMap.put(new Bytes(tag1), added);
|
||||
assert duplicate == null;
|
||||
}
|
||||
}
|
||||
key.erase();
|
||||
// Store the updated reordering window in the DB
|
||||
db.setReorderingWindow(t.contactId, transportId, t.period,
|
||||
t.window.getCentre(), t.window.getBitmap());
|
||||
// Clone the secret - the key manager will erase the original
|
||||
byte[] secret = t.secret.clone();
|
||||
return new StreamContext(t.contactId, transportId, secret,
|
||||
t.streamNumber, t.alice);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
// Store the updated reordering window in the DB
|
||||
db.setReorderingWindow(t.contactId, transportId, t.period,
|
||||
t.window.getCentre(), t.window.getBitmap());
|
||||
return new StreamContext(t.contactId, transportId, t.secret,
|
||||
t.streamNumber, t.alice);
|
||||
>>>>>>> theSource
|
||||
}
|
||||
|
||||
void addSecret(TemporarySecret s) {
|
||||
synchLock.lock();
|
||||
try{
|
||||
ContactId contactId = s.getContactId();
|
||||
boolean alice = s.getAlice();
|
||||
long period = s.getPeriod();
|
||||
byte[] secret = s.getSecret();
|
||||
long centre = s.getWindowCentre();
|
||||
byte[] bitmap = s.getWindowBitmap();
|
||||
// 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()) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, key, streamNumber);
|
||||
TagContext added = new TagContext(contactId, alice, period,
|
||||
secret, window, streamNumber);
|
||||
TagContext duplicate = tagMap.put(new Bytes(tag), added);
|
||||
assert duplicate == null;
|
||||
}
|
||||
key.erase();
|
||||
// Create a removal context to remove the window and the tags later
|
||||
RemovalContext r = new RemovalContext(window, secret, alice);
|
||||
removalMap.put(new RemovalKey(contactId, period), r);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
// Create a removal context to remove the window and the tags later
|
||||
RemovalContext r = new RemovalContext(window, secret, alice);
|
||||
removalMap.put(new RemovalKey(contactId, period), r);
|
||||
>>>>>>> theSource
|
||||
}
|
||||
|
||||
void removeSecret(ContactId contactId, long period) {
|
||||
synchLock.lock();
|
||||
try{
|
||||
RemovalKey k = new RemovalKey(contactId, period);
|
||||
RemovalContext removed = removalMap.remove(k);
|
||||
if(removed == null) throw new IllegalArgumentException();
|
||||
removeSecret(removed);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeSecret(RemovalContext r) {
|
||||
// Remove the expected tags
|
||||
SecretKey key = crypto.deriveTagKey(r.secret, !r.alice);
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
for(long streamNumber : r.window.getUnseen()) {
|
||||
crypto.encodeTag(tag, key, streamNumber);
|
||||
TagContext removed = tagMap.remove(new Bytes(tag));
|
||||
assert removed != null;
|
||||
}
|
||||
}
|
||||
|
||||
void removeSecrets(ContactId c) {
|
||||
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) removeSecret(k.contactId, k.period);
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void removeSecrets() {
|
||||
synchLock.lock();
|
||||
try{
|
||||
for(RemovalContext r : removalMap.values()) removeSecret(r);
|
||||
assert tagMap.isEmpty();
|
||||
removalMap.clear();
|
||||
}
|
||||
finally{
|
||||
synchLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TagContext {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final boolean alice;
|
||||
private final long period;
|
||||
private final byte[] secret;
|
||||
private final ReorderingWindow window;
|
||||
private final long streamNumber;
|
||||
|
||||
private TagContext(ContactId contactId, boolean alice, long period,
|
||||
byte[] secret, ReorderingWindow window, long streamNumber) {
|
||||
this.contactId = contactId;
|
||||
this.alice = alice;
|
||||
this.period = period;
|
||||
this.secret = secret;
|
||||
this.window = window;
|
||||
this.streamNumber = streamNumber;
|
||||
}
|
||||
|
||||
private TagContext(TagContext t, long streamNumber) {
|
||||
this(t.contactId, t.alice, t.period, t.secret, t.window,
|
||||
streamNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RemovalKey {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final long period;
|
||||
|
||||
private RemovalKey(ContactId contactId, long period) {
|
||||
this.contactId = contactId;
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return contactId.hashCode() ^ (int) (period ^ (period >>> 32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof RemovalKey) {
|
||||
RemovalKey k = (RemovalKey) o;
|
||||
return contactId.equals(k.contactId) && period == k.period;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RemovalContext {
|
||||
|
||||
private final ReorderingWindow window;
|
||||
private final byte[] secret;
|
||||
private final boolean alice;
|
||||
|
||||
private RemovalContext(ReorderingWindow window, byte[] secret,
|
||||
boolean alice) {
|
||||
this.window = window;
|
||||
this.secret = secret;
|
||||
this.alice = alice;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,11 +38,9 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
|
||||
private static final int WS_MINIMIZE = 0x20000000;
|
||||
|
||||
private final Map<String, Object> options;
|
||||
|
||||
private boolean initialised = false;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
private boolean initialised = false; // Locking: synchLock
|
||||
|
||||
WindowsShutdownManagerImpl() {
|
||||
// Use the Unicode versions of Win32 API calls
|
||||
@@ -68,6 +66,7 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
|
||||
return new StartOnce(r);
|
||||
}
|
||||
|
||||
// Locking: synchLock
|
||||
private void initialise() {
|
||||
if(OsUtils.isWindows()) {
|
||||
new EventLoop().start();
|
||||
|
||||
@@ -20,12 +20,11 @@ class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
private final RemovableDriveFinder finder;
|
||||
private final int pollingInterval;
|
||||
|
||||
private volatile boolean running = false;
|
||||
private volatile Callback callback = null;
|
||||
|
||||
private final Lock pollingLock = new ReentrantLock();
|
||||
private final Condition stopPolling = pollingLock.newCondition();
|
||||
|
||||
private volatile boolean running = false;
|
||||
private volatile Callback callback = null;
|
||||
|
||||
public PollingRemovableDriveMonitor(Executor ioExecutor,
|
||||
RemovableDriveFinder finder, int pollingInterval) {
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.briarproject.plugins.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
|
||||
|
||||
private final Executor ioExecutor;
|
||||
private final RemovableDriveFinder finder;
|
||||
<<<<<<< HEAD
|
||||
private final long pollingInterval;
|
||||
=======
|
||||
private final int pollingInterval;
|
||||
private final Object pollingLock = new Object();
|
||||
>>>>>>> theSource
|
||||
|
||||
private volatile boolean running = false;
|
||||
private volatile Callback callback = null;
|
||||
|
||||
private final Lock pollingLock = new ReentrantLock();
|
||||
private final Condition stopPolling = pollingLock.newCondition();
|
||||
|
||||
|
||||
public PollingRemovableDriveMonitor(Executor ioExecutor,
|
||||
RemovableDriveFinder finder, int pollingInterval) {
|
||||
this.ioExecutor = ioExecutor;
|
||||
this.finder = finder;
|
||||
this.pollingInterval = pollingInterval;
|
||||
}
|
||||
|
||||
public void start(Callback callback) throws IOException {
|
||||
this.callback = callback;
|
||||
running = true;
|
||||
ioExecutor.execute(this);
|
||||
}
|
||||
|
||||
public void stop() throws IOException {
|
||||
running = false;
|
||||
pollingLock.lock();
|
||||
try {
|
||||
stopPolling.signalAll();
|
||||
}
|
||||
finally {
|
||||
pollingLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
Collection<File> drives = finder.findRemovableDrives();
|
||||
while(running) {
|
||||
pollingLock.lock();
|
||||
try {
|
||||
stopPolling.await(pollingInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
finally{
|
||||
pollingLock.unlock();
|
||||
}
|
||||
if(!running) return;
|
||||
Collection<File> newDrives = finder.findRemovableDrives();
|
||||
for(File f : newDrives) {
|
||||
if(!drives.contains(f)) callback.driveInserted(f);
|
||||
}
|
||||
drives = newDrives;
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting to poll");
|
||||
Thread.currentThread().interrupt();
|
||||
} catch(IOException e) {
|
||||
callback.exceptionThrown(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,20 +13,22 @@ import net.contentobjects.jnotify.JNotifyListener;
|
||||
abstract class UnixRemovableDriveMonitor implements RemovableDriveMonitor,
|
||||
JNotifyListener {
|
||||
|
||||
//TODO: rationalise this in a further refactor
|
||||
private static final Lock staticSynchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: staticSynchLock
|
||||
private static boolean triedLoad = false;
|
||||
private static Throwable loadError = null;
|
||||
|
||||
private final List<Integer> watches = new ArrayList<Integer>();
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private final List<Integer> watches = new ArrayList<Integer>();
|
||||
private boolean started = false;
|
||||
private Callback callback = null;
|
||||
|
||||
protected abstract String[] getPathsToWatch();
|
||||
|
||||
//TODO: rationalise this in a further refactor
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
private static final Lock staticSynchLock = new ReentrantLock();
|
||||
|
||||
private static Throwable tryLoad() {
|
||||
try {
|
||||
Class.forName("net.contentobjects.jnotify.JNotify");
|
||||
|
||||
@@ -91,161 +91,160 @@ class CountryCodes {
|
||||
new Country("GP", "Guadeloupe", "590", "00", ""),
|
||||
new Country("GQ", "Equatorial Guinea", "240", "00", ""),
|
||||
new Country("GR", "Greece", "30", "00", ""),
|
||||
new Country("GS", "South Georgia and the South Sandwich Islands",
|
||||
"995", "8**10", "8"),
|
||||
new Country("GT", "Guatemala", "502", "00", ""),
|
||||
new Country("GU", "Guam", "1", "011", "1"),
|
||||
new Country("GW", "Guinea-Bissau", "245", "00", ""),
|
||||
new Country("GY", "Guyana", "592", "001", "0"),
|
||||
new Country("HK", "Hong Kong", "852", "001", ""),
|
||||
new Country("HM", "Heard Island and McDonald Islands", "692", "00", "0"),
|
||||
new Country("HN", "Honduras", "504", "00", "0"),
|
||||
new Country("HR", "Croatia", "385", "00", "0"),
|
||||
new Country("HT", "Haiti", "509", "00", "0"),
|
||||
new Country("HU", "Hungary", "36", "00", "06"),
|
||||
new Country("ID", "Indonesia", "62", "001", "0"),
|
||||
new Country("IE", "Ireland", "353", "00", "0"),
|
||||
new Country("IL", "Israel", "972", "00", "0"),
|
||||
new Country("IN", "India", "91", "00", "0"),
|
||||
new Country("IO", "British Indian Ocean Territory", "246", "00", ""),
|
||||
new Country("IQ", "Iraq", "964", "00", "0"),
|
||||
new Country("IR", "Iran", "98", "00", "0"),
|
||||
new Country("IS", "Iceland", "354", "00", "0"),
|
||||
new Country("IT", "Italy", "39", "00", ""),
|
||||
new Country("JM", "Jamaica", "1", "011", "1"),
|
||||
new Country("JO", "Jordan", "962", "00", "0"),
|
||||
new Country("JP", "Japan", "81", "001", "0"),
|
||||
new Country("KE", "Kenya", "254", "000", "0"),
|
||||
new Country("KG", "Kyrgyzstan", "996", "00", "0"),
|
||||
new Country("KH", "Cambodia", "855", "001", "0"),
|
||||
new Country("KI", "Kiribati", "686", "00", "0"),
|
||||
new Country("KM", "Comoros", "269", "00", ""),
|
||||
new Country("KN", "Saint Kitts and Nevis", "1", "011", "1"),
|
||||
new Country("KP", "Korea (North)", "850", "00", "0"),
|
||||
new Country("KR", "Korea (South)", "82", "001", "0"),
|
||||
new Country("KW", "Kuwait", "965", "00", "0"),
|
||||
new Country("KY", "Cayman Islands", "1", "011", "1"),
|
||||
new Country("KZ", "Kazakhstan", "7", "8**10", "8"),
|
||||
new Country("LA", "Laos", "856", "00", "0"),
|
||||
new Country("LB", "Lebanon", "961", "00", "0"),
|
||||
new Country("LC", "Saint Lucia", "1", "011", "1"),
|
||||
new Country("LI", "Liechtenstein", "423", "00", ""),
|
||||
new Country("LK", "Sri Lanka", "94", "00", "0"),
|
||||
new Country("LR", "Liberia", "231", "00", "22"),
|
||||
new Country("LS", "Lesotho", "266", "00", "0"),
|
||||
new Country("LT", "Lithuania", "370", "00", "8"),
|
||||
new Country("LU", "Luxembourg", "352", "00", ""),
|
||||
new Country("LV", "Latvia", "371", "00", "8"),
|
||||
new Country("LY", "Libya", "218", "00", "0"),
|
||||
new Country("MA", "Morocco", "212", "00", ""),
|
||||
new Country("MC", "Monaco", "377", "00", "0"),
|
||||
new Country("MD", "Moldova", "373", "00", "0"),
|
||||
new Country("ME", "Montenegro", "382", "99", "0"),
|
||||
new Country("MG", "Madagascar", "261", "00", "0"),
|
||||
new Country("MH", "Marshall Islands", "692", "011", "1"),
|
||||
new Country("MK", "Macedonia", "389", "00", "0"),
|
||||
new Country("ML", "Mali", "223", "00", "0"),
|
||||
new Country("MM", "Myanmar", "95", "00", ""),
|
||||
new Country("MN", "Mongolia", "976", "001", "0"),
|
||||
new Country("MO", "Macao", "853", "00", "0"),
|
||||
new Country("MP", "Northern Mariana Islands", "1", "011", "1"),
|
||||
new Country("MQ", "Martinique", "596", "00", "0"),
|
||||
new Country("MR", "Mauritania", "222", "00", "0"),
|
||||
new Country("MS", "Montserrat", "1", "011", "1"),
|
||||
new Country("MT", "Malta", "356", "00", "21"),
|
||||
new Country("MU", "Mauritius", "230", "00", "0"),
|
||||
new Country("MV", "Maldives", "960", "00", "0"),
|
||||
new Country("MW", "Malawi", "265", "00", ""),
|
||||
new Country("MX", "Mexico", "52", "00", "01"),
|
||||
new Country("MY", "Malaysia", "60", "00", "0"),
|
||||
new Country("MZ", "Mozambique", "258", "00", "0"),
|
||||
new Country("NA", "Namibia", "264", "00", "0"),
|
||||
new Country("NC", "New Caledonia", "687", "00", "0"),
|
||||
new Country("NE", "Niger", "227", "00", "0"),
|
||||
new Country("NF", "Norfolk Island", "672", "00", ""),
|
||||
new Country("NG", "Nigeria", "234", "009", "0"),
|
||||
new Country("NI", "Nicaragua", "505", "00", "0"),
|
||||
new Country("NL", "Netherlands", "31", "00", "0"),
|
||||
new Country("NO", "Norway", "47", "00", ""),
|
||||
new Country("NP", "Nepal", "977", "00", "0"),
|
||||
new Country("NR", "Nauru", "674", "00", "0"),
|
||||
new Country("NU", "Niue", "683", "00", "0"),
|
||||
new Country("NZ", "New Zealand", "64", "00", "0"),
|
||||
new Country("OM", "Oman", "968", "00", "0"),
|
||||
new Country("PA", "Panama", "507", "00", "0"),
|
||||
new Country("PE", "Peru", "51", "00", "0"),
|
||||
new Country("PF", "French Polynesia", "689", "00", ""),
|
||||
new Country("PG", "Papua New Guinea", "675", "05", ""),
|
||||
new Country("PH", "Philippines", "63", "00", "0"),
|
||||
new Country("PK", "Pakistan", "92", "00", "0"),
|
||||
new Country("PL", "Poland", "48", "00", "0"),
|
||||
new Country("PM", "Saint Pierre and Miquelon", "508", "00", "0"),
|
||||
new Country("PN", "Pitcairn", "872", "", ""),
|
||||
new Country("PR", "Puerto Rico", "1", "011", "1"),
|
||||
new Country("PS", "Palestine", "970", "00", "0"),
|
||||
new Country("PT", "Portugal", "351", "00", ""),
|
||||
new Country("PW", "Palau", "680", "011", ""),
|
||||
new Country("PY", "Paraguay", "595", "002", "0"),
|
||||
new Country("QA", "Qatar", "974", "00", "0"),
|
||||
new Country("RE", "Reunion", "262", "00", "0"),
|
||||
new Country("RO", "Romania", "40", "00", "0"),
|
||||
new Country("RS", "Serbia", "381", "99", "0"),
|
||||
new Country("RU", "Russia", "7", "8**10", "8"),
|
||||
new Country("RW", "Rwanda", "250", "00", "0"),
|
||||
new Country("SA", "Saudi Arabia", "966", "00", "0"),
|
||||
new Country("SB", "Solomon Islands", "677", "00", ""),
|
||||
new Country("SC", "Seychelles", "248", "00", "0"),
|
||||
new Country("SD", "Sudan", "249", "00", "0"),
|
||||
new Country("SE", "Sweden", "46", "00", "0"),
|
||||
new Country("SG", "Singapore", "65", "001", ""),
|
||||
new Country("SH", "Saint Helena", "290", "00", ""),
|
||||
new Country("SI", "Slovenia", "386", "00", "0"),
|
||||
new Country("SJ", "Svalbard and Jan Mayen", "378", "00", "0"),
|
||||
new Country("SK", "Slovakia", "421", "00", "0"),
|
||||
new Country("SL", "Sierra Leone", "232", "00", "0"),
|
||||
new Country("SM", "San Marino", "378", "00", "0"),
|
||||
new Country("SN", "Senegal", "221", "00", "0"),
|
||||
new Country("SO", "Somalia", "252", "00", ""),
|
||||
new Country("SR", "Suriname", "597", "00", ""),
|
||||
new Country("ST", "Sao Tome and Principe", "239", "00", "0"),
|
||||
new Country("SV", "El Salvador", "503", "00", ""),
|
||||
new Country("SY", "Syria", "963", "00", "0"),
|
||||
new Country("SZ", "Swaziland", "268", "00", ""),
|
||||
new Country("TC", "Turks and Caicos Islands", "1", "011", "1"),
|
||||
new Country("TD", "Chad", "235", "15", ""),
|
||||
new Country("TF", "French Southern Territories", "596", "00", "0"),
|
||||
new Country("TG", "Togo", "228", "00", ""),
|
||||
new Country("TH", "Thailand", "66", "001", "0"),
|
||||
new Country("TJ", "Tajikistan", "992", "8**10", "8"),
|
||||
new Country("TK", "Tokelau", "690", "00", ""),
|
||||
new Country("TL", "Timor-Leste", "670", "00", ""),
|
||||
new Country("TM", "Turkmenistan", "993", "8**10", "8"),
|
||||
new Country("TN", "Tunisia", "216", "00", "0"),
|
||||
new Country("TO", "Tonga Islands", "676", "00", ""),
|
||||
new Country("TR", "Turkey", "90", "00", "0"),
|
||||
new Country("TT", "Trinidad and Tobago", "1", "011", "1"),
|
||||
new Country("TV", "Tuvalu", "688", "00", ""),
|
||||
new Country("TW", "Taiwan", "886", "002", ""),
|
||||
new Country("TZ", "Tanzania", "255", "000", "0"),
|
||||
new Country("UA", "Ukraine", "380", "8**10", "8"),
|
||||
new Country("UG", "Uganda", "256", "000", "0"),
|
||||
new Country("US", "United States", "1", "011", "1"),
|
||||
new Country("UY", "Uruguay", "598", "00", "0"),
|
||||
new Country("UZ", "Uzbekistan", "998", "8**10", "8"),
|
||||
new Country("VA", "Holy See (Vatican City State)", "379", "00", ""),
|
||||
new Country("VC", "Saint Vincent and the Grenadines", "1", "011", "1"),
|
||||
new Country("VE", "Venezuela", "58", "00", "0"),
|
||||
new Country("VG", "Virgin Islands (British)", "1", "011", "1"),
|
||||
new Country("VI", "Virgin Islands (U.S.)", "1", "011", "1"),
|
||||
new Country("VN", "Viet Nam", "84", "00", "0"),
|
||||
new Country("VU", "Vanuatu", "678", "00", ""),
|
||||
new Country("WF", "Wallis and Futuna Islands", "681", "19", ""),
|
||||
new Country("WS", "Samoa (Western)", "685", "0", "0"),
|
||||
new Country("YE", "Yemen", "967", "00", "0"),
|
||||
new Country("YT", "Mayotte", "269", "00", ""),
|
||||
new Country("ZA", "South Africa", "27", "09", "0"),
|
||||
new Country("ZM", "Zambia", "260", "00", "0"),
|
||||
new Country("ZW", "Zimbabwe", "263", "110", "0")
|
||||
new Country("GS", "South Georgia and the South Sandwich Islands", "995", "8**10", "8"),
|
||||
new Country("GT", "Guatemala", "502", "00", ""),
|
||||
new Country("GU", "Guam", "1", "011", "1"),
|
||||
new Country("GW", "Guinea-Bissau", "245", "00", ""),
|
||||
new Country("GY", "Guyana", "592", "001", "0"),
|
||||
new Country("HK", "Hong Kong", "852", "001", ""),
|
||||
new Country("HM", "Heard Island and McDonald Islands", "692", "00", "0"),
|
||||
new Country("HN", "Honduras", "504", "00", "0"),
|
||||
new Country("HR", "Croatia", "385", "00", "0"),
|
||||
new Country("HT", "Haiti", "509", "00", "0"),
|
||||
new Country("HU", "Hungary", "36", "00", "06"),
|
||||
new Country("ID", "Indonesia", "62", "001", "0"),
|
||||
new Country("IE", "Ireland", "353", "00", "0"),
|
||||
new Country("IL", "Israel", "972", "00", "0"),
|
||||
new Country("IN", "India", "91", "00", "0"),
|
||||
new Country("IO", "British Indian Ocean Territory", "246", "00", ""),
|
||||
new Country("IQ", "Iraq", "964", "00", "0"),
|
||||
new Country("IR", "Iran", "98", "00", "0"),
|
||||
new Country("IS", "Iceland", "354", "00", "0"),
|
||||
new Country("IT", "Italy", "39", "00", ""),
|
||||
new Country("JM", "Jamaica", "1", "011", "1"),
|
||||
new Country("JO", "Jordan", "962", "00", "0"),
|
||||
new Country("JP", "Japan", "81", "001", "0"),
|
||||
new Country("KE", "Kenya", "254", "000", "0"),
|
||||
new Country("KG", "Kyrgyzstan", "996", "00", "0"),
|
||||
new Country("KH", "Cambodia", "855", "001", "0"),
|
||||
new Country("KI", "Kiribati", "686", "00", "0"),
|
||||
new Country("KM", "Comoros", "269", "00", ""),
|
||||
new Country("KN", "Saint Kitts and Nevis", "1", "011", "1"),
|
||||
new Country("KP", "Korea (North)", "850", "00", "0"),
|
||||
new Country("KR", "Korea (South)", "82", "001", "0"),
|
||||
new Country("KW", "Kuwait", "965", "00", "0"),
|
||||
new Country("KY", "Cayman Islands", "1", "011", "1"),
|
||||
new Country("KZ", "Kazakhstan", "7", "8**10", "8"),
|
||||
new Country("LA", "Laos", "856", "00", "0"),
|
||||
new Country("LB", "Lebanon", "961", "00", "0"),
|
||||
new Country("LC", "Saint Lucia", "1", "011", "1"),
|
||||
new Country("LI", "Liechtenstein", "423", "00", ""),
|
||||
new Country("LK", "Sri Lanka", "94", "00", "0"),
|
||||
new Country("LR", "Liberia", "231", "00", "22"),
|
||||
new Country("LS", "Lesotho", "266", "00", "0"),
|
||||
new Country("LT", "Lithuania", "370", "00", "8"),
|
||||
new Country("LU", "Luxembourg", "352", "00", ""),
|
||||
new Country("LV", "Latvia", "371", "00", "8"),
|
||||
new Country("LY", "Libya", "218", "00", "0"),
|
||||
new Country("MA", "Morocco", "212", "00", ""),
|
||||
new Country("MC", "Monaco", "377", "00", "0"),
|
||||
new Country("MD", "Moldova", "373", "00", "0"),
|
||||
new Country("ME", "Montenegro", "382", "99", "0"),
|
||||
new Country("MG", "Madagascar", "261", "00", "0"),
|
||||
new Country("MH", "Marshall Islands", "692", "011", "1"),
|
||||
new Country("MK", "Macedonia", "389", "00", "0"),
|
||||
new Country("ML", "Mali", "223", "00", "0"),
|
||||
new Country("MM", "Myanmar", "95", "00", ""),
|
||||
new Country("MN", "Mongolia", "976", "001", "0"),
|
||||
new Country("MO", "Macao", "853", "00", "0"),
|
||||
new Country("MP", "Northern Mariana Islands", "1", "011", "1"),
|
||||
new Country("MQ", "Martinique", "596", "00", "0"),
|
||||
new Country("MR", "Mauritania", "222", "00", "0"),
|
||||
new Country("MS", "Montserrat", "1", "011", "1"),
|
||||
new Country("MT", "Malta", "356", "00", "21"),
|
||||
new Country("MU", "Mauritius", "230", "00", "0"),
|
||||
new Country("MV", "Maldives", "960", "00", "0"),
|
||||
new Country("MW", "Malawi", "265", "00", ""),
|
||||
new Country("MX", "Mexico", "52", "00", "01"),
|
||||
new Country("MY", "Malaysia", "60", "00", "0"),
|
||||
new Country("MZ", "Mozambique", "258", "00", "0"),
|
||||
new Country("NA", "Namibia", "264", "00", "0"),
|
||||
new Country("NC", "New Caledonia", "687", "00", "0"),
|
||||
new Country("NE", "Niger", "227", "00", "0"),
|
||||
new Country("NF", "Norfolk Island", "672", "00", ""),
|
||||
new Country("NG", "Nigeria", "234", "009", "0"),
|
||||
new Country("NI", "Nicaragua", "505", "00", "0"),
|
||||
new Country("NL", "Netherlands", "31", "00", "0"),
|
||||
new Country("NO", "Norway", "47", "00", ""),
|
||||
new Country("NP", "Nepal", "977", "00", "0"),
|
||||
new Country("NR", "Nauru", "674", "00", "0"),
|
||||
new Country("NU", "Niue", "683", "00", "0"),
|
||||
new Country("NZ", "New Zealand", "64", "00", "0"),
|
||||
new Country("OM", "Oman", "968", "00", "0"),
|
||||
new Country("PA", "Panama", "507", "00", "0"),
|
||||
new Country("PE", "Peru", "51", "00", "0"),
|
||||
new Country("PF", "French Polynesia", "689", "00", ""),
|
||||
new Country("PG", "Papua New Guinea", "675", "05", ""),
|
||||
new Country("PH", "Philippines", "63", "00", "0"),
|
||||
new Country("PK", "Pakistan", "92", "00", "0"),
|
||||
new Country("PL", "Poland", "48", "00", "0"),
|
||||
new Country("PM", "Saint Pierre and Miquelon", "508", "00", "0"),
|
||||
new Country("PN", "Pitcairn", "872", "", ""),
|
||||
new Country("PR", "Puerto Rico", "1", "011", "1"),
|
||||
new Country("PS", "Palestine", "970", "00", "0"),
|
||||
new Country("PT", "Portugal", "351", "00", ""),
|
||||
new Country("PW", "Palau", "680", "011", ""),
|
||||
new Country("PY", "Paraguay", "595", "002", "0"),
|
||||
new Country("QA", "Qatar", "974", "00", "0"),
|
||||
new Country("RE", "Reunion", "262", "00", "0"),
|
||||
new Country("RO", "Romania", "40", "00", "0"),
|
||||
new Country("RS", "Serbia", "381", "99", "0"),
|
||||
new Country("RU", "Russia", "7", "8**10", "8"),
|
||||
new Country("RW", "Rwanda", "250", "00", "0"),
|
||||
new Country("SA", "Saudi Arabia", "966", "00", "0"),
|
||||
new Country("SB", "Solomon Islands", "677", "00", ""),
|
||||
new Country("SC", "Seychelles", "248", "00", "0"),
|
||||
new Country("SD", "Sudan", "249", "00", "0"),
|
||||
new Country("SE", "Sweden", "46", "00", "0"),
|
||||
new Country("SG", "Singapore", "65", "001", ""),
|
||||
new Country("SH", "Saint Helena", "290", "00", ""),
|
||||
new Country("SI", "Slovenia", "386", "00", "0"),
|
||||
new Country("SJ", "Svalbard and Jan Mayen", "378", "00", "0"),
|
||||
new Country("SK", "Slovakia", "421", "00", "0"),
|
||||
new Country("SL", "Sierra Leone", "232", "00", "0"),
|
||||
new Country("SM", "San Marino", "378", "00", "0"),
|
||||
new Country("SN", "Senegal", "221", "00", "0"),
|
||||
new Country("SO", "Somalia", "252", "00", ""),
|
||||
new Country("SR", "Suriname", "597", "00", ""),
|
||||
new Country("ST", "Sao Tome and Principe", "239", "00", "0"),
|
||||
new Country("SV", "El Salvador", "503", "00", ""),
|
||||
new Country("SY", "Syria", "963", "00", "0"),
|
||||
new Country("SZ", "Swaziland", "268", "00", ""),
|
||||
new Country("TC", "Turks and Caicos Islands", "1", "011", "1"),
|
||||
new Country("TD", "Chad", "235", "15", ""),
|
||||
new Country("TF", "French Southern Territories", "596", "00", "0"),
|
||||
new Country("TG", "Togo", "228", "00", ""),
|
||||
new Country("TH", "Thailand", "66", "001", "0"),
|
||||
new Country("TJ", "Tajikistan", "992", "8**10", "8"),
|
||||
new Country("TK", "Tokelau", "690", "00", ""),
|
||||
new Country("TL", "Timor-Leste", "670", "00", ""),
|
||||
new Country("TM", "Turkmenistan", "993", "8**10", "8"),
|
||||
new Country("TN", "Tunisia", "216", "00", "0"),
|
||||
new Country("TO", "Tonga Islands", "676", "00", ""),
|
||||
new Country("TR", "Turkey", "90", "00", "0"),
|
||||
new Country("TT", "Trinidad and Tobago", "1", "011", "1"),
|
||||
new Country("TV", "Tuvalu", "688", "00", ""),
|
||||
new Country("TW", "Taiwan", "886", "002", ""),
|
||||
new Country("TZ", "Tanzania", "255", "000", "0"),
|
||||
new Country("UA", "Ukraine", "380", "8**10", "8"),
|
||||
new Country("UG", "Uganda", "256", "000", "0"),
|
||||
new Country("US", "United States", "1", "011", "1"),
|
||||
new Country("UY", "Uruguay", "598", "00", "0"),
|
||||
new Country("UZ", "Uzbekistan", "998", "8**10", "8"),
|
||||
new Country("VA", "Holy See (Vatican City State)", "379", "00", ""),
|
||||
new Country("VC", "Saint Vincent and the Grenadines", "1", "011", "1"),
|
||||
new Country("VE", "Venezuela", "58", "00", "0"),
|
||||
new Country("VG", "Virgin Islands (British)", "1", "011", "1"),
|
||||
new Country("VI", "Virgin Islands (U.S.)", "1", "011", "1"),
|
||||
new Country("VN", "Viet Nam", "84", "00", "0"),
|
||||
new Country("VU", "Vanuatu", "678", "00", ""),
|
||||
new Country("WF", "Wallis and Futuna Islands", "681", "19", ""),
|
||||
new Country("WS", "Samoa (Western)", "685", "0", "0"),
|
||||
new Country("YE", "Yemen", "967", "00", "0"),
|
||||
new Country("YT", "Mayotte", "269", "00", ""),
|
||||
new Country("ZA", "South Africa", "27", "09", "0"),
|
||||
new Country("ZM", "Zambia", "260", "00", "0"),
|
||||
new Country("ZW", "Zimbabwe", "263", "110", "0")
|
||||
};
|
||||
|
||||
private static final Map<String, Country> COUNTRY_MAP =
|
||||
|
||||
@@ -44,15 +44,15 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
private final Semaphore stateChange;
|
||||
private final byte[] line;
|
||||
|
||||
private int lineLen = 0;
|
||||
|
||||
private ReliabilityLayer reliability = null;
|
||||
private boolean initialised = false, connected = false;
|
||||
|
||||
private final Lock synchLock = new ReentrantLock();
|
||||
private final Condition connectedStateChanged = synchLock.newCondition();
|
||||
private final Condition initialisedStateChanged = synchLock.newCondition();
|
||||
|
||||
// The following are locking: synchLock
|
||||
private ReliabilityLayer reliability = null;
|
||||
private boolean initialised = false, connected = false;
|
||||
|
||||
private int lineLen = 0;
|
||||
|
||||
ModemImpl(Executor ioExecutor, ReliabilityLayerFactory reliabilityFactory,
|
||||
Clock clock, Callback callback, SerialPort port) {
|
||||
@@ -161,6 +161,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: stateChange
|
||||
private void hangUpInner() throws IOException {
|
||||
ReliabilityLayer reliability;
|
||||
synchLock.lock();
|
||||
|
||||
@@ -213,9 +213,9 @@ public class StreamEncrypterImplTest extends BriarTestCase {
|
||||
FrameEncoder.encodeHeader(header1, true, payloadLength1,
|
||||
paddingLength1);
|
||||
byte[] expected = new byte[HEADER_LENGTH + payloadLength
|
||||
+ paddingLength + MAC_LENGTH
|
||||
+ HEADER_LENGTH + payloadLength1
|
||||
+ paddingLength1 + MAC_LENGTH];
|
||||
+ paddingLength + MAC_LENGTH + HEADER_LENGTH
|
||||
+ payloadLength + paddingLength1
|
||||
+ MAC_LENGTH];
|
||||
System.arraycopy(header, 0, expected, 0, HEADER_LENGTH);
|
||||
System.arraycopy(payload, 0, expected, HEADER_LENGTH, payloadLength);
|
||||
System.arraycopy(header1, 0, expected, HEADER_LENGTH + payloadLength
|
||||
|
||||
Reference in New Issue
Block a user