mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Fixed race condition in descriptor publication.
If two contacts publish their descriptors simultaneously, they may both stop polling without retrieving each other's descriptors. Continue polling for 2 intervals after publishing the descriptor.
This commit is contained in:
@@ -24,6 +24,7 @@ import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
|
|||||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.api.properties.TransportProperties;
|
import org.briarproject.api.properties.TransportProperties;
|
||||||
import org.briarproject.api.settings.Settings;
|
import org.briarproject.api.settings.Settings;
|
||||||
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.system.LocationUtils;
|
import org.briarproject.api.system.LocationUtils;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
@@ -72,13 +73,14 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
private static final int HOSTNAME_TIMEOUT = 30 * 1000; // Milliseconds
|
private static final int HOSTNAME_TIMEOUT = 30 * 1000; // Milliseconds
|
||||||
private static final Pattern ONION =
|
private static final Pattern ONION =
|
||||||
Pattern.compile("[a-z2-7]{16}\\.onion");
|
Pattern.compile("[a-z2-7]{16}\\.onion");
|
||||||
private static final int DESCRIPTOR_THRESHOLD = 3;
|
private static final int MIN_DESCRIPTORS_PUBLISHED = 3;
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(TorPlugin.class.getName());
|
Logger.getLogger(TorPlugin.class.getName());
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
|
private final Clock clock;
|
||||||
private final DuplexPluginCallback callback;
|
private final DuplexPluginCallback callback;
|
||||||
private final String architecture;
|
private final String architecture;
|
||||||
private final int maxLatency, maxIdleTime, pollingInterval, socketTimeout;
|
private final int maxLatency, maxIdleTime, pollingInterval, socketTimeout;
|
||||||
@@ -91,6 +93,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
private volatile boolean bootstrapped = false;
|
private volatile boolean bootstrapped = false;
|
||||||
private volatile boolean connectedToWifi = false;
|
private volatile boolean connectedToWifi = false;
|
||||||
private volatile boolean online = false;
|
private volatile boolean online = false;
|
||||||
|
private volatile long descriptorsPublishedTime = Long.MAX_VALUE;
|
||||||
|
|
||||||
private volatile ServerSocket socket = null;
|
private volatile ServerSocket socket = null;
|
||||||
private volatile Socket controlSocket = null;
|
private volatile Socket controlSocket = null;
|
||||||
@@ -98,12 +101,13 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
private volatile BroadcastReceiver networkStateReceiver = null;
|
private volatile BroadcastReceiver networkStateReceiver = null;
|
||||||
|
|
||||||
TorPlugin(Executor ioExecutor, Context appContext,
|
TorPlugin(Executor ioExecutor, Context appContext,
|
||||||
LocationUtils locationUtils, DuplexPluginCallback callback,
|
LocationUtils locationUtils, Clock clock,
|
||||||
String architecture, int maxLatency, int maxIdleTime,
|
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||||
int pollingInterval) {
|
int maxIdleTime, int pollingInterval) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
|
this.clock = clock;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.architecture = architecture;
|
this.architecture = architecture;
|
||||||
this.maxLatency = maxLatency;
|
this.maxLatency = maxLatency;
|
||||||
@@ -467,6 +471,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
if (!enable) {
|
if (!enable) {
|
||||||
circuitBuilt.set(false);
|
circuitBuilt.set(false);
|
||||||
descriptorsPublished.set(0);
|
descriptorsPublished.set(0);
|
||||||
|
descriptorsPublishedTime = Long.MAX_VALUE;
|
||||||
callback.transportDisabled();
|
callback.transportDisabled();
|
||||||
}
|
}
|
||||||
networkEnabled = enable;
|
networkEnabled = enable;
|
||||||
@@ -508,9 +513,12 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
|
|
||||||
public void poll(Collection<ContactId> connected) {
|
public void poll(Collection<ContactId> connected) {
|
||||||
if (!isRunning()) return;
|
if (!isRunning()) return;
|
||||||
if (descriptorsPublished.get() >= DESCRIPTOR_THRESHOLD) {
|
if (descriptorsPublished.get() >= MIN_DESCRIPTORS_PUBLISHED) {
|
||||||
LOG.info("Hidden service descriptor published, not polling");
|
long now = clock.currentTimeMillis();
|
||||||
return;
|
if (now - descriptorsPublishedTime >= 2 * pollingInterval) {
|
||||||
|
LOG.info("Hidden service descriptor published, not polling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: Pass properties to connectAndCallBack()
|
// TODO: Pass properties to connectAndCallBack()
|
||||||
for (ContactId c : callback.getRemoteProperties().keySet())
|
for (ContactId c : callback.getRemoteProperties().keySet())
|
||||||
@@ -589,8 +597,10 @@ class TorPlugin implements DuplexPlugin, EventHandler,
|
|||||||
public void unrecognized(String type, String msg) {
|
public void unrecognized(String type, String msg) {
|
||||||
if (type.equals("HS_DESC") && msg.startsWith("UPLOADED")) {
|
if (type.equals("HS_DESC") && msg.startsWith("UPLOADED")) {
|
||||||
int descriptors = descriptorsPublished.incrementAndGet();
|
int descriptors = descriptorsPublished.incrementAndGet();
|
||||||
if (descriptors == DESCRIPTOR_THRESHOLD)
|
if (descriptors == MIN_DESCRIPTORS_PUBLISHED) {
|
||||||
LOG.info("Hidden service descriptor published");
|
LOG.info("Hidden service descriptor published");
|
||||||
|
descriptorsPublishedTime = clock.currentTimeMillis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import org.briarproject.api.event.EventBus;
|
|||||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
|
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
||||||
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.system.LocationUtils;
|
import org.briarproject.api.system.LocationUtils;
|
||||||
|
import org.briarproject.system.SystemClock;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -21,12 +23,13 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
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
|
||||||
private static final int POLLING_INTERVAL = 3 * 60 * 1000; // 3 minutes
|
private static final int POLLING_INTERVAL = 2 * 60 * 1000; // 2 minutes
|
||||||
|
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
public TorPluginFactory(Executor ioExecutor, Context appContext,
|
public TorPluginFactory(Executor ioExecutor, Context appContext,
|
||||||
LocationUtils locationUtils, EventBus eventBus) {
|
LocationUtils locationUtils, EventBus eventBus) {
|
||||||
@@ -34,6 +37,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
this.locationUtils = locationUtils;
|
this.locationUtils = locationUtils;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
|
clock = new SystemClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportId getId() {
|
public TransportId getId() {
|
||||||
@@ -61,7 +65,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
|
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
|
||||||
|
|
||||||
TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils,
|
TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils,
|
||||||
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
|
clock, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
|
||||||
POLLING_INTERVAL);
|
POLLING_INTERVAL);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
|
|||||||
Reference in New Issue
Block a user