Compare commits

...

3 Commits

Author SHA1 Message Date
akwizgran
84b3670624 Create hidden service via conf file so we can use Tor 0.2.6. 2016-08-27 08:45:01 +01:00
akwizgran
749695187e Disable verification of Tor binaries so we can use old ones. 2016-08-26 23:30:58 +01:00
akwizgran
c4db72abf2 Revert Tor performance improvements for measurement. 2016-08-26 22:22:44 +01:00
6 changed files with 59 additions and 99 deletions

View File

@@ -189,8 +189,8 @@ project.afterEvaluate {
preBuild.dependsOn {
[
'verifyTorGeoIp',
'verifyTorBinaryArm',
'verifyTorBinaryArmPie',
// 'verifyTorBinaryArm',
// 'verifyTorBinaryArmPie',
'verifyTorBinaryX86',
'verifyTorBinaryX86Pie'
]

View File

@@ -38,7 +38,7 @@ public class AndroidPluginsModule {
DuplexPluginFactory bluetooth = new DroidtoothPluginFactory(ioExecutor,
androidExecutor, appContext, random, backoffFactory);
DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, appContext,
locationUtils, reporter, eventBus, backoffFactory);
locationUtils, reporter, eventBus);
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
backoffFactory, appContext);
final Collection<DuplexPluginFactory> duplex =

View File

