From 0dbfd7073f8edf6e3b9afde05da7ff16bedc8f2d Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Thu, 29 Jan 2015 11:05:46 +0000 Subject: [PATCH] Comments to indicate which locks guard which variables. --- .../AndroidNotificationManagerImpl.java | 10 +- .../android/ReferenceManagerImpl.java | 6 +- .../briarproject/crypto/FortunaGenerator.java | 5 +- .../src/org/briarproject/db/JdbcDatabase.java | 7 +- .../invitation/ConnectorGroup.java | 5 +- .../lifecycle/ShutdownManagerImpl.java | 6 +- .../plugins/ConnectionRegistryImpl.java | 7 +- .../briarproject/reliability/Receiver.java | 20 +- .../org/briarproject/reliability/Sender.java | 24 +- .../transport/KeyManagerImpl.java | 10 +- .../transport/KeyManagerImpl.java.orig | 546 ------------------ .../transport/TagRecogniserImpl.java | 5 +- .../transport/TransportTagRecogniser.java | 6 +- .../TransportTagRecogniser.java.orig | 235 -------- .../lifecycle/WindowsShutdownManagerImpl.java | 5 +- .../file/PollingRemovableDriveMonitor.java | 5 +- .../PollingRemovableDriveMonitor.java.orig | 83 --- .../file/UnixRemovableDriveMonitor.java | 12 +- .../plugins/modem/CountryCodes.java | 309 +++++----- .../briarproject/plugins/modem/ModemImpl.java | 11 +- .../crypto/StreamEncrypterImplTest.java | 6 +- 21 files changed, 233 insertions(+), 1090 deletions(-) delete mode 100644 briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig delete mode 100644 briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig delete mode 100644 briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig diff --git a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java index 90842481cf..0f6bccfe6f 100644 --- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java @@ -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; diff --git a/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java b/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java index e345b02d06..b7b764f097 100644 --- a/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java +++ b/briar-android/src/org/briarproject/android/ReferenceManagerImpl.java @@ -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 { diff --git a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java index f804db971d..4045db3ce1 100644 --- a/briar-core/src/org/briarproject/crypto/FortunaGenerator.java +++ b/briar-core/src/org/briarproject/crypto/FortunaGenerator.java @@ -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); } diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java index 19ea75e13c..256cda0dfc 100644 --- a/briar-core/src/org/briarproject/db/JdbcDatabase.java +++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java @@ -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 diff --git a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java index b8f471229c..97bd39ddaa 100644 --- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java +++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java @@ -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; diff --git a/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java b/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java index 030d15483a..880db5b5eb 100644 --- a/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java +++ b/briar-core/src/org/briarproject/lifecycle/ShutdownManagerImpl.java @@ -9,12 +9,12 @@ import org.briarproject.api.lifecycle.ShutdownManager; class ShutdownManagerImpl implements ShutdownManager { - protected final Map<Integer, Thread> hooks; + private final Lock synchLock = new ReentrantLock(); + // The following are locking: synchLock + protected final Map<Integer, Thread> hooks; private int nextHandle = 0; - private final Lock synchLock = new ReentrantLock(); - ShutdownManagerImpl() { hooks = new HashMap<Integer, Thread>(); } diff --git a/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java b/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java index c898036b13..358f6da43a 100644 --- a/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java +++ b/briar-core/src/org/briarproject/plugins/ConnectionRegistryImpl.java @@ -27,13 +27,12 @@ class ConnectionRegistryImpl implements ConnectionRegistry { Logger.getLogger(ConnectionRegistryImpl.class.getName()); private final EventBus eventBus; - // Locking: this + private final Lock synchLock = new ReentrantLock(); + + // The following are locking: synchLock private final Map<TransportId, Map<ContactId, Integer>> connections; - // Locking: this private final Map<ContactId, Integer> contactCounts; - private final Lock synchLock = new ReentrantLock(); - @Inject ConnectionRegistryImpl(EventBus eventBus) { this.eventBus = eventBus; diff --git a/briar-core/src/org/briarproject/reliability/Receiver.java b/briar-core/src/org/briarproject/reliability/Receiver.java index 5d27e3ec4c..b45bc27484 100644 --- a/briar-core/src/org/briarproject/reliability/Receiver.java +++ b/briar-core/src/org/briarproject/reliability/Receiver.java @@ -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(); } } diff --git a/briar-core/src/org/briarproject/reliability/Sender.java b/briar-core/src/org/briarproject/reliability/Sender.java index 77a30efaa2..6cb5d6d8f4 100644 --- a/briar-core/src/org/briarproject/reliability/Sender.java +++ b/briar-core/src/org/briarproject/reliability/Sender.java @@ -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(); } } diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java index 9f4f301f02..257b1ef619 100644 --- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java +++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java @@ -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()) diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig deleted file mode 100644 index 88863dadaa..0000000000 --- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java.orig +++ /dev/null @@ -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(); - } - } - } -} diff --git a/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java b/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java index ba3aa9bf40..ea4e5567b5 100644 --- a/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java +++ b/briar-core/src/org/briarproject/transport/TagRecogniserImpl.java @@ -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) { diff --git a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java index 71cd559254..0898120440 100644 --- a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java +++ b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java @@ -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); diff --git a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig b/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig deleted file mode 100644 index 0e46da82ef..0000000000 --- a/briar-core/src/org/briarproject/transport/TransportTagRecogniser.java.orig +++ /dev/null @@ -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; - } - } -} diff --git a/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java b/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java index 7fd8e77cfd..3585e557f2 100644 --- a/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java +++ b/briar-desktop/src/org/briarproject/lifecycle/WindowsShutdownManagerImpl.java @@ -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(); diff --git a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java index 33b485f5d8..c86b657d7e 100644 --- a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java +++ b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java @@ -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) { diff --git a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig b/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig deleted file mode 100644 index d27f65a0a1..0000000000 --- a/briar-desktop/src/org/briarproject/plugins/file/PollingRemovableDriveMonitor.java.orig +++ /dev/null @@ -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); - } - } -} diff --git a/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java b/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java index 8a788ddc61..bc2ca3fd9f 100644 --- a/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java +++ b/briar-desktop/src/org/briarproject/plugins/file/UnixRemovableDriveMonitor.java @@ -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"); diff --git a/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java b/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java index 7975c78580..b4fb65a00c 100644 --- a/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java +++ b/briar-desktop/src/org/briarproject/plugins/modem/CountryCodes.java @@ -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 = diff --git a/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java b/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java index f8be63c116..2896f48d02 100644 --- a/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java +++ b/briar-desktop/src/org/briarproject/plugins/modem/ModemImpl.java @@ -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(); diff --git a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java index a874314165..8d1e2aa088 100644 --- a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java +++ b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java @@ -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 -- GitLab