diff --git a/components/net/sf/briar/plugins/tor/TorPlugin.java b/components/net/sf/briar/plugins/tor/TorPlugin.java
index 96130acf8c6809f1b70e3a47e1d061b60068cf94..3a450e6e13e062405019f64f796eb7d928306b3f 100644
--- a/components/net/sf/briar/plugins/tor/TorPlugin.java
+++ b/components/net/sf/briar/plugins/tor/TorPlugin.java
@@ -17,6 +17,7 @@ import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.util.StringUtils;
 
+import org.silvertunnel.netlib.api.NetAddress;
 import org.silvertunnel.netlib.api.NetFactory;
 import org.silvertunnel.netlib.api.NetLayer;
 import org.silvertunnel.netlib.api.NetLayerIDs;
@@ -43,9 +44,9 @@ class TorPlugin implements DuplexPlugin {
 	private final DuplexPluginCallback callback;
 	private final long pollingInterval;
 
-	private boolean running = false; // Locking: this
-	private NetServerSocket socket = null; // Locking: this
+	private boolean running = false, connected = false; // Locking: this
 	private NetLayer netLayer = null; // Locking: this
+	private NetServerSocket socket = null; // Locking: this
 
 	TorPlugin(@PluginExecutor Executor pluginExecutor,
 			DuplexPluginCallback callback, long pollingInterval) {
@@ -72,18 +73,18 @@ class TorPlugin implements DuplexPlugin {
 	private void bind() {
 		// Retrieve the hidden service address, or create one if necessary
 		TorHiddenServicePrivateNetAddress addr;
+		TorNetLayerUtil util = TorNetLayerUtil.getInstance();
 		TransportConfig c = callback.getConfig();
 		String privateKey = c.get("privateKey");
 		if(privateKey == null) {
-			addr = createHiddenServiceAddress(c);
+			addr = createHiddenServiceAddress(util, c);
 		} else {
-			TorNetLayerUtil util = TorNetLayerUtil.getInstance();
 			try {
 				addr = util.parseTorHiddenServicePrivateNetAddressFromStrings(
 						privateKey, "", false);
 			} catch(IOException e) {
 				if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
-				addr = createHiddenServiceAddress(c);
+				addr = createHiddenServiceAddress(util, c);
 			}
 		}
 		TorHiddenServicePortPrivateNetAddress addrPort =
@@ -92,6 +93,15 @@ class TorPlugin implements DuplexPlugin {
 		NetFactory netFactory = NetFactory.getInstance();
 		NetLayer nl = netFactory.getNetLayerById(NetLayerIDs.TOR);
 		nl.waitUntilReady();
+		synchronized(this) {
+			if(!running) {
+				tryToClear(nl);
+				return;
+			}
+			netLayer = nl;
+			connected = true;
+			notifyAll();
+		}
 		// Publish the hidden service
 		NetServerSocket ss;
 		try {
@@ -106,7 +116,6 @@ class TorPlugin implements DuplexPlugin {
 				return;
 			}
 			socket = ss;
-			netLayer = nl;
 		}
 		String onion = addr.getPublicOnionHostname();
 		if(LOG.isLoggable(Level.INFO)) LOG.info("Listening on " + onion);
@@ -117,8 +126,7 @@ class TorPlugin implements DuplexPlugin {
 	}
 
 	private TorHiddenServicePrivateNetAddress createHiddenServiceAddress(
-			TransportConfig c) {
-		TorNetLayerUtil util = TorNetLayerUtil.getInstance();
+			TorNetLayerUtil util, TransportConfig c) {
 		TorHiddenServicePrivateNetAddress addr =
 			util.createNewTorHiddenServicePrivateNetAddress();
 		RSAKeyPair keyPair = addr.getKeyPair();
@@ -128,6 +136,14 @@ class TorPlugin implements DuplexPlugin {
 		return addr;
 	}
 
+	private void tryToClear(NetLayer nl) {
+		try {
+			nl.clear();
+		} catch(IOException e) {
+			if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
+		}
+	}
+
 	private void tryToClose(NetServerSocket ss) {
 		try {
 			ss.close();
@@ -156,15 +172,17 @@ class TorPlugin implements DuplexPlugin {
 	}
 
 	public synchronized void stop() throws IOException {
-		running = false;
-		if(socket != null) {
-			tryToClose(socket);
-			socket = null;
-		}
 		if(netLayer != null) {
 			netLayer.clear();
 			netLayer = null;
 		}
+		if(socket != null) {
+			tryToClose(socket);
+			socket = null;
+		}
+		running = false;
+		connected = false;
+		notifyAll();
 	}
 
 	public boolean shouldPoll() {
@@ -201,19 +219,28 @@ class TorPlugin implements DuplexPlugin {
 	}
 
 	public DuplexTransportConnection createConnection(ContactId c) {
+		NetLayer nl;
 		synchronized(this) {
-			if(!running) return null;
+			while(!connected) {
+				if(!running) return null;
+				try {
+					wait();
+				} catch(InterruptedException e) {
+					if(LOG.isLoggable(Level.INFO))
+						LOG.info("Interrupted while waiting to connect");
+					Thread.currentThread().interrupt();
+					return null;
+				}
+			}
+			nl = netLayer;
 		}
 		TransportProperties p = callback.getRemoteProperties().get(c);
 		if(p == null) return null;
 		String onion = p.get("onion");
 		if(onion == null) return null;
+		NetAddress addr = new TcpipNetAddress(onion, 80);
 		try {
-			TcpipNetAddress addr = new TcpipNetAddress(onion, 80);
-			NetFactory netFactory = NetFactory.getInstance();
-			NetLayer netLayer = netFactory.getNetLayerById(NetLayerIDs.TOR);
-			netLayer.waitUntilReady();
-			NetSocket s = netLayer.createNetSocket(null, null, addr);
+			NetSocket s = nl.createNetSocket(null, null, addr);
 			return new TorTransportConnection(s);
 		} catch(IOException e) {
 			if(LOG.isLoggable(Level.INFO)) LOG.info(e.toString());
diff --git a/test/net/sf/briar/plugins/tor/TorPluginTest.java b/test/net/sf/briar/plugins/tor/TorPluginTest.java
index 6d54311b80cb4ea5494d02aff3d7b8e640ddbcfc..28ed8a65b11e1935383e2c9a663cc3ee9b9da489 100644
--- a/test/net/sf/briar/plugins/tor/TorPluginTest.java
+++ b/test/net/sf/briar/plugins/tor/TorPluginTest.java
@@ -1,7 +1,9 @@
 package net.sf.briar.plugins.tor;
 
+import java.io.PrintStream;
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -40,10 +42,20 @@ public class TorPluginTest extends BriarTestCase {
 		TorPlugin clientPlugin = new TorPlugin(e, clientCallback, 0L);
 		clientPlugin.start();
 		// Connect to the server's hidden service
-		DuplexTransportConnection c = clientPlugin.createConnection(contactId);
-		assertNotNull(c);
-		c.dispose(false, false);
-		assertEquals(1, serverCallback.incomingConnections);
+		DuplexTransportConnection clientEnd =
+			clientPlugin.createConnection(contactId);
+		assertNotNull(clientEnd);
+		DuplexTransportConnection serverEnd = serverCallback.incomingConnection;
+		assertNotNull(serverEnd);
+		// Send some data through the Tor connection
+		PrintStream out = new PrintStream(clientEnd.getOutputStream());
+		out.println("Hello world");
+		out.flush();
+		Scanner in = new Scanner(serverEnd.getInputStream());
+		assertTrue(in.hasNextLine());
+		assertEquals("Hello world", in.nextLine());
+		serverEnd.dispose(false, false);
+		clientEnd.dispose(false, false);
 		// Stop the plugins
 		serverPlugin.stop();
 		clientPlugin.stop();
@@ -89,7 +101,7 @@ public class TorPluginTest extends BriarTestCase {
 		private TransportConfig config = new TransportConfig();
 		private TransportProperties local = new TransportProperties();
 
-		private volatile int incomingConnections = 0;
+		private volatile DuplexTransportConnection incomingConnection = null;
 
 		public TransportConfig getConfig() {
 			return config;
@@ -108,8 +120,8 @@ public class TorPluginTest extends BriarTestCase {
 		}
 
 		public void setLocalProperties(TransportProperties p) {
-			latch.countDown();
 			local = p;
+			latch.countDown();
 		}
 
 		public int showChoice(String[] options, String... message) {
@@ -123,7 +135,7 @@ public class TorPluginTest extends BriarTestCase {
 		public void showMessage(String... message) {}
 
 		public void incomingConnectionCreated(DuplexTransportConnection d) {
-			incomingConnections++;
+			incomingConnection = d;
 		}
 
 		public void outgoingConnectionCreated(ContactId c,