diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java index f37a8b5fe..9e14e7ab5 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPlugin.java @@ -41,12 +41,10 @@ public interface DuplexPlugin extends Plugin { /** * Attempts to connect to the remote peer specified in the given descriptor. * Returns null if no connection can be established. - * - * @param alice True if the local party is Alice */ @Nullable DuplexTransportConnection createKeyAgreementConnection( - byte[] remoteCommitment, BdfList descriptor, boolean alice); + byte[] remoteCommitment, BdfList descriptor); /** * Returns true if the plugin supports rendezvous connections. diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java index 444b667fd..23af3589e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/KeyAgreementConnector.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.keyagreement; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.crypto.KeyAgreementCrypto; import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.data.BdfList; @@ -114,7 +115,7 @@ class KeyAgreementConnector { this.alice = alice; aliceLatch.countDown(); - // Start connecting over best available transport + // Start connecting over supported transports in order of preference if (LOG.isLoggable(INFO)) { LOG.info("Starting outgoing BQP connections as " + (alice ? "Alice" : "Bob")); @@ -123,24 +124,26 @@ class KeyAgreementConnector { for (TransportDescriptor d : remotePayload.getTransportDescriptors()) { descriptors.put(d.getId(), d); } + List> transports = new ArrayList<>(); for (TransportId id : PREFERRED_TRANSPORTS) { TransportDescriptor d = descriptors.get(id); Plugin p = pluginManager.getPlugin(id); if (d != null && p instanceof DuplexPlugin) { if (LOG.isLoggable(INFO)) LOG.info("Connecting via " + id); - DuplexPlugin plugin = (DuplexPlugin) p; - byte[] commitment = remotePayload.getCommitment(); - BdfList descriptor = d.getDescriptor(); - connectionChooser.submit(new ReadableTask(new ConnectorTask( - plugin, commitment, descriptor, alice))); - break; + transports.add(new Pair<>((DuplexPlugin) p, d.getDescriptor())); } } // TODO: If we don't have any transports in common with the peer, // warn the user and give up (#1224) + if (!transports.isEmpty()) { + byte[] commitment = remotePayload.getCommitment(); + connectionChooser.submit(new ReadableTask(new ConnectorTask( + transports, commitment))); + } + // Get chosen connection try { KeyAgreementConnection chosen = @@ -166,17 +169,13 @@ class KeyAgreementConnector { private class ConnectorTask implements Callable { - private final DuplexPlugin plugin; + private final List> transports; private final byte[] commitment; - private final BdfList descriptor; - private final boolean alice; - private ConnectorTask(DuplexPlugin plugin, byte[] commitment, - BdfList descriptor, boolean alice) { - this.plugin = plugin; + private ConnectorTask(List> transports, + byte[] commitment) { + this.transports = transports; this.commitment = commitment; - this.descriptor = descriptor; - this.alice = alice; } @Nullable @@ -184,13 +183,18 @@ class KeyAgreementConnector { public KeyAgreementConnection call() throws Exception { // Repeat attempts until we connect, get stopped, or get interrupted while (!stopped) { - DuplexTransportConnection conn = - plugin.createKeyAgreementConnection(commitment, - descriptor, alice); - if (conn != null) { - if (LOG.isLoggable(INFO)) - LOG.info(plugin.getId() + ": Outgoing connection"); - return new KeyAgreementConnection(conn, plugin.getId()); + for (Pair pair : transports) { + if (stopped) return null; + DuplexPlugin plugin = pair.getFirst(); + BdfList descriptor = pair.getSecond(); + DuplexTransportConnection conn = + plugin.createKeyAgreementConnection(commitment, + descriptor); + if (conn != null) { + if (LOG.isLoggable(INFO)) + LOG.info(plugin.getId() + ": Outgoing connection"); + return new KeyAgreementConnection(conn, plugin.getId()); + } } // Wait 2s before retry (to circumvent transient failures) Thread.sleep(2000); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index 7c1ee4b59..f90469d56 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -430,22 +430,17 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { @Override public DuplexTransportConnection createKeyAgreementConnection( - byte[] commitment, BdfList descriptor, boolean alice) { + byte[] commitment, BdfList descriptor) { if (getState() != ACTIVE) return null; // No truncation necessary because COMMIT_LENGTH = 16 String uuid = UUID.nameUUIDFromBytes(commitment).toString(); DuplexTransportConnection conn; if (descriptor.size() == 1) { - if (alice) { - if (LOG.isLoggable(INFO)) { - LOG.info("Discovering address for key agreement UUID " + - uuid); - } - conn = discoverAndConnect(uuid); - } else { - LOG.info("No address in key agreement descriptor"); - return null; + if (LOG.isLoggable(INFO)) { + LOG.info("Discovering address for key agreement UUID " + + uuid); } + conn = discoverAndConnect(uuid); } else { String address; try { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java index 235ac5cb9..87706b7e5 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java @@ -376,7 +376,7 @@ class LanTcpPlugin extends TcpPlugin { @Override public DuplexTransportConnection createKeyAgreementConnection( - byte[] commitment, BdfList descriptor, boolean alice) { + byte[] commitment, BdfList descriptor) { ServerSocket ss = state.getServerSocket(true); if (ss == null) return null; InterfaceAddress local = getLocalInterfaceAddress(ss.getInetAddress()); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index 53ada12c1..f67121685 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -367,7 +367,7 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener { @Override public DuplexTransportConnection createKeyAgreementConnection( - byte[] commitment, BdfList descriptor, boolean alice) { + byte[] commitment, BdfList descriptor) { throw new UnsupportedOperationException(); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index a2ba04ed2..5fc93f885 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -708,7 +708,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { @Override public DuplexTransportConnection createKeyAgreementConnection( - byte[] commitment, BdfList descriptor, boolean alice) { + byte[] commitment, BdfList descriptor) { throw new UnsupportedOperationException(); } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java index 59f3b1923..cd560e3a6 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java @@ -276,7 +276,7 @@ public class LanTcpPluginTest extends BrambleTestCase { descriptor.add(local.getPort()); // Connect to the port DuplexTransportConnection d = plugin.createKeyAgreementConnection( - new byte[COMMIT_LENGTH], descriptor, true); + new byte[COMMIT_LENGTH], descriptor); assertNotNull(d); // Check that the connection was accepted assertTrue(latch.await(5, SECONDS)); diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java index 4d2ee0e1e..53a668f20 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java @@ -198,7 +198,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { @Override public DuplexTransportConnection createKeyAgreementConnection( - byte[] commitment, BdfList descriptor, boolean alice) { + byte[] commitment, BdfList descriptor) { throw new UnsupportedOperationException(); }