diff --git a/components/net/sf/briar/plugins/tor/TorPlugin.java b/components/net/sf/briar/plugins/tor/TorPlugin.java index 793c632b70227e256b2eeaec95c98aacd20df8dd..44c4f79840dae3e0aec2a595f76a83262057ed53 100644 --- a/components/net/sf/briar/plugins/tor/TorPlugin.java +++ b/components/net/sf/briar/plugins/tor/TorPlugin.java @@ -76,7 +76,11 @@ class TorPlugin implements DuplexPlugin { // Connect to Tor NetFactory netFactory = NetFactory.getInstance(); NetLayer nl = netFactory.getNetLayerById(NetLayerIDs.TOR); + if(LOG.isLoggable(Level.INFO)) + LOG.info("Waiting for net layer to be ready"); nl.waitUntilReady(); + if(LOG.isLoggable(Level.INFO)) + LOG.info("Net layer is ready"); synchronized(this) { if(!running) { tryToClear(nl); @@ -101,8 +105,12 @@ class TorPlugin implements DuplexPlugin { TorNetLayerUtil util = TorNetLayerUtil.getInstance(); String privateKey = c.get("privateKey"); if(privateKey == null) { + if(LOG.isLoggable(Level.INFO)) + LOG.info("Creating hidden service address"); addr = createHiddenServiceAddress(util, c); } else { + if(LOG.isLoggable(Level.INFO)) + LOG.info("Parsing hidden service address"); try { addr = util.parseTorHiddenServicePrivateNetAddressFromStrings( privateKey, "", false); @@ -115,6 +123,7 @@ class TorPlugin implements DuplexPlugin { new TorHiddenServicePortPrivateNetAddress(addr, 80); // Publish the hidden service NetServerSocket ss; + if(LOG.isLoggable(Level.INFO)) LOG.info("Publishing hidden service"); try { ss = nl.createNetServerSocket(null, addrPort); } catch(IOException e) { @@ -234,6 +243,8 @@ class TorPlugin implements DuplexPlugin { synchronized(this) { while(!connected) { if(!running) return null; + if(LOG.isLoggable(Level.INFO)) + LOG.info("Waiting for net layer before connecting"); try { wait(); } catch(InterruptedException e) { @@ -251,7 +262,11 @@ class TorPlugin implements DuplexPlugin { if(onion == null) return null; NetAddress addr = new TcpipNetAddress(onion, 80); try { + if(LOG.isLoggable(Level.INFO)) + LOG.info("Connecting to hidden service"); NetSocket s = nl.createNetSocket(null, null, addr); + if(LOG.isLoggable(Level.INFO)) + LOG.info("Connected to hidden service"); return new TorTransportConnection(s); } catch(IOException e) { if(LOG.isLoggable(Level.INFO)) LOG.info(e.toString()); diff --git a/test/build.xml b/test/build.xml index 311bada18bb90191b5242c8b26a8662c6b7c3d12..725693a361aa9d68e1fddd767fec1759836a3182 100644 --- a/test/build.xml +++ b/test/build.xml @@ -63,7 +63,7 @@ </junit> </target> <target name='test-slow' depends='depend'> - <junit printsummary='on' fork='yes' forkmode='once'> + <junit printsummary='withOutAndErr' fork='yes' forkmode='once'> <assertions> <enable/> </assertions> diff --git a/test/net/sf/briar/plugins/tor/TorPluginTest.java b/test/net/sf/briar/plugins/tor/TorPluginTest.java index 446b53ecaa6e3511534a1a66850abe31cc8522dc..43c152fd322c58f13df4a1f001f18659bdb9ba40 100644 --- a/test/net/sf/briar/plugins/tor/TorPluginTest.java +++ b/test/net/sf/briar/plugins/tor/TorPluginTest.java @@ -9,6 +9,8 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import junit.framework.AssertionFailedError; + import net.sf.briar.BriarTestCase; import net.sf.briar.api.ContactId; import net.sf.briar.api.TransportConfig; @@ -25,75 +27,103 @@ public class TorPluginTest extends BriarTestCase { @Test public void testHiddenService() throws Exception { Executor e = Executors.newCachedThreadPool(); - // Create a plugin instance for the server - Callback serverCallback = new Callback(); - TorPlugin serverPlugin = new TorPlugin(e, serverCallback, 0L); - serverPlugin.start(); - // The plugin should create a hidden service... eventually - assertTrue(serverCallback.latch.await(10, TimeUnit.MINUTES)); - String onion = serverCallback.local.get("onion"); - assertNotNull(onion); - assertTrue(onion.endsWith(".onion")); - // Create another plugin instance for the client - Callback clientCallback = new Callback(); - clientCallback.config.put("noHiddenService", ""); - TransportProperties p = new TransportProperties(); - p.put("onion", onion); - clientCallback.remote.put(contactId, p); - TorPlugin clientPlugin = new TorPlugin(e, clientCallback, 0L); - clientPlugin.start(); - // The plugin should start without creating a hidden service - assertTrue(clientCallback.latch.await(10, TimeUnit.MINUTES)); - // Connect to the server's hidden service - 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(); + TorPlugin serverPlugin = null, clientPlugin = null; + try { + // Create a plugin instance for the server + Callback serverCallback = new Callback(); + serverPlugin = new TorPlugin(e, serverCallback, 0L); + System.out.println("Starting server plugin"); + serverPlugin.start(); + // The plugin should create a hidden service... eventually + assertTrue(serverCallback.latch.await(5, TimeUnit.MINUTES)); + System.out.println("Started server plugin"); + String onion = serverCallback.local.get("onion"); + assertNotNull(onion); + assertTrue(onion.endsWith(".onion")); + // Create another plugin instance for the client + Callback clientCallback = new Callback(); + clientCallback.config.put("noHiddenService", ""); + TransportProperties p = new TransportProperties(); + p.put("onion", onion); + clientCallback.remote.put(contactId, p); + clientPlugin = new TorPlugin(e, clientCallback, 0L); + System.out.println("Starting client plugin"); + clientPlugin.start(); + // The plugin should start without creating a hidden service + assertTrue(clientCallback.latch.await(5, TimeUnit.MINUTES)); + System.out.println("Started client plugin"); + // Connect to the server's hidden service + System.out.println("Connecting to hidden service"); + DuplexTransportConnection clientEnd = + clientPlugin.createConnection(contactId); + assertNotNull(clientEnd); + DuplexTransportConnection serverEnd = serverCallback.incomingConnection; + assertNotNull(serverEnd); + System.out.println("Connected to hidden service"); + // 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); + } catch(AssertionFailedError e1) { + System.out.println(e); + } finally { + // Stop the plugins + System.out.println("Stopping plugins"); + if(serverPlugin != null) serverPlugin.stop(); + if(clientPlugin != null) clientPlugin.stop(); + System.out.println("Stopped plugins"); + } } @Test public void testStoreAndRetrievePrivateKey() throws Exception { Executor e = Executors.newCachedThreadPool(); - // Start a plugin instance with no private key - Callback callback = new Callback(); - TorPlugin plugin = new TorPlugin(e, callback, 0L); - plugin.start(); - // The plugin should create a hidden service... eventually - assertTrue(callback.latch.await(10, TimeUnit.MINUTES)); - String onion = callback.local.get("onion"); - assertNotNull(onion); - assertTrue(onion.endsWith(".onion")); - // Get the PEM-encoded private key - String privateKey = callback.config.get("privateKey"); - assertNotNull(privateKey); - // Stop the plugin - plugin.stop(); - // Start another instance, reusing the private key - callback = new Callback(); - callback.config.put("privateKey", privateKey); - plugin = new TorPlugin(e, callback, 0L); - plugin.start(); - // The plugin should create a hidden service... eventually - assertTrue(callback.latch.await(10, TimeUnit.MINUTES)); - // The onion URL should be the same - assertEquals(onion, callback.local.get("onion")); - // The private key should be the same - assertEquals(privateKey, callback.config.get("privateKey")); - // Stop the plugin - plugin.stop(); + TorPlugin plugin = null; + try { + // Start a plugin instance with no private key + Callback callback = new Callback(); + plugin = new TorPlugin(e, callback, 0L); + System.out.println("Starting plugin without private key"); + plugin.start(); + // The plugin should create a hidden service... eventually + assertTrue(callback.latch.await(5, TimeUnit.MINUTES)); + System.out.println("Started plugin"); + String onion = callback.local.get("onion"); + assertNotNull(onion); + assertTrue(onion.endsWith(".onion")); + // Get the PEM-encoded private key + String privateKey = callback.config.get("privateKey"); + assertNotNull(privateKey); + // Stop the plugin + System.out.println("Stopping plugin"); + plugin.stop(); + System.out.println("Stopped plugin"); + // Start another instance, reusing the private key + callback = new Callback(); + callback.config.put("privateKey", privateKey); + plugin = new TorPlugin(e, callback, 0L); + System.out.println("Starting plugin with private key"); + plugin.start(); + // The plugin should create a hidden service... eventually + assertTrue(callback.latch.await(5, TimeUnit.MINUTES)); + System.out.println("Started plugin"); + // The onion URL should be the same + assertEquals(onion, callback.local.get("onion")); + // The private key should be the same + assertEquals(privateKey, callback.config.get("privateKey")); + } catch(AssertionFailedError e1) { + System.out.println(e); + } finally { + // Stop the plugin + System.out.println("Stopping plugin"); + if(plugin != null) plugin.stop(); + System.out.println("Stopped plugin"); + } } private static class Callback implements DuplexPluginCallback {