mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 20:59:54 +01:00
Don't close the connection until both peers have finished. Bug #78.
This commit is contained in:
@@ -120,10 +120,12 @@ class AliceConnector extends Connector {
|
|||||||
if(remoteMatched) group.remoteConfirmationSucceeded();
|
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||||
else group.remoteConfirmationFailed();
|
else group.remoteConfirmationFailed();
|
||||||
if(!(localMatched && remoteMatched)) {
|
if(!(localMatched && remoteMatched)) {
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info(pluginName + " confirmation failed");
|
||||||
tryToClose(conn, false);
|
tryToClose(conn, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The timestamp is taken after exhanging confirmation results
|
// The timestamp is taken after exchanging confirmation results
|
||||||
long localTimestamp = clock.currentTimeMillis();
|
long localTimestamp = clock.currentTimeMillis();
|
||||||
// Confirmation succeeded - upgrade to a secure connection
|
// Confirmation succeeded - upgrade to a secure connection
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
@@ -145,13 +147,19 @@ class AliceConnector extends Connector {
|
|||||||
Author remoteAuthor;
|
Author remoteAuthor;
|
||||||
long remoteTimestamp;
|
long remoteTimestamp;
|
||||||
Map<TransportId, TransportProperties> remoteProps;
|
Map<TransportId, TransportProperties> remoteProps;
|
||||||
|
boolean remoteReuseConnection;
|
||||||
try {
|
try {
|
||||||
sendPseudonym(w, aliceNonce);
|
sendPseudonym(w, aliceNonce);
|
||||||
sendTimestamp(w, localTimestamp);
|
sendTimestamp(w, localTimestamp);
|
||||||
sendTransportProperties(w);
|
sendTransportProperties(w);
|
||||||
|
sendConfirmation(w, reuseConnection);
|
||||||
remoteAuthor = receivePseudonym(r, bobNonce);
|
remoteAuthor = receivePseudonym(r, bobNonce);
|
||||||
remoteTimestamp = receiveTimestamp(r);
|
remoteTimestamp = receiveTimestamp(r);
|
||||||
remoteProps = receiveTransportProperties(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) {
|
} catch(GeneralSecurityException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
@@ -174,12 +182,12 @@ class AliceConnector extends Connector {
|
|||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Reuse the connection as a transport connection if both peers agree
|
||||||
|
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||||
|
else tryToClose(conn, false);
|
||||||
// Pseudonym exchange succeeded
|
// Pseudonym exchange succeeded
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info(pluginName + " pseudonym exchange succeeded");
|
LOG.info(pluginName + " pseudonym exchange succeeded");
|
||||||
group.pseudonymExchangeSucceeded(remoteAuthor);
|
group.pseudonymExchangeSucceeded(remoteAuthor);
|
||||||
// Reuse the connection as an outgoing transport connection
|
|
||||||
if(reuseConnection) reuseConnection(conn, true);
|
|
||||||
else tryToClose(conn, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,10 +120,12 @@ class BobConnector extends Connector {
|
|||||||
if(remoteMatched) group.remoteConfirmationSucceeded();
|
if(remoteMatched) group.remoteConfirmationSucceeded();
|
||||||
else group.remoteConfirmationFailed();
|
else group.remoteConfirmationFailed();
|
||||||
if(!(localMatched && remoteMatched)) {
|
if(!(localMatched && remoteMatched)) {
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info(pluginName + " confirmation failed");
|
||||||
tryToClose(conn, false);
|
tryToClose(conn, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The timestamp is taken after exhanging confirmation results
|
// The timestamp is taken after exchanging confirmation results
|
||||||
long localTimestamp = clock.currentTimeMillis();
|
long localTimestamp = clock.currentTimeMillis();
|
||||||
// Confirmation succeeded - upgrade to a secure connection
|
// Confirmation succeeded - upgrade to a secure connection
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
@@ -145,13 +147,19 @@ class BobConnector extends Connector {
|
|||||||
Author remoteAuthor;
|
Author remoteAuthor;
|
||||||
long remoteTimestamp;
|
long remoteTimestamp;
|
||||||
Map<TransportId, TransportProperties> remoteProps;
|
Map<TransportId, TransportProperties> remoteProps;
|
||||||
|
boolean remoteReuseConnection;
|
||||||
try {
|
try {
|
||||||
remoteAuthor = receivePseudonym(r, aliceNonce);
|
remoteAuthor = receivePseudonym(r, aliceNonce);
|
||||||
remoteTimestamp = receiveTimestamp(r);
|
remoteTimestamp = receiveTimestamp(r);
|
||||||
remoteProps = receiveTransportProperties(r);
|
remoteProps = receiveTransportProperties(r);
|
||||||
|
remoteReuseConnection = receiveConfirmation(r);
|
||||||
sendPseudonym(w, bobNonce);
|
sendPseudonym(w, bobNonce);
|
||||||
sendTimestamp(w, localTimestamp);
|
sendTimestamp(w, localTimestamp);
|
||||||
sendTransportProperties(w);
|
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) {
|
} catch(GeneralSecurityException e) {
|
||||||
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
@@ -174,12 +182,12 @@ class BobConnector extends Connector {
|
|||||||
group.pseudonymExchangeFailed();
|
group.pseudonymExchangeFailed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Reuse the connection as a transport connection if both peers agree
|
||||||
|
if(reuseConnection && remoteReuseConnection) reuseConnection(conn);
|
||||||
|
else tryToClose(conn, false);
|
||||||
// Pseudonym exchange succeeded
|
// Pseudonym exchange succeeded
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info(pluginName + " pseudonym exchange succeeded");
|
LOG.info(pluginName + " pseudonym exchange succeeded");
|
||||||
group.pseudonymExchangeSucceeded(remoteAuthor);
|
group.pseudonymExchangeSucceeded(remoteAuthor);
|
||||||
// Reuse the connection as an incoming transport connection
|
|
||||||
if(reuseConnection) reuseConnection(conn, false);
|
|
||||||
else tryToClose(conn, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.briarproject.api.FormatException;
|
|||||||
import org.briarproject.api.LocalAuthor;
|
import org.briarproject.api.LocalAuthor;
|
||||||
import org.briarproject.api.TransportId;
|
import org.briarproject.api.TransportId;
|
||||||
import org.briarproject.api.TransportProperties;
|
import org.briarproject.api.TransportProperties;
|
||||||
import org.briarproject.api.UniqueId;
|
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
import org.briarproject.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.api.crypto.KeyManager;
|
import org.briarproject.api.crypto.KeyManager;
|
||||||
import org.briarproject.api.crypto.KeyPair;
|
import org.briarproject.api.crypto.KeyPair;
|
||||||
@@ -131,8 +130,9 @@ abstract class Connector extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] receivePublicKeyHash(Reader r) throws IOException {
|
protected byte[] receivePublicKeyHash(Reader r) throws IOException {
|
||||||
byte[] b = r.readBytes(UniqueId.LENGTH);
|
int hashLength = messageDigest.getDigestLength();
|
||||||
if(b.length < UniqueId.LENGTH) throw new FormatException();
|
byte[] b = r.readBytes(hashLength);
|
||||||
|
if(b.length < hashLength) throw new FormatException();
|
||||||
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash");
|
if(LOG.isLoggable(INFO)) LOG.info(pluginName + " received hash");
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -166,19 +166,19 @@ abstract class Connector extends Thread {
|
|||||||
return crypto.deriveMasterSecret(key, keyPair, alice);
|
return crypto.deriveMasterSecret(key, keyPair, alice);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendConfirmation(Writer w, boolean matched)
|
protected void sendConfirmation(Writer w, boolean confirmed)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
w.writeBoolean(matched);
|
w.writeBoolean(confirmed);
|
||||||
w.flush();
|
w.flush();
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info(pluginName + " sent confirmation: " + matched);
|
LOG.info(pluginName + " sent confirmation: " + confirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean receiveConfirmation(Reader r) throws IOException {
|
protected boolean receiveConfirmation(Reader r) throws IOException {
|
||||||
boolean matched = r.readBoolean();
|
boolean confirmed = r.readBoolean();
|
||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info(pluginName + " received confirmation: " + matched);
|
LOG.info(pluginName + " received confirmation: " + confirmed);
|
||||||
return matched;
|
return confirmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendPseudonym(Writer w, byte[] nonce)
|
protected void sendPseudonym(Writer w, byte[] nonce)
|
||||||
@@ -317,13 +317,10 @@ abstract class Connector extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reuseConnection(DuplexTransportConnection conn,
|
protected void reuseConnection(DuplexTransportConnection conn) {
|
||||||
boolean alice) {
|
|
||||||
if(contactId == null) throw new IllegalStateException();
|
if(contactId == null) throw new IllegalStateException();
|
||||||
TransportId t = plugin.getId();
|
TransportId t = plugin.getId();
|
||||||
if(alice)
|
connectionManager.manageOutgoingConnection(contactId, t, conn);
|
||||||
connectionManager.manageOutgoingConnection(contactId, t, conn);
|
|
||||||
else connectionManager.manageIncomingConnection(t, conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TransportIdComparator
|
private static class TransportIdComparator
|
||||||
|
|||||||
Reference in New Issue
Block a user