From 36d15358a120603c2780ae4e0ac8237e1dee4298 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 5 Aug 2016 13:59:25 +0100
Subject: [PATCH] Don't connect to Tor if it's already running.

Fixes #572, #578.
---
 .../briarproject/plugins/tor/TorPlugin.java   | 143 ++++++++----------
 1 file changed, 64 insertions(+), 79 deletions(-)

diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
index 0f7aaf65c1..4be70b4d8e 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
@@ -150,74 +150,64 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	@Override
 	public boolean start() throws IOException {
 		if (used.getAndSet(true)) throw new IllegalStateException();
-		// Try to connect to an existing Tor process if there is one
-		boolean startProcess = false;
+		// Install the binary, possibly overwriting an older version
+		if (!installBinary()) {
+			LOG.warning("Could not install Tor binary");
+			return false;
+		}
+		// Install the GeoIP database and config file if necessary
+		if (!isConfigInstalled() && !installConfig()) {
+			LOG.warning("Could not install Tor config");
+			return false;
+		}
+		LOG.info("Starting Tor");
+		// Watch for the auth cookie file being updated
+		cookieFile.getParentFile().mkdirs();
+		cookieFile.createNewFile();
+		CountDownLatch latch = new CountDownLatch(1);
+		FileObserver obs = new WriteObserver(cookieFile, latch);
+		obs.startWatching();
+		// Start a new Tor process
+		String torPath = torFile.getAbsolutePath();
+		String configPath = configFile.getAbsolutePath();
+		String pid = String.valueOf(android.os.Process.myPid());
+		String[] cmd = {torPath, "-f", configPath, OWNER, pid};
+		String[] env = {"HOME=" + torDirectory.getAbsolutePath()};
+		Process torProcess;
 		try {
-			controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
-			LOG.info("Tor is already running");
-		} catch (IOException e) {
-			LOG.info("Tor is not running");
-			startProcess = true;
-			// Install the binary, possibly overwriting an older version
-			if (!installBinary()) {
-				LOG.warning("Could not install Tor binary");
-				return false;
-			}
-			// Install the GeoIP database and config file if necessary
-			if (!isConfigInstalled() && !installConfig()) {
-				LOG.warning("Could not install Tor config");
-				return false;
-			}
-			LOG.info("Starting Tor");
-			// Watch for the auth cookie file being created/updated
-			cookieFile.getParentFile().mkdirs();
-			cookieFile.createNewFile();
-			CountDownLatch latch = new CountDownLatch(1);
-			FileObserver obs = new WriteObserver(cookieFile, latch);
-			obs.startWatching();
-			// Start a new Tor process
-			String torPath = torFile.getAbsolutePath();
-			String configPath = configFile.getAbsolutePath();
-			String pid = String.valueOf(android.os.Process.myPid());
-			String[] cmd = {torPath, "-f", configPath, OWNER, pid};
-			String[] env = {"HOME=" + torDirectory.getAbsolutePath()};
-			Process torProcess;
-			try {
-				torProcess = Runtime.getRuntime().exec(cmd, env, torDirectory);
-			} catch (SecurityException e1) {
+			torProcess = Runtime.getRuntime().exec(cmd, env, torDirectory);
+		} catch (SecurityException e1) {
+			if (LOG.isLoggable(WARNING))
+				LOG.log(WARNING, e1.toString(), e1);
+			return false;
+		}
+		// Log the process's standard output until it detaches
+		if (LOG.isLoggable(INFO)) {
+			Scanner stdout = new Scanner(torProcess.getInputStream());
+			while (stdout.hasNextLine()) LOG.info(stdout.nextLine());
+			stdout.close();
+		}
+		try {
+			// Wait for the process to detach or exit
+			int exit = torProcess.waitFor();
+			if (exit != 0) {
 				if (LOG.isLoggable(WARNING))
-					LOG.log(WARNING, e1.toString(), e1);
+					LOG.warning("Tor exited with value " + exit);
 				return false;
 			}
-			// Log the process's standard output until it detaches
-			if (LOG.isLoggable(INFO)) {
-				Scanner stdout = new Scanner(torProcess.getInputStream());
-				while (stdout.hasNextLine()) LOG.info(stdout.nextLine());
-				stdout.close();
-			}
-			try {
-				// Wait for the process to detach or exit
-				int exit = torProcess.waitFor();
-				if (exit != 0) {
-					if (LOG.isLoggable(WARNING))
-						LOG.warning("Tor exited with value " + exit);
-					return false;
-				}
-				// Wait for the auth cookie file to be created/updated
-				if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
-					LOG.warning("Auth cookie not created");
-					if (LOG.isLoggable(INFO)) listFiles(torDirectory);
-					return false;
-				}
-			} catch (InterruptedException e1) {
-				LOG.warning("Interrupted while starting Tor");
-				Thread.currentThread().interrupt();
+			// Wait for the auth cookie file to be created/updated
+			if (!latch.await(COOKIE_TIMEOUT, MILLISECONDS)) {
+				LOG.warning("Auth cookie not created");
+				if (LOG.isLoggable(INFO)) listFiles(torDirectory);
 				return false;
 			}
-			// Now we should be able to connect to the new process
-			controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
+		} catch (InterruptedException e1) {
+			LOG.warning("Interrupted while starting Tor");
+			Thread.currentThread().interrupt();
+			return false;
 		}
 		// Open a control connection and authenticate using the cookie file
+		controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
 		controlConnection = new TorControlConnection(controlSocket);
 		controlConnection.authenticate(read(cookieFile));
 		// Tell Tor to exit when the control connection is closed
@@ -227,13 +217,11 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 		// Register to receive events from the Tor process
 		controlConnection.setEventHandler(this);
 		controlConnection.setEvents(Arrays.asList(EVENTS));
-		// If Tor was already running, find out whether it's bootstrapped
-		if (!startProcess) {
-			String phase = controlConnection.getInfo("status/bootstrap-phase");
-			if (phase != null && phase.contains("PROGRESS=100")) {
-				LOG.info("Tor has already bootstrapped");
-				connectionStatus.setBootstrapped();
-			}
+		// Check whether Tor has already bootstrapped
+		String phase = controlConnection.getInfo("status/bootstrap-phase");
+		if (phase != null && phase.contains("PROGRESS=100")) {
+			LOG.info("Tor has already bootstrapped");
+			connectionStatus.setBootstrapped();
 		}
 		// Register to receive network status events
 		networkStateReceiver = new NetworkStateReceiver();
@@ -271,6 +259,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	}
 
 	private boolean installConfig() {
+		LOG.info("Installing Tor config");
 		InputStream in = null;
 		OutputStream out = null;
 		try {
@@ -500,19 +489,15 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 		tryToClose(socket);
 		if (networkStateReceiver != null)
 			appContext.unregisterReceiver(networkStateReceiver);
-		try {
-			LOG.info("Stopping Tor");
-			if (controlSocket == null)
-				controlSocket = new Socket("127.0.0.1", CONTROL_PORT);
-			if (controlConnection == null) {
-				controlConnection = new TorControlConnection(controlSocket);
-				controlConnection.authenticate(read(cookieFile));
+		if (controlSocket != null && controlConnection != null) {
+			try {
+				LOG.info("Stopping Tor");
+				controlConnection.setConf("DisableNetwork", "1");
+				controlConnection.shutdownTor("TERM");
+				controlSocket.close();
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
-			controlConnection.setConf("DisableNetwork", "1");
-			controlConnection.shutdownTor("TERM");
-			controlSocket.close();
-		} catch (IOException e) {
-			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 		}
 		wakeLock.release();
 	}
-- 
GitLab