From e1ec17f4b651834deedabf6d77593550c8b87431 Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Thu, 13 Jun 2013 12:53:44 +0100 Subject: [PATCH] Made the invitation protocol symmetrical. Both devices try to make outgoing connections and accept incoming connections simultaneously. This should lead to faster connection establishment when there are asymmetrical connectivity problems, such as devices that are unable to receive LAN multicast packets or make themselves discoverable via Bluetooth. --- .../api/plugins/duplex/DuplexPlugin.java | 14 +++---- .../sf/briar/invitation/AliceConnector.java | 10 +---- .../net/sf/briar/invitation/BobConnector.java | 10 +---- .../net/sf/briar/invitation/Connector.java | 27 ++---------- .../plugins/bluetooth/BluetoothPlugin.java | 42 +++++++------------ .../plugins/droidtooth/DroidtoothPlugin.java | 23 ++++------ .../sf/briar/plugins/modem/ModemPlugin.java | 7 +--- .../briar/plugins/tcp/DroidLanTcpPlugin.java | 19 +-------- .../sf/briar/plugins/tcp/LanTcpPlugin.java | 8 +--- .../sf/briar/plugins/tcp/WanTcpPlugin.java | 7 +--- .../net/sf/briar/plugins/tor/TorPlugin.java | 7 +--- .../sf/briar/plugins/DuplexClientTest.java | 21 +++------- .../sf/briar/plugins/DuplexServerTest.java | 18 ++------ 13 files changed, 52 insertions(+), 161 deletions(-) diff --git a/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexPlugin.java b/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexPlugin.java index 8b7c484379..4120e25c41 100644 --- a/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexPlugin.java +++ b/briar-api/src/net/sf/briar/api/plugins/duplex/DuplexPlugin.java @@ -18,14 +18,10 @@ public interface DuplexPlugin extends Plugin { boolean supportsInvitations(); /** - * Starts the invitation process from the inviter's side. Returns null if - * no connection can be established within the given timeout. + * Attempts to create and return an invitation connection to the remote + * peer. Returns null if no connection can be established within the given + * time. */ - DuplexTransportConnection sendInvitation(PseudoRandom r, long timeout); - - /** - * Starts the invitation process from the invitee's side. Returns null if - * no connection can be established within the given timeout. - */ - DuplexTransportConnection acceptInvitation(PseudoRandom r, long timeout); + DuplexTransportConnection createInvitationConnection(PseudoRandom r, + long timeout); } diff --git a/briar-core/src/net/sf/briar/invitation/AliceConnector.java b/briar-core/src/net/sf/briar/invitation/AliceConnector.java index b4e1b0cdf4..84cab4286e 100644 --- a/briar-core/src/net/sf/briar/invitation/AliceConnector.java +++ b/briar-core/src/net/sf/briar/invitation/AliceConnector.java @@ -2,7 +2,6 @@ package net.sf.briar.invitation; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static net.sf.briar.api.invitation.InvitationConstants.CONNECTION_TIMEOUT; import java.io.IOException; import java.io.InputStream; @@ -57,13 +56,8 @@ class AliceConnector extends Connector { @Override public void run() { - // Try an outgoing connection first, then an incoming connection - long halfTime = clock.currentTimeMillis() + CONNECTION_TIMEOUT; - DuplexTransportConnection conn = makeOutgoingConnection(); - if(conn == null) { - waitForHalfTime(halfTime); - conn = acceptIncomingConnection(); - } + // Create an incoming or outgoing connection + DuplexTransportConnection conn = createInvitationConnection(); if(conn == null) return; if(LOG.isLoggable(INFO)) LOG.info(pluginName + " connected"); // Don't proceed with more than one connection diff --git a/briar-core/src/net/sf/briar/invitation/BobConnector.java b/briar-core/src/net/sf/briar/invitation/BobConnector.java index 20bb1b71ee..ae7c02144c 100644 --- a/briar-core/src/net/sf/briar/invitation/BobConnector.java +++ b/briar-core/src/net/sf/briar/invitation/BobConnector.java @@ -2,7 +2,6 @@ package net.sf.briar.invitation; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static net.sf.briar.api.invitation.InvitationConstants.CONNECTION_TIMEOUT; import java.io.IOException; import java.io.InputStream; @@ -57,13 +56,8 @@ class BobConnector extends Connector { @Override public void run() { - // Try an incoming connection first, then an outgoing connection - long halfTime = clock.currentTimeMillis() + CONNECTION_TIMEOUT; - DuplexTransportConnection conn = acceptIncomingConnection(); - if(conn == null) { - waitForHalfTime(halfTime); - conn = makeOutgoingConnection(); - } + // Create an incoming or outgoing connection + DuplexTransportConnection conn = createInvitationConnection(); if(conn == null) return; if(LOG.isLoggable(INFO)) LOG.info(pluginName + " connected"); // Carry out the key agreement protocol diff --git a/briar-core/src/net/sf/briar/invitation/Connector.java b/briar-core/src/net/sf/briar/invitation/Connector.java index f0fd6b0955..076f77cf30 100644 --- a/briar-core/src/net/sf/briar/invitation/Connector.java +++ b/briar-core/src/net/sf/briar/invitation/Connector.java @@ -112,31 +112,10 @@ abstract class Connector extends Thread { messageDigest = crypto.getMessageDigest(); } - protected DuplexTransportConnection acceptIncomingConnection() { + protected DuplexTransportConnection createInvitationConnection() { if(LOG.isLoggable(INFO)) - LOG.info(pluginName + " accepting incoming connection"); - return plugin.acceptInvitation(random, CONNECTION_TIMEOUT); - } - - protected DuplexTransportConnection makeOutgoingConnection() { - if(LOG.isLoggable(INFO)) - LOG.info(pluginName + " making outgoing connection"); - return plugin.sendInvitation(random, CONNECTION_TIMEOUT); - } - - protected void waitForHalfTime(long halfTime) { - long now = clock.currentTimeMillis(); - if(now < halfTime) { - if(LOG.isLoggable(INFO)) - LOG.info(pluginName + " sleeping until half-time"); - try { - clock.sleep(halfTime - now); - } catch(InterruptedException e) { - if(LOG.isLoggable(INFO)) LOG.info("Interrupted while sleeping"); - Thread.currentThread().interrupt(); - return; - } - } + LOG.info(pluginName + " creating invitation connection"); + return plugin.createInvitationConnection(random, CONNECTION_TIMEOUT); } protected void sendPublicKeyHash(Writer w) throws IOException { diff --git a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java index 4036e10d87..f522fea0b2 100644 --- a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java @@ -166,13 +166,15 @@ class BluetoothPlugin implements DuplexPlugin { tryToClose(ss); return; } - BluetoothTransportConnection conn = - new BluetoothTransportConnection(this, s); - callback.incomingConnectionCreated(conn); + callback.incomingConnectionCreated(wrapSocket(s)); if(!running) return; } } + private DuplexTransportConnection wrapSocket(StreamConnection s) { + return new BluetoothTransportConnection(this, s); + } + public void stop() { running = false; tryToClose(socket); @@ -202,11 +204,8 @@ class BluetoothPlugin implements DuplexPlugin { public void run() { if(!running) return; StreamConnection s = connect(makeUrl(address, uuid)); - if(s != null) { - callback.outgoingConnectionCreated(c, - new BluetoothTransportConnection( - BluetoothPlugin.this, s)); - } + if(s != null) + callback.outgoingConnectionCreated(c, wrapSocket(s)); } }); } @@ -239,7 +238,7 @@ class BluetoothPlugin implements DuplexPlugin { return true; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { if(!running) return null; // Use the invitation codes to generate the UUID @@ -282,7 +281,6 @@ class BluetoothPlugin implements DuplexPlugin { private void makeDeviceDiscoverable() { // Try to make the device discoverable (requires root on Linux) - if(!running) return; try { localDevice.setDiscoverable(GIAC); } catch(BluetoothStateException e) { @@ -290,12 +288,6 @@ class BluetoothPlugin implements DuplexPlugin { } } - public DuplexTransportConnection acceptInvitation(PseudoRandom r, - long timeout) { - // FIXME - return sendInvitation(r, timeout); - } - private class DiscoveryThread extends Thread { private final LatchedReference<StreamConnection> socketLatch; @@ -325,18 +317,16 @@ class BluetoothPlugin implements DuplexPlugin { new InvitationListener(discoveryAgent, uuid); discoveryAgent.startInquiry(GIAC, listener); String url = listener.waitForUrl(); - if(url != null) { - StreamConnection s = connect(url); - if(s == null) return; + if(url == null) continue; + StreamConnection s = connect(url); + if(s == null) continue; + if(LOG.isLoggable(INFO)) LOG.info("Outgoing connection"); + if(!socketLatch.set(s)) { if(LOG.isLoggable(INFO)) - LOG.info("Outgoing connection"); - if(!socketLatch.set(s)) { - if(LOG.isLoggable(INFO)) - LOG.info("Closing redundant connection"); - tryToClose(s); - } - return; + LOG.info("Closing redundant connection"); + tryToClose(s); } + return; } catch(BluetoothStateException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); diff --git a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java index 12c9aab68d..407daedd68 100644 --- a/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java @@ -217,13 +217,15 @@ class DroidtoothPlugin implements DuplexPlugin { tryToClose(ss); return; } - DroidtoothTransportConnection conn = - new DroidtoothTransportConnection(this, s); - callback.incomingConnectionCreated(conn); + callback.incomingConnectionCreated(wrapSocket(s)); if(!running) return; } } + private DuplexTransportConnection wrapSocket(BluetoothSocket s) { + return new DroidtoothTransportConnection(this, s); + } + public void stop() { running = false; // Disable Bluetooth if we enabled it at startup @@ -277,11 +279,8 @@ class DroidtoothPlugin implements DuplexPlugin { public void run() { if(!running) return; BluetoothSocket s = connect(address, uuid); - if(s != null) { - callback.outgoingConnectionCreated(c, - new DroidtoothTransportConnection( - DroidtoothPlugin.this, s)); - } + if(s != null) + callback.outgoingConnectionCreated(c, wrapSocket(s)); } }); } @@ -343,7 +342,7 @@ class DroidtoothPlugin implements DuplexPlugin { return true; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { if(!running) return null; // Use the invitation codes to generate the UUID @@ -379,12 +378,6 @@ class DroidtoothPlugin implements DuplexPlugin { return null; } - public DuplexTransportConnection acceptInvitation(PseudoRandom r, - long timeout) { - // FIXME - return sendInvitation(r, timeout); - } - private static class BluetoothStateReceiver extends BroadcastReceiver { private final CountDownLatch finished = new CountDownLatch(1); diff --git a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java index 893205225c..ff9025f66a 100644 --- a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java @@ -219,12 +219,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { return false; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, - long timeout) { - throw new UnsupportedOperationException(); - } - - public DuplexTransportConnection acceptInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { throw new UnsupportedOperationException(); } diff --git a/briar-core/src/net/sf/briar/plugins/tcp/DroidLanTcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/DroidLanTcpPlugin.java index 067984e1df..7315dab01a 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/DroidLanTcpPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/DroidLanTcpPlugin.java @@ -25,7 +25,7 @@ class DroidLanTcpPlugin extends LanTcpPlugin { } @Override - public DuplexTransportConnection sendInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { WifiManager wifi = (WifiManager) appContext.getSystemService(WIFI_SERVICE); @@ -33,22 +33,7 @@ class DroidLanTcpPlugin extends LanTcpPlugin { MulticastLock lock = wifi.createMulticastLock("invitation"); lock.acquire(); try { - return super.sendInvitation(r, timeout); - } finally { - lock.release(); - } - } - - @Override - public DuplexTransportConnection acceptInvitation(PseudoRandom r, - long timeout) { - WifiManager wifi = - (WifiManager) appContext.getSystemService(WIFI_SERVICE); - if(wifi == null || !wifi.isWifiEnabled()) return null; - MulticastLock lock = wifi.createMulticastLock("invitation"); - lock.acquire(); - try { - return super.acceptInvitation(r, timeout); + return super.createInvitationConnection(r, timeout); } finally { lock.release(); } diff --git a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java index dff58aa677..a01a5f4344 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java @@ -119,7 +119,7 @@ class LanTcpPlugin extends TcpPlugin { return true; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { if(!running) return null; // Use the invitation codes to generate the group address and port @@ -244,12 +244,6 @@ class LanTcpPlugin extends TcpPlugin { ms.close(); } - public DuplexTransportConnection acceptInvitation(PseudoRandom r, - long timeout) { - // FIXME - return sendInvitation(r, timeout); - } - private class MulticastListenerThread extends Thread { private final LatchedReference<Socket> socketLatch; diff --git a/briar-core/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java index 770f2f7a56..45e145e5f4 100644 --- a/briar-core/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java @@ -125,12 +125,7 @@ class WanTcpPlugin extends TcpPlugin { return false; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, - long timeout) { - throw new UnsupportedOperationException(); - } - - public DuplexTransportConnection acceptInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { throw new UnsupportedOperationException(); } diff --git a/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java b/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java index 2b1eacee34..d169b3a6da 100644 --- a/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java +++ b/briar-core/src/net/sf/briar/plugins/tor/TorPlugin.java @@ -513,12 +513,7 @@ class TorPlugin implements DuplexPlugin, EventHandler { return false; } - public DuplexTransportConnection sendInvitation(PseudoRandom r, - long timeout) { - throw new UnsupportedOperationException(); - } - - public DuplexTransportConnection acceptInvitation(PseudoRandom r, + public DuplexTransportConnection createInvitationConnection(PseudoRandom r, long timeout) { throw new UnsupportedOperationException(); } diff --git a/briar-tests/src/net/sf/briar/plugins/DuplexClientTest.java b/briar-tests/src/net/sf/briar/plugins/DuplexClientTest.java index d00d839066..35269a94e0 100644 --- a/briar-tests/src/net/sf/briar/plugins/DuplexClientTest.java +++ b/briar-tests/src/net/sf/briar/plugins/DuplexClientTest.java @@ -8,6 +8,7 @@ import java.util.Map; import net.sf.briar.api.ContactId; import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportProperties; +import net.sf.briar.api.crypto.PseudoRandom; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; import net.sf.briar.api.plugins.duplex.DuplexTransportConnection; @@ -35,23 +36,13 @@ public abstract class DuplexClientTest extends DuplexTest { receiveChallengeSendResponse(d); } if(!plugin.supportsInvitations()) { - System.out.println("Skipping invitation tests"); + System.out.println("Skipping invitation test"); return; } - // Try to send an invitation - System.out.println("Sending invitation"); - d = plugin.sendInvitation(getPseudoRandom(123), CONNECTION_TIMEOUT); - if(d == null) { - System.out.println("Connection failed"); - return; - } else { - System.out.println("Connection created"); - receiveChallengeSendResponse(d); - } - // Try to accept an invitation - System.out.println("Accepting invitation"); - d = plugin.acceptInvitation(getPseudoRandom(456), - CONNECTION_TIMEOUT); + // Try to create an invitation connection + System.out.println("Creating invitation connection"); + PseudoRandom r = getPseudoRandom(123); + d = plugin.createInvitationConnection(r, CONNECTION_TIMEOUT); if(d == null) { System.out.println("Connection failed"); return; diff --git a/briar-tests/src/net/sf/briar/plugins/DuplexServerTest.java b/briar-tests/src/net/sf/briar/plugins/DuplexServerTest.java index f6bfc4b19c..5a3d0b583f 100644 --- a/briar-tests/src/net/sf/briar/plugins/DuplexServerTest.java +++ b/briar-tests/src/net/sf/briar/plugins/DuplexServerTest.java @@ -33,23 +33,13 @@ public abstract class DuplexServerTest extends DuplexTest { return; } if(!plugin.supportsInvitations()) { - System.out.println("Skipping invitation tests"); + System.out.println("Skipping invitation test"); return; } - // Try to accept an invitation - System.out.println("Accepting invitation"); - DuplexTransportConnection d = plugin.acceptInvitation( + // Try to create an invitation connection + System.out.println("Creating invitation connection"); + DuplexTransportConnection d = plugin.createInvitationConnection( getPseudoRandom(123), CONNECTION_TIMEOUT); - if(d == null) { - System.out.println("Connection failed"); - return; - } else { - System.out.println("Connection created"); - sendChallengeReceiveResponse(d); - } - // Try to send an invitation - System.out.println("Sending invitation"); - d = plugin.sendInvitation(getPseudoRandom(456), CONNECTION_TIMEOUT); if(d == null) { System.out.println("Connection failed"); return; -- GitLab