Try all transports in order of preference.

This commit is contained in:
akwizgran
2020-10-29 11:48:10 +00:00
parent 0caa522f07
commit e0f381a973
8 changed files with 37 additions and 40 deletions

View File

@@ -41,12 +41,10 @@ public interface DuplexPlugin extends Plugin {
/** /**
* Attempts to connect to the remote peer specified in the given descriptor. * Attempts to connect to the remote peer specified in the given descriptor.
* Returns null if no connection can be established. * Returns null if no connection can be established.
*
* @param alice True if the local party is Alice
*/ */
@Nullable @Nullable
DuplexTransportConnection createKeyAgreementConnection( DuplexTransportConnection createKeyAgreementConnection(
byte[] remoteCommitment, BdfList descriptor, boolean alice); byte[] remoteCommitment, BdfList descriptor);
/** /**
* Returns true if the plugin supports rendezvous connections. * Returns true if the plugin supports rendezvous connections.

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.keyagreement; package org.briarproject.bramble.keyagreement;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.crypto.KeyAgreementCrypto; import org.briarproject.bramble.api.crypto.KeyAgreementCrypto;
import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
@@ -114,7 +115,7 @@ class KeyAgreementConnector {
this.alice = alice; this.alice = alice;
aliceLatch.countDown(); aliceLatch.countDown();
// Start connecting over best available transport // Start connecting over supported transports in order of preference
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Starting outgoing BQP connections as " LOG.info("Starting outgoing BQP connections as "
+ (alice ? "Alice" : "Bob")); + (alice ? "Alice" : "Bob"));
@@ -123,24 +124,26 @@ class KeyAgreementConnector {
for (TransportDescriptor d : remotePayload.getTransportDescriptors()) { for (TransportDescriptor d : remotePayload.getTransportDescriptors()) {
descriptors.put(d.getId(), d); descriptors.put(d.getId(), d);
} }
List<Pair<DuplexPlugin, BdfList>> transports = new ArrayList<>();
for (TransportId id : PREFERRED_TRANSPORTS) { for (TransportId id : PREFERRED_TRANSPORTS) {
TransportDescriptor d = descriptors.get(id); TransportDescriptor d = descriptors.get(id);
Plugin p = pluginManager.getPlugin(id); Plugin p = pluginManager.getPlugin(id);
if (d != null && p instanceof DuplexPlugin) { if (d != null && p instanceof DuplexPlugin) {
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Connecting via " + id); LOG.info("Connecting via " + id);
DuplexPlugin plugin = (DuplexPlugin) p; transports.add(new Pair<>((DuplexPlugin) p, d.getDescriptor()));
byte[] commitment = remotePayload.getCommitment();
BdfList descriptor = d.getDescriptor();
connectionChooser.submit(new ReadableTask(new ConnectorTask(
plugin, commitment, descriptor, alice)));
break;
} }
} }
// TODO: If we don't have any transports in common with the peer, // TODO: If we don't have any transports in common with the peer,
// warn the user and give up (#1224) // 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 // Get chosen connection
try { try {
KeyAgreementConnection chosen = KeyAgreementConnection chosen =
@@ -166,17 +169,13 @@ class KeyAgreementConnector {
private class ConnectorTask implements Callable<KeyAgreementConnection> { private class ConnectorTask implements Callable<KeyAgreementConnection> {
private final DuplexPlugin plugin; private final List<Pair<DuplexPlugin, BdfList>> transports;
private final byte[] commitment; private final byte[] commitment;
private final BdfList descriptor;
private final boolean alice;
private ConnectorTask(DuplexPlugin plugin, byte[] commitment, private ConnectorTask(List<Pair<DuplexPlugin, BdfList>> transports,
BdfList descriptor, boolean alice) { byte[] commitment) {
this.plugin = plugin; this.transports = transports;
this.commitment = commitment; this.commitment = commitment;
this.descriptor = descriptor;
this.alice = alice;
} }
@Nullable @Nullable
@@ -184,13 +183,18 @@ class KeyAgreementConnector {
public KeyAgreementConnection call() throws Exception { public KeyAgreementConnection call() throws Exception {
// Repeat attempts until we connect, get stopped, or get interrupted // Repeat attempts until we connect, get stopped, or get interrupted
while (!stopped) { while (!stopped) {
DuplexTransportConnection conn = for (Pair<DuplexPlugin, BdfList> pair : transports) {
plugin.createKeyAgreementConnection(commitment, if (stopped) return null;
descriptor, alice); DuplexPlugin plugin = pair.getFirst();
if (conn != null) { BdfList descriptor = pair.getSecond();
if (LOG.isLoggable(INFO)) DuplexTransportConnection conn =
LOG.info(plugin.getId() + ": Outgoing connection"); plugin.createKeyAgreementConnection(commitment,
return new KeyAgreementConnection(conn, plugin.getId()); 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) // Wait 2s before retry (to circumvent transient failures)
Thread.sleep(2000); Thread.sleep(2000);

View File

@@ -430,22 +430,17 @@ abstract class BluetoothPlugin<S, SS> implements DuplexPlugin, EventListener {
@Override @Override
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, boolean alice) { byte[] commitment, BdfList descriptor) {
if (getState() != ACTIVE) return null; if (getState() != ACTIVE) return null;
// No truncation necessary because COMMIT_LENGTH = 16 // No truncation necessary because COMMIT_LENGTH = 16
String uuid = UUID.nameUUIDFromBytes(commitment).toString(); String uuid = UUID.nameUUIDFromBytes(commitment).toString();
DuplexTransportConnection conn; DuplexTransportConnection conn;
if (descriptor.size() == 1) { if (descriptor.size() == 1) {
if (alice) { if (LOG.isLoggable(INFO)) {
if (LOG.isLoggable(INFO)) { LOG.info("Discovering address for key agreement UUID " +
LOG.info("Discovering address for key agreement UUID " + uuid);
uuid);
}
conn = discoverAndConnect(uuid);
} else {
LOG.info("No address in key agreement descriptor");
return null;
} }
conn = discoverAndConnect(uuid);
} else { } else {
String address; String address;
try { try {

View File

@@ -376,7 +376,7 @@ class LanTcpPlugin extends TcpPlugin {
@Override @Override
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, boolean alice) { byte[] commitment, BdfList descriptor) {
ServerSocket ss = state.getServerSocket(true); ServerSocket ss = state.getServerSocket(true);
if (ss == null) return null; if (ss == null) return null;
InterfaceAddress local = getLocalInterfaceAddress(ss.getInetAddress()); InterfaceAddress local = getLocalInterfaceAddress(ss.getInetAddress());

View File

@@ -367,7 +367,7 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
@Override @Override
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, boolean alice) { byte[] commitment, BdfList descriptor) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@@ -708,7 +708,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override @Override
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, boolean alice) { byte[] commitment, BdfList descriptor) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@@ -276,7 +276,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
descriptor.add(local.getPort()); descriptor.add(local.getPort());
// Connect to the port // Connect to the port
DuplexTransportConnection d = plugin.createKeyAgreementConnection( DuplexTransportConnection d = plugin.createKeyAgreementConnection(
new byte[COMMIT_LENGTH], descriptor, true); new byte[COMMIT_LENGTH], descriptor);
assertNotNull(d); assertNotNull(d);
// Check that the connection was accepted // Check that the connection was accepted
assertTrue(latch.await(5, SECONDS)); assertTrue(latch.await(5, SECONDS));

View File

@@ -198,7 +198,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
@Override @Override
public DuplexTransportConnection createKeyAgreementConnection( public DuplexTransportConnection createKeyAgreementConnection(
byte[] commitment, BdfList descriptor, boolean alice) { byte[] commitment, BdfList descriptor) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }