From 708e4f87dcfd8799100fcdbe9f86cf9b9cfb0226 Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Fri, 19 Oct 2012 21:05:21 +0100 Subject: [PATCH] Fixed some bugs and cleaned up code in TransportConnectionRecogniser. --- .../TransportConnectionRecogniser.java | 95 +++++++++++-------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/components/net/sf/briar/transport/TransportConnectionRecogniser.java b/components/net/sf/briar/transport/TransportConnectionRecogniser.java index 9ddaacfc28..d5bbb12dd0 100644 --- a/components/net/sf/briar/transport/TransportConnectionRecogniser.java +++ b/components/net/sf/briar/transport/TransportConnectionRecogniser.java @@ -26,7 +26,7 @@ class TransportConnectionRecogniser { private final DatabaseComponent db; private final TransportId transportId; private final Map<Bytes, WindowContext> tagMap; // Locking: this - private final Map<RemovalKey, RemovalContext> windowMap; // Locking: this + private final Map<RemovalKey, RemovalContext> removalMap; // Locking: this TransportConnectionRecogniser(CryptoComponent crypto, DatabaseComponent db, TransportId transportId) { @@ -34,72 +34,87 @@ class TransportConnectionRecogniser { this.db = db; this.transportId = transportId; tagMap = new HashMap<Bytes, WindowContext>(); - windowMap = new HashMap<RemovalKey, RemovalContext>(); + removalMap = new HashMap<RemovalKey, RemovalContext>(); } synchronized ConnectionContext acceptConnection(byte[] tag) throws DbException { WindowContext wctx = tagMap.remove(new Bytes(tag)); - if(wctx == null) return null; - ConnectionWindow w = wctx.window; + if(wctx == null) return null; // The tag was not expected + ConnectionWindow window = wctx.window; ConnectionContext ctx = wctx.context; + long period = wctx.period; + ContactId contactId = ctx.getContactId(); + byte[] secret = ctx.getSecret(); long connection = ctx.getConnectionNumber(); + boolean alice = ctx.getAlice(); + // Update the connection window and the expected tags Cipher cipher = crypto.getTagCipher(); - ErasableKey key = crypto.deriveTagKey(ctx.getSecret(), ctx.getAlice()); - byte[] changedTag = new byte[TAG_LENGTH]; - Bytes changedTagWrapper = new Bytes(changedTag); - for(long conn : w.setSeen(connection)) { - TagEncoder.encodeTag(changedTag, cipher, key, conn); - WindowContext old; - if(conn <= connection) old = tagMap.remove(changedTagWrapper); - else old = tagMap.put(changedTagWrapper, wctx); - assert old == null; + ErasableKey key = crypto.deriveTagKey(secret, alice); + for(long connection1 : window.setSeen(connection)) { + byte[] tag1 = new byte[TAG_LENGTH]; + TagEncoder.encodeTag(tag1, cipher, key, connection1); + if(connection1 <= connection) { + WindowContext old = tagMap.remove(new Bytes(tag1)); + assert old == null; + } else { + ConnectionContext ctx1 = new ConnectionContext(contactId, + transportId, tag1, secret, connection1, alice); + WindowContext wctx1 = new WindowContext(window, ctx1, period); + WindowContext old = tagMap.put(new Bytes(tag1), wctx1); + assert old == null; + } } key.erase(); - ContactId c = ctx.getContactId(); - long centre = w.getCentre(); - byte[] bitmap = w.getBitmap(); - db.setConnectionWindow(c, transportId, wctx.period, centre, bitmap); - return wctx.context; + // Store the updated connection window in the DB + long centre = window.getCentre(); + byte[] bitmap = window.getBitmap(); + db.setConnectionWindow(contactId, transportId, period, centre, bitmap); + return ctx; } - synchronized void addWindow(ContactId c, long period, boolean alice, + synchronized void addWindow(ContactId contactId, long period, boolean alice, byte[] secret, long centre, byte[] bitmap) throws DbException { + // Create the connection window and the expected tags Cipher cipher = crypto.getTagCipher(); ErasableKey key = crypto.deriveTagKey(secret, alice); - ConnectionWindow w = new ConnectionWindow(centre, bitmap); - for(long conn : w.getUnseen()) { + ConnectionWindow window = new ConnectionWindow(centre, bitmap); + for(long connection : window.getUnseen()) { byte[] tag = new byte[TAG_LENGTH]; - TagEncoder.encodeTag(tag, cipher, key, conn); - ConnectionContext ctx = new ConnectionContext(c, transportId, tag, - secret, conn, alice); - WindowContext wctx = new WindowContext(w, ctx, period); - tagMap.put(new Bytes(tag), wctx); + TagEncoder.encodeTag(tag, cipher, key, connection); + ConnectionContext ctx = new ConnectionContext(contactId, + transportId, tag, secret, connection, alice); + WindowContext wctx = new WindowContext(window, ctx, period); + WindowContext old = tagMap.put(new Bytes(tag), wctx); + assert old == null; } - db.setConnectionWindow(c, transportId, period, centre, bitmap); - RemovalContext ctx = new RemovalContext(w, secret, alice); - windowMap.put(new RemovalKey(c, period), ctx); + // Store the new connection window in the DB + db.setConnectionWindow(contactId, transportId, period, centre, bitmap); + // Create a removal context to remove the window when the key expires + RemovalContext rctx = new RemovalContext(window, secret, alice); + removalMap.put(new RemovalKey(contactId, period), rctx); } - synchronized void removeWindow(ContactId c, long period) { - RemovalContext ctx = windowMap.remove(new RemovalKey(c, period)); - if(ctx == null) throw new IllegalArgumentException(); + synchronized void removeWindow(ContactId contactId, long period) { + RemovalKey rk = new RemovalKey(contactId, period); + RemovalContext rctx = removalMap.remove(rk); + if(rctx == null) throw new IllegalArgumentException(); + // Remove the expected tags Cipher cipher = crypto.getTagCipher(); - ErasableKey key = crypto.deriveTagKey(ctx.secret, ctx.alice); - byte[] removedTag = new byte[TAG_LENGTH]; - Bytes removedTagWrapper = new Bytes(removedTag); - for(long conn : ctx.window.getUnseen()) { - TagEncoder.encodeTag(removedTag, cipher, key, conn); - WindowContext old = tagMap.remove(removedTagWrapper); + ErasableKey key = crypto.deriveTagKey(rctx.secret, rctx.alice); + byte[] tag = new byte[TAG_LENGTH]; + for(long connection : rctx.window.getUnseen()) { + TagEncoder.encodeTag(tag, cipher, key, connection); + WindowContext old = tagMap.remove(new Bytes(tag)); assert old != null; } key.erase(); - ByteUtils.erase(ctx.secret); + ByteUtils.erase(rctx.secret); } synchronized void removeWindows(ContactId c) { Collection<RemovalKey> keysToRemove = new ArrayList<RemovalKey>(); - for(RemovalKey k : windowMap.keySet()) { + for(RemovalKey k : removalMap.keySet()) { if(k.contactId.equals(c)) keysToRemove.add(k); } for(RemovalKey k : keysToRemove) removeWindow(k.contactId, k.period); -- GitLab