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:
akwizgran
2016-02-25 10:01:07 +00:00
parent 066285b86a
commit d8079b1841
2 changed files with 24 additions and 10 deletions

View File

@@ -24,6 +24,7 @@ import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.LocationUtils;
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 Pattern 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 =
Logger.getLogger(TorPlugin.class.getName());
private final Executor ioExecutor;
private final Context appContext;
private final LocationUtils locationUtils;
private final Clock clock;
private final DuplexPluginCallback callback;
private final String architecture;
private final int maxLatency, maxIdleTime, pollingInterval, socketTimeout;
@@ -91,6 +93,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
private volatile boolean bootstrapped = false;
private volatile boolean connectedToWifi = false;
private volatile boolean online = false;
private volatile long descriptorsPublishedTime = Long.MAX_VALUE;
private volatile ServerSocket socket = null;
private volatile Socket controlSocket = null;
@@ -98,12 +101,13 @@ class TorPlugin implements DuplexPlugin, EventHandler,
private volatile BroadcastReceiver networkStateReceiver = null;
TorPlugin(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, DuplexPluginCallback callback,
String architecture, int maxLatency, int maxIdleTime,
int pollingInterval) {
LocationUtils locationUtils, Clock clock,
DuplexPluginCallback callback, String architecture, int maxLatency,
int maxIdleTime, int pollingInterval) {
this.ioExecutor = ioExecutor;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.clock = clock;
this.callback = callback;
this.architecture = architecture;
this.maxLatency = maxLatency;
@@ -467,6 +471,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
if (!enable) {
circuitBuilt.set(false);
descriptorsPublished.set(0);
descriptorsPublishedTime = Long.MAX_VALUE;
callback.transportDisabled();
}
networkEnabled = enable;
@@ -508,9 +513,12 @@ class TorPlugin implements DuplexPlugin, EventHandler,
public void poll(Collection<ContactId> connected) {
if (!isRunning()) return;
if (descriptorsPublished.get() >= DESCRIPTOR_THRESHOLD) {
LOG.info("Hidden service descriptor published, not polling");
return;
if (descriptorsPublished.get() >= MIN_DESCRIPTORS_PUBLISHED) {
long now = clock.currentTimeMillis();
if (now - descriptorsPublishedTime >= 2 * pollingInterval) {
LOG.info("Hidden service descriptor published, not polling");
return;
}
}
// TODO: Pass properties to connectAndCallBack()
for (ContactId c : callback.getRemoteProperties().keySet())
@@ -589,8 +597,10 @@ class TorPlugin implements DuplexPlugin, EventHandler,
public void unrecognized(String type, String msg) {
if (type.equals("HS_DESC") && msg.startsWith("UPLOADED")) {
int descriptors = descriptorsPublished.incrementAndGet();
if (descriptors == DESCRIPTOR_THRESHOLD)
if (descriptors == MIN_DESCRIPTORS_PUBLISHED) {
LOG.info("Hidden service descriptor published");
descriptorsPublishedTime = clock.currentTimeMillis();
}
}
}

View File

@@ -9,7 +9,9 @@ import org.briarproject.api.event.EventBus;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.system.SystemClock;
import java.util.concurrent.Executor;
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_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 Context appContext;
private final LocationUtils locationUtils;
private final EventBus eventBus;
private final Clock clock;
public TorPluginFactory(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, EventBus eventBus) {
@@ -34,6 +37,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
this.appContext = appContext;
this.locationUtils = locationUtils;
this.eventBus = eventBus;
clock = new SystemClock();
}
public TransportId getId() {
@@ -61,7 +65,7 @@ public class TorPluginFactory implements DuplexPluginFactory {
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils,
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
clock, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
POLLING_INTERVAL);
eventBus.addListener(plugin);
return plugin;