From d8079b1841aa7fdac9a61e4d7c4827f88574ff43 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Thu, 25 Feb 2016 10:01:07 +0000 Subject: [PATCH] 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. --- .../briarproject/plugins/tor/TorPlugin.java | 26 +++++++++++++------ .../plugins/tor/TorPluginFactory.java | 8 ++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java index 4831a0f7ca..d98c213436 100644 --- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java @@ -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(); + } } } diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java index 8561e4cdff..3c6a749867 100644 --- a/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java +++ b/briar-android/src/org/briarproject/plugins/tor/TorPluginFactory.java @@ -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; -- GitLab