@@ -26,7 +26,6 @@ import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.keyagreement.KeyAgreementListener;
import org.briarproject.api.keyagreement.TransportDescriptor;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
@@ -52,7 +51,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -70,8 +68,6 @@ import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.util.PrivacyUtils.scrubOnion;
class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@@ -85,6 +81,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private static final String OWNER = "__OwningControllerProcess";
private static final int SOCKS_PORT = 59050, CONTROL_PORT = 59051;
private static final int COOKIE_TIMEOUT = 3000; // Milliseconds
private static final int HOSTNAME_TIMEOUT = 30 * 1000; // Milliseconds
private static final Pattern ONION = Pattern.compile("[a-z2-7]{16}");
private static final Logger LOG =
Logger.getLogger(TorPlugin.class.getName());
@@ -93,13 +90,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private final Context appContext;
private final LocationUtils locationUtils;
private final DevReporter reporter;
private final Backoff backoff;
private final DuplexPluginCallback callback;
private final String architecture;
private final int maxLatency, maxIdleTime, socketTimeout;
private final int pollingInterval;
private final ConnectionStatus connectionStatus;
private final File torDirectory, torFile, geoIpFile, configFile;
private final File doneFile, cookieFile;
private final File doneFile, cookieFile, hostnameFile;
private final PowerManager.WakeLock wakeLock;
private final AtomicBoolean used = new AtomicBoolean(false);
@@ -110,18 +107,18 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private volatile BroadcastReceiver networkStateReceiver = null;
TorPlugin(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, DevReporter reporter, Backoff backoff,
LocationUtils locationUtils, DevReporter reporter,
DuplexPluginCallback callback, String architecture, int maxLatency,
int maxIdleTime) {
int maxIdleTime, int pollingInterval) {
this.ioExecutor = ioExecutor;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.reporter = reporter;
this.backoff = backoff;
this.callback = callback;
this.architecture = architecture;
this.maxLatency = maxLatency;
this.maxIdleTime = maxIdleTime;
this.pollingInterval = pollingInterval;
if (maxIdleTime > Integer.MAX_VALUE / 2)
socketTimeout = Integer.MAX_VALUE;
else socketTimeout = maxIdleTime * 2;
@@ -132,6 +129,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
configFile = new File(torDirectory, "torrc");
doneFile = new File(torDirectory, "done");
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
hostnameFile = new File(torDirectory, "hs/hostname");
Object o = appContext.getSystemService(POWER_SERVICE);
PowerManager pm = (PowerManager) o;
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "TorPlugin");
@@ -363,7 +361,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
publishHiddenService(localPort);
}
});
backoff.reset();
// Accept incoming hidden service connections from Tor
acceptContactConnections(ss);
}
@@ -382,40 +379,48 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
private void publishHiddenService(String port) {
if (!running) return;
LOG.info("Creating hidden service");
String privKey = callback.getSettings().get(HS_PRIVKEY);
Map<Integer, String> portLines =
Collections.singletonMap(80, "127.0.0.1:" + port);
Map<String, String> response;
try {
// Use the control connection to set up the hidden service
if (privKey == null)
response = controlConnection.addOnion(portLines);
else response = controlConnection.addOnion(privKey, portLines);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return;
}
if (!response.containsKey(HS_ADDRESS)) {
LOG.warning("Tor did not return a hidden service address");
return;
}
if (privKey == null && !response.containsKey(HS_PRIVKEY)) {
LOG.warning("Tor did not return a private key");
return;
if (!hostnameFile.exists()) {
LOG.info("Creating hidden service");
try {
// Watch for the hostname file being created/updated
File serviceDirectory = hostnameFile.getParentFile();
serviceDirectory.mkdirs();
hostnameFile.createNewFile();
CountDownLatch latch = new CountDownLatch(1);
FileObserver obs = new WriteObserver(hostnameFile, latch);
obs.startWatching();
// Use the control connection to update the Tor config
List<String> config = Arrays.asList(
"HiddenServiceDir " +
serviceDirectory.getAbsolutePath(),
"HiddenServicePort 80 127.0.0.1:" + port);
controlConnection.setConf(config);
controlConnection.saveConf();
// Wait for the hostname file to be created/updated
if (!latch.await(HOSTNAME_TIMEOUT, MILLISECONDS)) {
LOG.warning("Hidden service not created");
if (LOG.isLoggable(INFO)) listFiles(torDirectory);
return;
}
if (!running) return;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (InterruptedException e) {
LOG.warning("Interrupted while creating hidden service");
Thread.currentThread().interrupt();
return;
}
}
// Publish the hidden service's onion hostname in transport properties
String hostname = response.get(HS_ADDRESS);
if (LOG.isLoggable(INFO))
LOG.info("Hidden service " + scrubOnion(hostname));
TransportProperties p = new TransportProperties();
p.put(PROP_ONION, hostname);
callback.mergeLocalProperties(p);
if (privKey == null) {
// Save the hidden service's private key for next time
Settings s = new Settings();
s.put(HS_PRIVKEY, response.get(HS_PRIVKEY));
callback.mergeSettings(s);
try {
String hostname = new String(read(hostnameFile), "UTF-8").trim();
if (LOG.isLoggable(INFO))
LOG.info("Hidden service " + scrubOnion(hostname));
TransportProperties p = new TransportProperties();
p.put(PROP_ONION, hostname.substring(0, 16));
callback.mergeLocalProperties(p);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
@@ -431,7 +436,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
return;
}
LOG.info("Connection received");
backoff.reset();
TorTransportConnection conn = new TorTransportConnection(this, s);
callback.incomingConnectionCreated(conn);
}
@@ -479,14 +483,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public int getPollingInterval() {
return backoff.getPollingInterval();
return pollingInterval;
}
@Override
public void poll(Collection<ContactId> connected) {
if (!isRunning()) return;
backoff.increment();
// TODO: Pass properties to connectAndCallBack()
for (ContactId c : callback.getRemoteProperties().keySet())
if (!connected.contains(c)) connectAndCallBack(c);
}
@@ -496,10 +498,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
@Override
public void run() {
DuplexTransportConnection d = createConnection(c);
if (d != null) {
backoff.reset();
callback.outgoingConnectionCreated(c, d);
}
if (d != null) callback.outgoingConnectionCreated(c, d);
}
});
}
@@ -519,7 +518,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
try {
if (LOG.isLoggable(INFO))
LOG.info("Connecting to " + scrubOnion(onion));
controlConnection.forgetHiddenService(onion);
Socks5Proxy proxy = new Socks5Proxy("127.0.0.1", SOCKS_PORT);
proxy.resolveAddrLocally(false);
Socket s = new SocksSocket(proxy, onion + ".onion", 80);
@@ -528,9 +526,10 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Connected to " + scrubOnion(onion));
return new TorTransportConnection(this, s);
} catch (IOException e) {
if (LOG.isLoggable(INFO))
if (LOG.isLoggable(INFO)) {
LOG.info("Could not connect to " + scrubOnion(onion) + ": " +
e.toString());
}
return null;
}
}
@@ -567,7 +566,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (status.equals("BUILT") &&
connectionStatus.getAndSetCircuitBuilt()) {
LOG.info("First circuit built");
backoff.reset();
if (isRunning()) {
sendDevReports();
callback.transportEnabled();
@@ -597,7 +595,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
if (LOG.isLoggable(INFO)) LOG.info(severity + " " + msg);
if (severity.equals("NOTICE") && msg.startsWith("Bootstrapped 100%")) {
connectionStatus.setBootstrapped();
backoff.reset();
if (isRunning()) {
sendDevReports();
callback.transportEnabled();

View File

@@ -6,8 +6,6 @@ import android.os.Build;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.plugins.Backoff;
import org.briarproject.api.plugins.BackoffFactory;
import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
@@ -24,26 +22,22 @@ 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 MIN_POLLING_INTERVAL = 60 * 1000; // 1 minute
private static final int MAX_POLLING_INTERVAL = 10 * 60 * 1000; // 10 mins
private static final double BACKOFF_BASE = 1.2;
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 DevReporter reporter;
private final EventBus eventBus;
private final BackoffFactory backoffFactory;
public TorPluginFactory(Executor ioExecutor, Context appContext,
LocationUtils locationUtils, DevReporter reporter,
EventBus eventBus, BackoffFactory backoffFactory) {
EventBus eventBus) {
this.ioExecutor = ioExecutor;
this.appContext = appContext;
this.locationUtils = locationUtils;
this.reporter = reporter;
this.eventBus = eventBus;
this.backoffFactory = backoffFactory;
}
@Override
@@ -77,11 +71,9 @@ public class TorPluginFactory implements DuplexPluginFactory {
// Use position-independent executable for SDK >= 16
if (Build.VERSION.SDK_INT >= 16) architecture += "-pie";
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorPlugin plugin = new TorPlugin(ioExecutor, appContext, locationUtils,
reporter, backoff, callback, architecture, MAX_LATENCY,
MAX_IDLE_TIME);
reporter, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME,
POLLING_INTERVAL);
eventBus.addListener(plugin);
return plugin;
}

View File

@@ -2,8 +2,6 @@ package org.briarproject.plugins;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.event.ConnectionClosedEvent;
import org.briarproject.api.event.ConnectionOpenedEvent;
import org.briarproject.api.event.ContactStatusChangedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
@@ -71,18 +69,6 @@ class Poller implements EventListener {
// Connect to the newly activated contact
connectToContact(c.getContactId());
}
} else if (e instanceof ConnectionClosedEvent) {
ConnectionClosedEvent c = (ConnectionClosedEvent) e;
// Reschedule polling, the polling interval may have decreased
reschedule(c.getTransportId());
if (!c.isIncoming()) {
// Connect to the disconnected contact
connectToContact(c.getContactId(), c.getTransportId());
}
} else if (e instanceof ConnectionOpenedEvent) {
ConnectionOpenedEvent c = (ConnectionOpenedEvent) e;
// Reschedule polling, the polling interval may have decreased
reschedule(c.getTransportId());
} else if (e instanceof TransportEnabledEvent) {
TransportEnabledEvent t = (TransportEnabledEvent) e;
// Poll the newly enabled transport
@@ -97,14 +83,6 @@ class Poller implements EventListener {
if (d.shouldPoll()) connectToContact(c, d);
}
private void connectToContact(ContactId c, TransportId t) {
Plugin p = pluginManager.getPlugin(t);
if (p instanceof SimplexPlugin && p.shouldPoll())
connectToContact(c, (SimplexPlugin) p);
else if (p instanceof DuplexPlugin && p.shouldPoll())
connectToContact(c, (DuplexPlugin) p);
}
private void connectToContact(final ContactId c, final SimplexPlugin p) {
ioExecutor.execute(new Runnable() {
@Override
@@ -133,11 +111,6 @@ class Poller implements EventListener {
});
}
private void reschedule(TransportId t) {
Plugin p = pluginManager.getPlugin(t);
if (p.shouldPoll()) schedule(p, p.getPollingInterval(), false);
}
private void pollNow(TransportId t) {
Plugin p = pluginManager.getPlugin(t);
// Randomise next polling interval

View File

@@ -1,6 +1,5 @@
package org.briarproject.util;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -9,8 +8,7 @@ import java.net.SocketAddress;
public class PrivacyUtils {
public static String scrubOnion(String onion) {
// keep first three characters of onion address
return onion.substring(0, 3) + "[_scrubbed_]";
return onion;
}
public static String scrubMacAddress(String address) {