Fixed race condition when closing redundant sockets.

When more than one invitation socket is opened, Alice should pick which one to use and Bob should use whichever one Alice picks. This fixes a race condition where each party picked a different socket and closed the other.
This commit is contained in:
akwizgran
2016-02-25 13:59:43 +00:00
parent 5b47d6d3ff
commit 0ac67239e3
15 changed files with 228 additions and 532 deletions
@@ -51,7 +51,7 @@ class AliceConnector extends Connector {
@Override
public void run() {
// Create an incoming or outgoing connection
DuplexTransportConnection conn = createInvitationConnection();
DuplexTransportConnection conn = createInvitationConnection(true);
if (conn == null) return;
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
// Don't proceed with more than one connection
@@ -51,7 +51,7 @@ class BobConnector extends Connector {
@Override
public void run() {
// Create an incoming or outgoing connection
DuplexTransportConnection conn = createInvitationConnection();
DuplexTransportConnection conn = createInvitationConnection(false);
if (conn == null) return;
if (LOG.isLoggable(INFO)) LOG.info(pluginName + " connected");
// Carry out the key agreement protocol
@@ -93,10 +93,12 @@ abstract class Connector extends Thread {
messageDigest = crypto.getMessageDigest();
}
protected DuplexTransportConnection createInvitationConnection() {
protected DuplexTransportConnection createInvitationConnection(
boolean alice) {
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " creating invitation connection");
return plugin.createInvitationConnection(random, CONNECTION_TIMEOUT);
return plugin.createInvitationConnection(random, CONNECTION_TIMEOUT,
alice);
}
protected void sendPublicKeyHash(BdfWriter w) throws IOException {
@@ -246,7 +246,7 @@ abstract class TcpPlugin implements DuplexPlugin {
}
public DuplexTransportConnection createInvitationConnection(PseudoRandom r,
long timeout) {
long timeout, boolean alice) {
throw new UnsupportedOperationException();
}
@@ -1,30 +0,0 @@
package org.briarproject.util;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class LatchedReference<T> {
private final CountDownLatch latch = new CountDownLatch(1);
private final AtomicReference<T> reference = new AtomicReference<T>();
public boolean isSet() {
return reference.get() != null;
}
public boolean set(T t) {
if (t == null) throw new IllegalArgumentException();
if (reference.compareAndSet(null, t)) {
latch.countDown();
return true;
}
return false;
}
public T waitForReference(long timeout) throws InterruptedException {
latch.await(timeout, MILLISECONDS);
return reference.get();
}
}