diff --git a/api/net/sf/briar/api/transport/ConnectionWindow.java b/api/net/sf/briar/api/transport/ConnectionWindow.java index 4d0a9d59cec071d715f56d11021c0d04d450dea5..1a403f6c947c33de971298144a81d79a410f39a1 100644 --- a/api/net/sf/briar/api/transport/ConnectionWindow.java +++ b/api/net/sf/briar/api/transport/ConnectionWindow.java @@ -6,7 +6,7 @@ public interface ConnectionWindow { boolean isSeen(long connection); - void setSeen(long connection); + byte[] setSeen(long connection); Map<Long, byte[]> getUnseen(); } diff --git a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java index b4da6dc02ea1c50e1eab9fc7cdffa4aab0c38c3d..745aaf842f557eafb7e8a08a854b7163ea9d6666 100644 --- a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java +++ b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java @@ -46,7 +46,7 @@ DatabaseListener { private final CryptoComponent crypto; private final DatabaseComponent db; private final Cipher ivCipher; - private final Map<Bytes, ConnectionContext> expected; + private final Map<Bytes, Context> expected; private final Collection<TransportId> localTransportIds; private boolean initialised = false; @@ -56,7 +56,7 @@ DatabaseListener { this.crypto = crypto; this.db = db; ivCipher = crypto.getIvCipher(); - expected = new HashMap<Bytes, ConnectionContext>(); + expected = new HashMap<Bytes, Context>(); localTransportIds = new ArrayList<TransportId>(); db.addListener(this); } @@ -93,7 +93,7 @@ DatabaseListener { ErasableKey ivKey = crypto.deriveIvKey(secret, true); Bytes iv = new Bytes(encryptIv(i, unseen, ivKey)); ivKey.erase(); - expected.put(iv, new ConnectionContextImpl(c, i, unseen, secret)); + expected.put(iv, new Context(c, i, unseen, w)); } } @@ -117,28 +117,25 @@ DatabaseListener { if(encryptedIv.length != IV_LENGTH) throw new IllegalArgumentException(); if(!initialised) initialise(); - ConnectionContext ctx = expected.remove(new Bytes(encryptedIv)); + Context ctx = expected.remove(new Bytes(encryptedIv)); if(ctx == null) return null; // The IV was not expected + // Get the secret and update the connection window + byte[] secret = ctx.window.setSeen(ctx.connection); try { - ContactId c = ctx.getContactId(); - TransportIndex i = ctx.getTransportIndex(); - // Update the connection window - ConnectionWindow w = db.getConnectionWindow(c, i); - w.setSeen(ctx.getConnectionNumber()); - db.setConnectionWindow(c, i, w); - // Update the set of expected IVs - Iterator<ConnectionContext> it = expected.values().iterator(); - while(it.hasNext()) { - ConnectionContext ctx1 = it.next(); - ContactId c1 = ctx1.getContactId(); - TransportIndex i1 = ctx1.getTransportIndex(); - if(c1.equals(c) && i1.equals(i)) it.remove(); - } - calculateIvs(c, i, w); + db.setConnectionWindow(ctx.contactId, ctx.index, ctx.window); } catch(NoSuchContactException e) { // The contact was removed - clean up when we get the event } - return ctx; + // Update the set of expected IVs + Iterator<Context> it = expected.values().iterator(); + while(it.hasNext()) { + Context ctx1 = it.next(); + if(ctx1.contactId.equals(ctx.contactId) + && ctx1.index.equals(ctx.index)) it.remove(); + } + calculateIvs(ctx.contactId, ctx.index, ctx.window); + return new ConnectionContextImpl(ctx.contactId, ctx.index, + ctx.connection, secret); } public void eventOccurred(DatabaseEvent e) { @@ -175,9 +172,8 @@ DatabaseListener { } private synchronized void removeIvs(ContactId c) { - if(!initialised) return; - Iterator<ConnectionContext> it = expected.values().iterator(); - while(it.hasNext()) if(it.next().getContactId().equals(c)) it.remove(); + Iterator<Context> it = expected.values().iterator(); + while(it.hasNext()) if(it.next().contactId.equals(c)) it.remove(); } private synchronized void calculateIvs(TransportId t) throws DbException { @@ -193,4 +189,20 @@ DatabaseListener { } } } + + private static class Context { + + private final ContactId contactId; + private final TransportIndex index; + private final long connection; + private final ConnectionWindow window; + + private Context(ContactId contactId, TransportIndex index, + long connection, ConnectionWindow window) { + this.contactId = contactId; + this.index = index; + this.connection = connection; + this.window = window; + } + } } diff --git a/components/net/sf/briar/transport/ConnectionWindowImpl.java b/components/net/sf/briar/transport/ConnectionWindowImpl.java index 0bd397c300f8f5c64ca08586a442034468a20823..fcc4e9ac55ae5a9722f1d9d3492140b714fbba7d 100644 --- a/components/net/sf/briar/transport/ConnectionWindowImpl.java +++ b/components/net/sf/briar/transport/ConnectionWindowImpl.java @@ -54,7 +54,7 @@ class ConnectionWindowImpl implements ConnectionWindow { return !unseen.containsKey(connection); } - public void setSeen(long connection) { + public byte[] setSeen(long connection) { long bottom = getBottom(centre); long top = getTop(centre); if(connection < bottom || connection > top) @@ -78,7 +78,7 @@ class ConnectionWindowImpl implements ConnectionWindow { } byte[] seen = unseen.remove(connection); assert seen != null; - ByteUtils.erase(seen); + return seen; } // Returns the lowest value contained in a window with the given centre diff --git a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java index b5a36278951207a8acfbaf5a648466e4943a5093..a0c552f8e1081b5c639f8881f06b0d7e4a42356a 100644 --- a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java +++ b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java @@ -106,8 +106,6 @@ public class ConnectionRecogniserImplTest extends TestCase { oneOf(db).getConnectionWindow(contactId, remoteIndex); will(returnValue(connectionWindow)); // Update the window - oneOf(db).getConnectionWindow(contactId, remoteIndex); - will(returnValue(connectionWindow)); oneOf(db).setConnectionWindow(contactId, remoteIndex, connectionWindow); }});