mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
2 Commits
misc-code-
...
test-immed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33bfef12e4 | ||
|
|
92163d6a99 |
@@ -12,7 +12,7 @@ test:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
|
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom animalSnifferMain animalSnifferTest
|
||||||
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom test
|
- ./gradlew --no-daemon -Djava.security.egd=file:/dev/urandom test --continue
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
# these file change every time but should not be cached
|
# these file change every time but should not be cached
|
||||||
|
|||||||
@@ -9,22 +9,19 @@ import org.briarproject.bramble.api.account.AccountManager;
|
|||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
|
|
||||||
|
|
||||||
class AndroidAccountManager extends AccountManagerImpl
|
class AndroidAccountManager extends AccountManagerImpl
|
||||||
implements AccountManager {
|
implements AccountManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AndroidAccountManager.class.getName());
|
Logger.getLogger(AndroidAccountManager.class.getName());
|
||||||
|
|
||||||
private static final String PREF_DB_KEY = "key";
|
private static final String PREF_DB_KEY = "key";
|
||||||
|
|
||||||
@@ -40,7 +37,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
appContext = app.getApplicationContext();
|
appContext = app.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
protected String loadEncryptedDatabaseKey() {
|
protected String loadEncryptedDatabaseKey() {
|
||||||
@@ -50,7 +47,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getDatabaseKeyFromPreferences() {
|
private String getDatabaseKeyFromPreferences() {
|
||||||
String key = prefs.getString(PREF_DB_KEY, null);
|
String key = prefs.getString(PREF_DB_KEY, null);
|
||||||
@@ -59,7 +56,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
private void migrateDatabaseKeyToFile(String key) {
|
private void migrateDatabaseKeyToFile(String key) {
|
||||||
if (storeEncryptedDatabaseKey(key)) {
|
if (storeEncryptedDatabaseKey(key)) {
|
||||||
if (prefs.edit().remove(PREF_DB_KEY).commit())
|
if (prefs.edit().remove(PREF_DB_KEY).commit())
|
||||||
@@ -84,7 +81,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
return PreferenceManager.getDefaultSharedPreferences(appContext);
|
return PreferenceManager.getDefaultSharedPreferences(appContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
private void deleteAppData(SharedPreferences... clear) {
|
private void deleteAppData(SharedPreferences... clear) {
|
||||||
// Clear and commit shared preferences
|
// Clear and commit shared preferences
|
||||||
for (SharedPreferences prefs : clear) {
|
for (SharedPreferences prefs : clear) {
|
||||||
@@ -100,7 +97,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
for (File child : children) {
|
for (File child : children) {
|
||||||
String name = child.getName();
|
String name = child.getName();
|
||||||
if (!name.equals("lib") && !name.equals("shared_prefs")) {
|
if (!name.equals("lib") && !name.equals("shared_prefs")) {
|
||||||
deleteFileOrDir(child);
|
IoUtils.deleteFileOrDir(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import javax.inject.Inject;
|
|||||||
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
||||||
import static android.content.Intent.ACTION_POWER_CONNECTED;
|
import static android.content.Intent.ACTION_POWER_CONNECTED;
|
||||||
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
|
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
|
||||||
import static android.os.BatteryManager.EXTRA_PLUGGED;
|
import static android.os.BatteryManager.BATTERY_STATUS_CHARGING;
|
||||||
|
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
|
||||||
|
import static android.os.BatteryManager.EXTRA_STATUS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
@@ -46,8 +48,9 @@ class AndroidBatteryManager implements BatteryManager, Service {
|
|||||||
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
|
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
|
||||||
Intent i = appContext.registerReceiver(null, filter);
|
Intent i = appContext.registerReceiver(null, filter);
|
||||||
if (i == null) return false;
|
if (i == null) return false;
|
||||||
int status = i.getIntExtra(EXTRA_PLUGGED, 0);
|
int status = i.getIntExtra(EXTRA_STATUS, -1);
|
||||||
return status != 0;
|
return status == BATTERY_STATUS_CHARGING ||
|
||||||
|
status == BATTERY_STATUS_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import org.briarproject.bramble.api.lifecycle.Service;
|
|||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkStatus;
|
import org.briarproject.bramble.api.network.NetworkStatus;
|
||||||
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.Scheduler;
|
import org.briarproject.bramble.api.system.Scheduler;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@@ -33,17 +34,16 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
|||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
|
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
class AndroidNetworkManager implements NetworkManager, Service {
|
class AndroidNetworkManager implements NetworkManager, Service {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AndroidNetworkManager.class.getName());
|
Logger.getLogger(AndroidNetworkManager.class.getName());
|
||||||
|
|
||||||
// See android.net.wifi.WifiManager
|
// See android.net.wifi.WifiManager
|
||||||
private static final String WIFI_AP_STATE_CHANGED_ACTION =
|
private static final String WIFI_AP_STATE_CHANGED_ACTION =
|
||||||
@@ -56,7 +56,6 @@ class AndroidNetworkManager implements NetworkManager, Service {
|
|||||||
new AtomicReference<>();
|
new AtomicReference<>();
|
||||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private volatile BroadcastReceiver networkStateReceiver = null;
|
private volatile BroadcastReceiver networkStateReceiver = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -90,8 +89,9 @@ class AndroidNetworkManager implements NetworkManager, Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatus getNetworkStatus() {
|
public NetworkStatus getNetworkStatus() {
|
||||||
ConnectivityManager cm = (ConnectivityManager) requireNonNull(
|
ConnectivityManager cm = (ConnectivityManager)
|
||||||
appContext.getSystemService(CONNECTIVITY_SERVICE));
|
appContext.getSystemService(CONNECTIVITY_SERVICE);
|
||||||
|
if (cm == null) throw new AssertionError();
|
||||||
NetworkInfo net = cm.getActiveNetworkInfo();
|
NetworkInfo net = cm.getActiveNetworkInfo();
|
||||||
boolean connected = net != null && net.isConnected();
|
boolean connected = net != null && net.isConnected();
|
||||||
boolean wifi = connected && net.getType() == TYPE_WIFI;
|
boolean wifi = connected && net.getType() == TYPE_WIFI;
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
|||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.util.AndroidUtils;
|
import org.briarproject.bramble.util.AndroidUtils;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@@ -47,11 +48,10 @@ import static android.bluetooth.BluetoothAdapter.STATE_OFF;
|
|||||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||||
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
|
import static android.bluetooth.BluetoothDevice.ACTION_FOUND;
|
||||||
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
|
import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
|
||||||
import static java.util.Collections.shuffle;
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -59,7 +59,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
|||||||
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AndroidBluetoothPlugin.class.getName());
|
Logger.getLogger(AndroidBluetoothPlugin.class.getName());
|
||||||
|
|
||||||
private static final int MAX_DISCOVERY_MS = 10_000;
|
private static final int MAX_DISCOVERY_MS = 10_000;
|
||||||
|
|
||||||
@@ -161,7 +161,11 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void tryToClose(@Nullable BluetoothServerSocket ss) {
|
void tryToClose(@Nullable BluetoothServerSocket ss) {
|
||||||
IoUtils.tryToClose(ss, LOG, WARNING);
|
try {
|
||||||
|
if (ss != null) ss.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,7 +195,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
s.connect();
|
s.connect();
|
||||||
return wrapSocket(s);
|
return wrapSocket(s);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
IoUtils.tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,10 +264,18 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
appContext.unregisterReceiver(receiver);
|
appContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
// Shuffle the addresses so we don't always try the same one first
|
// Shuffle the addresses so we don't always try the same one first
|
||||||
shuffle(addresses);
|
Collections.shuffle(addresses);
|
||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Closeable c) {
|
||||||
|
try {
|
||||||
|
if (c != null) c.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,19 +32,17 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
|
|||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
|
class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
getLogger(AndroidLanTcpPlugin.class.getName());
|
|
||||||
|
|
||||||
private static final byte[] WIFI_AP_ADDRESS_BYTES =
|
private static final byte[] WIFI_AP_ADDRESS_BYTES =
|
||||||
{(byte) 192, (byte) 168, 43, 1};
|
{(byte) 192, (byte) 168, 43, 1};
|
||||||
private static final InetAddress WIFI_AP_ADDRESS;
|
private static final InetAddress WIFI_AP_ADDRESS;
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(AndroidLanTcpPlugin.class.getName());
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES);
|
WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES);
|
||||||
@@ -68,8 +66,10 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener {
|
|||||||
// Don't execute more than one connection status check at a time
|
// Don't execute more than one connection status check at a time
|
||||||
connectionStatusExecutor =
|
connectionStatusExecutor =
|
||||||
new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1);
|
new PoliteExecutor("AndroidLanTcpPlugin", ioExecutor, 1);
|
||||||
connectivityManager = (ConnectivityManager) requireNonNull(
|
ConnectivityManager connectivityManager = (ConnectivityManager)
|
||||||
appContext.getSystemService(CONNECTIVITY_SERVICE));
|
appContext.getSystemService(CONNECTIVITY_SERVICE);
|
||||||
|
if (connectivityManager == null) throw new AssertionError();
|
||||||
|
this.connectivityManager = connectivityManager;
|
||||||
wifiManager = (WifiManager) appContext.getApplicationContext()
|
wifiManager = (WifiManager) appContext.getApplicationContext()
|
||||||
.getSystemService(WIFI_SERVICE);
|
.getSystemService(WIFI_SERVICE);
|
||||||
socketFactory = SocketFactory.getDefault();
|
socketFactory = SocketFactory.getDefault();
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import android.os.PowerManager;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.Backoff;
|
import org.briarproject.bramble.api.plugin.Backoff;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
@@ -25,10 +26,10 @@ import javax.net.SocketFactory;
|
|||||||
import static android.content.Context.MODE_PRIVATE;
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
import static android.content.Context.POWER_SERVICE;
|
import static android.content.Context.POWER_SERVICE;
|
||||||
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
|
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
|
||||||
@NotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
class AndroidTorPlugin extends TorPlugin {
|
class AndroidTorPlugin extends TorPlugin {
|
||||||
|
|
||||||
// This tag may prevent Huawei's power manager from killing us
|
// This tag may prevent Huawei's power manager from killing us
|
||||||
@@ -51,7 +52,8 @@ class AndroidTorPlugin extends TorPlugin {
|
|||||||
appContext.getDir("tor", MODE_PRIVATE));
|
appContext.getDir("tor", MODE_PRIVATE));
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
PowerManager pm = (PowerManager)
|
PowerManager pm = (PowerManager)
|
||||||
requireNonNull(appContext.getSystemService(POWER_SERVICE));
|
appContext.getSystemService(POWER_SERVICE);
|
||||||
|
if (pm == null) throw new AssertionError();
|
||||||
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
||||||
WAKE_LOCK_TAG, 1, MINUTES);
|
WAKE_LOCK_TAG, 1, MINUTES);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.plugin.tor;
|
package org.briarproject.bramble.plugin.tor;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
@@ -25,15 +26,12 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AndroidTorPluginFactory.class.getName());
|
Logger.getLogger(AndroidTorPluginFactory.class.getName());
|
||||||
|
|
||||||
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
private static final int MAX_LATENCY = 30 * 1000; // 30 seconds
|
||||||
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
private static final int MAX_IDLE_TIME = 30 * 1000; // 30 seconds
|
||||||
@@ -104,7 +102,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Use position-independent executable for SDK >= 16
|
// Use position-independent executable for SDK >= 16
|
||||||
if (SDK_INT >= 16) architecture += "_pie";
|
if (Build.VERSION.SDK_INT >= 16) architecture += "_pie";
|
||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.content.Context.TELEPHONY_SERVICE;
|
import static android.content.Context.TELEPHONY_SERVICE;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidLocationUtils implements LocationUtils {
|
class AndroidLocationUtils implements LocationUtils {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AndroidLocationUtils.class.getName());
|
Logger.getLogger(AndroidLocationUtils.class.getName());
|
||||||
|
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
|
|
||||||
@@ -60,14 +59,14 @@ class AndroidLocationUtils implements LocationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getCountryFromPhoneNetwork() {
|
private String getCountryFromPhoneNetwork() {
|
||||||
TelephonyManager tm = (TelephonyManager)
|
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
|
||||||
appContext.getSystemService(TELEPHONY_SERVICE);
|
TelephonyManager tm = (TelephonyManager) o;
|
||||||
return tm == null ? "" : tm.getNetworkCountryIso();
|
return tm.getNetworkCountryIso();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCountryFromSimCard() {
|
private String getCountryFromSimCard() {
|
||||||
TelephonyManager tm = (TelephonyManager)
|
Object o = appContext.getSystemService(TELEPHONY_SERVICE);
|
||||||
appContext.getSystemService(TELEPHONY_SERVICE);
|
TelephonyManager tm = (TelephonyManager) o;
|
||||||
return tm == null ? "" : tm.getSimCountryIso();
|
return tm.getSimCountryIso();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.system;
|
package org.briarproject.bramble.system;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@@ -8,6 +7,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.wifi.WifiConfiguration;
|
import android.net.wifi.WifiConfiguration;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.StrictMode;
|
import android.os.StrictMode;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -22,14 +22,11 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static android.content.Context.WIFI_SERVICE;
|
import static android.content.Context.WIFI_SERVICE;
|
||||||
import static android.os.Build.FINGERPRINT;
|
|
||||||
import static android.os.Build.SERIAL;
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static android.provider.Settings.Secure.ANDROID_ID;
|
import static android.provider.Settings.Secure.ANDROID_ID;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
|
||||||
|
|
||||||
private static final int SEED_LENGTH = 32;
|
private static final int SEED_LENGTH = 32;
|
||||||
|
|
||||||
@@ -40,28 +37,25 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
|||||||
appContext = app.getApplicationContext();
|
appContext = app.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("HardwareIds")
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
|
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
|
||||||
super.writeToEntropyPool(out);
|
super.writeToEntropyPool(out);
|
||||||
out.writeInt(android.os.Process.myPid());
|
out.writeInt(android.os.Process.myPid());
|
||||||
out.writeInt(android.os.Process.myTid());
|
out.writeInt(android.os.Process.myTid());
|
||||||
out.writeInt(android.os.Process.myUid());
|
out.writeInt(android.os.Process.myUid());
|
||||||
if (FINGERPRINT != null) out.writeUTF(FINGERPRINT);
|
if (Build.FINGERPRINT != null) out.writeUTF(Build.FINGERPRINT);
|
||||||
if (SERIAL != null) out.writeUTF(SERIAL);
|
if (Build.SERIAL != null) out.writeUTF(Build.SERIAL);
|
||||||
ContentResolver contentResolver = appContext.getContentResolver();
|
ContentResolver contentResolver = appContext.getContentResolver();
|
||||||
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
|
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
|
||||||
if (id != null) out.writeUTF(id);
|
if (id != null) out.writeUTF(id);
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
WifiManager wm = (WifiManager) appContext.getApplicationContext()
|
WifiManager wm =
|
||||||
.getSystemService(WIFI_SERVICE);
|
(WifiManager) appContext.getSystemService(WIFI_SERVICE);
|
||||||
if (wm != null) {
|
|
||||||
List<WifiConfiguration> configs = wm.getConfiguredNetworks();
|
List<WifiConfiguration> configs = wm.getConfiguredNetworks();
|
||||||
if (configs != null) {
|
if (configs != null) {
|
||||||
for (WifiConfiguration config : configs)
|
for (WifiConfiguration config : configs)
|
||||||
parcel.writeParcelable(config, 0);
|
parcel.writeParcelable(config, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (bt != null) {
|
if (bt != null) {
|
||||||
for (BluetoothDevice device : bt.getBondedDevices())
|
for (BluetoothDevice device : bt.getBondedDevices())
|
||||||
@@ -76,18 +70,20 @@ class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
|||||||
// Silence strict mode
|
// Silence strict mode
|
||||||
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
|
StrictMode.ThreadPolicy tp = StrictMode.allowThreadDiskWrites();
|
||||||
super.writeSeed();
|
super.writeSeed();
|
||||||
if (SDK_INT >= 16 && SDK_INT <= 18) applyOpenSslFix();
|
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT <= 18)
|
||||||
|
applyOpenSslFix();
|
||||||
StrictMode.setThreadPolicy(tp);
|
StrictMode.setThreadPolicy(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
||||||
private void applyOpenSslFix() {
|
private void applyOpenSslFix() {
|
||||||
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(SEED_LENGTH);
|
byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
|
||||||
|
SEED_LENGTH);
|
||||||
try {
|
try {
|
||||||
// Seed the OpenSSL PRNG
|
// Seed the OpenSSL PRNG
|
||||||
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||||
.getMethod("RAND_seed", byte[].class)
|
.getMethod("RAND_seed", byte[].class)
|
||||||
.invoke(null, (Object) seed);
|
.invoke(null, seed);
|
||||||
// Mix the output of the Linux PRNG into the OpenSSL PRNG
|
// Mix the output of the Linux PRNG into the OpenSSL PRNG
|
||||||
int bytesRead = (Integer) Class.forName(
|
int bytesRead = (Integer) Class.forName(
|
||||||
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||||
|
|||||||
@@ -3,20 +3,17 @@ package org.briarproject.bramble.util;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static android.content.Context.MODE_PRIVATE;
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
import static android.os.Build.CPU_ABI;
|
|
||||||
import static android.os.Build.CPU_ABI2;
|
|
||||||
import static android.os.Build.SUPPORTED_ABIS;
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|
||||||
|
|
||||||
public class AndroidUtils {
|
public class AndroidUtils {
|
||||||
|
|
||||||
@@ -25,13 +22,14 @@ public class AndroidUtils {
|
|||||||
|
|
||||||
private static final String STORED_REPORTS = "dev-reports";
|
private static final String STORED_REPORTS = "dev-reports";
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static Collection<String> getSupportedArchitectures() {
|
public static Collection<String> getSupportedArchitectures() {
|
||||||
List<String> abis = new ArrayList<>();
|
List<String> abis = new ArrayList<>();
|
||||||
if (SDK_INT >= 21) {
|
if (SDK_INT >= 21) {
|
||||||
abis.addAll(asList(SUPPORTED_ABIS));
|
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
|
||||||
} else {
|
} else {
|
||||||
abis.add(CPU_ABI);
|
abis.add(Build.CPU_ABI);
|
||||||
if (CPU_ABI2 != null) abis.add(CPU_ABI2);
|
if (Build.CPU_ABI2 != null) abis.add(Build.CPU_ABI2);
|
||||||
}
|
}
|
||||||
return abis;
|
return abis;
|
||||||
}
|
}
|
||||||
@@ -51,7 +49,7 @@ public class AndroidUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isValidBluetoothAddress(String address) {
|
private static boolean isValidBluetoothAddress(String address) {
|
||||||
return !isNullOrEmpty(address)
|
return !StringUtils.isNullOrEmpty(address)
|
||||||
&& BluetoothAdapter.checkBluetoothAddress(address)
|
&& BluetoothAdapter.checkBluetoothAddress(address)
|
||||||
&& !address.equals(FAKE_BLUETOOTH_ADDRESS);
|
&& !address.equals(FAKE_BLUETOOTH_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,19 +10,17 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class RenewableWakeLock {
|
public class RenewableWakeLock {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(RenewableWakeLock.class.getName());
|
Logger.getLogger(RenewableWakeLock.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically release the lock this many milliseconds after it's due
|
* Automatically release the lock this many milliseconds after it's due
|
||||||
@@ -38,12 +36,10 @@ public class RenewableWakeLock {
|
|||||||
private final Runnable renewTask;
|
private final Runnable renewTask;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
@GuardedBy("lock")
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PowerManager.WakeLock wakeLock;
|
private PowerManager.WakeLock wakeLock; // Locking: lock
|
||||||
@GuardedBy("lock")
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ScheduledFuture future;
|
private ScheduledFuture future; // Locking: lock
|
||||||
|
|
||||||
public RenewableWakeLock(PowerManager powerManager,
|
public RenewableWakeLock(PowerManager powerManager,
|
||||||
ScheduledExecutorService scheduler, int levelAndFlags, String tag,
|
ScheduledExecutorService scheduler, int levelAndFlags, String tag,
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
package org.briarproject.bramble.api;
|
package org.briarproject.bramble.api;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around a byte array, to allow it to be stored in maps etc.
|
* A wrapper around a byte array, to allow it to be stored in maps etc.
|
||||||
*/
|
*/
|
||||||
@@ -57,7 +56,8 @@ public class Bytes implements Comparable<Bytes> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "(" + toHexString(getBytes()) + ")";
|
return getClass().getSimpleName() +
|
||||||
|
"(" + StringUtils.toHexString(getBytes()) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BytesComparator implements Comparator<Bytes> {
|
public static class BytesComparator implements Comparator<Bytes> {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.api;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@@ -9,8 +10,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableSet;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class Multiset<T> {
|
public class Multiset<T> {
|
||||||
@@ -97,6 +96,6 @@ public class Multiset<T> {
|
|||||||
* is unmodifiable.
|
* is unmodifiable.
|
||||||
*/
|
*/
|
||||||
public Set<T> keySet() {
|
public Set<T> keySet() {
|
||||||
return unmodifiableSet(map.keySet());
|
return Collections.unmodifiableSet(map.keySet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class BdfMessageContext {
|
public class BdfMessageContext {
|
||||||
@@ -24,7 +23,7 @@ public class BdfMessageContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BdfMessageContext(BdfDictionary dictionary) {
|
public BdfMessageContext(BdfDictionary dictionary) {
|
||||||
this(dictionary, emptyList());
|
this(dictionary, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary getDictionary() {
|
public BdfDictionary getDictionary() {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -24,7 +23,7 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
|
|||||||
public abstract class BdfMessageValidator implements MessageValidator {
|
public abstract class BdfMessageValidator implements MessageValidator {
|
||||||
|
|
||||||
protected static final Logger LOG =
|
protected static final Logger LOG =
|
||||||
getLogger(BdfMessageValidator.class.getName());
|
Logger.getLogger(BdfMessageValidator.class.getName());
|
||||||
|
|
||||||
protected final ClientHelper clientHelper;
|
protected final ClientHelper clientHelper;
|
||||||
protected final MetadataEncoder metadataEncoder;
|
protected final MetadataEncoder metadataEncoder;
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.FAILED;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface ContactManager {
|
public interface ContactManager {
|
||||||
|
|
||||||
@@ -54,35 +52,6 @@ public interface ContactManager {
|
|||||||
long timestamp, boolean alice, boolean verified, boolean active)
|
long timestamp, boolean alice, boolean verified, boolean active)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the static link that needs to be sent to the contact to be added.
|
|
||||||
*/
|
|
||||||
String getRemoteContactLink();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given link is syntactically valid.
|
|
||||||
*/
|
|
||||||
boolean isValidRemoteContactLink(String link);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests a new contact to be added via the given {@code link}.
|
|
||||||
*
|
|
||||||
* @param link The link received from the contact we want to add.
|
|
||||||
* @param alias The alias the user has given this contact.
|
|
||||||
* @return A PendingContact representing the contact to be added.
|
|
||||||
*/
|
|
||||||
PendingContact addRemoteContactRequest(String link, String alias);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of {@link PendingContact}s.
|
|
||||||
*/
|
|
||||||
Collection<PendingContact> getPendingContacts();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a {@link PendingContact} that is in state {@link FAILED}.
|
|
||||||
*/
|
|
||||||
void removePendingContact(PendingContact pendingContact);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the contact with the given ID.
|
* Returns the contact with the given ID.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
public class PendingContact {
|
|
||||||
|
|
||||||
public enum PendingContactState {
|
|
||||||
WAITING_FOR_CONNECTION,
|
|
||||||
CONNECTED,
|
|
||||||
ADDING_CONTACT,
|
|
||||||
FAILED
|
|
||||||
}
|
|
||||||
|
|
||||||
private final PendingContactId id;
|
|
||||||
private final String alias;
|
|
||||||
private final PendingContactState state;
|
|
||||||
private final long timestamp;
|
|
||||||
|
|
||||||
public PendingContact(PendingContactId id, String alias,
|
|
||||||
PendingContactState state, long timestamp) {
|
|
||||||
this.id = id;
|
|
||||||
this.alias = alias;
|
|
||||||
this.state = state;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlias() {
|
|
||||||
return alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PendingContactState getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return id.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return o instanceof PendingContact &&
|
|
||||||
id.equals(((PendingContact) o).id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
|
||||||
|
|
||||||
public class PendingContactId extends UniqueId {
|
|
||||||
|
|
||||||
public PendingContactId(byte[] id) {
|
|
||||||
super(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.contact.event;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.PendingContact.PendingContactState;
|
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An event that is broadcast when a pending contact's state is changed.
|
|
||||||
*/
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
public class PendingContactStateChangedEvent extends Event {
|
|
||||||
|
|
||||||
private final PendingContactId id;
|
|
||||||
private final PendingContactState state;
|
|
||||||
|
|
||||||
public PendingContactStateChangedEvent(PendingContactId id,
|
|
||||||
PendingContactState state) {
|
|
||||||
this.id = id;
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PendingContactId getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PendingContactState getPendingContactState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.Bytes;
|
|||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -23,9 +24,9 @@ public class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
* );
|
* );
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public static BdfDictionary of(BdfEntry... entries) {
|
public static BdfDictionary of(Entry<String, ?>... entries) {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
for (BdfEntry e : entries) d.put(e.getKey(), e.getValue());
|
for (Entry<String, ?> e : entries) d.put(e.getKey(), e.getValue());
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import org.briarproject.bramble.api.Bytes;
|
|||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@@ -22,7 +22,7 @@ public class BdfList extends ArrayList<Object> {
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public static BdfList of(Object... items) {
|
public static BdfList of(Object... items) {
|
||||||
return new BdfList(asList(items));
|
return new BdfList(Arrays.asList(items));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList() {
|
public BdfList() {
|
||||||
@@ -33,7 +33,6 @@ public class BdfList extends ArrayList<Object> {
|
|||||||
super(items);
|
super(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
private boolean isInRange(int index) {
|
private boolean isInRange(int index) {
|
||||||
return index >= 0 && index < size();
|
return index >= 0 && index < size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ package org.briarproject.bramble.api.db;
|
|||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around a database transaction. Transactions are not thread-safe.
|
* A wrapper around a database transaction. Transactions are not thread-safe.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +53,7 @@ public class Transaction {
|
|||||||
* Returns any events attached to the transaction.
|
* Returns any events attached to the transaction.
|
||||||
*/
|
*/
|
||||||
public List<Event> getEvents() {
|
public List<Event> getEvents() {
|
||||||
if (events == null) return emptyList();
|
if (events == null) return Collections.emptyList();
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package org.briarproject.bramble.api.identity;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.Nameable;
|
import org.briarproject.bramble.api.Nameable;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pseudonym for a user.
|
* A pseudonym for a user.
|
||||||
@@ -28,7 +28,7 @@ public class Author implements Nameable {
|
|||||||
|
|
||||||
public Author(AuthorId id, int formatVersion, String name,
|
public Author(AuthorId id, int formatVersion, String name,
|
||||||
byte[] publicKey) {
|
byte[] publicKey) {
|
||||||
int nameLength = toUtf8(name).length;
|
int nameLength = StringUtils.toUtf8(name).length;
|
||||||
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
|
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
|
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public interface TorConstants {
|
|||||||
String PREF_TOR_NETWORK = "network2";
|
String PREF_TOR_NETWORK = "network2";
|
||||||
String PREF_TOR_PORT = "port";
|
String PREF_TOR_PORT = "port";
|
||||||
String PREF_TOR_MOBILE = "useMobileData";
|
String PREF_TOR_MOBILE = "useMobileData";
|
||||||
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
|
|
||||||
|
|
||||||
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
||||||
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.briarproject.bramble.api.plugin;
|
package org.briarproject.bramble.api.plugin;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-safe wrapper for a namespaced string that uniquely identifies a
|
* Type-safe wrapper for a namespaced string that uniquely identifies a
|
||||||
@@ -11,12 +11,12 @@ public class TransportId {
|
|||||||
/**
|
/**
|
||||||
* The maximum length of a transport identifier in UTF-8 bytes.
|
* The maximum length of a transport identifier in UTF-8 bytes.
|
||||||
*/
|
*/
|
||||||
public static final int MAX_TRANSPORT_ID_LENGTH = 100;
|
public static int MAX_TRANSPORT_ID_LENGTH = 100;
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
||||||
public TransportId(String id) {
|
public TransportId(String id) {
|
||||||
int length = toUtf8(id).length;
|
int length = StringUtils.toUtf8(id).length;
|
||||||
if (length == 0 || length > MAX_TRANSPORT_ID_LENGTH)
|
if (length == 0 || length > MAX_TRANSPORT_ID_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package org.briarproject.bramble.api.sync;
|
package org.briarproject.bramble.api.sync;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-safe wrapper for a namespaced string that uniquely identifies a sync
|
* Type-safe wrapper for a namespaced string that uniquely identifies a sync
|
||||||
* client.
|
* client.
|
||||||
@@ -17,12 +16,12 @@ public class ClientId implements Comparable<ClientId> {
|
|||||||
/**
|
/**
|
||||||
* The maximum length of a client identifier in UTF-8 bytes.
|
* The maximum length of a client identifier in UTF-8 bytes.
|
||||||
*/
|
*/
|
||||||
public static final int MAX_CLIENT_ID_LENGTH = 100;
|
public static int MAX_CLIENT_ID_LENGTH = 100;
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
|
||||||
public ClientId(String id) {
|
public ClientId(String id) {
|
||||||
int length = toUtf8(id).length;
|
int length = StringUtils.toUtf8(id).length;
|
||||||
if (length == 0 || length > MAX_CLIENT_ID_LENGTH)
|
if (length == 0 || length > MAX_CLIENT_ID_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import org.briarproject.bramble.api.db.Metadata;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class MessageContext {
|
public class MessageContext {
|
||||||
@@ -23,7 +22,7 @@ public class MessageContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public MessageContext(Metadata metadata) {
|
public MessageContext(Metadata metadata) {
|
||||||
this(metadata, emptyList());
|
this(metadata, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Metadata getMetadata() {
|
public Metadata getMetadata() {
|
||||||
|
|||||||
@@ -38,13 +38,6 @@ public interface ClientVersioningManager {
|
|||||||
Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
||||||
ClientId clientId, int majorVersion) throws DbException;
|
ClientId clientId, int majorVersion) throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the minor version of the given client that is supported by the
|
|
||||||
* given contact, or -1 if the contact does not support the client.
|
|
||||||
*/
|
|
||||||
int getClientMinorVersion(Transaction txn, ContactId contactId,
|
|
||||||
ClientId clientId, int majorVersion) throws DbException;
|
|
||||||
|
|
||||||
interface ClientVersioningHook {
|
interface ClientVersioningHook {
|
||||||
|
|
||||||
void onClientVisibilityChanging(Transaction txn, Contact c,
|
void onClientVisibilityChanging(Transaction txn, Contact c,
|
||||||
|
|||||||
@@ -8,21 +8,17 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class IoUtils {
|
public class IoUtils {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(IoUtils.class.getName());
|
private static final Logger LOG = Logger.getLogger(IoUtils.class.getName());
|
||||||
|
|
||||||
public static void deleteFileOrDir(File f) {
|
public static void deleteFileOrDir(File f) {
|
||||||
if (f.isFile()) {
|
if (f.isFile()) {
|
||||||
@@ -58,35 +54,16 @@ public class IoUtils {
|
|||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(in, LOG, WARNING);
|
tryToClose(in);
|
||||||
tryToClose(out, LOG, WARNING);
|
tryToClose(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tryToClose(@Nullable Closeable c, Logger logger,
|
private static void tryToClose(@Nullable Closeable c) {
|
||||||
Level level) {
|
|
||||||
try {
|
try {
|
||||||
if (c != null) c.close();
|
if (c != null) c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(logger, level, e);
|
// We did our best
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void tryToClose(@Nullable Socket s, Logger logger,
|
|
||||||
Level level) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(logger, level, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void tryToClose(@Nullable ServerSocket ss, Logger logger,
|
|
||||||
Level level) {
|
|
||||||
try {
|
|
||||||
if (ss != null) ss.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(logger, level, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public class OsUtils {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static final String os = System.getProperty("os.name");
|
private static final String os = System.getProperty("os.name");
|
||||||
@Nullable
|
@Nullable
|
||||||
|
private static final String version = System.getProperty("os.version");
|
||||||
|
@Nullable
|
||||||
private static final String vendor = System.getProperty("java.vendor");
|
private static final String vendor = System.getProperty("java.vendor");
|
||||||
|
|
||||||
public static boolean isWindows() {
|
public static boolean isWindows() {
|
||||||
|
|||||||
@@ -7,15 +7,13 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class ValidationUtils {
|
public class ValidationUtils {
|
||||||
|
|
||||||
public static void checkLength(@Nullable String s, int minLength,
|
public static void checkLength(@Nullable String s, int minLength,
|
||||||
int maxLength) throws FormatException {
|
int maxLength) throws FormatException {
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
int length = toUtf8(s).length;
|
int length = StringUtils.toUtf8(s).length;
|
||||||
if (length < minLength) throw new FormatException();
|
if (length < minLength) throw new FormatException();
|
||||||
if (length > maxLength) throw new FormatException();
|
if (length > maxLength) throw new FormatException();
|
||||||
}
|
}
|
||||||
@@ -23,7 +21,7 @@ public class ValidationUtils {
|
|||||||
|
|
||||||
public static void checkLength(@Nullable String s, int length)
|
public static void checkLength(@Nullable String s, int length)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
if (s != null && toUtf8(s).length != length)
|
if (s != null && StringUtils.toUtf8(s).length != length)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.util.Collections;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -20,15 +19,15 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
public void testConstructors() {
|
public void testConstructors() {
|
||||||
assertEquals(Collections.<String, Object>emptyMap(),
|
assertEquals(Collections.<String, Object>emptyMap(),
|
||||||
new BdfDictionary());
|
new BdfDictionary());
|
||||||
assertEquals(singletonMap("foo", NULL_VALUE),
|
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
|
||||||
new BdfDictionary(singletonMap("foo", NULL_VALUE)));
|
new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFactoryMethod() {
|
public void testFactoryMethod() {
|
||||||
assertEquals(Collections.<String, Object>emptyMap(),
|
assertEquals(Collections.<String, Object>emptyMap(),
|
||||||
BdfDictionary.of());
|
BdfDictionary.of());
|
||||||
assertEquals(singletonMap("foo", NULL_VALUE),
|
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
|
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +67,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeySetIteratorIsOrderedByKeys() {
|
public void testKeySetIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
@@ -87,7 +86,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValuesIteratorIsOrderedByKeys() {
|
public void testValuesIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
@@ -106,7 +105,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntrySetIteratorIsOrderedByKeys() {
|
public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
|
|||||||
@@ -5,31 +5,26 @@ import org.briarproject.bramble.api.FormatException;
|
|||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class BdfListTest extends BrambleTestCase {
|
public class BdfListTest extends BrambleTestCase {
|
||||||
|
|
||||||
private final Random random = new Random();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstructors() {
|
public void testConstructors() {
|
||||||
assertEquals(emptyList(), new BdfList());
|
assertEquals(Collections.emptyList(), new BdfList());
|
||||||
assertEquals(asList(1, 2, NULL_VALUE),
|
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
|
||||||
new BdfList(asList(1, 2, NULL_VALUE)));
|
new BdfList(Arrays.asList(1, 2, NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFactoryMethod() {
|
public void testFactoryMethod() {
|
||||||
assertEquals(emptyList(), BdfList.of());
|
assertEquals(Collections.emptyList(), BdfList.of());
|
||||||
assertEquals(asList(1, 2, NULL_VALUE),
|
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
|
||||||
BdfList.of(1, 2, NULL_VALUE));
|
BdfList.of(1, 2, NULL_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,21 +64,22 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIndexOutOfBoundsReturnsDefaultValue() {
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception {
|
||||||
BdfList list = BdfList.of(1, 2, 3);
|
BdfList list = BdfList.of(1, 2, 3);
|
||||||
boolean defaultBoolean = random.nextBoolean();
|
boolean defaultBoolean = true;
|
||||||
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
|
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
|
||||||
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
|
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
|
||||||
Long defaultLong = random.nextLong();
|
Long defaultLong = 123L;
|
||||||
assertEquals(defaultLong, list.getLong(-1, defaultLong));
|
assertEquals(defaultLong, list.getLong(-1, defaultLong));
|
||||||
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
||||||
Double defaultDouble = random.nextDouble();
|
Double defaultDouble = 1.23;
|
||||||
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
|
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
|
||||||
assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
|
assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
|
||||||
String defaultString = getRandomString(123);
|
String defaultString = "123";
|
||||||
assertEquals(defaultString, list.getString(-1, defaultString));
|
assertEquals(defaultString, list.getString(-1, defaultString));
|
||||||
assertEquals(defaultString, list.getString(3, defaultString));
|
assertEquals(defaultString, list.getString(3, defaultString));
|
||||||
byte[] defaultBytes = getRandomBytes(123);
|
byte[] defaultBytes = new byte[] {1, 2, 3};
|
||||||
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
|
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
|
||||||
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
|
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
|
||||||
BdfList defaultList = BdfList.of(1, 2, 3);
|
BdfList defaultList = BdfList.of(1, 2, 3);
|
||||||
@@ -99,17 +95,18 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWrongTypeReturnsDefaultValue() {
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public void testWrongTypeReturnsDefaultValue() throws Exception {
|
||||||
BdfList list = BdfList.of(1, 2, 3, true);
|
BdfList list = BdfList.of(1, 2, 3, true);
|
||||||
boolean defaultBoolean = random.nextBoolean();
|
boolean defaultBoolean = true;
|
||||||
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
|
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
|
||||||
Long defaultLong = random.nextLong();
|
Long defaultLong = 123L;
|
||||||
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
||||||
Double defaultDouble = random.nextDouble();
|
Double defaultDouble = 1.23;
|
||||||
assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
|
assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
|
||||||
String defaultString = getRandomString(123);
|
String defaultString = "123";
|
||||||
assertEquals(defaultString, list.getString(0, defaultString));
|
assertEquals(defaultString, list.getString(0, defaultString));
|
||||||
byte[] defaultBytes = getRandomBytes(123);
|
byte[] defaultBytes = new byte[] {1, 2, 3};
|
||||||
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
|
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
|
||||||
BdfList defaultList = BdfList.of(1, 2, 3);
|
BdfList defaultList = BdfList.of(1, 2, 3);
|
||||||
assertEquals(defaultList, list.getList(0, defaultList));
|
assertEquals(defaultList, list.getList(0, defaultList));
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import org.briarproject.bramble.api.sync.Group;
|
|||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -23,7 +25,6 @@ import java.util.Random;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.sort;
|
|
||||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
@@ -32,7 +33,6 @@ import static org.briarproject.bramble.api.properties.TransportPropertyConstants
|
|||||||
import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
|
import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
|
|
||||||
public class TestUtils {
|
public class TestUtils {
|
||||||
@@ -48,10 +48,8 @@ public class TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteTestDirectory(File testDir) {
|
public static void deleteTestDirectory(File testDir) {
|
||||||
deleteFileOrDir(testDir);
|
IoUtils.deleteFileOrDir(testDir);
|
||||||
// Delete parent directory only if it's empty
|
testDir.getParentFile().delete(); // Delete if empty
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
testDir.getParentFile().delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getRandomBytes(int length) {
|
public static byte[] getRandomBytes(int length) {
|
||||||
@@ -147,7 +145,7 @@ public class TestUtils {
|
|||||||
if (size == 0) throw new IllegalArgumentException();
|
if (size == 0) throw new IllegalArgumentException();
|
||||||
List<Double> sorted = new ArrayList<>(size);
|
List<Double> sorted = new ArrayList<>(size);
|
||||||
for (Number n : samples) sorted.add(n.doubleValue());
|
for (Number n : samples) sorted.add(n.doubleValue());
|
||||||
sort(sorted);
|
Collections.sort(sorted);
|
||||||
if (size % 2 == 1) return sorted.get(size / 2);
|
if (size % 2 == 1) return sorted.get(size / 2);
|
||||||
double low = sorted.get(size / 2 - 1), high = sorted.get(size / 2);
|
double low = sorted.get(size / 2 - 1), high = sorted.get(size / 2);
|
||||||
return (low + high) / 2;
|
return (low + high) / 2;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
|
||||||
import static java.util.logging.Level.FINE;
|
import static java.util.logging.Level.FINE;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +42,7 @@ public class PoliteExecutor implements Executor {
|
|||||||
int maxConcurrentTasks) {
|
int maxConcurrentTasks) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.maxConcurrentTasks = maxConcurrentTasks;
|
this.maxConcurrentTasks = maxConcurrentTasks;
|
||||||
log = getLogger(tag);
|
log = Logger.getLogger(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.FINE;
|
import static java.util.logging.Level.FINE;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -23,7 +22,7 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
|
|||||||
RejectedExecutionHandler handler) {
|
RejectedExecutionHandler handler) {
|
||||||
super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue,
|
super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue,
|
||||||
handler);
|
handler);
|
||||||
log = getLogger(tag);
|
log = Logger.getLogger(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -17,21 +19,19 @@ import java.io.InputStreamReader;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.deleteFileOrDir;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||||
|
|
||||||
@NotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
class AccountManagerImpl implements AccountManager {
|
class AccountManagerImpl implements AccountManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(AccountManagerImpl.class.getName());
|
Logger.getLogger(AccountManagerImpl.class.getName());
|
||||||
|
|
||||||
private static final String DB_KEY_FILENAME = "db.key";
|
private static final String DB_KEY_FILENAME = "db.key";
|
||||||
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
|
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
|
||||||
@@ -68,7 +68,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
return databaseKey;
|
return databaseKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
@Nullable
|
@Nullable
|
||||||
protected String loadEncryptedDatabaseKey() {
|
protected String loadEncryptedDatabaseKey() {
|
||||||
String key = readDbKeyFromFile(dbKeyFile);
|
String key = readDbKeyFromFile(dbKeyFile);
|
||||||
@@ -83,7 +83,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
@Nullable
|
@Nullable
|
||||||
private String readDbKeyFromFile(File f) {
|
private String readDbKeyFromFile(File f) {
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
@@ -102,8 +102,8 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
boolean storeEncryptedDatabaseKey(String hex) {
|
protected boolean storeEncryptedDatabaseKey(String hex) {
|
||||||
LOG.info("Storing database key in file");
|
LOG.info("Storing database key in file");
|
||||||
// Create the directory if necessary
|
// Create the directory if necessary
|
||||||
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
|
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
|
||||||
@@ -140,7 +140,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
private void writeDbKeyToFile(String key, File f) throws IOException {
|
private void writeDbKeyToFile(String key, File f) throws IOException {
|
||||||
FileOutputStream out = new FileOutputStream(f);
|
FileOutputStream out = new FileOutputStream(f);
|
||||||
out.write(key.getBytes("UTF-8"));
|
out.write(key.getBytes("UTF-8"));
|
||||||
@@ -170,7 +170,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
|
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
|
||||||
byte[] plaintext = key.getBytes();
|
byte[] plaintext = key.getBytes();
|
||||||
byte[] ciphertext = crypto.encryptWithPassword(plaintext, password);
|
byte[] ciphertext = crypto.encryptWithPassword(plaintext, password);
|
||||||
@@ -181,8 +181,8 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
public void deleteAccount() {
|
public void deleteAccount() {
|
||||||
synchronized (stateChangeLock) {
|
synchronized (stateChangeLock) {
|
||||||
LOG.info("Deleting account");
|
LOG.info("Deleting account");
|
||||||
deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
||||||
deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
||||||
databaseKey = null;
|
databaseKey = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("stateChangeLock")
|
// Locking: stateChangeLock
|
||||||
@Nullable
|
@Nullable
|
||||||
private SecretKey loadAndDecryptDatabaseKey(String password) {
|
private SecretKey loadAndDecryptDatabaseKey(String password) {
|
||||||
String hex = loadEncryptedDatabaseKey();
|
String hex = loadEncryptedDatabaseKey();
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
|
import static org.briarproject.bramble.api.contact.RecordTypes.CONTACT_INFO;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
@@ -55,7 +54,7 @@ import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
|||||||
class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ContactExchangeTaskImpl.class.getName());
|
Logger.getLogger(ContactExchangeTaskImpl.class.getName());
|
||||||
|
|
||||||
private static final String SIGNING_LABEL_EXCHANGE =
|
private static final String SIGNING_LABEL_EXCHANGE =
|
||||||
"org.briarproject.briar.contact/EXCHANGE";
|
"org.briarproject.briar.contact/EXCHANGE";
|
||||||
@@ -191,7 +190,6 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
streamWriter.sendEndOfStream();
|
streamWriter.sendEndOfStream();
|
||||||
// Skip any remaining records from the incoming stream
|
// Skip any remaining records from the incoming stream
|
||||||
try {
|
try {
|
||||||
//noinspection InfiniteLoopStatement
|
|
||||||
while (true) recordReader.readRecord();
|
while (true) recordReader.readRecord();
|
||||||
} catch (EOFException expected) {
|
} catch (EOFException expected) {
|
||||||
LOG.info("End of stream");
|
LOG.info("End of stream");
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package org.briarproject.bramble.contact;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -21,16 +19,12 @@ import org.briarproject.bramble.api.transport.KeyManager;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.WAITING_FOR_CONNECTION;
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
||||||
@@ -42,12 +36,6 @@ import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ContactManagerImpl implements ContactManager {
|
class ContactManagerImpl implements ContactManager {
|
||||||
|
|
||||||
private static final int LINK_LENGTH = 64;
|
|
||||||
private static final String REMOTE_CONTACT_LINK =
|
|
||||||
"briar://" + getRandomBase32String(LINK_LENGTH);
|
|
||||||
private static final Pattern LINK_REGEX =
|
|
||||||
Pattern.compile("(briar://)?([a-z2-7]{" + LINK_LENGTH + "})");
|
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final KeyManager keyManager;
|
private final KeyManager keyManager;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
@@ -96,48 +84,6 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
verified, active));
|
verified, active));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRemoteContactLink() {
|
|
||||||
// TODO replace with real implementation
|
|
||||||
return REMOTE_CONTACT_LINK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
|
||||||
private static String getRandomBase32String(int length) {
|
|
||||||
Random random = new Random();
|
|
||||||
char[] c = new char[length];
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
int character = random.nextInt(32);
|
|
||||||
if (character < 26) c[i] = (char) ('a' + character);
|
|
||||||
else c[i] = (char) ('2' + (character - 26));
|
|
||||||
}
|
|
||||||
return new String(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidRemoteContactLink(String link) {
|
|
||||||
return LINK_REGEX.matcher(link).matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PendingContact addRemoteContactRequest(String link, String alias) {
|
|
||||||
// TODO replace with real implementation
|
|
||||||
PendingContactId id = new PendingContactId(link.getBytes());
|
|
||||||
return new PendingContact(id, alias, WAITING_FOR_CONNECTION,
|
|
||||||
System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<PendingContact> getPendingContacts() {
|
|
||||||
// TODO replace with real implementation
|
|
||||||
return emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removePendingContact(PendingContact pendingContact) {
|
|
||||||
// TODO replace with real implementation
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Contact getContact(ContactId c) throws DbException {
|
public Contact getContact(ContactId c) throws DbException {
|
||||||
return db.transactionWithResult(true, txn -> db.getContact(txn, c));
|
return db.transactionWithResult(true, txn -> db.getContact(txn, c));
|
||||||
|
|||||||
@@ -2,20 +2,18 @@ package org.briarproject.bramble.crypto;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AsciiArmour {
|
class AsciiArmour {
|
||||||
|
|
||||||
static String wrap(byte[] b, int lineLength) {
|
static String wrap(byte[] b, int lineLength) {
|
||||||
String wrapped = toHexString(b);
|
String wrapped = StringUtils.toHexString(b);
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
int length = wrapped.length();
|
int length = wrapped.length();
|
||||||
for (int i = 0; i < length; i += lineLength) {
|
for (int i = 0; i < length; i += lineLength) {
|
||||||
int end = Math.min(i + lineLength, length);
|
int end = Math.min(i + lineLength, length);
|
||||||
s.append(wrapped, i, end);
|
s.append(wrapped.substring(i, end));
|
||||||
s.append("\r\n");
|
s.append("\r\n");
|
||||||
}
|
}
|
||||||
return s.toString();
|
return s.toString();
|
||||||
@@ -23,7 +21,7 @@ class AsciiArmour {
|
|||||||
|
|
||||||
static byte[] unwrap(String s) throws FormatException {
|
static byte[] unwrap(String s) throws FormatException {
|
||||||
try {
|
try {
|
||||||
return fromHexString(s.replaceAll("[^0-9a-fA-F]", ""));
|
return StringUtils.fromHexString(s.replaceAll("[^0-9a-fA-F]", ""));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import org.briarproject.bramble.api.crypto.PublicKey;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.spongycastle.crypto.CryptoException;
|
import org.spongycastle.crypto.CryptoException;
|
||||||
import org.spongycastle.crypto.Digest;
|
import org.spongycastle.crypto.Digest;
|
||||||
import org.spongycastle.crypto.digests.Blake2bDigest;
|
import org.spongycastle.crypto.digests.Blake2bDigest;
|
||||||
@@ -28,21 +30,16 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint32;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class CryptoComponentImpl implements CryptoComponent {
|
class CryptoComponentImpl implements CryptoComponent {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(CryptoComponentImpl.class.getName());
|
Logger.getLogger(CryptoComponentImpl.class.getName());
|
||||||
|
|
||||||
private static final int SIGNATURE_KEY_PAIR_BITS = 256;
|
private static final int SIGNATURE_KEY_PAIR_BITS = 256;
|
||||||
private static final int STORAGE_IV_BYTES = 24; // 196 bits
|
private static final int STORAGE_IV_BYTES = 24; // 196 bits
|
||||||
@@ -191,7 +188,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
PrivateKey ourPriv = ourKeyPair.getPrivate();
|
PrivateKey ourPriv = ourKeyPair.getPrivate();
|
||||||
byte[][] hashInputs = new byte[inputs.length + 1][];
|
byte[][] hashInputs = new byte[inputs.length + 1][];
|
||||||
hashInputs[0] = performRawKeyAgreement(ourPriv, theirPublicKey);
|
hashInputs[0] = performRawKeyAgreement(ourPriv, theirPublicKey);
|
||||||
arraycopy(inputs, 0, hashInputs, 1, inputs.length);
|
System.arraycopy(inputs, 0, hashInputs, 1, inputs.length);
|
||||||
byte[] hash = hash(label, hashInputs);
|
byte[] hash = hash(label, hashInputs);
|
||||||
if (hash.length != SecretKey.LENGTH) throw new IllegalStateException();
|
if (hash.length != SecretKey.LENGTH) throw new IllegalStateException();
|
||||||
return new SecretKey(hash);
|
return new SecretKey(hash);
|
||||||
@@ -219,26 +216,26 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
|
|
||||||
private void updateSignature(Signature signature, String label,
|
private void updateSignature(Signature signature, String label,
|
||||||
byte[] toSign) throws GeneralSecurityException {
|
byte[] toSign) throws GeneralSecurityException {
|
||||||
byte[] labelBytes = toUtf8(label);
|
byte[] labelBytes = StringUtils.toUtf8(label);
|
||||||
byte[] length = new byte[INT_32_BYTES];
|
byte[] length = new byte[INT_32_BYTES];
|
||||||
writeUint32(labelBytes.length, length, 0);
|
ByteUtils.writeUint32(labelBytes.length, length, 0);
|
||||||
signature.update(length);
|
signature.update(length);
|
||||||
signature.update(labelBytes);
|
signature.update(labelBytes);
|
||||||
writeUint32(toSign.length, length, 0);
|
ByteUtils.writeUint32(toSign.length, length, 0);
|
||||||
signature.update(length);
|
signature.update(length);
|
||||||
signature.update(toSign);
|
signature.update(toSign);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] hash(String label, byte[]... inputs) {
|
public byte[] hash(String label, byte[]... inputs) {
|
||||||
byte[] labelBytes = toUtf8(label);
|
byte[] labelBytes = StringUtils.toUtf8(label);
|
||||||
Digest digest = new Blake2bDigest(256);
|
Digest digest = new Blake2bDigest(256);
|
||||||
byte[] length = new byte[INT_32_BYTES];
|
byte[] length = new byte[INT_32_BYTES];
|
||||||
writeUint32(labelBytes.length, length, 0);
|
ByteUtils.writeUint32(labelBytes.length, length, 0);
|
||||||
digest.update(length, 0, length.length);
|
digest.update(length, 0, length.length);
|
||||||
digest.update(labelBytes, 0, labelBytes.length);
|
digest.update(labelBytes, 0, labelBytes.length);
|
||||||
for (byte[] input : inputs) {
|
for (byte[] input : inputs) {
|
||||||
writeUint32(input.length, length, 0);
|
ByteUtils.writeUint32(input.length, length, 0);
|
||||||
digest.update(length, 0, length.length);
|
digest.update(length, 0, length.length);
|
||||||
digest.update(input, 0, input.length);
|
digest.update(input, 0, input.length);
|
||||||
}
|
}
|
||||||
@@ -249,14 +246,14 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] mac(String label, SecretKey macKey, byte[]... inputs) {
|
public byte[] mac(String label, SecretKey macKey, byte[]... inputs) {
|
||||||
byte[] labelBytes = toUtf8(label);
|
byte[] labelBytes = StringUtils.toUtf8(label);
|
||||||
Digest mac = new Blake2bDigest(macKey.getBytes(), 32, null, null);
|
Digest mac = new Blake2bDigest(macKey.getBytes(), 32, null, null);
|
||||||
byte[] length = new byte[INT_32_BYTES];
|
byte[] length = new byte[INT_32_BYTES];
|
||||||
writeUint32(labelBytes.length, length, 0);
|
ByteUtils.writeUint32(labelBytes.length, length, 0);
|
||||||
mac.update(length, 0, length.length);
|
mac.update(length, 0, length.length);
|
||||||
mac.update(labelBytes, 0, labelBytes.length);
|
mac.update(labelBytes, 0, labelBytes.length);
|
||||||
for (byte[] input : inputs) {
|
for (byte[] input : inputs) {
|
||||||
writeUint32(input.length, length, 0);
|
ByteUtils.writeUint32(input.length, length, 0);
|
||||||
mac.update(length, 0, length.length);
|
mac.update(length, 0, length.length);
|
||||||
mac.update(input, 0, input.length);
|
mac.update(input, 0, input.length);
|
||||||
}
|
}
|
||||||
@@ -300,13 +297,13 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
output[outputOff] = PBKDF_FORMAT_SCRYPT;
|
output[outputOff] = PBKDF_FORMAT_SCRYPT;
|
||||||
outputOff++;
|
outputOff++;
|
||||||
// Salt
|
// Salt
|
||||||
arraycopy(salt, 0, output, outputOff, salt.length);
|
System.arraycopy(salt, 0, output, outputOff, salt.length);
|
||||||
outputOff += salt.length;
|
outputOff += salt.length;
|
||||||
// Cost parameter
|
// Cost parameter
|
||||||
writeUint32(cost, output, outputOff);
|
ByteUtils.writeUint32(cost, output, outputOff);
|
||||||
outputOff += INT_32_BYTES;
|
outputOff += INT_32_BYTES;
|
||||||
// IV
|
// IV
|
||||||
arraycopy(iv, 0, output, outputOff, iv.length);
|
System.arraycopy(iv, 0, output, outputOff, iv.length);
|
||||||
outputOff += iv.length;
|
outputOff += iv.length;
|
||||||
// Initialise the cipher and encrypt the plaintext
|
// Initialise the cipher and encrypt the plaintext
|
||||||
try {
|
try {
|
||||||
@@ -336,16 +333,16 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
return null; // Unknown format
|
return null; // Unknown format
|
||||||
// Salt
|
// Salt
|
||||||
byte[] salt = new byte[PBKDF_SALT_BYTES];
|
byte[] salt = new byte[PBKDF_SALT_BYTES];
|
||||||
arraycopy(input, inputOff, salt, 0, salt.length);
|
System.arraycopy(input, inputOff, salt, 0, salt.length);
|
||||||
inputOff += salt.length;
|
inputOff += salt.length;
|
||||||
// Cost parameter
|
// Cost parameter
|
||||||
long cost = readUint32(input, inputOff);
|
long cost = ByteUtils.readUint32(input, inputOff);
|
||||||
inputOff += INT_32_BYTES;
|
inputOff += INT_32_BYTES;
|
||||||
if (cost < 2 || cost > Integer.MAX_VALUE)
|
if (cost < 2 || cost > Integer.MAX_VALUE)
|
||||||
return null; // Invalid cost parameter
|
return null; // Invalid cost parameter
|
||||||
// IV
|
// IV
|
||||||
byte[] iv = new byte[STORAGE_IV_BYTES];
|
byte[] iv = new byte[STORAGE_IV_BYTES];
|
||||||
arraycopy(input, inputOff, iv, 0, iv.length);
|
System.arraycopy(input, inputOff, iv, 0, iv.length);
|
||||||
inputOff += iv.length;
|
inputOff += iv.length;
|
||||||
// Derive the key from the password
|
// Derive the key from the password
|
||||||
SecretKey key = passwordBasedKdf.deriveKey(password, salt, (int) cost);
|
SecretKey key = passwordBasedKdf.deriveKey(password, salt, (int) cost);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
|
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class Curve25519KeyParser implements KeyParser {
|
class Curve25519KeyParser implements KeyParser {
|
||||||
|
|
||||||
@@ -28,7 +26,7 @@ class Curve25519KeyParser implements KeyParser {
|
|||||||
|
|
||||||
static byte[] clamp(byte[] b) {
|
static byte[] clamp(byte[] b) {
|
||||||
byte[] clamped = new byte[32];
|
byte[] clamped = new byte[32];
|
||||||
arraycopy(b, 0, clamped, 0, 32);
|
System.arraycopy(b, 0, clamped, 0, 32);
|
||||||
clamped[0] &= 248;
|
clamped[0] &= 248;
|
||||||
clamped[31] &= 127;
|
clamped[31] &= 127;
|
||||||
clamped[31] |= 64;
|
clamped[31] |= 64;
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
package org.briarproject.bramble.crypto;
|
package org.briarproject.bramble.crypto;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FrameEncoder {
|
class FrameEncoder {
|
||||||
@@ -18,7 +16,7 @@ class FrameEncoder {
|
|||||||
if (dest.length < FRAME_NONCE_LENGTH)
|
if (dest.length < FRAME_NONCE_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
if (frameNumber < 0) throw new IllegalArgumentException();
|
if (frameNumber < 0) throw new IllegalArgumentException();
|
||||||
writeUint64(frameNumber, dest, 0);
|
ByteUtils.writeUint64(frameNumber, dest, 0);
|
||||||
if (header) dest[0] |= 0x80;
|
if (header) dest[0] |= 0x80;
|
||||||
for (int i = INT_64_BYTES; i < FRAME_NONCE_LENGTH; i++) dest[i] = 0;
|
for (int i = INT_64_BYTES; i < FRAME_NONCE_LENGTH; i++) dest[i] = 0;
|
||||||
}
|
}
|
||||||
@@ -31,8 +29,8 @@ class FrameEncoder {
|
|||||||
if (paddingLength < 0) throw new IllegalArgumentException();
|
if (paddingLength < 0) throw new IllegalArgumentException();
|
||||||
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
writeUint16(payloadLength, dest, 0);
|
ByteUtils.writeUint16(payloadLength, dest, 0);
|
||||||
writeUint16(paddingLength, dest, INT_16_BYTES);
|
ByteUtils.writeUint16(paddingLength, dest, INT_16_BYTES);
|
||||||
if (finalFrame) dest[0] |= 0x80;
|
if (finalFrame) dest[0] |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,12 +43,12 @@ class FrameEncoder {
|
|||||||
static int getPayloadLength(byte[] header) {
|
static int getPayloadLength(byte[] header) {
|
||||||
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
|
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
return readUint16(header, 0) & 0x7FFF;
|
return ByteUtils.readUint16(header, 0) & 0x7FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getPaddingLength(byte[] header) {
|
static int getPaddingLength(byte[] header) {
|
||||||
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
|
if (header.length < FRAME_HEADER_PLAINTEXT_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
return readUint16(header, INT_16_BYTES);
|
return ByteUtils.readUint16(header, INT_16_BYTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||||
|
|
||||||
class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
|
class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
|
||||||
@@ -25,7 +24,7 @@ class KeyAgreementCryptoImpl implements KeyAgreementCrypto {
|
|||||||
byte[] hash = crypto.hash(COMMIT_LABEL, publicKey.getEncoded());
|
byte[] hash = crypto.hash(COMMIT_LABEL, publicKey.getEncoded());
|
||||||
// The output is the first COMMIT_LENGTH bytes of the hash
|
// The output is the first COMMIT_LENGTH bytes of the hash
|
||||||
byte[] commitment = new byte[COMMIT_LENGTH];
|
byte[] commitment = new byte[COMMIT_LENGTH];
|
||||||
arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
|
System.arraycopy(hash, 0, commitment, 0, COMMIT_LENGTH);
|
||||||
return commitment;
|
return commitment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.crypto.KeyParser;
|
|||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
||||||
import org.spongycastle.asn1.x9.X9ECParameters;
|
import org.spongycastle.asn1.x9.X9ECParameters;
|
||||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||||
@@ -44,9 +45,6 @@ import java.util.Scanner;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class MessageEncrypter {
|
public class MessageEncrypter {
|
||||||
@@ -159,7 +157,6 @@ public class MessageEncrypter {
|
|||||||
printUsage();
|
printUsage();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
//noinspection IfCanBeSwitch
|
|
||||||
if (args[0].equals("generate")) {
|
if (args[0].equals("generate")) {
|
||||||
if (args.length != 3) {
|
if (args.length != 3) {
|
||||||
printUsage();
|
printUsage();
|
||||||
@@ -213,11 +210,11 @@ public class MessageEncrypter {
|
|||||||
MessageEncrypter encrypter = new MessageEncrypter(random);
|
MessageEncrypter encrypter = new MessageEncrypter(random);
|
||||||
KeyPair keyPair = encrypter.generateKeyPair();
|
KeyPair keyPair = encrypter.generateKeyPair();
|
||||||
PrintStream out = new PrintStream(new FileOutputStream(publicKeyFile));
|
PrintStream out = new PrintStream(new FileOutputStream(publicKeyFile));
|
||||||
out.print(toHexString(keyPair.getPublic().getEncoded()));
|
out.print(StringUtils.toHexString(keyPair.getPublic().getEncoded()));
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
out = new PrintStream(new FileOutputStream(privateKeyFile));
|
out = new PrintStream(new FileOutputStream(privateKeyFile));
|
||||||
out.print(toHexString(keyPair.getPrivate().getEncoded()));
|
out.print(StringUtils.toHexString(keyPair.getPrivate().getEncoded()));
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
@@ -226,7 +223,7 @@ public class MessageEncrypter {
|
|||||||
SecureRandom random = new SecureRandom();
|
SecureRandom random = new SecureRandom();
|
||||||
MessageEncrypter encrypter = new MessageEncrypter(random);
|
MessageEncrypter encrypter = new MessageEncrypter(random);
|
||||||
InputStream in = new FileInputStream(publicKeyFile);
|
InputStream in = new FileInputStream(publicKeyFile);
|
||||||
byte[] keyBytes = fromHexString(readFully(in).trim());
|
byte[] keyBytes = StringUtils.fromHexString(readFully(in).trim());
|
||||||
PublicKey publicKey =
|
PublicKey publicKey =
|
||||||
encrypter.getKeyParser().parsePublicKey(keyBytes);
|
encrypter.getKeyParser().parsePublicKey(keyBytes);
|
||||||
String message = readFully(System.in);
|
String message = readFully(System.in);
|
||||||
@@ -239,7 +236,7 @@ public class MessageEncrypter {
|
|||||||
SecureRandom random = new SecureRandom();
|
SecureRandom random = new SecureRandom();
|
||||||
MessageEncrypter encrypter = new MessageEncrypter(random);
|
MessageEncrypter encrypter = new MessageEncrypter(random);
|
||||||
InputStream in = new FileInputStream(privateKeyFile);
|
InputStream in = new FileInputStream(privateKeyFile);
|
||||||
byte[] keyBytes = fromHexString(readFully(in).trim());
|
byte[] keyBytes = StringUtils.fromHexString(readFully(in).trim());
|
||||||
PrivateKey privateKey =
|
PrivateKey privateKey =
|
||||||
encrypter.getKeyParser().parsePrivateKey(keyBytes);
|
encrypter.getKeyParser().parsePrivateKey(keyBytes);
|
||||||
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));
|
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.crypto;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.spongycastle.crypto.generators.SCrypt;
|
import org.spongycastle.crypto.generators.SCrypt;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -9,14 +10,13 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
class ScryptKdf implements PasswordBasedKdf {
|
class ScryptKdf implements PasswordBasedKdf {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(ScryptKdf.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(ScryptKdf.class.getName());
|
||||||
|
|
||||||
private static final int MIN_COST = 256; // Min parameter N
|
private static final int MIN_COST = 256; // Min parameter N
|
||||||
private static final int MAX_COST = 1024 * 1024; // Max parameter N
|
private static final int MAX_COST = 1024 * 1024; // Max parameter N
|
||||||
@@ -53,7 +53,7 @@ class ScryptKdf implements PasswordBasedKdf {
|
|||||||
@Override
|
@Override
|
||||||
public SecretKey deriveKey(String password, byte[] salt, int cost) {
|
public SecretKey deriveKey(String password, byte[] salt, int cost) {
|
||||||
long start = now();
|
long start = now();
|
||||||
byte[] passwordBytes = toUtf8(password);
|
byte[] passwordBytes = StringUtils.toUtf8(password);
|
||||||
SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost,
|
SecretKey k = new SecretKey(SCrypt.generate(passwordBytes, salt, cost,
|
||||||
BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH));
|
BLOCK_SIZE, PARALLELIZATION, SecretKey.LENGTH));
|
||||||
logDuration(LOG, "Deriving key from password", start);
|
logDuration(LOG, "Deriving key from password", start);
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
|
||||||
@@ -30,7 +28,8 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class Sec1KeyParser implements KeyParser {
|
class Sec1KeyParser implements KeyParser {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(Sec1KeyParser.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(Sec1KeyParser.class.getName());
|
||||||
|
|
||||||
private final ECDomainParameters params;
|
private final ECDomainParameters params;
|
||||||
private final BigInteger modulus;
|
private final BigInteger modulus;
|
||||||
@@ -57,12 +56,12 @@ class Sec1KeyParser implements KeyParser {
|
|||||||
if (encodedKey[0] != 4) throw new GeneralSecurityException();
|
if (encodedKey[0] != 4) throw new GeneralSecurityException();
|
||||||
// The x co-ordinate must be >= 0 and < p
|
// The x co-ordinate must be >= 0 and < p
|
||||||
byte[] xBytes = new byte[bytesPerInt];
|
byte[] xBytes = new byte[bytesPerInt];
|
||||||
arraycopy(encodedKey, 1, xBytes, 0, bytesPerInt);
|
System.arraycopy(encodedKey, 1, xBytes, 0, bytesPerInt);
|
||||||
BigInteger x = new BigInteger(1, xBytes); // Positive signum
|
BigInteger x = new BigInteger(1, xBytes); // Positive signum
|
||||||
if (x.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
if (x.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||||
// The y co-ordinate must be >= 0 and < p
|
// The y co-ordinate must be >= 0 and < p
|
||||||
byte[] yBytes = new byte[bytesPerInt];
|
byte[] yBytes = new byte[bytesPerInt];
|
||||||
arraycopy(encodedKey, 1 + bytesPerInt, yBytes, 0, bytesPerInt);
|
System.arraycopy(encodedKey, 1 + bytesPerInt, yBytes, 0, bytesPerInt);
|
||||||
BigInteger y = new BigInteger(1, yBytes); // Positive signum
|
BigInteger y = new BigInteger(1, yBytes); // Positive signum
|
||||||
if (y.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
if (y.compareTo(modulus) >= 0) throw new GeneralSecurityException();
|
||||||
// Verify that y^2 == x^3 + ax + b (mod p)
|
// Verify that y^2 == x^3 + ax + b (mod p)
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package org.briarproject.bramble.crypto;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class Sec1Utils {
|
class Sec1Utils {
|
||||||
|
|
||||||
@@ -12,10 +10,10 @@ class Sec1Utils {
|
|||||||
if (src.length < destLen) {
|
if (src.length < destLen) {
|
||||||
int padding = destLen - src.length;
|
int padding = destLen - src.length;
|
||||||
for (int i = destOff; i < destOff + padding; i++) dest[i] = 0;
|
for (int i = destOff; i < destOff + padding; i++) dest[i] = 0;
|
||||||
arraycopy(src, 0, dest, destOff + padding, src.length);
|
System.arraycopy(src, 0, dest, destOff + padding, src.length);
|
||||||
} else {
|
} else {
|
||||||
int srcOff = src.length - destLen;
|
int srcOff = src.length - destLen;
|
||||||
arraycopy(src, srcOff, dest, destOff, destLen);
|
System.arraycopy(src, srcOff, dest, destOff, destLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.crypto.StreamDecrypter;
|
import org.briarproject.bramble.api.crypto.StreamDecrypter;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -13,7 +14,6 @@ import java.security.GeneralSecurityException;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
||||||
@@ -26,8 +26,6 @@ import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_H
|
|||||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint64;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -132,7 +130,7 @@ class StreamDecrypterImpl implements StreamDecrypter {
|
|||||||
}
|
}
|
||||||
// Extract the nonce
|
// Extract the nonce
|
||||||
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
|
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
|
||||||
arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce, 0,
|
System.arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce, 0,
|
||||||
STREAM_HEADER_NONCE_LENGTH);
|
STREAM_HEADER_NONCE_LENGTH);
|
||||||
// Decrypt and authenticate the stream header
|
// Decrypt and authenticate the stream header
|
||||||
try {
|
try {
|
||||||
@@ -147,16 +145,17 @@ class StreamDecrypterImpl implements StreamDecrypter {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
// Check the protocol version
|
// Check the protocol version
|
||||||
int receivedProtocolVersion = readUint16(streamHeaderPlaintext, 0);
|
int receivedProtocolVersion =
|
||||||
|
ByteUtils.readUint16(streamHeaderPlaintext, 0);
|
||||||
if (receivedProtocolVersion != PROTOCOL_VERSION)
|
if (receivedProtocolVersion != PROTOCOL_VERSION)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
// Check the stream number
|
// Check the stream number
|
||||||
long receivedStreamNumber = readUint64(streamHeaderPlaintext,
|
long receivedStreamNumber = ByteUtils.readUint64(streamHeaderPlaintext,
|
||||||
INT_16_BYTES);
|
INT_16_BYTES);
|
||||||
if (receivedStreamNumber != streamNumber) throw new FormatException();
|
if (receivedStreamNumber != streamNumber) throw new FormatException();
|
||||||
// Extract the frame key
|
// Extract the frame key
|
||||||
byte[] frameKeyBytes = new byte[SecretKey.LENGTH];
|
byte[] frameKeyBytes = new byte[SecretKey.LENGTH];
|
||||||
arraycopy(streamHeaderPlaintext, INT_16_BYTES + INT_64_BYTES,
|
System.arraycopy(streamHeaderPlaintext, INT_16_BYTES + INT_64_BYTES,
|
||||||
frameKeyBytes, 0, SecretKey.LENGTH);
|
frameKeyBytes, 0, SecretKey.LENGTH);
|
||||||
frameKey = new SecretKey(frameKeyBytes);
|
frameKey = new SecretKey(frameKeyBytes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.crypto;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.crypto.StreamEncrypter;
|
import org.briarproject.bramble.api.crypto.StreamEncrypter;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -11,7 +12,6 @@ import java.security.GeneralSecurityException;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_HEADER_PLAINTEXT_LENGTH;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.FRAME_NONCE_LENGTH;
|
||||||
@@ -24,8 +24,6 @@ import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_H
|
|||||||
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.STREAM_HEADER_PLAINTEXT_LENGTH;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -90,7 +88,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
|||||||
throw new RuntimeException(badCipher);
|
throw new RuntimeException(badCipher);
|
||||||
}
|
}
|
||||||
// Combine the payload and padding
|
// Combine the payload and padding
|
||||||
arraycopy(payload, 0, framePlaintext, 0, payloadLength);
|
System.arraycopy(payload, 0, framePlaintext, 0, payloadLength);
|
||||||
for (int i = 0; i < paddingLength; i++)
|
for (int i = 0; i < paddingLength; i++)
|
||||||
framePlaintext[payloadLength + i] = 0;
|
framePlaintext[payloadLength + i] = 0;
|
||||||
// Encrypt and authenticate the payload and padding
|
// Encrypt and authenticate the payload and padding
|
||||||
@@ -120,12 +118,13 @@ class StreamEncrypterImpl implements StreamEncrypter {
|
|||||||
private void writeStreamHeader() throws IOException {
|
private void writeStreamHeader() throws IOException {
|
||||||
// The header contains the protocol version, stream number and frame key
|
// The header contains the protocol version, stream number and frame key
|
||||||
byte[] streamHeaderPlaintext = new byte[STREAM_HEADER_PLAINTEXT_LENGTH];
|
byte[] streamHeaderPlaintext = new byte[STREAM_HEADER_PLAINTEXT_LENGTH];
|
||||||
writeUint16(PROTOCOL_VERSION, streamHeaderPlaintext, 0);
|
ByteUtils.writeUint16(PROTOCOL_VERSION, streamHeaderPlaintext, 0);
|
||||||
writeUint64(streamNumber, streamHeaderPlaintext, INT_16_BYTES);
|
ByteUtils.writeUint64(streamNumber, streamHeaderPlaintext,
|
||||||
arraycopy(frameKey.getBytes(), 0, streamHeaderPlaintext,
|
INT_16_BYTES);
|
||||||
|
System.arraycopy(frameKey.getBytes(), 0, streamHeaderPlaintext,
|
||||||
INT_16_BYTES + INT_64_BYTES, SecretKey.LENGTH);
|
INT_16_BYTES + INT_64_BYTES, SecretKey.LENGTH);
|
||||||
byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
|
byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
|
||||||
arraycopy(streamHeaderNonce, 0, streamHeaderCiphertext, 0,
|
System.arraycopy(streamHeaderNonce, 0, streamHeaderCiphertext, 0,
|
||||||
STREAM_HEADER_NONCE_LENGTH);
|
STREAM_HEADER_NONCE_LENGTH);
|
||||||
// Encrypt and authenticate the stream header key
|
// Encrypt and authenticate the stream header key
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ import org.briarproject.bramble.api.plugin.TransportId;
|
|||||||
import org.briarproject.bramble.api.transport.IncomingKeys;
|
import org.briarproject.bramble.api.transport.IncomingKeys;
|
||||||
import org.briarproject.bramble.api.transport.OutgoingKeys;
|
import org.briarproject.bramble.api.transport.OutgoingKeys;
|
||||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.spongycastle.crypto.Digest;
|
import org.spongycastle.crypto.Digest;
|
||||||
import org.spongycastle.crypto.digests.Blake2bDigest;
|
import org.spongycastle.crypto.digests.Blake2bDigest;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_HEADER_LABEL;
|
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_HEADER_LABEL;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_TAG_LABEL;
|
import static org.briarproject.bramble.api.transport.TransportConstants.ALICE_TAG_LABEL;
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.BOB_HEADER_LABEL;
|
import static org.briarproject.bramble.api.transport.TransportConstants.BOB_HEADER_LABEL;
|
||||||
@@ -23,9 +24,6 @@ import static org.briarproject.bramble.util.ByteUtils.INT_16_BYTES;
|
|||||||
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_64_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
|
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
import static org.briarproject.bramble.util.ByteUtils.MAX_32_BIT_UNSIGNED;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint64;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
class TransportCryptoImpl implements TransportCrypto {
|
class TransportCryptoImpl implements TransportCrypto {
|
||||||
|
|
||||||
@@ -93,21 +91,21 @@ class TransportCryptoImpl implements TransportCrypto {
|
|||||||
|
|
||||||
private SecretKey rotateKey(SecretKey k, long rotationPeriod) {
|
private SecretKey rotateKey(SecretKey k, long rotationPeriod) {
|
||||||
byte[] period = new byte[INT_64_BYTES];
|
byte[] period = new byte[INT_64_BYTES];
|
||||||
writeUint64(rotationPeriod, period, 0);
|
ByteUtils.writeUint64(rotationPeriod, period, 0);
|
||||||
return crypto.deriveKey(ROTATE_LABEL, k, period);
|
return crypto.deriveKey(ROTATE_LABEL, k, period);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecretKey deriveTagKey(SecretKey master, TransportId t,
|
private SecretKey deriveTagKey(SecretKey master, TransportId t,
|
||||||
boolean alice) {
|
boolean alice) {
|
||||||
String label = alice ? ALICE_TAG_LABEL : BOB_TAG_LABEL;
|
String label = alice ? ALICE_TAG_LABEL : BOB_TAG_LABEL;
|
||||||
byte[] id = toUtf8(t.getString());
|
byte[] id = StringUtils.toUtf8(t.getString());
|
||||||
return crypto.deriveKey(label, master, id);
|
return crypto.deriveKey(label, master, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecretKey deriveHeaderKey(SecretKey master, TransportId t,
|
private SecretKey deriveHeaderKey(SecretKey master, TransportId t,
|
||||||
boolean alice) {
|
boolean alice) {
|
||||||
String label = alice ? ALICE_HEADER_LABEL : BOB_HEADER_LABEL;
|
String label = alice ? ALICE_HEADER_LABEL : BOB_HEADER_LABEL;
|
||||||
byte[] id = toUtf8(t.getString());
|
byte[] id = StringUtils.toUtf8(t.getString());
|
||||||
return crypto.deriveKey(label, master, id);
|
return crypto.deriveKey(label, master, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,14 +125,14 @@ class TransportCryptoImpl implements TransportCrypto {
|
|||||||
// The input is the protocol version as a 16-bit integer, followed by
|
// The input is the protocol version as a 16-bit integer, followed by
|
||||||
// the stream number as a 64-bit integer
|
// the stream number as a 64-bit integer
|
||||||
byte[] protocolVersionBytes = new byte[INT_16_BYTES];
|
byte[] protocolVersionBytes = new byte[INT_16_BYTES];
|
||||||
writeUint16(protocolVersion, protocolVersionBytes, 0);
|
ByteUtils.writeUint16(protocolVersion, protocolVersionBytes, 0);
|
||||||
prf.update(protocolVersionBytes, 0, protocolVersionBytes.length);
|
prf.update(protocolVersionBytes, 0, protocolVersionBytes.length);
|
||||||
byte[] streamNumberBytes = new byte[INT_64_BYTES];
|
byte[] streamNumberBytes = new byte[INT_64_BYTES];
|
||||||
writeUint64(streamNumber, streamNumberBytes, 0);
|
ByteUtils.writeUint64(streamNumber, streamNumberBytes, 0);
|
||||||
prf.update(streamNumberBytes, 0, streamNumberBytes.length);
|
prf.update(streamNumberBytes, 0, streamNumberBytes.length);
|
||||||
byte[] mac = new byte[macLength];
|
byte[] mac = new byte[macLength];
|
||||||
prf.doFinal(mac, 0);
|
prf.doFinal(mac, 0);
|
||||||
// The output is the first TAG_LENGTH bytes of the MAC
|
// The output is the first TAG_LENGTH bytes of the MAC
|
||||||
arraycopy(mac, 0, tag, 0, TAG_LENGTH);
|
System.arraycopy(mac, 0, tag, 0, TAG_LENGTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ interface Database<T> {
|
|||||||
* bytes. This is based on the minimum of the space available on the device
|
* bytes. This is based on the minimum of the space available on the device
|
||||||
* where the database is stored and the database's configured size.
|
* where the database is stored and the database's configured size.
|
||||||
*/
|
*/
|
||||||
long getFreeSpace();
|
long getFreeSpace() throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the group with the given ID.
|
* Returns the group with the given ID.
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import org.briarproject.bramble.api.transport.TransportKeys;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -71,9 +72,7 @@ import javax.annotation.Nullable;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
@@ -88,7 +87,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
class DatabaseComponentImpl<T> implements DatabaseComponent {
|
class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(DatabaseComponentImpl.class.getName());
|
Logger.getLogger(DatabaseComponentImpl.class.getName());
|
||||||
|
|
||||||
private final Database<T> db;
|
private final Database<T> db;
|
||||||
private final Class<T> txnClass;
|
private final Class<T> txnClass;
|
||||||
@@ -899,7 +898,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
if (old == INVISIBLE) db.addGroupVisibility(txn, c, g, v == SHARED);
|
if (old == INVISIBLE) db.addGroupVisibility(txn, c, g, v == SHARED);
|
||||||
else if (v == INVISIBLE) db.removeGroupVisibility(txn, c, g);
|
else if (v == INVISIBLE) db.removeGroupVisibility(txn, c, g);
|
||||||
else db.setGroupVisibility(txn, c, g, v == SHARED);
|
else db.setGroupVisibility(txn, c, g, v == SHARED);
|
||||||
List<ContactId> affected = singletonList(c);
|
List<ContactId> affected = Collections.singletonList(c);
|
||||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.briarproject.bramble.api.db.MigrationListener;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -14,24 +15,16 @@ import java.sql.DriverManager;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all the H2-specific code for the database.
|
* Contains all the H2-specific code for the database.
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class H2Database extends JdbcDatabase {
|
class H2Database extends JdbcDatabase {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(H2Database.class.getName());
|
|
||||||
|
|
||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
@@ -107,7 +100,7 @@ class H2Database extends JdbcDatabase {
|
|||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("user", "user");
|
props.setProperty("user", "user");
|
||||||
// Separate the file password from the user password with a space
|
// Separate the file password from the user password with a space
|
||||||
String hex = toHexString(key.getBytes());
|
String hex = StringUtils.toHexString(key.getBytes());
|
||||||
props.put("password", hex + " password");
|
props.put("password", hex + " password");
|
||||||
return DriverManager.getConnection(getUrl(), props);
|
return DriverManager.getConnection(getUrl(), props);
|
||||||
}
|
}
|
||||||
@@ -128,8 +121,8 @@ class H2Database extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
tryToClose(c, LOG, WARNING);
|
tryToClose(c);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,31 +7,23 @@ import org.briarproject.bramble.api.db.MigrationListener;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all the HSQLDB-specific code for the database.
|
* Contains all the HSQLDB-specific code for the database.
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class HyperSqlDatabase extends JdbcDatabase {
|
class HyperSqlDatabase extends JdbcDatabase {
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
getLogger(HyperSqlDatabase.class.getName());
|
|
||||||
|
|
||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
@@ -80,8 +72,8 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
tryToClose(c, LOG, WARNING);
|
tryToClose(c);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +106,7 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
protected Connection createConnection() throws SQLException {
|
protected Connection createConnection() throws SQLException {
|
||||||
SecretKey key = this.key;
|
SecretKey key = this.key;
|
||||||
if (key == null) throw new IllegalStateException();
|
if (key == null) throw new IllegalStateException();
|
||||||
String hex = toHexString(key.getBytes());
|
String hex = StringUtils.toHexString(key.getBytes());
|
||||||
return DriverManager.getConnection(url + ";crypt_key=" + hex);
|
return DriverManager.getConnection(url + ";crypt_key=" + hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +122,8 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
tryToClose(c, LOG, WARNING);
|
tryToClose(c);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -52,17 +54,11 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
import static java.sql.Types.INTEGER;
|
import static java.sql.Types.INTEGER;
|
||||||
import static java.sql.Types.VARCHAR;
|
import static java.sql.Types.VARCHAR;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.emptyMap;
|
|
||||||
import static java.util.Collections.emptySet;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
@@ -76,7 +72,6 @@ import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
|
|||||||
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
|
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
|
||||||
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
|
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
@@ -313,20 +308,19 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
"CREATE INDEX IF NOT EXISTS statusesByContactIdTimestamp"
|
"CREATE INDEX IF NOT EXISTS statusesByContactIdTimestamp"
|
||||||
+ " ON statuses (contactId, timestamp)";
|
+ " ON statuses (contactId, timestamp)";
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(JdbcDatabase.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(JdbcDatabase.class.getName());
|
||||||
|
|
||||||
// Different database libraries use different names for certain types
|
// Different database libraries use different names for certain types
|
||||||
private final MessageFactory messageFactory;
|
private final MessageFactory messageFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final DatabaseTypes dbTypes;
|
private final DatabaseTypes dbTypes;
|
||||||
|
|
||||||
@GuardedBy("connectionsLock")
|
// Locking: connectionsLock
|
||||||
private final LinkedList<Connection> connections = new LinkedList<>();
|
private final LinkedList<Connection> connections = new LinkedList<>();
|
||||||
|
|
||||||
@GuardedBy("connectionsLock")
|
private int openConnections = 0; // Locking: connectionsLock
|
||||||
private int openConnections = 0;
|
private boolean closed = false; // Locking: connectionsLock
|
||||||
@GuardedBy("connectionsLock")
|
|
||||||
private boolean closed = false;
|
|
||||||
|
|
||||||
protected abstract Connection createConnection() throws SQLException;
|
protected abstract Connection createConnection() throws SQLException;
|
||||||
|
|
||||||
@@ -342,7 +336,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
protected void open(String driverClass, boolean reopen, SecretKey key,
|
protected void open(String driverClass, boolean reopen, SecretKey key,
|
||||||
@Nullable MigrationListener listener) throws DbException {
|
@Nullable MigrationListener listener) throws DbException {
|
||||||
// Load the JDBC driver
|
// Load the JDBC driver
|
||||||
@@ -430,7 +423,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
|
|
||||||
// Package access for testing
|
// Package access for testing
|
||||||
List<Migration<Connection>> getMigrations() {
|
List<Migration<Connection>> getMigrations() {
|
||||||
return asList(
|
return Arrays.asList(
|
||||||
new Migration38_39(),
|
new Migration38_39(),
|
||||||
new Migration39_40(),
|
new Migration39_40(),
|
||||||
new Migration40_41(dbTypes)
|
new Migration40_41(dbTypes)
|
||||||
@@ -465,6 +458,30 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
|
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable ResultSet rs) {
|
||||||
|
try {
|
||||||
|
if (rs != null) rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void tryToClose(@Nullable Statement s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void tryToClose(@Nullable Connection c) {
|
||||||
|
try {
|
||||||
|
if (c != null) c.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createTables(Connection txn) throws DbException {
|
private void createTables(Connection txn) throws DbException {
|
||||||
Statement s = null;
|
Statement s = null;
|
||||||
try {
|
try {
|
||||||
@@ -485,7 +502,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
|
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,7 +519,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,7 +566,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
// Try to close the connection
|
// Try to close the connection
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
tryToClose(txn, LOG, WARNING);
|
try {
|
||||||
|
txn.close();
|
||||||
|
} catch (SQLException e1) {
|
||||||
|
logException(LOG, WARNING, e1);
|
||||||
|
}
|
||||||
// Whatever happens, allow the database to close
|
// Whatever happens, allow the database to close
|
||||||
connectionsLock.lock();
|
connectionsLock.lock();
|
||||||
try {
|
try {
|
||||||
@@ -638,8 +659,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return c;
|
return c;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,7 +681,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,7 +704,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
// Create a status row for each message in the group
|
// Create a status row for each message in the group
|
||||||
addStatus(txn, c, g, groupShared);
|
addStatus(txn, c, g, groupShared);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,8 +735,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -740,7 +761,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -772,7 +793,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
for (Entry<ContactId, Boolean> e : visibility.entrySet()) {
|
for (Entry<ContactId, Boolean> e : visibility.entrySet()) {
|
||||||
ContactId c = e.getKey();
|
ContactId c = e.getKey();
|
||||||
boolean offered = removeOfferedMessage(txn, c, m.getId());
|
boolean offered = removeOfferedMessage(txn, c, m.getId());
|
||||||
boolean seen = offered || c.equals(sender);
|
boolean seen = offered || (sender != null && c.equals(sender));
|
||||||
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
|
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
|
||||||
raw.length, state, e.getValue(), messageShared,
|
raw.length, state, e.getValue(), messageShared,
|
||||||
false, seen);
|
false, seen);
|
||||||
@@ -789,7 +810,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -819,8 +840,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -852,7 +873,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -894,8 +915,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -914,7 +935,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -994,8 +1015,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return keySetId;
|
return keySetId;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,8 +1039,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1040,8 +1061,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1062,8 +1083,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1084,8 +1105,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1106,8 +1127,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1128,8 +1149,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1153,8 +1174,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1177,8 +1198,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return count;
|
return count;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1202,7 +1223,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1219,7 +1240,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1252,8 +1273,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
return new Contact(c, author, localAuthorId, alias, verified,
|
return new Contact(c, author, localAuthorId, alias, verified,
|
||||||
active);
|
active);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1289,8 +1310,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return contacts;
|
return contacts;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1312,8 +1333,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1350,8 +1371,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return contacts;
|
return contacts;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1374,8 +1395,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return new Group(g, clientId, majorVersion, descriptor);
|
return new Group(g, clientId, majorVersion, descriptor);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1402,8 +1423,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return groups;
|
return groups;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1428,8 +1449,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return v;
|
return v;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1452,8 +1473,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return visible;
|
return visible;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1484,8 +1505,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return localAuthor;
|
return localAuthor;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1516,8 +1537,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return authors;
|
return authors;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1542,11 +1563,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (raw == null) throw new MessageDeletedException();
|
if (raw == null) throw new MessageDeletedException();
|
||||||
if (raw.length <= MESSAGE_HEADER_LENGTH) throw new AssertionError();
|
if (raw.length <= MESSAGE_HEADER_LENGTH) throw new AssertionError();
|
||||||
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
|
byte[] body = new byte[raw.length - MESSAGE_HEADER_LENGTH];
|
||||||
arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
|
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
|
||||||
return new Message(m, g, timestamp, body);
|
return new Message(m, g, timestamp, body);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1569,8 +1590,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1602,13 +1623,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (intersection == null) intersection = ids;
|
if (intersection == null) intersection = ids;
|
||||||
else intersection.retainAll(ids);
|
else intersection.retainAll(ids);
|
||||||
// Return early if there are no matches
|
// Return early if there are no matches
|
||||||
if (intersection.isEmpty()) return emptySet();
|
if (intersection.isEmpty()) return Collections.emptySet();
|
||||||
}
|
}
|
||||||
if (intersection == null) throw new AssertionError();
|
if (intersection == null) throw new AssertionError();
|
||||||
return intersection;
|
return intersection;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1640,8 +1661,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return all;
|
return all;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1651,7 +1672,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
GroupId g, Metadata query) throws DbException {
|
GroupId g, Metadata query) throws DbException {
|
||||||
// Retrieve the matching message IDs
|
// Retrieve the matching message IDs
|
||||||
Collection<MessageId> matches = getMessageIds(txn, g, query);
|
Collection<MessageId> matches = getMessageIds(txn, g, query);
|
||||||
if (matches.isEmpty()) return emptyMap();
|
if (matches.isEmpty()) return Collections.emptyMap();
|
||||||
// Retrieve the metadata for each match
|
// Retrieve the metadata for each match
|
||||||
Map<MessageId, Metadata> all = new HashMap<>(matches.size());
|
Map<MessageId, Metadata> all = new HashMap<>(matches.size());
|
||||||
for (MessageId m : matches) all.put(m, getMessageMetadata(txn, m));
|
for (MessageId m : matches) all.put(m, getMessageMetadata(txn, m));
|
||||||
@@ -1675,8 +1696,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1699,8 +1720,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1725,8 +1746,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1755,8 +1776,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return statuses;
|
return statuses;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1786,8 +1807,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return status;
|
return status;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1816,8 +1837,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return dependencies;
|
return dependencies;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1847,8 +1868,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return dependents;
|
return dependents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1870,8 +1891,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return state;
|
return state;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1895,8 +1916,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1929,8 +1950,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1954,8 +1975,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1993,8 +2014,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2027,8 +2048,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2055,8 +2076,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2085,8 +2106,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return nextSendTime;
|
return nextSendTime;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2124,8 +2145,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2147,8 +2168,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return s;
|
return s;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2213,8 +2234,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return keys;
|
return keys;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2233,7 +2254,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2260,7 +2281,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2287,7 +2308,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2317,7 +2338,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2362,8 +2383,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2401,7 +2422,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
ps.close();
|
ps.close();
|
||||||
}
|
}
|
||||||
if (notRemoved.isEmpty()) return emptyMap();
|
if (notRemoved.isEmpty()) return Collections.emptyMap();
|
||||||
// Update any keys that already exist
|
// Update any keys that already exist
|
||||||
String sql = "UPDATE " + tableName + " SET value = ?"
|
String sql = "UPDATE " + tableName + " SET value = ?"
|
||||||
+ " WHERE " + columnName + " = ? AND metaKey = ?";
|
+ " WHERE " + columnName + " = ? AND metaKey = ?";
|
||||||
@@ -2429,7 +2450,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
return added;
|
return added;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2476,7 +2497,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2495,7 +2516,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2514,7 +2535,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2533,7 +2554,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2550,7 +2571,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2566,7 +2587,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2594,7 +2615,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2611,7 +2632,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2627,7 +2648,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2646,7 +2667,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return affected == 1;
|
return affected == 1;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2671,7 +2692,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2688,7 +2709,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2709,7 +2730,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2728,7 +2749,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2746,7 +2767,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2764,7 +2785,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2783,7 +2804,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2813,7 +2834,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2839,7 +2860,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2892,7 +2913,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2915,7 +2936,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2934,7 +2955,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2970,8 +2991,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3038,7 +3059,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows < 0 || rows > 1) throw new DbStateException();
|
if (rows < 0 || rows > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.briarproject.bramble.db;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
class JdbcUtils {
|
|
||||||
|
|
||||||
static void tryToClose(@Nullable ResultSet rs, Logger logger, Level level) {
|
|
||||||
try {
|
|
||||||
if (rs != null) rs.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(logger, level, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tryToClose(@Nullable Statement s, Logger logger, Level level) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(logger, level, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tryToClose(@Nullable Connection c, Logger logger, Level level) {
|
|
||||||
try {
|
|
||||||
if (c != null) c.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(logger, level, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,13 +7,15 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
|
||||||
|
|
||||||
class Migration38_39 implements Migration<Connection> {
|
class Migration38_39 implements Migration<Connection> {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(Migration38_39.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(Migration38_39.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartVersion() {
|
public int getStartVersion() {
|
||||||
@@ -38,8 +40,16 @@ class Migration38_39 implements Migration<Connection> {
|
|||||||
+ " ALTER COLUMN contactId"
|
+ " ALTER COLUMN contactId"
|
||||||
+ " SET NOT NULL");
|
+ " SET NOT NULL");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Statement s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
|
||||||
|
|
||||||
class Migration39_40 implements Migration<Connection> {
|
class Migration39_40 implements Migration<Connection> {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(Migration39_40.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(Migration39_40.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStartVersion() {
|
public int getStartVersion() {
|
||||||
@@ -37,8 +39,16 @@ class Migration39_40 implements Migration<Connection> {
|
|||||||
+ " ALTER COLUMN eta"
|
+ " ALTER COLUMN eta"
|
||||||
+ " SET NOT NULL");
|
+ " SET NOT NULL");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Statement s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
class Migration40_41 implements Migration<Connection> {
|
class Migration40_41 implements Migration<Connection> {
|
||||||
|
|
||||||
@@ -17,7 +19,7 @@ class Migration40_41 implements Migration<Connection> {
|
|||||||
|
|
||||||
private final DatabaseTypes dbTypes;
|
private final DatabaseTypes dbTypes;
|
||||||
|
|
||||||
Migration40_41(DatabaseTypes databaseTypes) {
|
public Migration40_41(DatabaseTypes databaseTypes) {
|
||||||
this.dbTypes = databaseTypes;
|
this.dbTypes = databaseTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +41,16 @@ class Migration40_41 implements Migration<Connection> {
|
|||||||
s.execute("ALTER TABLE contacts"
|
s.execute("ALTER TABLE contacts"
|
||||||
+ dbTypes.replaceTypes(" ADD alias _STRING"));
|
+ dbTypes.replaceTypes(" ADD alias _STRING"));
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Statement s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import org.briarproject.bramble.api.identity.AuthorId;
|
|||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -14,8 +16,6 @@ import javax.inject.Inject;
|
|||||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
|
import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -58,8 +58,8 @@ class AuthorFactoryImpl implements AuthorFactory {
|
|||||||
|
|
||||||
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
|
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
|
||||||
byte[] formatVersionBytes = new byte[INT_32_BYTES];
|
byte[] formatVersionBytes = new byte[INT_32_BYTES];
|
||||||
writeUint32(formatVersion, formatVersionBytes, 0);
|
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0);
|
||||||
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
|
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
|
||||||
toUtf8(name), publicKey));
|
StringUtils.toUtf8(name), publicKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import javax.annotation.Nullable;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
class IdentityManagerImpl implements IdentityManager {
|
class IdentityManagerImpl implements IdentityManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(IdentityManagerImpl.class.getName());
|
Logger.getLogger(IdentityManagerImpl.class.getName());
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.briarproject.bramble.keyagreement;
|
|||||||
|
|
||||||
class AbortException extends Exception {
|
class AbortException extends Exception {
|
||||||
|
|
||||||
final boolean receivedAbort;
|
boolean receivedAbort;
|
||||||
|
|
||||||
AbortException() {
|
AbortException() {
|
||||||
this(false);
|
this(false);
|
||||||
|
|||||||
@@ -20,14 +20,13 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
class ConnectionChooserImpl implements ConnectionChooser {
|
class ConnectionChooserImpl implements ConnectionChooser {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ConnectionChooserImpl.class.getName());
|
Logger.getLogger(ConnectionChooserImpl.class.getName());
|
||||||
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.CONNECTION_TIMEOUT;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ class KeyAgreementConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(KeyAgreementConnector.class.getName());
|
Logger.getLogger(KeyAgreementConnector.class.getName());
|
||||||
|
|
||||||
private final Callbacks callbacks;
|
private final Callbacks callbacks;
|
||||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -37,7 +36,7 @@ class KeyAgreementTaskImpl extends Thread implements KeyAgreementTask,
|
|||||||
KeyAgreementProtocol.Callbacks, KeyAgreementConnector.Callbacks {
|
KeyAgreementProtocol.Callbacks, KeyAgreementConnector.Callbacks {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(KeyAgreementTaskImpl.class.getName());
|
Logger.getLogger(KeyAgreementTaskImpl.class.getName());
|
||||||
|
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
private final KeyAgreementCrypto keyAgreementCrypto;
|
private final KeyAgreementCrypto keyAgreementCrypto;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.io.OutputStream;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
|
import static org.briarproject.bramble.api.keyagreement.RecordTypes.ABORT;
|
||||||
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
|
import static org.briarproject.bramble.api.keyagreement.RecordTypes.CONFIRM;
|
||||||
@@ -30,7 +29,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
class KeyAgreementTransport {
|
class KeyAgreementTransport {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(KeyAgreementTransport.class.getName());
|
Logger.getLogger(KeyAgreementTransport.class.getName());
|
||||||
|
|
||||||
private final KeyAgreementConnection kac;
|
private final KeyAgreementConnection kac;
|
||||||
private final RecordReader reader;
|
private final RecordReader reader;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.FINE;
|
import static java.util.logging.Level.FINE;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
||||||
@@ -50,7 +49,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(LifecycleManagerImpl.class.getName());
|
Logger.getLogger(LifecycleManagerImpl.class.getName());
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
|||||||
@@ -26,14 +26,13 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
class ConnectionManagerImpl implements ConnectionManager {
|
class ConnectionManagerImpl implements ConnectionManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ConnectionManagerImpl.class.getName());
|
Logger.getLogger(ConnectionManagerImpl.class.getName());
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final KeyManager keyManager;
|
private final KeyManager keyManager;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -23,16 +24,14 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ConnectionRegistryImpl implements ConnectionRegistry {
|
class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ConnectionRegistryImpl.class.getName());
|
Logger.getLogger(ConnectionRegistryImpl.class.getName());
|
||||||
|
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final Lock lock = new ReentrantLock();
|
private final Lock lock = new ReentrantLock();
|
||||||
@@ -104,7 +103,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
Multiset<ContactId> m = connections.get(t);
|
Multiset<ContactId> m = connections.get(t);
|
||||||
if (m == null) return emptyList();
|
if (m == null) return Collections.emptyList();
|
||||||
List<ContactId> ids = new ArrayList<>(m.keySet());
|
List<ContactId> ids = new ArrayList<>(m.keySet());
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info(ids.size() + " contacts connected: " + t);
|
LOG.info(ids.size() + " contacts connected: " + t);
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.FINE;
|
import static java.util.logging.Level.FINE;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
@@ -62,7 +61,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
class PluginManagerImpl implements PluginManager, Service {
|
class PluginManagerImpl implements PluginManager, Service {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(PluginManagerImpl.class.getName());
|
Logger.getLogger(PluginManagerImpl.class.getName());
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
|
|||||||
@@ -36,20 +36,18 @@ import java.util.concurrent.locks.Lock;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class Poller implements EventListener {
|
class Poller implements EventListener {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(Poller.class.getName());
|
private static final Logger LOG = Logger.getLogger(Poller.class.getName());
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
@@ -60,8 +58,7 @@ class Poller implements EventListener {
|
|||||||
private final SecureRandom random;
|
private final SecureRandom random;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Lock lock;
|
private final Lock lock;
|
||||||
@GuardedBy("lock")
|
private final Map<TransportId, ScheduledPollTask> tasks; // Locking: lock
|
||||||
private final Map<TransportId, ScheduledPollTask> tasks;
|
|
||||||
|
|
||||||
Poller(@IoExecutor Executor ioExecutor,
|
Poller(@IoExecutor Executor ioExecutor,
|
||||||
@Scheduler ScheduledExecutorService scheduler,
|
@Scheduler ScheduledExecutorService scheduler,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ interface BluetoothConnectionLimiter {
|
|||||||
* Returns true if a contact connection can be opened. This method does not
|
* Returns true if a contact connection can be opened. This method does not
|
||||||
* need to be called for key agreement connections.
|
* need to be called for key agreement connections.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
boolean canOpenContactConnection();
|
boolean canOpenContactConnection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -21,7 +20,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
class BluetoothConnectionLimiterImpl implements BluetoothConnectionLimiter {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(BluetoothConnectionLimiterImpl.class.getName());
|
Logger.getLogger(BluetoothConnectionLimiterImpl.class.getName());
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
// The following are locking: lock
|
// The following are locking: lock
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
|
||||||
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
|
||||||
@@ -55,7 +54,7 @@ import static org.briarproject.bramble.util.StringUtils.macToString;
|
|||||||
abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(BluetoothPlugin.class.getName());
|
Logger.getLogger(BluetoothPlugin.class.getName());
|
||||||
|
|
||||||
final BluetoothConnectionLimiter connectionLimiter;
|
final BluetoothConnectionLimiter connectionLimiter;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.io.IOException;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH;
|
import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
@@ -22,7 +21,8 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
abstract class FilePlugin implements SimplexPlugin {
|
abstract class FilePlugin implements SimplexPlugin {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(FilePlugin.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(FilePlugin.class.getName());
|
||||||
|
|
||||||
protected final SimplexPluginCallback callback;
|
protected final SimplexPluginCallback callback;
|
||||||
protected final int maxLatency;
|
protected final int maxLatency;
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FileTransportReader implements TransportConnectionReader {
|
class FileTransportReader implements TransportConnectionReader {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(FileTransportReader.class.getName());
|
Logger.getLogger(FileTransportReader.class.getName());
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
@@ -34,7 +34,11 @@ class FileTransportReader implements TransportConnectionReader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(boolean exception, boolean recognised) {
|
public void dispose(boolean exception, boolean recognised) {
|
||||||
tryToClose(in, LOG, WARNING);
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
plugin.readerFinished(file, exception, recognised);
|
plugin.readerFinished(file, exception, recognised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FileTransportWriter implements TransportConnectionWriter {
|
class FileTransportWriter implements TransportConnectionWriter {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(FileTransportWriter.class.getName());
|
Logger.getLogger(FileTransportWriter.class.getName());
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
@@ -44,7 +44,11 @@ class FileTransportWriter implements TransportConnectionWriter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(boolean exception) {
|
public void dispose(boolean exception) {
|
||||||
tryToClose(out, LOG, WARNING);
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
plugin.writerFinished(file, exception);
|
plugin.writerFinished(file, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
@@ -22,30 +22,27 @@ import java.net.Socket;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.Collections.addAll;
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.Collections.sort;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
|
import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.join;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class LanTcpPlugin extends TcpPlugin {
|
class LanTcpPlugin extends TcpPlugin {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(LanTcpPlugin.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(LanTcpPlugin.class.getName());
|
||||||
|
|
||||||
private static final LanAddressComparator ADDRESS_COMPARATOR =
|
private static final LanAddressComparator ADDRESS_COMPARATOR =
|
||||||
new LanAddressComparator();
|
new LanAddressComparator();
|
||||||
@@ -80,13 +77,12 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
locals.add(new InetSocketAddress(local, 0));
|
locals.add(new InetSocketAddress(local, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//noinspection Java8ListSort
|
Collections.sort(locals, ADDRESS_COMPARATOR);
|
||||||
sort(locals, ADDRESS_COMPARATOR);
|
|
||||||
return locals;
|
return locals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<InetSocketAddress> parseSocketAddresses(String ipPorts) {
|
private List<InetSocketAddress> parseSocketAddresses(String ipPorts) {
|
||||||
if (isNullOrEmpty(ipPorts)) return emptyList();
|
if (StringUtils.isNullOrEmpty(ipPorts)) return Collections.emptyList();
|
||||||
String[] split = ipPorts.split(SEPARATOR);
|
String[] split = ipPorts.split(SEPARATOR);
|
||||||
List<InetSocketAddress> addresses = new ArrayList<>();
|
List<InetSocketAddress> addresses = new ArrayList<>();
|
||||||
for (String ipPort : split) {
|
for (String ipPort : split) {
|
||||||
@@ -102,23 +98,24 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
// Get the list of recently used addresses
|
// Get the list of recently used addresses
|
||||||
String setting = callback.getSettings().get(PREF_LAN_IP_PORTS);
|
String setting = callback.getSettings().get(PREF_LAN_IP_PORTS);
|
||||||
List<String> recent = new ArrayList<>();
|
List<String> recent = new ArrayList<>();
|
||||||
if (!isNullOrEmpty(setting)) addAll(recent, setting.split(SEPARATOR));
|
if (!StringUtils.isNullOrEmpty(setting))
|
||||||
|
Collections.addAll(recent, setting.split(SEPARATOR));
|
||||||
// Is the address already in the list?
|
// Is the address already in the list?
|
||||||
if (recent.remove(ipPort)) {
|
if (recent.remove(ipPort)) {
|
||||||
// Move the address to the start of the list
|
// Move the address to the start of the list
|
||||||
recent.add(0, ipPort);
|
recent.add(0, ipPort);
|
||||||
setting = join(recent, SEPARATOR);
|
setting = StringUtils.join(recent, SEPARATOR);
|
||||||
} else {
|
} else {
|
||||||
// Add the address to the start of the list
|
// Add the address to the start of the list
|
||||||
recent.add(0, ipPort);
|
recent.add(0, ipPort);
|
||||||
// Drop the least recently used address if the list is full
|
// Drop the least recently used address if the list is full
|
||||||
if (recent.size() > MAX_ADDRESSES)
|
if (recent.size() > MAX_ADDRESSES)
|
||||||
recent = recent.subList(0, MAX_ADDRESSES);
|
recent = recent.subList(0, MAX_ADDRESSES);
|
||||||
setting = join(recent, SEPARATOR);
|
setting = StringUtils.join(recent, SEPARATOR);
|
||||||
// Update the list of addresses shared with contacts
|
// Update the list of addresses shared with contacts
|
||||||
List<String> shared = new ArrayList<>(recent);
|
List<String> shared = new ArrayList<>(recent);
|
||||||
sort(shared);
|
Collections.sort(shared);
|
||||||
String property = join(shared, SEPARATOR);
|
String property = StringUtils.join(shared, SEPARATOR);
|
||||||
TransportProperties properties = new TransportProperties();
|
TransportProperties properties = new TransportProperties();
|
||||||
properties.put(PROP_IP_PORTS, property);
|
properties.put(PROP_IP_PORTS, property);
|
||||||
callback.mergeLocalProperties(properties);
|
callback.mergeLocalProperties(properties);
|
||||||
@@ -296,7 +293,11 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
IoUtils.tryToClose(ss, LOG, WARNING);
|
try {
|
||||||
|
ss.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
|
||||||
|
|
||||||
@@ -26,7 +25,8 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
|
|||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
class PortMapperImpl implements PortMapper {
|
class PortMapperImpl implements PortMapper {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(PortMapperImpl.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(PortMapperImpl.class.getName());
|
||||||
|
|
||||||
private final ShutdownManager shutdownManager;
|
private final ShutdownManager shutdownManager;
|
||||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
@@ -40,19 +40,17 @@ import static java.util.Collections.emptyList;
|
|||||||
import static java.util.Collections.list;
|
import static java.util.Collections.list;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
abstract class TcpPlugin implements DuplexPlugin {
|
abstract class TcpPlugin implements DuplexPlugin {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(TcpPlugin.class.getName());
|
|
||||||
|
|
||||||
private static final Pattern DOTTED_QUAD =
|
private static final Pattern DOTTED_QUAD =
|
||||||
Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
|
Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$");
|
||||||
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(TcpPlugin.class.getName());
|
||||||
|
|
||||||
protected final Executor ioExecutor, bindExecutor;
|
protected final Executor ioExecutor, bindExecutor;
|
||||||
protected final Backoff backoff;
|
protected final Backoff backoff;
|
||||||
@@ -85,7 +83,6 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
/**
|
/**
|
||||||
* Returns true if connections to the given address can be attempted.
|
* Returns true if connections to the given address can be attempted.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
protected abstract boolean isConnectable(InetSocketAddress remote);
|
protected abstract boolean isConnectable(InetSocketAddress remote);
|
||||||
|
|
||||||
TcpPlugin(Executor ioExecutor, Backoff backoff,
|
TcpPlugin(Executor ioExecutor, Backoff backoff,
|
||||||
@@ -156,9 +153,14 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void tryToClose(@Nullable ServerSocket ss) {
|
protected void tryToClose(@Nullable ServerSocket ss) {
|
||||||
IoUtils.tryToClose(ss, LOG, WARNING);
|
try {
|
||||||
|
if (ss != null) ss.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
} finally {
|
||||||
callback.transportDisabled();
|
callback.transportDisabled();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String getIpPortString(InetSocketAddress a) {
|
String getIpPortString(InetSocketAddress a) {
|
||||||
String addr = a.getAddress().getHostAddress();
|
String addr = a.getAddress().getHostAddress();
|
||||||
@@ -265,7 +267,7 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
InetSocketAddress parseSocketAddress(String ipPort) {
|
InetSocketAddress parseSocketAddress(String ipPort) {
|
||||||
if (isNullOrEmpty(ipPort)) return null;
|
if (StringUtils.isNullOrEmpty(ipPort)) return null;
|
||||||
String[] split = ipPort.split(":");
|
String[] split = ipPort.split(":");
|
||||||
if (split.length != 2) return null;
|
if (split.length != 2) return null;
|
||||||
String addr = split[0], port = split[1];
|
String addr = split[0], port = split[1];
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ import org.briarproject.bramble.api.properties.TransportProperties;
|
|||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -81,7 +80,8 @@ class WanTcpPlugin extends TcpPlugin {
|
|||||||
protected List<InetSocketAddress> getRemoteSocketAddresses(
|
protected List<InetSocketAddress> getRemoteSocketAddresses(
|
||||||
TransportProperties p) {
|
TransportProperties p) {
|
||||||
InetSocketAddress parsed = parseSocketAddress(p.get(PROP_IP_PORT));
|
InetSocketAddress parsed = parseSocketAddress(p.get(PROP_IP_PORT));
|
||||||
return parsed == null ? emptyList() : singletonList(parsed);
|
if (parsed == null) return Collections.emptyList();
|
||||||
|
return Collections.singletonList(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.briarproject.bramble.api.system.LocationUtils;
|
|||||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -42,7 +43,9 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -56,12 +59,8 @@ import java.util.zip.ZipInputStream;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static java.util.Collections.singletonList;
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
|
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
|
||||||
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
|
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
|
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
|
||||||
@@ -71,11 +70,9 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
|
|||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING;
|
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
||||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
@@ -84,7 +81,8 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(TorPlugin.class.getName());
|
private static final Logger LOG =
|
||||||
|
Logger.getLogger(TorPlugin.class.getName());
|
||||||
|
|
||||||
private static final String[] EVENTS = {
|
private static final String[] EVENTS = {
|
||||||
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
"CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR"
|
||||||
@@ -253,11 +251,11 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
controlConnection.authenticate(read(cookieFile));
|
controlConnection.authenticate(read(cookieFile));
|
||||||
// Tell Tor to exit when the control connection is closed
|
// Tell Tor to exit when the control connection is closed
|
||||||
controlConnection.takeOwnership();
|
controlConnection.takeOwnership();
|
||||||
controlConnection.resetConf(singletonList(OWNER));
|
controlConnection.resetConf(Collections.singletonList(OWNER));
|
||||||
running = true;
|
running = true;
|
||||||
// Register to receive events from the Tor process
|
// Register to receive events from the Tor process
|
||||||
controlConnection.setEventHandler(this);
|
controlConnection.setEventHandler(this);
|
||||||
controlConnection.setEvents(asList(EVENTS));
|
controlConnection.setEvents(Arrays.asList(EVENTS));
|
||||||
// Check whether Tor has already bootstrapped
|
// Check whether Tor has already bootstrapped
|
||||||
String phase = controlConnection.getInfo("status/bootstrap-phase");
|
String phase = controlConnection.getInfo("status/bootstrap-phase");
|
||||||
if (phase != null && phase.contains("PROGRESS=100")) {
|
if (phase != null && phase.contains("PROGRESS=100")) {
|
||||||
@@ -282,34 +280,31 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
try {
|
try {
|
||||||
// The done file may already exist from a previous installation
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
doneFile.delete();
|
doneFile.delete();
|
||||||
// Unzip the Tor binary to the filesystem
|
// Unzip the Tor binary to the filesystem
|
||||||
in = getTorInputStream();
|
in = getTorInputStream();
|
||||||
out = new FileOutputStream(torFile);
|
out = new FileOutputStream(torFile);
|
||||||
copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
// Make the Tor binary executable
|
// Make the Tor binary executable
|
||||||
if (!torFile.setExecutable(true, true)) throw new IOException();
|
if (!torFile.setExecutable(true, true)) throw new IOException();
|
||||||
// Unzip the GeoIP database to the filesystem
|
// Unzip the GeoIP database to the filesystem
|
||||||
in = getGeoIpInputStream();
|
in = getGeoIpInputStream();
|
||||||
out = new FileOutputStream(geoIpFile);
|
out = new FileOutputStream(geoIpFile);
|
||||||
copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
// Unzip the Obfs4 proxy to the filesystem
|
// Unzip the Obfs4 proxy to the filesystem
|
||||||
in = getObfs4InputStream();
|
in = getObfs4InputStream();
|
||||||
out = new FileOutputStream(obfs4File);
|
out = new FileOutputStream(obfs4File);
|
||||||
copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
// Make the Obfs4 proxy executable
|
// Make the Obfs4 proxy executable
|
||||||
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||||
// Copy the config file to the filesystem
|
// Copy the config file to the filesystem
|
||||||
in = getConfigInputStream();
|
in = getConfigInputStream();
|
||||||
out = new FileOutputStream(configFile);
|
out = new FileOutputStream(configFile);
|
||||||
copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
if (!doneFile.createNewFile())
|
doneFile.createNewFile();
|
||||||
LOG.warning("Failed to create done file");
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
IoUtils.tryToClose(in, LOG, WARNING);
|
tryToClose(in);
|
||||||
IoUtils.tryToClose(out, LOG, WARNING);
|
tryToClose(out);
|
||||||
throw new PluginException(e);
|
throw new PluginException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,6 +341,22 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
return getClass().getClassLoader().getResourceAsStream("torrc");
|
return getClass().getClassLoader().getResourceAsStream("torrc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Closeable c) {
|
||||||
|
try {
|
||||||
|
if (c != null) c.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Socket s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void listFiles(File f) {
|
private void listFiles(File f) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
File[] children = f.listFiles();
|
File[] children = f.listFiles();
|
||||||
@@ -367,7 +378,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
} finally {
|
} finally {
|
||||||
IoUtils.tryToClose(in, LOG, WARNING);
|
tryToClose(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,15 +418,21 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable ServerSocket ss) {
|
private void tryToClose(@Nullable ServerSocket ss) {
|
||||||
IoUtils.tryToClose(ss, LOG, WARNING);
|
try {
|
||||||
|
if (ss != null) ss.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
} finally {
|
||||||
callback.transportDisabled();
|
callback.transportDisabled();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void publishHiddenService(String port) {
|
private void publishHiddenService(String port) {
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
LOG.info("Creating hidden service");
|
LOG.info("Creating hidden service");
|
||||||
String privKey = settings.get(HS_PRIVKEY);
|
String privKey = settings.get(HS_PRIVKEY);
|
||||||
Map<Integer, String> portLines = singletonMap(80, "127.0.0.1:" + port);
|
Map<Integer, String> portLines =
|
||||||
|
Collections.singletonMap(80, "127.0.0.1:" + port);
|
||||||
Map<String, String> response;
|
Map<String, String> response;
|
||||||
try {
|
try {
|
||||||
// Use the control connection to set up the hidden service
|
// Use the control connection to set up the hidden service
|
||||||
@@ -576,7 +593,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
LOG.info("Could not connect to " + scrubOnion(bestOnion)
|
LOG.info("Could not connect to " + scrubOnion(bestOnion)
|
||||||
+ ": " + e.toString());
|
+ ": " + e.toString());
|
||||||
}
|
}
|
||||||
IoUtils.tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -653,10 +670,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (s.getNamespace().equals(ID.getString())) {
|
if (s.getNamespace().equals(ID.getString())) {
|
||||||
LOG.info("Tor settings updated");
|
LOG.info("Tor settings updated");
|
||||||
settings = s.getSettings();
|
settings = s.getSettings();
|
||||||
// Works around a bug introduced in Tor 0.3.4.8.
|
// Works around a bug introduced in Tor 0.3.4.8. Could be
|
||||||
// https://trac.torproject.org/projects/tor/ticket/28027
|
// replaced with callback.transportDisabled() when fixed.
|
||||||
// Could be replaced with callback.transportDisabled()
|
|
||||||
// when fixed.
|
|
||||||
disableNetwork();
|
disableNetwork();
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus(),
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
batteryManager.isCharging());
|
batteryManager.isCharging());
|
||||||
@@ -692,8 +707,6 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
int network = settings.getInt(PREF_TOR_NETWORK,
|
int network = settings.getInt(PREF_TOR_NETWORK,
|
||||||
PREF_TOR_NETWORK_AUTOMATIC);
|
PREF_TOR_NETWORK_AUTOMATIC);
|
||||||
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
|
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
|
||||||
boolean onlyWhenCharging =
|
|
||||||
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
|
|
||||||
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
||||||
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
|
|
||||||
@@ -708,12 +721,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (!online) {
|
if (!online) {
|
||||||
LOG.info("Disabling network, device is offline");
|
LOG.info("Disabling network, device is offline");
|
||||||
enableNetwork(false);
|
enableNetwork(false);
|
||||||
} else if (!charging && onlyWhenCharging) {
|
|
||||||
LOG.info("Disabling network, device is on battery");
|
|
||||||
enableNetwork(false);
|
|
||||||
} else if (network == PREF_TOR_NETWORK_NEVER ||
|
} else if (network == PREF_TOR_NETWORK_NEVER ||
|
||||||
(!useMobile && !wifi)) {
|
(!useMobile && !wifi)) {
|
||||||
LOG.info("Disabling network, device is using mobile data");
|
LOG.info("Disabling network due to setting");
|
||||||
enableNetwork(false);
|
enableNetwork(false);
|
||||||
} else if (automatic && blocked && !bridgesWork) {
|
} else if (automatic && blocked && !bridgesWork) {
|
||||||
LOG.info("Disabling network, country is blocked");
|
LOG.info("Disabling network, country is blocked");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.record.Record;
|
import org.briarproject.bramble.api.record.Record;
|
||||||
import org.briarproject.bramble.api.record.RecordReader;
|
import org.briarproject.bramble.api.record.RecordReader;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -13,7 +14,6 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
|
|
||||||
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||||
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
|
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint16;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -31,7 +31,7 @@ class RecordReaderImpl implements RecordReader {
|
|||||||
in.readFully(header);
|
in.readFully(header);
|
||||||
byte protocolVersion = header[0];
|
byte protocolVersion = header[0];
|
||||||
byte recordType = header[1];
|
byte recordType = header[1];
|
||||||
int payloadLength = readUint16(header, 2);
|
int payloadLength = ByteUtils.readUint16(header, 2);
|
||||||
if (payloadLength < 0 || payloadLength > MAX_RECORD_PAYLOAD_BYTES)
|
if (payloadLength < 0 || payloadLength > MAX_RECORD_PAYLOAD_BYTES)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
byte[] payload = new byte[payloadLength];
|
byte[] payload = new byte[payloadLength];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.record;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.record.Record;
|
import org.briarproject.bramble.api.record.Record;
|
||||||
import org.briarproject.bramble.api.record.RecordWriter;
|
import org.briarproject.bramble.api.record.RecordWriter;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -10,7 +11,6 @@ import java.io.OutputStream;
|
|||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
|
import static org.briarproject.bramble.api.record.Record.RECORD_HEADER_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -28,7 +28,7 @@ class RecordWriterImpl implements RecordWriter {
|
|||||||
byte[] payload = r.getPayload();
|
byte[] payload = r.getPayload();
|
||||||
header[0] = r.getProtocolVersion();
|
header[0] = r.getProtocolVersion();
|
||||||
header[1] = r.getRecordType();
|
header[1] = r.getRecordType();
|
||||||
writeUint16(payload.length, header, 2);
|
ByteUtils.writeUint16(payload.length, header, 2);
|
||||||
out.write(header);
|
out.write(header);
|
||||||
out.write(payload);
|
out.write(payload);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package org.briarproject.bramble.reliability;
|
package org.briarproject.bramble.reliability;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint16;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class Ack extends Frame {
|
class Ack extends Frame {
|
||||||
@@ -25,10 +23,10 @@ class Ack extends Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getWindowSize() {
|
int getWindowSize() {
|
||||||
return readUint16(buf, 5);
|
return ByteUtils.readUint16(buf, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowSize(int windowSize) {
|
void setWindowSize(int windowSize) {
|
||||||
writeUint16(windowSize, buf, 5);
|
ByteUtils.writeUint16(windowSize, buf, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
package org.briarproject.bramble.reliability;
|
package org.briarproject.bramble.reliability;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.readUint32;
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
abstract class Frame {
|
abstract class Frame {
|
||||||
|
|
||||||
static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
|
static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
|
||||||
|
|
||||||
final byte[] buf;
|
protected final byte[] buf;
|
||||||
|
|
||||||
Frame(byte[] buf) {
|
Frame(byte[] buf) {
|
||||||
this.buf = buf;
|
this.buf = buf;
|
||||||
@@ -28,11 +26,11 @@ abstract class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long getChecksum() {
|
long getChecksum() {
|
||||||
return readUint32(buf, buf.length - 4);
|
return ByteUtils.readUint32(buf, buf.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setChecksum(long checksum) {
|
void setChecksum(long checksum) {
|
||||||
writeUint32(checksum, buf, buf.length - 4);
|
ByteUtils.writeUint32(checksum, buf, buf.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
long calculateChecksum() {
|
long calculateChecksum() {
|
||||||
@@ -40,11 +38,11 @@ abstract class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long getSequenceNumber() {
|
long getSequenceNumber() {
|
||||||
return readUint32(buf, 1);
|
return ByteUtils.readUint32(buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSequenceNumber(long sequenceNumber) {
|
void setSequenceNumber(long sequenceNumber) {
|
||||||
writeUint32(sequenceNumber, buf, 1);
|
ByteUtils.writeUint32(sequenceNumber, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ class Receiver implements ReadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("StatementWithEmptyBody")
|
|
||||||
private void handleData(byte[] b) throws IOException {
|
private void handleData(byte[] b) throws IOException {
|
||||||
windowLock.lock();
|
windowLock.lock();
|
||||||
try {
|
try {
|
||||||
@@ -125,7 +124,6 @@ class Receiver implements ReadHandler {
|
|||||||
finalSequenceNumber = sequenceNumber;
|
finalSequenceNumber = sequenceNumber;
|
||||||
// Remove any data frames with higher sequence numbers
|
// Remove any data frames with higher sequence numbers
|
||||||
Iterator<Data> it = dataFrames.iterator();
|
Iterator<Data> it = dataFrames.iterator();
|
||||||
//noinspection Java8CollectionRemoveIf
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Data d1 = it.next();
|
Data d1 = it.next();
|
||||||
if (d1.getSequenceNumber() >= finalSequenceNumber)
|
if (d1.getSequenceNumber() >= finalSequenceNumber)
|
||||||
@@ -150,7 +148,6 @@ class Receiver implements ReadHandler {
|
|||||||
|
|
||||||
private static class SequenceNumberComparator implements Comparator<Data> {
|
private static class SequenceNumberComparator implements Comparator<Data> {
|
||||||
|
|
||||||
@SuppressWarnings("UseCompareMethod")
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Data d1, Data d2) {
|
public int compare(Data d1, Data d2) {
|
||||||
long s1 = d1.getSequenceNumber(), s2 = d2.getSequenceNumber();
|
long s1 = d1.getSequenceNumber(), s2 = d2.getSequenceNumber();
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import java.io.InputStream;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ReceiverInputStream extends InputStream {
|
class ReceiverInputStream extends InputStream {
|
||||||
@@ -46,13 +44,12 @@ class ReceiverInputStream extends InputStream {
|
|||||||
while (length == 0) if (!receive()) return -1;
|
while (length == 0) if (!receive()) return -1;
|
||||||
if (data == null) throw new AssertionError();
|
if (data == null) throw new AssertionError();
|
||||||
len = Math.min(len, length);
|
len = Math.min(len, length);
|
||||||
arraycopy(data.getBuffer(), offset, b, off, len);
|
System.arraycopy(data.getBuffer(), offset, b, off, len);
|
||||||
offset += len;
|
offset += len;
|
||||||
length -= len;
|
length -= len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
private boolean receive() throws IOException {
|
private boolean receive() throws IOException {
|
||||||
if (length != 0) throw new AssertionError();
|
if (length != 0) throw new AssertionError();
|
||||||
if (data != null && data.isLastFrame()) {
|
if (data != null && data.isLastFrame()) {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -26,7 +25,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
|
|||||||
private static final int TICK_INTERVAL = 500; // Milliseconds
|
private static final int TICK_INTERVAL = 500; // Milliseconds
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ReliabilityLayerImpl.class.getName());
|
Logger.getLogger(ReliabilityLayerImpl.class.getName());
|
||||||
|
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -97,7 +96,7 @@ class Sender {
|
|||||||
}
|
}
|
||||||
// If any older data frames are outstanding, retransmit the oldest
|
// If any older data frames are outstanding, retransmit the oldest
|
||||||
if (foundIndex > 0) {
|
if (foundIndex > 0) {
|
||||||
fastRetransmit = requireNonNull(outstanding.poll());
|
fastRetransmit = outstanding.poll();
|
||||||
fastRetransmit.lastTransmitted = now;
|
fastRetransmit.lastTransmitted = now;
|
||||||
fastRetransmit.retransmitted = true;
|
fastRetransmit.retransmitted = true;
|
||||||
outstanding.add(fastRetransmit);
|
outstanding.add(fastRetransmit);
|
||||||
@@ -192,7 +191,7 @@ class Sender {
|
|||||||
writeHandler.handleWrite(d.getBuffer());
|
writeHandler.handleWrite(d.getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush() throws InterruptedException {
|
void flush() throws IOException, InterruptedException {
|
||||||
windowLock.lock();
|
windowLock.lock();
|
||||||
try {
|
try {
|
||||||
while (dataWaiting || !outstanding.isEmpty())
|
while (dataWaiting || !outstanding.isEmpty())
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import java.io.OutputStream;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class SenderOutputStream extends OutputStream {
|
class SenderOutputStream extends OutputStream {
|
||||||
@@ -61,20 +59,20 @@ class SenderOutputStream extends OutputStream {
|
|||||||
public void write(byte[] b, int off, int len) throws IOException {
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
||||||
while (available <= len) {
|
while (available <= len) {
|
||||||
arraycopy(b, off, buf, offset, available);
|
System.arraycopy(b, off, buf, offset, available);
|
||||||
offset += available;
|
offset += available;
|
||||||
send(false);
|
send(false);
|
||||||
off += available;
|
off += available;
|
||||||
len -= available;
|
len -= available;
|
||||||
available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
|
||||||
}
|
}
|
||||||
arraycopy(b, off, buf, offset, len);
|
System.arraycopy(b, off, buf, offset, len);
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send(boolean lastFrame) throws IOException {
|
private void send(boolean lastFrame) throws IOException {
|
||||||
byte[] frame = new byte[offset + Data.FOOTER_LENGTH];
|
byte[] frame = new byte[offset + Data.FOOTER_LENGTH];
|
||||||
arraycopy(buf, 0, frame, 0, frame.length);
|
System.arraycopy(buf, 0, frame, 0, frame.length);
|
||||||
Data d = new Data(frame);
|
Data d = new Data(frame);
|
||||||
d.setLastFrame(lastFrame);
|
d.setLastFrame(lastFrame);
|
||||||
d.setSequenceNumber(sequenceNumber++);
|
d.setSequenceNumber(sequenceNumber++);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class SlipDecoder implements ReadHandler {
|
class SlipDecoder implements ReadHandler {
|
||||||
@@ -38,7 +36,7 @@ class SlipDecoder implements ReadHandler {
|
|||||||
} else {
|
} else {
|
||||||
if (decodedLength > 0) {
|
if (decodedLength > 0) {
|
||||||
byte[] decoded = new byte[decodedLength];
|
byte[] decoded = new byte[decodedLength];
|
||||||
arraycopy(buf, 0, decoded, 0, decodedLength);
|
System.arraycopy(buf, 0, decoded, 0, decodedLength);
|
||||||
readHandler.handleRead(decoded);
|
readHandler.handleRead(decoded);
|
||||||
}
|
}
|
||||||
reset(false);
|
reset(false);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.reporting;
|
package org.briarproject.bramble.reporting;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -16,9 +17,6 @@ import java.util.concurrent.Semaphore;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.io.File.createTempFile;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.getInputStream;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class DevReportServer {
|
public class DevReportServer {
|
||||||
@@ -44,7 +42,6 @@ public class DevReportServer {
|
|||||||
TokenBucket bucket = new TokenBucket();
|
TokenBucket bucket = new TokenBucket();
|
||||||
bucket.start();
|
bucket.start();
|
||||||
try {
|
try {
|
||||||
//noinspection InfiniteLoopStatement
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Socket s = ss.accept();
|
Socket s = ss.accept();
|
||||||
System.out.println("Incoming connection");
|
System.out.println("Incoming connection");
|
||||||
@@ -104,7 +101,6 @@ public class DevReportServer {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
//noinspection InfiniteLoopStatement
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// If the bucket isn't full, add a token
|
// If the bucket isn't full, add a token
|
||||||
if (semaphore.availablePermits() < MAX_TOKENS) {
|
if (semaphore.availablePermits() < MAX_TOKENS) {
|
||||||
@@ -135,11 +131,9 @@ public class DevReportServer {
|
|||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
try {
|
try {
|
||||||
socket.setSoTimeout(SOCKET_TIMEOUT_MS);
|
socket.setSoTimeout(SOCKET_TIMEOUT_MS);
|
||||||
in = getInputStream(socket);
|
in = IoUtils.getInputStream(socket);
|
||||||
// Directory may already exist
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
reportDir.mkdirs();
|
reportDir.mkdirs();
|
||||||
reportFile = createTempFile(FILE_PREFIX, FILE_SUFFIX,
|
reportFile = File.createTempFile(FILE_PREFIX, FILE_SUFFIX,
|
||||||
reportDir);
|
reportDir);
|
||||||
out = new FileOutputStream(reportFile);
|
out = new FileOutputStream(reportFile);
|
||||||
System.out.println("Saving report to " + reportFile);
|
System.out.println("Saving report to " + reportFile);
|
||||||
@@ -157,8 +151,7 @@ public class DevReportServer {
|
|||||||
System.out.println("Saved " + length + " bytes");
|
System.out.println("Saved " + length + " bytes");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
if (reportFile != null && !reportFile.delete())
|
if (reportFile != null) reportFile.delete();
|
||||||
System.err.println("Failed to delete report");
|
|
||||||
} finally {
|
} finally {
|
||||||
tryToClose(in);
|
tryToClose(in);
|
||||||
tryToClose(out);
|
tryToClose(out);
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import org.briarproject.bramble.api.plugin.TorConstants;
|
|||||||
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
|
||||||
import org.briarproject.bramble.api.reporting.DevConfig;
|
import org.briarproject.bramble.api.reporting.DevConfig;
|
||||||
import org.briarproject.bramble.api.reporting.DevReporter;
|
import org.briarproject.bramble.api.reporting.DevReporter;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -23,23 +26,20 @@ import java.net.Socket;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.getOutputStream;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class DevReporterImpl implements DevReporter, EventListener {
|
class DevReporterImpl implements DevReporter, EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(DevReporterImpl.class.getName());
|
Logger.getLogger(DevReporterImpl.class.getName());
|
||||||
|
|
||||||
private static final int SOCKET_TIMEOUT = 30 * 1000; // 30 seconds
|
private static final int SOCKET_TIMEOUT = 30 * 1000; // 30 seconds
|
||||||
private static final int LINE_LENGTH = 70;
|
private static final int LINE_LENGTH = 70;
|
||||||
@@ -66,7 +66,7 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
s.setSoTimeout(SOCKET_TIMEOUT);
|
s.setSoTimeout(SOCKET_TIMEOUT);
|
||||||
return s;
|
return s;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(s, LOG, WARNING);
|
tryToClose(s);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
public void encryptReportToFile(File reportDir, String filename,
|
public void encryptReportToFile(File reportDir, String filename,
|
||||||
String report) throws FileNotFoundException {
|
String report) throws FileNotFoundException {
|
||||||
LOG.info("Encrypting report to file");
|
LOG.info("Encrypting report to file");
|
||||||
byte[] plaintext = toUtf8(report);
|
byte[] plaintext = StringUtils.toUtf8(report);
|
||||||
byte[] ciphertext = crypto.encryptToKey(devConfig.getDevPublicKey(),
|
byte[] ciphertext = crypto.encryptToKey(devConfig.getDevPublicKey(),
|
||||||
plaintext);
|
plaintext);
|
||||||
String armoured = crypto.asciiArmour(ciphertext, LINE_LENGTH);
|
String armoured = crypto.asciiArmour(ciphertext, LINE_LENGTH);
|
||||||
@@ -88,7 +88,8 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
writer.append(armoured);
|
writer.append(armoured);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
} finally {
|
} finally {
|
||||||
tryToClose(writer, LOG, WARNING);
|
if (writer != null)
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,18 +112,36 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
LOG.info("Sending reports to developers");
|
LOG.info("Sending reports to developers");
|
||||||
for (File f : reports) {
|
for (File f : reports) {
|
||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
|
InputStream in = null;
|
||||||
try {
|
try {
|
||||||
Socket s = connectToDevelopers();
|
Socket s = connectToDevelopers();
|
||||||
out = getOutputStream(s);
|
out = IoUtils.getOutputStream(s);
|
||||||
InputStream in = new FileInputStream(f);
|
in = new FileInputStream(f);
|
||||||
copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
if (!f.delete()) LOG.warning("Failed to delete report");
|
f.delete();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(WARNING, "Failed to send reports", e);
|
LOG.log(WARNING, "Failed to send reports", e);
|
||||||
tryToClose(out, LOG, WARNING);
|
tryToClose(out);
|
||||||
|
tryToClose(in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG.info("Reports sent");
|
LOG.info("Reports sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Closeable c) {
|
||||||
|
try {
|
||||||
|
if (c != null) c.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryToClose(@Nullable Socket s) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble.socks;
|
package org.briarproject.bramble.socks;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -11,9 +12,6 @@ import java.net.Socket;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint16;
|
|
||||||
import static org.briarproject.bramble.util.IoUtils.read;
|
|
||||||
|
|
||||||
class SocksSocket extends Socket {
|
class SocksSocket extends Socket {
|
||||||
|
|
||||||
private static final String[] ERRORS = {
|
private static final String[] ERRORS = {
|
||||||
@@ -28,7 +26,6 @@ class SocksSocket extends Socket {
|
|||||||
"Address type not supported"
|
"Address type not supported"
|
||||||
};
|
};
|
||||||
|
|
||||||
@SuppressWarnings("MismatchedReadAndWriteOfArray")
|
|
||||||
private static final byte[] UNSPECIFIED_ADDRESS = new byte[4];
|
private static final byte[] UNSPECIFIED_ADDRESS = new byte[4];
|
||||||
|
|
||||||
private final SocketAddress proxy;
|
private final SocketAddress proxy;
|
||||||
@@ -91,7 +88,7 @@ class SocksSocket extends Socket {
|
|||||||
|
|
||||||
private void receiveMethodResponse(InputStream in) throws IOException {
|
private void receiveMethodResponse(InputStream in) throws IOException {
|
||||||
byte[] methodResponse = new byte[2];
|
byte[] methodResponse = new byte[2];
|
||||||
read(in, methodResponse);
|
IoUtils.read(in, methodResponse);
|
||||||
byte version = methodResponse[0];
|
byte version = methodResponse[0];
|
||||||
byte method = methodResponse[1];
|
byte method = methodResponse[1];
|
||||||
if (version != 5)
|
if (version != 5)
|
||||||
@@ -111,14 +108,14 @@ class SocksSocket extends Socket {
|
|||||||
connectRequest[4] = (byte) host.length(); // Length of domain name
|
connectRequest[4] = (byte) host.length(); // Length of domain name
|
||||||
for (int i = 0; i < host.length(); i++)
|
for (int i = 0; i < host.length(); i++)
|
||||||
connectRequest[5 + i] = (byte) host.charAt(i);
|
connectRequest[5 + i] = (byte) host.charAt(i);
|
||||||
writeUint16(port, connectRequest, connectRequest.length - 2);
|
ByteUtils.writeUint16(port, connectRequest, connectRequest.length - 2);
|
||||||
out.write(connectRequest);
|
out.write(connectRequest);
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void receiveConnectResponse(InputStream in) throws IOException {
|
private void receiveConnectResponse(InputStream in) throws IOException {
|
||||||
byte[] connectResponse = new byte[4];
|
byte[] connectResponse = new byte[4];
|
||||||
read(in, connectResponse);
|
IoUtils.read(in, connectResponse);
|
||||||
int version = connectResponse[0] & 0xFF;
|
int version = connectResponse[0] & 0xFF;
|
||||||
int reply = connectResponse[1] & 0xFF;
|
int reply = connectResponse[1] & 0xFF;
|
||||||
int addressType = connectResponse[3] & 0xFF;
|
int addressType = connectResponse[3] & 0xFF;
|
||||||
@@ -129,9 +126,9 @@ class SocksSocket extends Socket {
|
|||||||
throw new IOException("Connection failed: " + ERRORS[reply]);
|
throw new IOException("Connection failed: " + ERRORS[reply]);
|
||||||
else throw new IOException("Connection failed: " + reply);
|
else throw new IOException("Connection failed: " + reply);
|
||||||
}
|
}
|
||||||
if (addressType == 1) read(in, new byte[4]); // IPv4
|
if (addressType == 1) IoUtils.read(in, new byte[4]); // IPv4
|
||||||
else if (addressType == 4) read(in, new byte[16]); // IPv6
|
else if (addressType == 4) IoUtils.read(in, new byte[16]); // IPv6
|
||||||
else throw new IOException("Unsupported address type: " + addressType);
|
else throw new IOException("Unsupported address type: " + addressType);
|
||||||
read(in, new byte[2]); // Port number
|
IoUtils.read(in, new byte[2]); // Port number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class SocksSocketFactory extends SocketFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Socket createSocket(InetAddress address, int port,
|
public Socket createSocket(InetAddress address, int port,
|
||||||
InetAddress localAddress, int localPort) {
|
InetAddress localAddress, int localPort) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.STOPPING;
|
||||||
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||||
@@ -56,7 +55,7 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
class DuplexOutgoingSession implements SyncSession, EventListener {
|
class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(DuplexOutgoingSession.class.getName());
|
Logger.getLogger(DuplexOutgoingSession.class.getName());
|
||||||
|
|
||||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {
|
private static final ThrowingRunnable<IOException> CLOSE = () -> {
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import org.briarproject.bramble.api.sync.ClientId;
|
|||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -13,8 +15,6 @@ import javax.inject.Inject;
|
|||||||
import static org.briarproject.bramble.api.sync.Group.FORMAT_VERSION;
|
import static org.briarproject.bramble.api.sync.Group.FORMAT_VERSION;
|
||||||
import static org.briarproject.bramble.api.sync.GroupId.LABEL;
|
import static org.briarproject.bramble.api.sync.GroupId.LABEL;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||||
import static org.briarproject.bramble.util.ByteUtils.writeUint32;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -33,9 +33,10 @@ class GroupFactoryImpl implements GroupFactory {
|
|||||||
@Override
|
@Override
|
||||||
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
|
public Group createGroup(ClientId c, int majorVersion, byte[] descriptor) {
|
||||||
byte[] majorVersionBytes = new byte[INT_32_BYTES];
|
byte[] majorVersionBytes = new byte[INT_32_BYTES];
|
||||||
writeUint32(majorVersion, majorVersionBytes, 0);
|
ByteUtils.writeUint32(majorVersion, majorVersionBytes, 0);
|
||||||
byte[] hash = crypto.hash(LABEL, FORMAT_VERSION_BYTES,
|
byte[] hash = crypto.hash(LABEL, FORMAT_VERSION_BYTES,
|
||||||
toUtf8(c.getString()), majorVersionBytes, descriptor);
|
StringUtils.toUtf8(c.getString()), majorVersionBytes,
|
||||||
|
descriptor);
|
||||||
return new Group(new GroupId(hash), c, majorVersion, descriptor);
|
return new Group(new GroupId(hash), c, majorVersion, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user