diff --git a/briar-android/res/values/roboguice.xml b/briar-android/res/values/roboguice.xml
index fb5c39112..5c62fc7df 100644
--- a/briar-android/res/values/roboguice.xml
+++ b/briar-android/res/values/roboguice.xml
@@ -13,7 +13,7 @@
- org.briarproject.lifecycle.LifecycleModule
- org.briarproject.messaging.MessagingModule
- org.briarproject.plugins.AndroidPluginsModule
- - org.briarproject.property.PropertyModule
+ - org.briarproject.properties.PropertiesModule
- org.briarproject.sync.SyncModule
- org.briarproject.system.AndroidSystemModule
- org.briarproject.transport.TransportModule
diff --git a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
index a355f6b73..fac266a43 100644
--- a/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
+++ b/briar-android/src/org/briarproject/android/AndroidNotificationManagerImpl.java
@@ -11,7 +11,6 @@ import android.support.v4.app.TaskStackBuilder;
import org.briarproject.R;
import org.briarproject.android.contact.ConversationActivity;
import org.briarproject.android.forum.ForumActivity;
-import org.briarproject.api.Settings;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.android.AndroidNotificationManager;
import org.briarproject.api.db.DatabaseComponent;
@@ -24,6 +23,7 @@ import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.messaging.MessagingManager;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
import org.briarproject.util.StringUtils;
diff --git a/briar-android/src/org/briarproject/android/TestingActivity.java b/briar-android/src/org/briarproject/android/TestingActivity.java
index 797188eba..ce770e7d9 100644
--- a/briar-android/src/org/briarproject/android/TestingActivity.java
+++ b/briar-android/src/org/briarproject/android/TestingActivity.java
@@ -29,13 +29,13 @@ import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager;
-import org.briarproject.api.property.TransportPropertyManager;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.util.StringUtils;
import java.io.File;
diff --git a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
index b3c5d946d..71f70d09c 100644
--- a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
+++ b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
@@ -25,12 +25,12 @@ import org.briarproject.android.util.FixedVerticalSpace;
import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar;
-import org.briarproject.api.Settings;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.SettingsUpdatedEvent;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager;
import org.briarproject.util.StringUtils;
diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
index d548b4cfb..3ee032a58 100644
--- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
+++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
@@ -1,15 +1,11 @@
package org.briarproject.android.invitation;
-import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import org.briarproject.R;
import org.briarproject.android.BriarActivity;
-import org.briarproject.android.util.AndroidUtils;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportId;
import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.db.DatabaseComponent;
@@ -60,8 +56,6 @@ implements InvitationListener {
// Fields that are accessed from background threads must be volatile
@Inject private volatile DatabaseComponent db;
@Inject private volatile IdentityManager identityManager;
- private volatile boolean bluetoothWasEnabled = false;
- private volatile boolean leaveBluetoothEnabled = false;
@Override
public void onCreate(Bundle state) {
@@ -69,9 +63,6 @@ implements InvitationListener {
if (state == null) {
// This is a new activity
setView(new ChooseIdentityView(this));
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- if (adapter != null) bluetoothWasEnabled = adapter.isEnabled();
} else {
// Restore the activity's state
byte[] b = state.getByteArray("briar.LOCAL_AUTHOR_ID");
@@ -79,8 +70,6 @@ implements InvitationListener {
taskHandle = state.getLong("briar.TASK_HANDLE", -1);
task = referenceManager.getReference(taskHandle,
InvitationTask.class);
- bluetoothWasEnabled =
- state.getBoolean("briar.BLUETOOTH_WAS_ENABLED");
if (task == null) {
// No background task - we must be in an initial or final state
@@ -162,26 +151,6 @@ implements InvitationListener {
public void onResume() {
super.onResume();
view.populate();
- loadBluetoothSetting();
- }
-
- private void loadBluetoothSetting() {
- runOnDbThread(new Runnable() {
- public void run() {
- try {
- long now = System.currentTimeMillis();
- Settings s = db.getSettings("bt");
- long duration = System.currentTimeMillis() - now;
- if (LOG.isLoggable(INFO))
- LOG.info("Loading setting took " + duration + " ms");
- leaveBluetoothEnabled = bluetoothWasEnabled
- || s.getBoolean("enable", false);
- } catch (DbException e) {
- if (LOG.isLoggable(WARNING))
- LOG.log(WARNING, e.toString(), e);
- }
- }
- });
}
@Override
@@ -196,15 +165,12 @@ implements InvitationListener {
state.putBoolean("briar.FAILED", connectionFailed);
state.putString("briar.CONTACT_NAME", contactName);
if (task != null) state.putLong("briar.TASK_HANDLE", taskHandle);
- state.putBoolean("briar.BLUETOOTH_WAS_ENABLED", bluetoothWasEnabled);
}
@Override
public void onDestroy() {
super.onDestroy();
-
if (task != null) task.removeListener(this);
- if (isFinishing()) disableBluetooth();
}
@Override
@@ -295,7 +261,7 @@ implements InvitationListener {
setView(new InvitationCodeView(this, true));
task = invitationTaskFactory.createTask(localAuthorId,
- localInvitationCode, code, leaveBluetoothEnabled);
+ localInvitationCode, code);
taskHandle = referenceManager.putReference(task, InvitationTask.class);
task.addListener(AddContactActivity.this);
// Add a second listener so we can remove the first in onDestroy(),
@@ -329,15 +295,6 @@ implements InvitationListener {
}
}
- public void disableBluetooth() {
- if (!leaveBluetoothEnabled) {
- if (LOG.isLoggable(INFO)) LOG.info("Turning off Bluetooth again");
-
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- if (adapter != null) AndroidUtils.setBluetooth(adapter, false);
- }
- }
-
public void connectionSucceeded() {
runOnUiThread(new Runnable() {
public void run() {
diff --git a/briar-android/src/org/briarproject/android/invitation/ErrorView.java b/briar-android/src/org/briarproject/android/invitation/ErrorView.java
index f87966d66..fa0f8fc33 100644
--- a/briar-android/src/org/briarproject/android/invitation/ErrorView.java
+++ b/briar-android/src/org/briarproject/android/invitation/ErrorView.java
@@ -1,23 +1,19 @@
package org.briarproject.android.invitation;
-import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
-import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION;
-import static android.view.Gravity.CENTER;
-import static org.briarproject.android.invitation.AddContactActivity.REQUEST_BLUETOOTH;
-import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
-
-import org.briarproject.R;
-
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.TextView;
+import org.briarproject.R;
+
+import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
+import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION;
+import static org.briarproject.android.invitation.AddContactActivity.REQUEST_BLUETOOTH;
+
class ErrorView extends AddContactView implements OnClickListener {
private final int error;
@@ -39,8 +35,6 @@ class ErrorView extends AddContactView implements OnClickListener {
removeAllViews();
Context ctx = getContext();
- container.disableBluetooth();
-
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.invitation_error, this);
diff --git a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
index 7bbbe7a15..646e498d9 100644
--- a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPlugin.java
@@ -10,13 +10,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.system.Clock;
import org.briarproject.util.LatchedReference;
import org.briarproject.util.StringUtils;
diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
index 149c8d36b..b6c2f345a 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
@@ -13,9 +13,7 @@ import net.freehaven.tor.control.TorControlConnection;
import net.sourceforge.jsocks.socks.Socks5Proxy;
import net.sourceforge.jsocks.socks.SocksSocket;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.event.Event;
@@ -24,6 +22,8 @@ import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.util.StringUtils;
diff --git a/briar-api/src/org/briarproject/api/StringMap.java b/briar-api/src/org/briarproject/api/StringMap.java
index 7b897f45e..299f8f3f1 100644
--- a/briar-api/src/org/briarproject/api/StringMap.java
+++ b/briar-api/src/org/briarproject/api/StringMap.java
@@ -3,7 +3,7 @@ package org.briarproject.api;
import java.util.Hashtable;
import java.util.Map;
-abstract class StringMap extends Hashtable {
+public abstract class StringMap extends Hashtable {
private static final long serialVersionUID = 2497176435908100448L;
diff --git a/briar-api/src/org/briarproject/api/TransportId.java b/briar-api/src/org/briarproject/api/TransportId.java
index 9f123ab83..f7644891c 100644
--- a/briar-api/src/org/briarproject/api/TransportId.java
+++ b/briar-api/src/org/briarproject/api/TransportId.java
@@ -1,12 +1,13 @@
package org.briarproject.api;
-import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH;
-
/**
* Type-safe wrapper for a string that uniquely identifies a transport plugin.
*/
public class TransportId {
+ /** The maximum length of transport identifier in UTF-8 bytes. */
+ public static int MAX_TRANSPORT_ID_LENGTH = 10;
+
private final String id;
public TransportId(String id) {
@@ -21,8 +22,7 @@ public class TransportId {
@Override
public boolean equals(Object o) {
- if (o instanceof TransportId) return id.equals(((TransportId) o).id);
- return false;
+ return o instanceof TransportId && id.equals(((TransportId) o).id);
}
@Override
diff --git a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
index 33f893949..dd165c481 100644
--- a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
+++ b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java
@@ -1,12 +1,12 @@
package org.briarproject.api.db;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
diff --git a/briar-api/src/org/briarproject/api/event/LocalTransportsUpdatedEvent.java b/briar-api/src/org/briarproject/api/event/LocalTransportsUpdatedEvent.java
deleted file mode 100644
index c8cc743e9..000000000
--- a/briar-api/src/org/briarproject/api/event/LocalTransportsUpdatedEvent.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.briarproject.api.event;
-
-/**
- * An event that is broadcast when the local transport properties are
- * updated.
- */
-public class LocalTransportsUpdatedEvent extends Event {
-
-}
diff --git a/briar-api/src/org/briarproject/api/event/RemoteTransportsUpdatedEvent.java b/briar-api/src/org/briarproject/api/event/RemoteTransportsUpdatedEvent.java
deleted file mode 100644
index 52d36961b..000000000
--- a/briar-api/src/org/briarproject/api/event/RemoteTransportsUpdatedEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.briarproject.api.event;
-
-import org.briarproject.api.TransportId;
-import org.briarproject.api.contact.ContactId;
-
-/**
- * An event that is broadcast when a contact's remote transport properties
- * are updated.
- */
-public class RemoteTransportsUpdatedEvent extends Event {
-
- private final ContactId contactId;
- private final TransportId transportId;
-
- public RemoteTransportsUpdatedEvent(ContactId contactId,
- TransportId transportId) {
- this.contactId = contactId;
- this.transportId = transportId;
- }
-
- public ContactId getContactId() {
- return contactId;
- }
-
- public TransportId getTransportId() {
- return transportId;
- }
-}
diff --git a/briar-api/src/org/briarproject/api/invitation/InvitationTaskFactory.java b/briar-api/src/org/briarproject/api/invitation/InvitationTaskFactory.java
index 85b4f882d..35053ff61 100644
--- a/briar-api/src/org/briarproject/api/invitation/InvitationTaskFactory.java
+++ b/briar-api/src/org/briarproject/api/invitation/InvitationTaskFactory.java
@@ -7,5 +7,5 @@ public interface InvitationTaskFactory {
/** Creates a task using the given pseudonym and invitation codes. */
InvitationTask createTask(AuthorId localAuthorId, int localCode,
- int remoteCode, boolean reuseConnection);
+ int remoteCode);
}
diff --git a/briar-api/src/org/briarproject/api/plugins/PluginCallback.java b/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
index 8216cafdf..6e3d0e4fa 100644
--- a/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
+++ b/briar-api/src/org/briarproject/api/plugins/PluginCallback.java
@@ -1,8 +1,8 @@
package org.briarproject.api.plugins;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
-import org.briarproject.api.Settings;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import java.util.Map;
diff --git a/briar-api/src/org/briarproject/api/TransportProperties.java b/briar-api/src/org/briarproject/api/properties/TransportProperties.java
similarity index 76%
rename from briar-api/src/org/briarproject/api/TransportProperties.java
rename to briar-api/src/org/briarproject/api/properties/TransportProperties.java
index 7d05515e8..512f3917c 100644
--- a/briar-api/src/org/briarproject/api/TransportProperties.java
+++ b/briar-api/src/org/briarproject/api/properties/TransportProperties.java
@@ -1,4 +1,6 @@
-package org.briarproject.api;
+package org.briarproject.api.properties;
+
+import org.briarproject.api.StringMap;
import java.util.Map;
diff --git a/briar-api/src/org/briarproject/api/TransportPropertyConstants.java b/briar-api/src/org/briarproject/api/properties/TransportPropertyConstants.java
similarity index 61%
rename from briar-api/src/org/briarproject/api/TransportPropertyConstants.java
rename to briar-api/src/org/briarproject/api/properties/TransportPropertyConstants.java
index cd2e106e3..fd0171094 100644
--- a/briar-api/src/org/briarproject/api/TransportPropertyConstants.java
+++ b/briar-api/src/org/briarproject/api/properties/TransportPropertyConstants.java
@@ -1,13 +1,7 @@
-package org.briarproject.api;
+package org.briarproject.api.properties;
public interface TransportPropertyConstants {
- /**
- * The maximum length of a string that uniquely identifies a transport
- * plugin.
- */
- int MAX_TRANSPORT_ID_LENGTH = 10;
-
/** The maximum number of properties per transport. */
int MAX_PROPERTIES_PER_TRANSPORT = 100;
diff --git a/briar-api/src/org/briarproject/api/property/TransportPropertyManager.java b/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java
similarity index 73%
rename from briar-api/src/org/briarproject/api/property/TransportPropertyManager.java
rename to briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java
index ce7bc96e1..0e8b76d68 100644
--- a/briar-api/src/org/briarproject/api/property/TransportPropertyManager.java
+++ b/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java
@@ -1,7 +1,6 @@
-package org.briarproject.api.property;
+package org.briarproject.api.properties;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
@@ -26,11 +25,4 @@ public interface TransportPropertyManager {
*/
void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException;
-
- /**
- * Sets the remote transport properties for the given contact, replacing
- * any existing properties.
- */
- void setRemoteProperties(ContactId c,
- Map p) throws DbException;
}
diff --git a/briar-api/src/org/briarproject/api/Settings.java b/briar-api/src/org/briarproject/api/settings/Settings.java
similarity index 59%
rename from briar-api/src/org/briarproject/api/Settings.java
rename to briar-api/src/org/briarproject/api/settings/Settings.java
index 465a0c300..43fe1e566 100644
--- a/briar-api/src/org/briarproject/api/Settings.java
+++ b/briar-api/src/org/briarproject/api/settings/Settings.java
@@ -1,4 +1,6 @@
-package org.briarproject.api;
+package org.briarproject.api.settings;
+
+import org.briarproject.api.StringMap;
public class Settings extends StringMap {
diff --git a/briar-api/src/org/briarproject/api/settings/SettingsManager.java b/briar-api/src/org/briarproject/api/settings/SettingsManager.java
index 33c36e4ef..05166529b 100644
--- a/briar-api/src/org/briarproject/api/settings/SettingsManager.java
+++ b/briar-api/src/org/briarproject/api/settings/SettingsManager.java
@@ -1,6 +1,5 @@
package org.briarproject.api.settings;
-import org.briarproject.api.Settings;
import org.briarproject.api.db.DbException;
public interface SettingsManager {
diff --git a/briar-api/src/org/briarproject/api/transport/KeyManager.java b/briar-api/src/org/briarproject/api/transport/KeyManager.java
index 32800d7af..1d6ece09a 100644
--- a/briar-api/src/org/briarproject/api/transport/KeyManager.java
+++ b/briar-api/src/org/briarproject/api/transport/KeyManager.java
@@ -4,8 +4,6 @@ import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
-import java.util.Collection;
-
/**
* Responsible for managing transport keys and recognising the pseudo-random
* tags of incoming streams.
@@ -18,8 +16,8 @@ public interface KeyManager {
* {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned.
*/
- void addContact(ContactId c, Collection transports,
- SecretKey master, long timestamp, boolean alice);
+ void addContact(ContactId c, SecretKey master, long timestamp,
+ boolean alice);
/**
* Returns a {@link StreamContext} for sending a stream to the given
diff --git a/briar-core/src/org/briarproject/crypto/CryptoModule.java b/briar-core/src/org/briarproject/crypto/CryptoModule.java
index 35a4b0136..5df7e38f0 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoModule.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoModule.java
@@ -10,6 +10,7 @@ import org.briarproject.api.crypto.StreamDecrypterFactory;
import org.briarproject.api.crypto.StreamEncrypterFactory;
import org.briarproject.api.lifecycle.LifecycleManager;
+import java.security.SecureRandom;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@@ -57,4 +58,9 @@ public class CryptoModule extends AbstractModule {
lifecycleManager.registerForShutdown(cryptoExecutor);
return cryptoExecutor;
}
+
+ @Provides
+ SecureRandom getSecureRandom(CryptoComponent crypto) {
+ return crypto.getSecureRandom();
+ }
}
diff --git a/briar-core/src/org/briarproject/db/Database.java b/briar-core/src/org/briarproject/db/Database.java
index e539d8d4c..9236c6e29 100644
--- a/briar-core/src/org/briarproject/db/Database.java
+++ b/briar-core/src/org/briarproject/db/Database.java
@@ -1,6 +1,5 @@
package org.briarproject.db;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -10,6 +9,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 2b01c7e6f..ccfa60ecc 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -1,6 +1,5 @@
package org.briarproject.db;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -35,6 +34,7 @@ import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.ShutdownManager;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
diff --git a/briar-core/src/org/briarproject/db/DatabaseConstants.java b/briar-core/src/org/briarproject/db/DatabaseConstants.java
index 2c06feca1..ddeb138db 100644
--- a/briar-core/src/org/briarproject/db/DatabaseConstants.java
+++ b/briar-core/src/org/briarproject/db/DatabaseConstants.java
@@ -1,5 +1,7 @@
package org.briarproject.db;
+import org.briarproject.api.settings.Settings;
+
interface DatabaseConstants {
/**
@@ -8,4 +10,34 @@ interface DatabaseConstants {
* limit is reached, additional offers will not be stored.
*/
int MAX_OFFERED_MESSAGES = 1000;
+
+ /**
+ * The namespace of the {@link Settings Settings}
+ * where the database schema version is stored.
+ */
+ String DB_SETTINGS_NAMESPACE = "db";
+
+ /**
+ * The {@link Settings Settings} key under which the
+ * database schema version is stored.
+ */
+ String SCHEMA_VERSION_KEY = "schemaVersion";
+
+ /**
+ * The {@link Settings Settings} key under which the
+ * minimum supported database schema version is stored.
+ */
+ String MIN_SCHEMA_VERSION_KEY = "minSchemaVersion";
+
+ /**
+ * The namespace of the {@link Settings Settings}
+ * where the unique device ID is stored.
+ */
+ String DEVICE_SETTINGS_NAMESPACE = "device";
+
+ /**
+ * The {@link Settings Settings} key under which the
+ * unique device ID is stored.
+ */
+ String DEVICE_ID_KEY = "deviceId";
}
diff --git a/briar-core/src/org/briarproject/db/DatabaseModule.java b/briar-core/src/org/briarproject/db/DatabaseModule.java
index a76155bdb..9ac531c07 100644
--- a/briar-core/src/org/briarproject/db/DatabaseModule.java
+++ b/briar-core/src/org/briarproject/db/DatabaseModule.java
@@ -9,8 +9,9 @@ import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.ShutdownManager;
-import org.briarproject.system.SystemClock;
+import org.briarproject.api.system.Clock;
+import java.security.SecureRandom;
import java.sql.Connection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
@@ -39,13 +40,12 @@ public class DatabaseModule extends AbstractModule {
}
@Override
- protected void configure() {
- // Nothing to bind
- }
+ protected void configure() {}
@Provides @Singleton
- Database getDatabase(DatabaseConfig config) {
- return new H2Database(config, new SystemClock());
+ Database getDatabase(DatabaseConfig config,
+ SecureRandom random, Clock clock) {
+ return new H2Database(config, random, clock);
}
@Provides @Singleton
diff --git a/briar-core/src/org/briarproject/db/H2Database.java b/briar-core/src/org/briarproject/db/H2Database.java
index dd8c8d8c1..f67153085 100644
--- a/briar-core/src/org/briarproject/db/H2Database.java
+++ b/briar-core/src/org/briarproject/db/H2Database.java
@@ -6,6 +6,7 @@ import org.briarproject.api.system.Clock;
import org.briarproject.util.StringUtils;
import java.io.File;
+import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@@ -25,13 +26,13 @@ class H2Database extends JdbcDatabase {
private final String url;
@Inject
- H2Database(DatabaseConfig config, Clock clock) {
- super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, clock);
+ H2Database(DatabaseConfig config, SecureRandom random, Clock clock) {
+ super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, random, clock);
this.config = config;
File dir = config.getDatabaseDirectory();
String path = new File(dir, "db").getAbsolutePath();
url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1"
- + ";DB_CLOSE_ON_EXIT=false";
+ + ";WRITE_DELAY=0;DB_CLOSE_ON_EXIT=false";
}
public boolean open() throws DbException {
diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java
index 05b9d2ce2..63b6aa186 100644
--- a/briar-core/src/org/briarproject/db/JdbcDatabase.java
+++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java
@@ -1,7 +1,7 @@
package org.briarproject.db;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
+import org.briarproject.api.UniqueId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
@@ -12,6 +12,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
@@ -24,7 +25,9 @@ import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.TransportKeys;
+import org.briarproject.util.StringUtils;
+import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -53,6 +56,11 @@ import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.sync.ValidationManager.Status.INVALID;
import static org.briarproject.api.sync.ValidationManager.Status.UNKNOWN;
import static org.briarproject.api.sync.ValidationManager.Status.VALID;
+import static org.briarproject.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
+import static org.briarproject.db.DatabaseConstants.DEVICE_ID_KEY;
+import static org.briarproject.db.DatabaseConstants.DEVICE_SETTINGS_NAMESPACE;
+import static org.briarproject.db.DatabaseConstants.MIN_SCHEMA_VERSION_KEY;
+import static org.briarproject.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
/**
@@ -61,8 +69,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
*/
abstract class JdbcDatabase implements Database {
- private static final int SCHEMA_VERSION = 17;
- private static final int MIN_SCHEMA_VERSION = 17;
+ private static final int SCHEMA_VERSION = 18;
+ private static final int MIN_SCHEMA_VERSION = 18;
private static final String CREATE_SETTINGS =
"CREATE TABLE settings"
@@ -244,6 +252,7 @@ abstract class JdbcDatabase implements Database {
// Different database libraries use different names for certain types
private final String hashType, binaryType, counterType, secretType;
+ private final SecureRandom random;
private final Clock clock;
private final LinkedList connections =
@@ -260,11 +269,12 @@ abstract class JdbcDatabase implements Database {
private final Condition connectionsChanged = connectionsLock.newCondition();
JdbcDatabase(String hashType, String binaryType, String counterType,
- String secretType, Clock clock) {
+ String secretType, SecureRandom random, Clock clock) {
this.hashType = hashType;
this.binaryType = binaryType;
this.counterType = counterType;
this.secretType = secretType;
+ this.random = random;
this.clock = clock;
}
@@ -283,6 +293,7 @@ abstract class JdbcDatabase implements Database {
} else {
createTables(txn);
storeSchemaVersion(txn);
+ storeDeviceId(txn);
}
commitTransaction(txn);
} catch (DbException e) {
@@ -292,19 +303,27 @@ abstract class JdbcDatabase implements Database {
}
private boolean checkSchemaVersion(Connection txn) throws DbException {
- Settings s = getSettings(txn, "db");
- int schemaVersion = s.getInt("schemaVersion", -1);
+ Settings s = getSettings(txn, DB_SETTINGS_NAMESPACE);
+ int schemaVersion = s.getInt(SCHEMA_VERSION_KEY, -1);
if (schemaVersion == SCHEMA_VERSION) return true;
if (schemaVersion < MIN_SCHEMA_VERSION) return false;
- int minSchemaVersion = s.getInt("minSchemaVersion", -1);
+ int minSchemaVersion = s.getInt(MIN_SCHEMA_VERSION_KEY, -1);
return SCHEMA_VERSION >= minSchemaVersion;
}
private void storeSchemaVersion(Connection txn) throws DbException {
Settings s = new Settings();
- s.putInt("schemaVersion", SCHEMA_VERSION);
- s.putInt("minSchemaVersion", MIN_SCHEMA_VERSION);
- mergeSettings(txn, s, "db");
+ s.putInt(SCHEMA_VERSION_KEY, SCHEMA_VERSION);
+ s.putInt(MIN_SCHEMA_VERSION_KEY, MIN_SCHEMA_VERSION);
+ mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
+ }
+
+ private void storeDeviceId(Connection txn) throws DbException {
+ byte[] deviceId = new byte[UniqueId.LENGTH];
+ random.nextBytes(deviceId);
+ Settings s = new Settings();
+ s.put(DEVICE_ID_KEY, StringUtils.toHexString(deviceId));
+ mergeSettings(txn, s, DEVICE_SETTINGS_NAMESPACE);
}
private void tryToClose(ResultSet rs) {
diff --git a/briar-core/src/org/briarproject/forum/ForumModule.java b/briar-core/src/org/briarproject/forum/ForumModule.java
index 3d82cdfe4..9dd05f22d 100644
--- a/briar-core/src/org/briarproject/forum/ForumModule.java
+++ b/briar-core/src/org/briarproject/forum/ForumModule.java
@@ -16,6 +16,8 @@ import org.briarproject.api.system.Clock;
import javax.inject.Singleton;
+import static org.briarproject.forum.ForumManagerImpl.CLIENT_ID;
+
public class ForumModule extends AbstractModule {
@Override
@@ -26,16 +28,14 @@ public class ForumModule extends AbstractModule {
@Provides @Singleton
ForumPostValidator getValidator(ValidationManager validationManager,
- ForumManager forumManager, CryptoComponent crypto,
- BdfReaderFactory bdfReaderFactory,
+ CryptoComponent crypto, BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory,
ObjectReader authorReader, MetadataEncoder metadataEncoder,
Clock clock) {
ForumPostValidator validator = new ForumPostValidator(crypto,
bdfReaderFactory, bdfWriterFactory, authorReader,
metadataEncoder, clock);
- validationManager.registerMessageValidator(forumManager.getClientId(),
- validator);
+ validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}
}
diff --git a/briar-core/src/org/briarproject/invitation/AliceConnector.java b/briar-core/src/org/briarproject/invitation/AliceConnector.java
index 590fc5458..7d7807b80 100644
--- a/briar-core/src/org/briarproject/invitation/AliceConnector.java
+++ b/briar-core/src/org/briarproject/invitation/AliceConnector.java
@@ -1,7 +1,5 @@
package org.briarproject.invitation;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
@@ -17,7 +15,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
-import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
-import java.util.Map;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
@@ -47,17 +43,12 @@ class AliceConnector extends Connector {
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
- ContactManager contactManager,
- TransportPropertyManager transportPropertyManager, Clock clock,
- boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
- LocalAuthor localAuthor,
- Map localProps,
- PseudoRandom random) {
+ ContactManager contactManager, Clock clock, ConnectorGroup group,
+ DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
- streamWriterFactory, authorFactory, groupFactory,
- keyManager, connectionManager, contactManager,
- transportPropertyManager, clock, reuseConnection, group,
- plugin, localAuthor, localProps, random);
+ streamWriterFactory, authorFactory, groupFactory, keyManager,
+ connectionManager, contactManager, clock, group, plugin,
+ localAuthor, random);
}
@Override
@@ -152,20 +143,14 @@ class AliceConnector extends Connector {
// Derive the invitation nonces
byte[] aliceNonce = crypto.deriveSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveSignatureNonce(master, false);
- // Exchange pseudonyms, signed nonces, timestamps and transports
+ // Exchange pseudonyms, signed nonces, and timestamps
Author remoteAuthor;
long remoteTimestamp;
- Map 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");
@@ -182,18 +167,17 @@ class AliceConnector extends Connector {
}
// The agreed timestamp is the minimum of the peers' timestamps
long timestamp = Math.min(localTimestamp, remoteTimestamp);
- // Add the contact and store the transports
+ // Add the contact
try {
- addContact(remoteAuthor, remoteProps, master, timestamp, true);
+ addContact(remoteAuthor, master, timestamp, true);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn, true);
group.pseudonymExchangeFailed();
return;
}
- // Reuse the connection as a transport connection if both peers agree
- if (reuseConnection && remoteReuseConnection) reuseConnection(conn);
- else tryToClose(conn, false);
+ // Reuse the connection as a transport connection
+ reuseConnection(conn);
// Pseudonym exchange succeeded
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded");
diff --git a/briar-core/src/org/briarproject/invitation/BobConnector.java b/briar-core/src/org/briarproject/invitation/BobConnector.java
index 584a06a3d..84e0f2987 100644
--- a/briar-core/src/org/briarproject/invitation/BobConnector.java
+++ b/briar-core/src/org/briarproject/invitation/BobConnector.java
@@ -1,7 +1,5 @@
package org.briarproject.invitation;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
@@ -17,7 +15,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
-import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
-import java.util.Map;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
@@ -47,17 +43,12 @@ class BobConnector extends Connector {
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
- ContactManager contactManager,
- TransportPropertyManager transportPropertyManager, Clock clock,
- boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
- LocalAuthor localAuthor,
- Map localProps,
- PseudoRandom random) {
+ ContactManager contactManager, Clock clock, ConnectorGroup group,
+ DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
- streamWriterFactory, authorFactory, groupFactory,
- keyManager, connectionManager, contactManager,
- transportPropertyManager, clock, reuseConnection, group,
- plugin, localAuthor, localProps, random);
+ streamWriterFactory, authorFactory, groupFactory, keyManager,
+ connectionManager, contactManager, clock, group, plugin,
+ localAuthor, random);
}
@Override
@@ -152,20 +143,14 @@ class BobConnector extends Connector {
// Derive the nonces
byte[] aliceNonce = crypto.deriveSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveSignatureNonce(master, false);
- // Exchange pseudonyms, signed nonces, timestamps and transports
+ // Exchange pseudonyms, signed nonces and timestamps
Author remoteAuthor;
long remoteTimestamp;
- Map 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");
@@ -182,18 +167,17 @@ class BobConnector extends Connector {
}
// The agreed timestamp is the minimum of the peers' timestamps
long timestamp = Math.min(localTimestamp, remoteTimestamp);
- // Add the contact and store the transports
+ // Add the contact
try {
- addContact(remoteAuthor, remoteProps, master, timestamp, false);
+ addContact(remoteAuthor, master, timestamp, false);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn, true);
group.pseudonymExchangeFailed();
return;
}
- // Reuse the connection as a transport connection if both peers agree
- if (reuseConnection && remoteReuseConnection) reuseConnection(conn);
- else tryToClose(conn, false);
+ // Reuse the connection as a transport connection
+ reuseConnection(conn);
// Pseudonym exchange succeeded
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded");
diff --git a/briar-core/src/org/briarproject/invitation/Connector.java b/briar-core/src/org/briarproject/invitation/Connector.java
index 21f84ef2f..a89aef88a 100644
--- a/briar-core/src/org/briarproject/invitation/Connector.java
+++ b/briar-core/src/org/briarproject/invitation/Connector.java
@@ -2,7 +2,6 @@ package org.briarproject.invitation;
import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
@@ -23,7 +22,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
-import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -33,16 +31,10 @@ import org.briarproject.api.transport.StreamWriterFactory;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
-import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
-import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
-import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
@@ -64,13 +56,10 @@ abstract class Connector extends Thread {
protected final KeyManager keyManager;
protected final ConnectionManager connectionManager;
protected final ContactManager contactManager;
- protected final TransportPropertyManager transportPropertyManager;
protected final Clock clock;
- protected final boolean reuseConnection;
protected final ConnectorGroup group;
protected final DuplexPlugin plugin;
protected final LocalAuthor localAuthor;
- protected final Map localProps;
protected final PseudoRandom random;
protected final String pluginName;
@@ -87,12 +76,8 @@ abstract class Connector extends Thread {
StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
- ContactManager contactManager,
- TransportPropertyManager transportPropertyManager, Clock clock,
- boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
- LocalAuthor localAuthor,
- Map localProps,
- PseudoRandom random) {
+ ContactManager contactManager, Clock clock, ConnectorGroup group,
+ DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
super("Connector");
this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory;
@@ -104,13 +89,10 @@ abstract class Connector extends Thread {
this.keyManager = keyManager;
this.connectionManager = connectionManager;
this.contactManager = contactManager;
- this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
- this.reuseConnection = reuseConnection;
this.group = group;
this.plugin = plugin;
this.localAuthor = localAuthor;
- this.localProps = localProps;
this.random = random;
pluginName = plugin.getClass().getName();
keyPair = crypto.generateAgreementKeyPair();
@@ -233,57 +215,14 @@ abstract class Connector extends Thread {
return timestamp;
}
- protected void sendTransportProperties(BdfWriter w) throws IOException {
- w.writeListStart();
- for (Entry e :
- localProps.entrySet()) {
- w.writeString(e.getKey().getString());
- w.writeDictionary(e.getValue());
- }
- w.writeListEnd();
- w.flush();
- if (LOG.isLoggable(INFO))
- LOG.info(pluginName + " sent transport properties");
- }
-
- protected Map receiveTransportProperties(
- BdfReader r) throws IOException {
- Map remoteProps =
- new HashMap();
- r.readListStart();
- while (!r.hasListEnd()) {
- String idString = r.readString(MAX_TRANSPORT_ID_LENGTH);
- if (idString.length() == 0) throw new FormatException();
- TransportId id = new TransportId(idString);
- Map p = new HashMap();
- r.readDictionaryStart();
- for (int i = 0; !r.hasDictionaryEnd(); i++) {
- if (i == MAX_PROPERTIES_PER_TRANSPORT)
- throw new FormatException();
- String key = r.readString(MAX_PROPERTY_LENGTH);
- String value = r.readString(MAX_PROPERTY_LENGTH);
- p.put(key, value);
- }
- r.readDictionaryEnd();
- remoteProps.put(id, new TransportProperties(p));
- }
- r.readListEnd();
- if (LOG.isLoggable(INFO))
- LOG.info(pluginName + " received transport properties");
- return remoteProps;
- }
-
- protected void addContact(Author remoteAuthor,
- Map remoteProps, SecretKey master,
+ protected ContactId addContact(Author remoteAuthor, SecretKey master,
long timestamp, boolean alice) throws DbException {
// Add the contact to the database
contactId = contactManager.addContact(remoteAuthor,
localAuthor.getId());
- // Store the remote transport properties
- transportPropertyManager.setRemoteProperties(contactId, remoteProps);
- // Derive transport keys for each transport shared with the contact
- keyManager.addContact(contactId, remoteProps.keySet(), master,
- timestamp, alice);
+ // Derive transport keys
+ keyManager.addContact(contactId, master, timestamp, alice);
+ return contactId;
}
protected void tryToClose(DuplexTransportConnection conn,
diff --git a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
index 1a24b782c..9025c9dff 100644
--- a/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
+++ b/briar-core/src/org/briarproject/invitation/ConnectorGroup.java
@@ -1,7 +1,5 @@
package org.briarproject.invitation;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom;
@@ -19,7 +17,6 @@ import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
-import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import org.briarproject.api.transport.StreamWriterFactory;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -57,12 +53,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
private final ConnectionManager connectionManager;
private final IdentityManager identityManager;
private final ContactManager contactManager;
- private final TransportPropertyManager transportPropertyManager;
private final Clock clock;
private final PluginManager pluginManager;
private final AuthorId localAuthorId;
private final int localInvitationCode, remoteInvitationCode;
- private final boolean reuseConnection;
private final Collection listeners;
private final AtomicBoolean connected;
private final CountDownLatch localConfirmationLatch;
@@ -83,10 +77,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
IdentityManager identityManager, ContactManager contactManager,
- TransportPropertyManager transportPropertyManager, Clock clock,
- PluginManager pluginManager, AuthorId localAuthorId,
- int localInvitationCode, int remoteInvitationCode,
- boolean reuseConnection) {
+ Clock clock, PluginManager pluginManager, AuthorId localAuthorId,
+ int localInvitationCode, int remoteInvitationCode) {
super("ConnectorGroup");
this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory;
@@ -99,13 +91,11 @@ class ConnectorGroup extends Thread implements InvitationTask {
this.connectionManager = connectionManager;
this.identityManager = identityManager;
this.contactManager = contactManager;
- this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
this.pluginManager = pluginManager;
this.localAuthorId = localAuthorId;
this.localInvitationCode = localInvitationCode;
this.remoteInvitationCode = remoteInvitationCode;
- this.reuseConnection = reuseConnection;
listeners = new CopyOnWriteArrayList();
connected = new AtomicBoolean(false);
localConfirmationLatch = new CountDownLatch(1);
@@ -136,11 +126,9 @@ class ConnectorGroup extends Thread implements InvitationTask {
@Override
public void run() {
LocalAuthor localAuthor;
- Map localProps;
- // Load the local pseudonym and transport properties
+ // Load the local pseudonym
try {
localAuthor = identityManager.getLocalAuthor(localAuthorId);
- localProps = transportPropertyManager.getLocalProperties();
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
lock.lock();
@@ -157,15 +145,13 @@ class ConnectorGroup extends Thread implements InvitationTask {
// Alice is the party with the smaller invitation code
if (localInvitationCode < remoteInvitationCode) {
for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) {
- Connector c = createAliceConnector(plugin, localAuthor,
- localProps);
+ Connector c = createAliceConnector(plugin, localAuthor);
connectors.add(c);
c.start();
}
} else {
for (DuplexPlugin plugin: pluginManager.getInvitationPlugins()) {
- Connector c = createBobConnector(plugin, localAuthor,
- localProps);
+ Connector c = createBobConnector(plugin, localAuthor);
connectors.add(c);
c.start();
}
@@ -190,27 +176,23 @@ class ConnectorGroup extends Thread implements InvitationTask {
}
private Connector createAliceConnector(DuplexPlugin plugin,
- LocalAuthor localAuthor,
- Map localProps) {
+ LocalAuthor localAuthor) {
PseudoRandom random = crypto.getPseudoRandom(localInvitationCode,
remoteInvitationCode);
return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, contactManager,
- transportPropertyManager, clock, reuseConnection, this, plugin,
- localAuthor, localProps, random);
+ clock, this, plugin, localAuthor, random);
}
private Connector createBobConnector(DuplexPlugin plugin,
- LocalAuthor localAuthor,
- Map localProps) {
+ LocalAuthor localAuthor) {
PseudoRandom random = crypto.getPseudoRandom(remoteInvitationCode,
localInvitationCode);
return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, contactManager,
- transportPropertyManager, clock, reuseConnection, this, plugin,
- localAuthor, localProps, random);
+ clock, this, plugin, localAuthor, random);
}
public void localConfirmationSucceeded() {
diff --git a/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java b/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java
index db131b376..0b6b4cdf8 100644
--- a/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java
+++ b/briar-core/src/org/briarproject/invitation/InvitationTaskFactoryImpl.java
@@ -11,7 +11,6 @@ import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.invitation.InvitationTaskFactory;
import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager;
-import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager;
@@ -33,7 +32,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
private final ConnectionManager connectionManager;
private final IdentityManager identityManager;
private final ContactManager contactManager;
- private final TransportPropertyManager transportPropertyManager;
private final Clock clock;
private final PluginManager pluginManager;
@@ -45,7 +43,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager,
IdentityManager identityManager, ContactManager contactManager,
- TransportPropertyManager transportPropertyManager,
Clock clock, PluginManager pluginManager) {
this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory;
@@ -58,17 +55,16 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
this.connectionManager = connectionManager;
this.identityManager = identityManager;
this.contactManager = contactManager;
- this.transportPropertyManager = transportPropertyManager;
this.clock = clock;
this.pluginManager = pluginManager;
}
public InvitationTask createTask(AuthorId localAuthorId, int localCode,
- int remoteCode, boolean reuseConnection) {
+ int remoteCode) {
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, identityManager,
- contactManager, transportPropertyManager, clock, pluginManager,
- localAuthorId, localCode, remoteCode, reuseConnection);
+ contactManager, clock, pluginManager, localAuthorId, localCode,
+ remoteCode);
}
}
diff --git a/briar-core/src/org/briarproject/messaging/MessagingModule.java b/briar-core/src/org/briarproject/messaging/MessagingModule.java
index 0e55193e0..fe531f715 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingModule.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingModule.java
@@ -13,6 +13,8 @@ import org.briarproject.api.system.Clock;
import javax.inject.Singleton;
+import static org.briarproject.messaging.MessagingManagerImpl.CLIENT_ID;
+
public class MessagingModule extends AbstractModule {
@Override
@@ -22,14 +24,11 @@ public class MessagingModule extends AbstractModule {
@Provides @Singleton
PrivateMessageValidator getValidator(ValidationManager validationManager,
- MessagingManager messagingManager,
BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
Clock clock) {
PrivateMessageValidator validator = new PrivateMessageValidator(
bdfReaderFactory, metadataEncoder, clock);
- validationManager.registerMessageValidator(
- messagingManager.getClientId(),
- validator);
+ validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}
diff --git a/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java b/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java
index eeda6bbd1..0b6fe073d 100644
--- a/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java
+++ b/briar-core/src/org/briarproject/plugins/ConnectionManagerImpl.java
@@ -73,8 +73,7 @@ class ConnectionManagerImpl implements ConnectionManager {
ioExecutor.execute(new ManageOutgoingDuplexConnection(c, t, d));
}
- private byte[] readTag(TransportId t, TransportConnectionReader r)
- throws IOException {
+ private byte[] readTag(TransportConnectionReader r) throws IOException {
// Read the tag
byte[] tag = new byte[TAG_LENGTH];
InputStream in = r.getInputStream();
@@ -128,7 +127,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag
StreamContext ctx;
try {
- byte[] tag = readTag(transportId, reader);
+ byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -228,7 +227,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag
StreamContext ctx;
try {
- byte[] tag = readTag(transportId, reader);
+ byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -353,7 +352,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag
StreamContext ctx;
try {
- byte[] tag = readTag(transportId, reader);
+ byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
diff --git a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
index 0625b2d24..66987c4fd 100644
--- a/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
+++ b/briar-core/src/org/briarproject/plugins/PluginManagerImpl.java
@@ -1,8 +1,6 @@
package org.briarproject.plugins;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
@@ -26,7 +24,9 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
-import org.briarproject.api.property.TransportPropertyManager;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.properties.TransportPropertyManager;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback;
diff --git a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java
index 182c81e25..01b377f0f 100644
--- a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java
+++ b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPlugin.java
@@ -1,5 +1,9 @@
package org.briarproject.plugins.tcp;
+import org.briarproject.api.TransportId;
+import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
+import org.briarproject.api.properties.TransportProperties;
+
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -8,10 +12,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
-import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
-
class LanTcpPlugin extends TcpPlugin {
static final TransportId ID = new TransportId("lan");
diff --git a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
index 3388de5f1..a7a0b201d 100644
--- a/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
+++ b/briar-core/src/org/briarproject/plugins/tcp/TcpPlugin.java
@@ -1,11 +1,11 @@
package org.briarproject.plugins.tcp;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
import org.briarproject.util.StringUtils;
import java.io.IOException;
diff --git a/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java b/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java
index d28997c51..64c924e4e 100644
--- a/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java
+++ b/briar-core/src/org/briarproject/plugins/tcp/WanTcpPlugin.java
@@ -1,5 +1,9 @@
package org.briarproject.plugins.tcp;
+import org.briarproject.api.TransportId;
+import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
+import org.briarproject.api.properties.TransportProperties;
+
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -8,10 +12,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
-import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
-
class WanTcpPlugin extends TcpPlugin {
static final TransportId ID = new TransportId("wan");
diff --git a/briar-core/src/org/briarproject/properties/PropertiesModule.java b/briar-core/src/org/briarproject/properties/PropertiesModule.java
new file mode 100644
index 000000000..9edbf7e16
--- /dev/null
+++ b/briar-core/src/org/briarproject/properties/PropertiesModule.java
@@ -0,0 +1,40 @@
+package org.briarproject.properties;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+import org.briarproject.api.contact.ContactManager;
+import org.briarproject.api.data.BdfReaderFactory;
+import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.properties.TransportPropertyManager;
+import org.briarproject.api.sync.ValidationManager;
+import org.briarproject.api.system.Clock;
+
+import javax.inject.Singleton;
+
+import static org.briarproject.properties.TransportPropertyManagerImpl.CLIENT_ID;
+
+public class PropertiesModule extends AbstractModule {
+
+ @Override
+ protected void configure() {}
+
+ @Provides @Singleton
+ TransportPropertyValidator getValidator(ValidationManager validationManager,
+ BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
+ Clock clock) {
+ TransportPropertyValidator validator = new TransportPropertyValidator(
+ bdfReaderFactory, metadataEncoder, clock);
+ validationManager.registerMessageValidator(CLIENT_ID, validator);
+ return validator;
+ }
+
+ @Provides @Singleton
+ TransportPropertyManager getTransportPropertyManager(
+ ContactManager contactManager,
+ TransportPropertyManagerImpl transportPropertyManager) {
+ contactManager.registerAddContactHook(transportPropertyManager);
+ contactManager.registerRemoveContactHook(transportPropertyManager);
+ return transportPropertyManager;
+ }
+}
diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
new file mode 100644
index 000000000..2d4fc5bcc
--- /dev/null
+++ b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java
@@ -0,0 +1,339 @@
+package org.briarproject.properties;
+
+import com.google.inject.Inject;
+
+import org.briarproject.api.FormatException;
+import org.briarproject.api.TransportId;
+import org.briarproject.api.UniqueId;
+import org.briarproject.api.contact.Contact;
+import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.contact.ContactManager.AddContactHook;
+import org.briarproject.api.contact.ContactManager.RemoveContactHook;
+import org.briarproject.api.data.BdfDictionary;
+import org.briarproject.api.data.BdfReader;
+import org.briarproject.api.data.BdfReaderFactory;
+import org.briarproject.api.data.BdfWriter;
+import org.briarproject.api.data.BdfWriterFactory;
+import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.data.MetadataParser;
+import org.briarproject.api.db.DatabaseComponent;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.db.Metadata;
+import org.briarproject.api.db.NoSuchSubscriptionException;
+import org.briarproject.api.identity.AuthorId;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.properties.TransportPropertyManager;
+import org.briarproject.api.sync.ClientId;
+import org.briarproject.api.sync.Group;
+import org.briarproject.api.sync.GroupFactory;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageFactory;
+import org.briarproject.api.sync.MessageId;
+import org.briarproject.api.system.Clock;
+import org.briarproject.util.StringUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+import static java.util.logging.Level.WARNING;
+import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
+import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
+
+class TransportPropertyManagerImpl implements TransportPropertyManager,
+ AddContactHook, RemoveContactHook {
+
+ static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
+ "673ea091673561e28f70122f6a8ea8f4"
+ + "97c3624b86fa07f785bb15f09fb87b4b"));
+
+ private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
+
+ private static final Logger LOG =
+ Logger.getLogger(TransportPropertyManagerImpl.class.getName());
+
+ private final DatabaseComponent db;
+ private final GroupFactory groupFactory;
+ private final MessageFactory messageFactory;
+ private final BdfReaderFactory bdfReaderFactory;
+ private final BdfWriterFactory bdfWriterFactory;
+ private final MetadataEncoder metadataEncoder;
+ private final MetadataParser metadataParser;
+ private final Clock clock;
+ private final Group localGroup;
+
+ /** Ensures isolation between database reads and writes. */
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+ @Inject
+ TransportPropertyManagerImpl(DatabaseComponent db, GroupFactory groupFactory,
+ MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
+ BdfWriterFactory bdfWriterFactory, MetadataEncoder metadataEncoder,
+ MetadataParser metadataParser, Clock clock) {
+ this.db = db;
+ this.groupFactory = groupFactory;
+ this.messageFactory = messageFactory;
+ this.bdfReaderFactory = bdfReaderFactory;
+ this.bdfWriterFactory = bdfWriterFactory;
+ this.metadataEncoder = metadataEncoder;
+ this.metadataParser = metadataParser;
+ this.clock = clock;
+ localGroup = groupFactory.createGroup(CLIENT_ID,
+ LOCAL_GROUP_DESCRIPTOR);
+ }
+
+ @Override
+ public void addingContact(ContactId c) {
+ lock.writeLock().lock();
+ try {
+ // Create a group to share with the contact
+ Group g = getContactGroup(db.getContact(c));
+ // Subscribe to the group and share it with the contact
+ db.addGroup(g);
+ db.addContactGroup(c, g);
+ db.setVisibility(g.getId(), Collections.singletonList(c));
+ // Copy the latest local properties into the group
+ Map local = getLocalProperties();
+ for (Entry e : local.entrySet())
+ storeMessage(g.getId(), e.getKey(), e.getValue(), 0);
+ } catch (DbException e) {
+ if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+ } catch (FormatException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private Group getContactGroup(Contact c) {
+ AuthorId local = c.getLocalAuthorId();
+ AuthorId remote = c.getAuthor().getId();
+ byte[] descriptor = encodeGroupDescriptor(local, remote);
+ return groupFactory.createGroup(CLIENT_ID, descriptor);
+ }
+
+ private byte[] encodeGroupDescriptor(AuthorId local, AuthorId remote) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ BdfWriter w = bdfWriterFactory.createWriter(out);
+ try {
+ w.writeListStart();
+ if (UniqueId.IdComparator.INSTANCE.compare(local, remote) < 0) {
+ w.writeRaw(local.getBytes());
+ w.writeRaw(remote.getBytes());
+ } else {
+ w.writeRaw(remote.getBytes());
+ w.writeRaw(local.getBytes());
+ }
+ w.writeListEnd();
+ } catch (IOException e) {
+ // Shouldn't happen with ByteArrayOutputStream
+ throw new RuntimeException(e);
+ }
+ return out.toByteArray();
+ }
+
+ private void storeMessage(GroupId g, TransportId t, TransportProperties p,
+ long version) throws DbException, IOException {
+ byte[] body = encodeProperties(t, p, version);
+ long now = clock.currentTimeMillis();
+ Message m = messageFactory.createMessage(g, now, body);
+ BdfDictionary d = new BdfDictionary();
+ d.put("transportId", t.getString());
+ d.put("version", version);
+ d.put("local", true);
+ db.addLocalMessage(m, CLIENT_ID, metadataEncoder.encode(d));
+ }
+
+ private byte[] encodeProperties(TransportId t, TransportProperties p,
+ long version) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ BdfWriter w = bdfWriterFactory.createWriter(out);
+ try {
+ // TODO: Device ID
+ w.writeListStart();
+ w.writeString(t.getString());
+ w.writeInteger(version);
+ w.writeDictionary(p);
+ w.writeListEnd();
+ } catch (IOException e) {
+ // Shouldn't happen with ByteArrayOutputStream
+ throw new RuntimeException(e);
+ }
+ return out.toByteArray();
+ }
+
+ @Override
+ public void removingContact(ContactId c) {
+ lock.writeLock().lock();
+ try {
+ db.removeGroup(getContactGroup(db.getContact(c)));
+ } catch (DbException e) {
+ if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public Map getLocalProperties()
+ throws DbException {
+ lock.readLock().lock();
+ try {
+ // Find the latest local version for each transport
+ Map latest =
+ findLatest(localGroup.getId(), true);
+ // Retrieve and decode the latest local properties
+ Map local =
+ new HashMap();
+ for (Entry e : latest.entrySet()) {
+ byte[] raw = db.getRawMessage(e.getValue().messageId);
+ local.put(e.getKey(), decodeProperties(raw));
+ }
+ return Collections.unmodifiableMap(local);
+ } catch (NoSuchSubscriptionException e) {
+ // Local group doesn't exist - there are no local properties
+ return Collections.emptyMap();
+ } catch (IOException e) {
+ throw new DbException(e);
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ private Map findLatest(GroupId g, boolean local)
+ throws DbException, FormatException {
+ // TODO: Use metadata queries
+ Map latest = new HashMap();
+ Map metadata = db.getMessageMetadata(g);
+ for (Entry e : metadata.entrySet()) {
+ BdfDictionary mm = metadataParser.parse(e.getValue());
+ if (mm.getBoolean("local") != local) continue;
+ TransportId t = new TransportId(mm.getString("transportId"));
+ long version = mm.getInteger("version");
+ Latest l = latest.get(t);
+ if (l == null || version > l.version)
+ latest.put(t, new Latest(e.getKey(), version));
+ }
+ return latest;
+ }
+
+ private TransportProperties decodeProperties(byte[] raw)
+ throws IOException {
+ TransportProperties p = new TransportProperties();
+ ByteArrayInputStream in = new ByteArrayInputStream(raw,
+ MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH);
+ BdfReader r = bdfReaderFactory.createReader(in);
+ // TODO: Device ID
+ r.readListStart();
+ r.skipString(); // Transport ID
+ r.skipInteger(); // Version
+ r.readDictionaryStart();
+ while (!r.hasDictionaryEnd()) {
+ String key = r.readString(MAX_PROPERTY_LENGTH);
+ String value = r.readString(MAX_PROPERTY_LENGTH);
+ p.put(key, value);
+ }
+ r.readDictionaryEnd();
+ r.readListEnd();
+ if (!r.eof()) throw new FormatException();
+ return p;
+ }
+
+ @Override
+ public TransportProperties getLocalProperties(TransportId t)
+ throws DbException {
+ lock.readLock().lock();
+ try {
+ // Find the latest local version
+ Latest latest = findLatest(localGroup.getId(), true).get(t);
+ if (latest == null) return null;
+ // Retrieve and decode the latest local properties
+ return decodeProperties(db.getRawMessage(latest.messageId));
+ } catch (NoSuchSubscriptionException e) {
+ // Local group doesn't exist - there are no local properties
+ return null;
+ } catch (IOException e) {
+ throw new DbException(e);
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public Map getRemoteProperties(
+ TransportId t) throws DbException {
+ lock.readLock().lock();
+ try {
+ Map remote =
+ new HashMap();
+ for (Contact c : db.getContacts()) {
+ Group g = getContactGroup(c);
+ // Find the latest remote version
+ Latest latest = findLatest(g.getId(), false).get(t);
+ if (latest != null) {
+ // Retrieve and decode the latest remote properties
+ byte[] raw = db.getRawMessage(latest.messageId);
+ remote.put(c.getId(), decodeProperties(raw));
+ }
+ }
+ return Collections.unmodifiableMap(remote);
+ } catch (IOException e) {
+ throw new DbException(e);
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void mergeLocalProperties(TransportId t, TransportProperties p)
+ throws DbException {
+ lock.writeLock().lock();
+ try {
+ // Create the local group if necessary
+ db.addGroup(localGroup);
+ // Merge the new properties with any existing properties
+ Latest latest = findLatest(localGroup.getId(), true).get(t);
+ if (latest != null) {
+ byte[] raw = db.getRawMessage(latest.messageId);
+ TransportProperties old = decodeProperties(raw);
+ if (old.equals(p)) return; // Unchanged
+ old.putAll(p);
+ p = old;
+ }
+ // Store the merged properties in the local group
+ long version = latest == null ? 0 : latest.version + 1;
+ storeMessage(localGroup.getId(), t, p, version);
+ // Store the merged properties in each contact's group
+ for (Contact c : db.getContacts()) {
+ Group g = getContactGroup(c);
+ latest = findLatest(g.getId(), true).get(t);
+ version = latest == null ? 0 : latest.version + 1;
+ storeMessage(g.getId(), t, p, version);
+ }
+ } catch (IOException e) {
+ throw new DbException(e);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private static class Latest {
+
+ private final MessageId messageId;
+ private final long version;
+
+ private Latest(MessageId messageId, long version) {
+ this.messageId = messageId;
+ this.version = version;
+ }
+ }
+}
diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyValidator.java b/briar-core/src/org/briarproject/properties/TransportPropertyValidator.java
new file mode 100644
index 000000000..0a140dd5b
--- /dev/null
+++ b/briar-core/src/org/briarproject/properties/TransportPropertyValidator.java
@@ -0,0 +1,83 @@
+package org.briarproject.properties;
+
+import org.briarproject.api.FormatException;
+import org.briarproject.api.data.BdfDictionary;
+import org.briarproject.api.data.BdfReader;
+import org.briarproject.api.data.BdfReaderFactory;
+import org.briarproject.api.data.MetadataEncoder;
+import org.briarproject.api.db.Metadata;
+import org.briarproject.api.sync.Message;
+import org.briarproject.api.sync.MessageValidator;
+import org.briarproject.api.system.Clock;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+
+import static org.briarproject.api.TransportId.MAX_TRANSPORT_ID_LENGTH;
+import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
+import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
+import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
+import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
+
+class TransportPropertyValidator implements MessageValidator {
+
+ private static final Logger LOG =
+ Logger.getLogger(TransportPropertyValidator.class.getName());
+
+ private final BdfReaderFactory bdfReaderFactory;
+ private final MetadataEncoder metadataEncoder;
+ private final Clock clock;
+
+ @Inject
+ TransportPropertyValidator(BdfReaderFactory bdfReaderFactory,
+ MetadataEncoder metadataEncoder, Clock clock) {
+ this.bdfReaderFactory = bdfReaderFactory;
+ this.metadataEncoder = metadataEncoder;
+ this.clock = clock;
+ }
+
+ @Override
+ public Metadata validateMessage(Message m) {
+ // Reject the message if it's too far in the future
+ long now = clock.currentTimeMillis();
+ if (m.getTimestamp() - now > MAX_CLOCK_DIFFERENCE) {
+ LOG.info("Timestamp is too far in the future");
+ return null;
+ }
+ try {
+ // Parse the message body
+ byte[] raw = m.getRaw();
+ ByteArrayInputStream in = new ByteArrayInputStream(raw,
+ MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH);
+ BdfReader r = bdfReaderFactory.createReader(in);
+ // TODO: Device ID
+ r.readListStart();
+ String id = r.readString(MAX_TRANSPORT_ID_LENGTH);
+ if (id.length() == 0) throw new FormatException();
+ long version = r.readInteger();
+ if (version < 0) throw new FormatException();
+ r.readDictionaryStart();
+ for (int i = 0; !r.hasDictionaryEnd(); i++) {
+ if (i == MAX_PROPERTIES_PER_TRANSPORT)
+ throw new FormatException();
+ r.readString(MAX_PROPERTY_LENGTH);
+ r.readString(MAX_PROPERTY_LENGTH);
+ }
+ r.readDictionaryEnd();
+ r.readListEnd();
+ if (!r.eof()) throw new FormatException();
+ // Return the metadata
+ BdfDictionary d = new BdfDictionary();
+ d.put("transportId", id);
+ d.put("version", version);
+ d.put("local", false);
+ return metadataEncoder.encode(d);
+ } catch (IOException e) {
+ LOG.info("Invalid transport update");
+ return null;
+ }
+ }
+}
diff --git a/briar-core/src/org/briarproject/property/PropertyModule.java b/briar-core/src/org/briarproject/property/PropertyModule.java
deleted file mode 100644
index 23c349953..000000000
--- a/briar-core/src/org/briarproject/property/PropertyModule.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.briarproject.property;
-
-import com.google.inject.AbstractModule;
-
-import org.briarproject.api.property.TransportPropertyManager;
-
-public class PropertyModule extends AbstractModule {
-
- @Override
- protected void configure() {
- bind(TransportPropertyManager.class).to(
- TransportPropertyManagerImpl.class);
- }
-}
diff --git a/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java
deleted file mode 100644
index 1264591e6..000000000
--- a/briar-core/src/org/briarproject/property/TransportPropertyManagerImpl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.briarproject.property;
-
-import com.google.inject.Inject;
-
-import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
-import org.briarproject.api.contact.ContactId;
-import org.briarproject.api.db.DatabaseComponent;
-import org.briarproject.api.db.DbException;
-import org.briarproject.api.property.TransportPropertyManager;
-
-import java.util.Collections;
-import java.util.Map;
-
-// Temporary facade during sync protocol refactoring
-class TransportPropertyManagerImpl implements TransportPropertyManager {
-
- private final DatabaseComponent db;
-
- @Inject
- TransportPropertyManagerImpl(DatabaseComponent db) {
- this.db = db;
- }
-
- @Override
- public Map getLocalProperties()
- throws DbException {
- // TODO
- return Collections.emptyMap();
- }
-
- @Override
- public TransportProperties getLocalProperties(TransportId t)
- throws DbException {
- // TODO
- return new TransportProperties();
- }
-
- @Override
- public Map getRemoteProperties(
- TransportId t) throws DbException {
- // TODO
- return Collections.emptyMap();
- }
-
- @Override
- public void mergeLocalProperties(TransportId t, TransportProperties p)
- throws DbException {
- // TODO
- }
-
- @Override
- public void setRemoteProperties(ContactId c,
- Map p) throws DbException {
- // TODO
- }
-}
diff --git a/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java b/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
index d003f9e35..ee7a3ed68 100644
--- a/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
+++ b/briar-core/src/org/briarproject/settings/SettingsManagerImpl.java
@@ -2,9 +2,9 @@ package org.briarproject.settings;
import com.google.inject.Inject;
-import org.briarproject.api.Settings;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager;
class SettingsManagerImpl implements SettingsManager {
diff --git a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
index 9804cab61..9c99e2819 100644
--- a/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
+++ b/briar-core/src/org/briarproject/transport/KeyManagerImpl.java
@@ -18,7 +18,6 @@ import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext;
-import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -71,12 +70,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return true;
}
- public void addContact(ContactId c, Collection transports,
- SecretKey master, long timestamp, boolean alice) {
- for (TransportId t : transports) {
- TransportKeyManager m = managers.get(t);
- if (m != null) m.addContact(c, master, timestamp, alice);
- }
+ public void addContact(ContactId c, SecretKey master, long timestamp,
+ boolean alice) {
+ for (TransportKeyManager m : managers.values())
+ m.addContact(c, master, timestamp, alice);
}
public StreamContext getStreamContext(ContactId c, TransportId t) {
diff --git a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
index 1796d9a6a..4eeccc567 100644
--- a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
+++ b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPlugin.java
@@ -1,12 +1,12 @@
package org.briarproject.plugins.bluetooth;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.system.Clock;
import org.briarproject.util.LatchedReference;
import org.briarproject.util.OsUtils;
diff --git a/briar-desktop/src/org/briarproject/plugins/modem/ModemPlugin.java b/briar-desktop/src/org/briarproject/plugins/modem/ModemPlugin.java
index fdfeb52c3..0245ad17d 100644
--- a/briar-desktop/src/org/briarproject/plugins/modem/ModemPlugin.java
+++ b/briar-desktop/src/org/briarproject/plugins/modem/ModemPlugin.java
@@ -1,7 +1,6 @@
package org.briarproject.plugins.modem;
import org.briarproject.api.TransportId;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.TransportConnectionReader;
@@ -9,6 +8,7 @@ import org.briarproject.api.plugins.TransportConnectionWriter;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
import org.briarproject.util.StringUtils;
import java.io.IOException;
diff --git a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
index 069b7ed8a..5dd120898 100644
--- a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
+++ b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
@@ -3,7 +3,6 @@ package org.briarproject.db;
import org.briarproject.BriarTestCase;
import org.briarproject.TestDatabaseConfig;
import org.briarproject.TestUtils;
-import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey;
@@ -13,6 +12,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
+import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
@@ -28,6 +28,7 @@ import org.junit.Before;
import org.junit.Test;
import java.io.File;
+import java.security.SecureRandom;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1121,7 +1122,7 @@ public class H2DatabaseTest extends BriarTestCase {
private Database open(boolean resume) throws Exception {
Database db = new H2Database(new TestDatabaseConfig(testDir,
- MAX_SIZE), new SystemClock());
+ MAX_SIZE), new SecureRandom(), new SystemClock());
if (!resume) TestUtils.deleteTestDirectory(testDir);
db.open();
return db;
diff --git a/briar-tests/src/org/briarproject/forum/ForumManagerImplTest.java b/briar-tests/src/org/briarproject/forum/ForumManagerImplTest.java
new file mode 100644
index 000000000..0e7245122
--- /dev/null
+++ b/briar-tests/src/org/briarproject/forum/ForumManagerImplTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.forum;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class ForumManagerImplTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/forum/ForumPostValidatorTest.java b/briar-tests/src/org/briarproject/forum/ForumPostValidatorTest.java
new file mode 100644
index 000000000..089cce54d
--- /dev/null
+++ b/briar-tests/src/org/briarproject/forum/ForumPostValidatorTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.forum;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class ForumPostValidatorTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/messaging/MessagingManagerImplTest.java b/briar-tests/src/org/briarproject/messaging/MessagingManagerImplTest.java
new file mode 100644
index 000000000..9e9227806
--- /dev/null
+++ b/briar-tests/src/org/briarproject/messaging/MessagingManagerImplTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.messaging;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class MessagingManagerImplTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java b/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java
new file mode 100644
index 000000000..28668520f
--- /dev/null
+++ b/briar-tests/src/org/briarproject/messaging/PrivateMessageValidatorTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.messaging;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class PrivateMessageValidatorTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java b/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
index ebfedddbd..b241ec4e8 100644
--- a/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/DuplexClientTest.java
@@ -1,11 +1,11 @@
package org.briarproject.plugins;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import java.io.IOException;
import java.util.Map;
diff --git a/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java b/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
index fe2323c1b..ab60c9272 100644
--- a/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/DuplexServerTest.java
@@ -1,10 +1,10 @@
package org.briarproject.plugins;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
diff --git a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
index ddfd3b150..4ec79282e 100644
--- a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
@@ -13,7 +13,7 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
-import org.briarproject.api.property.TransportPropertyManager;
+import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback;
import org.briarproject.system.SystemClock;
diff --git a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
index caf7f7514..35102e1c9 100644
--- a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
@@ -1,8 +1,8 @@
package org.briarproject.plugins.bluetooth;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexClientTest;
import org.briarproject.system.SystemClock;
diff --git a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
index ca71e8cf0..105519c42 100644
--- a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
@@ -1,7 +1,7 @@
package org.briarproject.plugins.bluetooth;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexServerTest;
import org.briarproject.system.SystemClock;
diff --git a/briar-tests/src/org/briarproject/plugins/modem/ModemPluginTest.java b/briar-tests/src/org/briarproject/plugins/modem/ModemPluginTest.java
index 10f885130..af9c32983 100644
--- a/briar-tests/src/org/briarproject/plugins/modem/ModemPluginTest.java
+++ b/briar-tests/src/org/briarproject/plugins/modem/ModemPluginTest.java
@@ -1,9 +1,9 @@
package org.briarproject.plugins.modem;
import org.briarproject.BriarTestCase;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
+import org.briarproject.api.properties.TransportProperties;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
index 8ad17b59c..c8bfb3118 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
@@ -1,8 +1,8 @@
package org.briarproject.plugins.tcp;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexClientTest;
import java.util.Collections;
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
index cd52f2622..cef6fb7ad 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
@@ -1,12 +1,12 @@
package org.briarproject.plugins.tcp;
import org.briarproject.BriarTestCase;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.junit.Test;
import java.io.IOException;
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
index b415cc194..51d7b2ff3 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
@@ -1,7 +1,7 @@
package org.briarproject.plugins.tcp;
-import org.briarproject.api.Settings;
-import org.briarproject.api.TransportProperties;
+import org.briarproject.api.properties.TransportProperties;
+import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexServerTest;
import java.util.Collections;
diff --git a/briar-tests/src/org/briarproject/properties/TransportPropertyManagerImplTest.java b/briar-tests/src/org/briarproject/properties/TransportPropertyManagerImplTest.java
new file mode 100644
index 000000000..c5f69eee7
--- /dev/null
+++ b/briar-tests/src/org/briarproject/properties/TransportPropertyManagerImplTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.properties;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class TransportPropertyManagerImplTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/properties/TransportPropertyValidatorTest.java b/briar-tests/src/org/briarproject/properties/TransportPropertyValidatorTest.java
new file mode 100644
index 000000000..3dbb5d5ee
--- /dev/null
+++ b/briar-tests/src/org/briarproject/properties/TransportPropertyValidatorTest.java
@@ -0,0 +1,14 @@
+package org.briarproject.properties;
+
+import org.briarproject.BriarTestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class TransportPropertyValidatorTest extends BriarTestCase {
+
+ @Test
+ public void testUnitTestsExist() {
+ fail(); // FIXME: Write tests
+ }
+}
diff --git a/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java b/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java
index 198ac61a3..a4bd5d20e 100644
--- a/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java
+++ b/briar-tests/src/org/briarproject/sync/SimplexMessagingIntegrationTest.java
@@ -54,7 +54,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.Collections;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -132,8 +131,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor, aliceId);
// Derive and store the transport keys
- keyManager.addContact(contactId, Collections.singletonList(transportId),
- master, timestamp, true);
+ keyManager.addContact(contactId, master, timestamp, true);
// Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId);
@@ -198,8 +196,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor, bobId);
// Derive and store the transport keys
- keyManager.addContact(contactId, Collections.singletonList(transportId),
- master, timestamp, false);
+ keyManager.addContact(contactId, master, timestamp, false);
// Set up an event listener
MessageListener listener = new MessageListener();