mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Ensure responses shown after requests, clarify wording, reuse transactions
When devices' clocks are out of sync, it is possible that a response is shown before the request. This commit makes sure that the timestamp of responses is always later than the last message in the conversation. Some wording could be misunderstood to thing introductions were successful even though they were not. That has been clarified. A new database transaction was created when getting contacts and local transport properties. This has been changed to re-use the existing transaction. Also addresses minor issues found in review.
This commit is contained in:
@@ -109,6 +109,7 @@ public class IntroduceeEngine
|
||||
msg.put(E_PUBLIC_KEY, localState.getRaw(OUR_PUBLIC_KEY));
|
||||
msg.put(TRANSPORT, localAction.getDictionary(TRANSPORT));
|
||||
}
|
||||
msg.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME));
|
||||
messages.add(msg);
|
||||
logAction(currentState, localState, msg);
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_K
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.INTRODUCER;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.OUR_PRIVATE_KEY;
|
||||
@@ -159,9 +160,10 @@ class IntroduceeManager {
|
||||
}
|
||||
|
||||
public void acceptIntroduction(Transaction txn, final ContactId contactId,
|
||||
final SessionId sessionId) throws DbException, FormatException {
|
||||
final SessionId sessionId, final long timestamp)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Contact c = contactManager.getContact(contactId);
|
||||
Contact c = db.getContact(txn, contactId);
|
||||
Group g = introductionManager.getIntroductionGroup(c);
|
||||
|
||||
BdfDictionary state = introductionManager
|
||||
@@ -173,7 +175,7 @@ class IntroduceeManager {
|
||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
||||
byte[] privateKey = keyPair.getPrivate().getEncoded();
|
||||
Map<TransportId, TransportProperties> transportProperties =
|
||||
transportPropertyManager.getLocalProperties();
|
||||
transportPropertyManager.getLocalProperties(txn);
|
||||
|
||||
// update session state for later
|
||||
state.put(ACCEPT, true);
|
||||
@@ -186,6 +188,7 @@ class IntroduceeManager {
|
||||
localAction.put(TYPE, TYPE_RESPONSE);
|
||||
localAction.put(TRANSPORT,
|
||||
encodeTransportProperties(transportProperties));
|
||||
localAction.put(MESSAGE_TIME, timestamp);
|
||||
|
||||
// start engine and process its state update
|
||||
IntroduceeEngine engine = new IntroduceeEngine();
|
||||
@@ -193,9 +196,10 @@ class IntroduceeManager {
|
||||
}
|
||||
|
||||
public void declineIntroduction(Transaction txn, final ContactId contactId,
|
||||
final SessionId sessionId) throws DbException, FormatException {
|
||||
final SessionId sessionId, final long timestamp)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Contact c = contactManager.getContact(contactId);
|
||||
Contact c = db.getContact(txn, contactId);
|
||||
Group g = introductionManager.getIntroductionGroup(c);
|
||||
|
||||
BdfDictionary state = introductionManager
|
||||
@@ -207,6 +211,7 @@ class IntroduceeManager {
|
||||
// define action
|
||||
BdfDictionary localAction = new BdfDictionary();
|
||||
localAction.put(TYPE, TYPE_RESPONSE);
|
||||
localAction.put(MESSAGE_TIME, timestamp);
|
||||
|
||||
// start engine and process its state update
|
||||
IntroduceeEngine engine = new IntroduceeEngine();
|
||||
|
||||
@@ -56,6 +56,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_1
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
|
||||
@@ -104,6 +105,7 @@ public class IntroducerEngine
|
||||
if (localAction.containsKey(MSG)) {
|
||||
msg1.put(MSG, localAction.getString(MSG));
|
||||
}
|
||||
msg1.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME));
|
||||
messages.add(msg1);
|
||||
logLocalAction(currentState, localState, msg1);
|
||||
BdfDictionary msg2 = new BdfDictionary();
|
||||
@@ -115,6 +117,7 @@ public class IntroducerEngine
|
||||
if (localAction.containsKey(MSG)) {
|
||||
msg2.put(MSG, localAction.getString(MSG));
|
||||
}
|
||||
msg2.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME));
|
||||
messages.add(msg2);
|
||||
logLocalAction(currentState, localState, msg2);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.MSG;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY1;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY2;
|
||||
@@ -38,6 +39,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRO
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STORAGE_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TIME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
@@ -99,7 +101,7 @@ class IntroducerManager {
|
||||
}
|
||||
|
||||
public void makeIntroduction(Transaction txn, Contact c1, Contact c2,
|
||||
String msg) throws DbException, FormatException {
|
||||
String msg, long timestamp) throws DbException, FormatException {
|
||||
|
||||
// TODO check for existing session with those contacts?
|
||||
// deny new introduction under which conditions?
|
||||
@@ -115,6 +117,7 @@ class IntroducerManager {
|
||||
}
|
||||
localAction.put(PUBLIC_KEY1, c1.getAuthor().getPublicKey());
|
||||
localAction.put(PUBLIC_KEY2, c2.getAuthor().getPublicKey());
|
||||
localAction.put(MESSAGE_TIME, timestamp);
|
||||
|
||||
// start engine and process its state update
|
||||
IntroducerEngine engine = new IntroducerEngine();
|
||||
|
||||
@@ -44,7 +44,6 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -268,12 +267,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
|
||||
@Override
|
||||
public void makeIntroduction(Contact c1, Contact c2, String msg)
|
||||
public void makeIntroduction(Contact c1, Contact c2, String msg,
|
||||
final long timestamp)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
introducerManager.makeIntroduction(txn, c1, c2, msg);
|
||||
introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -282,11 +282,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
|
||||
@Override
|
||||
public void acceptIntroduction(final ContactId contactId,
|
||||
final SessionId sessionId) throws DbException, FormatException {
|
||||
final SessionId sessionId, final long timestamp)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
introduceeManager.acceptIntroduction(txn, contactId, sessionId);
|
||||
introduceeManager
|
||||
.acceptIntroduction(txn, contactId, sessionId, timestamp);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -295,11 +297,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
|
||||
@Override
|
||||
public void declineIntroduction(final ContactId contactId,
|
||||
final SessionId sessionId) throws DbException, FormatException {
|
||||
final SessionId sessionId, final long timestamp)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
introduceeManager.declineIntroduction(txn, contactId, sessionId);
|
||||
introduceeManager
|
||||
.declineIntroduction(txn, contactId, sessionId, timestamp);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
@@ -501,9 +505,10 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
byte[] body = clientHelper.toByteArray(bdfList);
|
||||
GroupId groupId = new GroupId(message.getRaw(GROUP_ID));
|
||||
Group group = db.getGroup(txn, groupId);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
long timestamp =
|
||||
message.getLong(MESSAGE_TIME, System.currentTimeMillis());
|
||||
message.put(MESSAGE_TIME, timestamp);
|
||||
|
||||
Metadata metadata = metadataEncoder.encode(message);
|
||||
|
||||
messageQueueManager
|
||||
|
||||
@@ -108,6 +108,27 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
return Collections.unmodifiableMap(local);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<TransportId, TransportProperties> getLocalProperties(
|
||||
Transaction txn) throws DbException {
|
||||
try {
|
||||
Map<TransportId, TransportProperties> local =
|
||||
new HashMap<TransportId, TransportProperties>();
|
||||
// Find the latest local update for each transport
|
||||
Map<TransportId, LatestUpdate> latest = findLatest(txn,
|
||||
localGroup.getId(), true);
|
||||
// Retrieve and parse the latest local properties
|
||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||
BdfList message = clientHelper.getMessageAsList(txn,
|
||||
e.getValue().messageId);
|
||||
local.put(e.getKey(), parseProperties(message));
|
||||
}
|
||||
return local;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportProperties getLocalProperties(TransportId t)
|
||||
throws DbException {
|
||||
@@ -212,26 +233,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
return privateGroupFactory.createPrivateGroup(CLIENT_ID, c);
|
||||
}
|
||||
|
||||
private Map<TransportId, TransportProperties> getLocalProperties(
|
||||
Transaction txn) throws DbException {
|
||||
try {
|
||||
Map<TransportId, TransportProperties> local =
|
||||
new HashMap<TransportId, TransportProperties>();
|
||||
// Find the latest local update for each transport
|
||||
Map<TransportId, LatestUpdate> latest = findLatest(txn,
|
||||
localGroup.getId(), true);
|
||||
// Retrieve and parse the latest local properties
|
||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||
BdfList message = clientHelper.getMessageAsList(txn,
|
||||
e.getValue().messageId);
|
||||
local.put(e.getKey(), parseProperties(message));
|
||||
}
|
||||
return local;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeMessage(Transaction txn, GroupId g, TransportId t,
|
||||
TransportProperties p, long version, boolean local, boolean shared)
|
||||
throws DbException {
|
||||
|
||||
Reference in New Issue
Block a user