Don't close the connection until both peers have finished. Bug #78.

This commit is contained in:
akwizgran
2015-01-14 19:58:54 +00:00
parent 03247aedd6
commit 6ff8f5ce69
3 changed files with 35 additions and 22 deletions

View File

@@ -120,10 +120,12 @@ class AliceConnector extends Connector {
if(remoteMatched) group.remoteConfirmationSucceeded();
else group.remoteConfirmationFailed();
if(!(localMatched && remoteMatched)) {
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " confirmation failed");
tryToClose(conn, false);
return;
}
// The timestamp is taken after exhanging confirmation results
// The timestamp is taken after exchanging confirmation results
long localTimestamp = clock.currentTimeMillis();
// Confirmation succeeded - upgrade to a secure connection
if(LOG.isLoggable(INFO))
@@ -145,13 +147,19 @@ class AliceConnector extends Connector {
Author remoteAuthor;
long remoteTimestamp;
Map<TransportId, TransportProperties> remoteProps;
boolean remoteReuseConnection;
try {
sendPseudonym(w, aliceNonce);
sendTimestamp(w, localTimestamp);
sendTransportProperties(w);
sendConfirmation(w, reuseConnection);
remoteAuthor = receivePseudonym(r, bobNonce);
remoteTimestamp = receiveTimestamp(r);
remoteProps = receiveTransportProperties(r);
remoteReuseConnection = receiveConfirmation(r);
// Close the outgoing stream and expect EOF on the incoming stream
w.close();
if(!r.eof()) LOG.warning("Unexpected data at end of connection");
} catch(GeneralSecurityException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
group.pseudonymExchangeFailed();
@@ -174,12 +182,12 @@ class AliceConnector extends Connector {
group.pseudonymExchangeFailed();
return;
}
// Reuse the connection as a transport connection if both peers agree
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
else tryToClose(conn, false);
// Pseudonym exchange succeeded
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded");
group.pseudonymExchangeSucceeded(remoteAuthor);
// Reuse the connection as an outgoing transport connection
if(reuseConnection) reuseConnection(conn, true);
else tryToClose(conn, false);
}
}

View File

@@ -120,10 +120,12 @@ class BobConnector extends Connector {
if(remoteMatched) group.remoteConfirmationSucceeded();
else group.remoteConfirmationFailed();
if(!(localMatched && remoteMatched)) {
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " confirmation failed");
tryToClose(conn, false);
return;
}
// The timestamp is taken after exhanging confirmation results
// The timestamp is taken after exchanging confirmation results
long localTimestamp = clock.currentTimeMillis();
// Confirmation succeeded - upgrade to a secure connection
if(LOG.isLoggable(INFO))
@@ -145,13 +147,19 @@ class BobConnector extends Connector {
Author remoteAuthor;
long remoteTimestamp;
Map<TransportId, TransportProperties> remoteProps;
boolean remoteReuseConnection;
try {
remoteAuthor = receivePseudonym(r, aliceNonce);
remoteTimestamp = receiveTimestamp(r);
remoteProps = receiveTransportProperties(r);
remoteReuseConnection = receiveConfirmation(r);
sendPseudonym(w, bobNonce);
sendTimestamp(w, localTimestamp);
sendTransportProperties(w);
sendConfirmation(w, reuseConnection);
// Close the outgoing stream and expect EOF on the incoming stream
w.close();
if(!r.eof()) LOG.warning("Unexpected data at end of connection");
} catch(GeneralSecurityException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
group.pseudonymExchangeFailed();
@@ -174,12 +182,12 @@ class BobConnector extends Connector {
group.pseudonymExchangeFailed();
return;
}
// Reuse the connection as a transport connection if both peers agree
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
else tryToClose(conn, false);
// Pseudonym exchange succeeded
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded");
group.pseudonymExchangeSucceeded(remoteAuthor);
// Reuse the connection as an incoming transport connection
if(reuseConnection) reuseConnection(conn, false);
else tryToClose(conn, false);
}
}

View File

@@ -29,7 +29,6 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.LocalAuthor;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.UniqueId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyManager;
import org.briarproject.api.crypto.KeyPair;
@@ -131,8 +130,9 @@ abstract class Connector extends Thread {
}
protected byte[] receivePublicKeyHash(Reader r) throws IOException {
byte[] b = r.readBytes(UniqueId.LENGTH);
if(b.length < UniqueId.LENGTH) throw new FormatException();
int hashLength = messageDigest.getDigestLength();
byte[] b = r.readBytes(hashLength);
if(b.length < hashLength) throw new FormatException();
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash");
return b;
}
@@ -166,19 +166,19 @@ abstract class Connector extends Thread {
return crypto.deriveMasterSecret(key, keyPair, alice);
}
protected void sendConfirmation(Writer w, boolean matched)
protected void sendConfirmation(Writer w, boolean confirmed)
throws IOException {
w.writeBoolean(matched);
w.writeBoolean(confirmed);
w.flush();
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " sent confirmation: " + matched);
LOG.info(pluginName + " sent confirmation: " + confirmed);
}
protected boolean receiveConfirmation(Reader r) throws IOException {
boolean matched = r.readBoolean();
boolean confirmed = r.readBoolean();
if(LOG.isLoggable(INFO))
LOG.info(pluginName + " received confirmation: " + matched);
return matched;
LOG.info(pluginName + " received confirmation: " + confirmed);
return confirmed;
}
protected void sendPseudonym(Writer w, byte[] nonce)
@@ -317,13 +317,10 @@ abstract class Connector extends Thread {
}
}
protected void reuseConnection(DuplexTransportConnection conn,
boolean alice) {
protected void reuseConnection(DuplexTransportConnection conn) {
if(contactId == null) throw new IllegalStateException();
TransportId t = plugin.getId();
if(alice)
connectionManager.manageOutgoingConnection(contactId, t, conn);
else connectionManager.manageIncomingConnection(t, conn);
connectionManager.manageOutgoingConnection(contactId, t, conn);
}
private static class TransportIdComparator