diff --git a/components/net/sf/briar/plugins/PluginManagerImpl.java b/components/net/sf/briar/plugins/PluginManagerImpl.java index 652882fd4592c81bb5acb3c0d5f7e039b3c404e2..0b1b5532955eb9c5dfc0b4baf005337aab7fbe94 100644 --- a/components/net/sf/briar/plugins/PluginManagerImpl.java +++ b/components/net/sf/briar/plugins/PluginManagerImpl.java @@ -48,7 +48,8 @@ class PluginManagerImpl implements PluginManager { private static final String[] DUPLEX_PLUGIN_FACTORIES = new String[] { "net.sf.briar.plugins.bluetooth.BluetoothPluginFactory", - "net.sf.briar.plugins.socket.SimpleSocketPluginFactory" + "net.sf.briar.plugins.socket.SimpleSocketPluginFactory", + "net.sf.briar.plugins.tor.TorPluginFactory" }; private final ExecutorService pluginExecutor; diff --git a/components/net/sf/briar/plugins/tor/TorPlugin.java b/components/net/sf/briar/plugins/tor/TorPlugin.java index 7000fc032f81b25dcf9dea7511746f578c1a306a..fb9fbee5f55ec3cec0c597c52b0862fc6f30cc1d 100644 --- a/components/net/sf/briar/plugins/tor/TorPlugin.java +++ b/components/net/sf/briar/plugins/tor/TorPlugin.java @@ -45,7 +45,8 @@ class TorPlugin implements DuplexPlugin { private final long pollingInterval; private boolean running = false; // Locking: this - private TorNetServerSocket socket = null; // Locking: this + private NetServerSocket socket = null; // Locking: this + private NetLayer netLayer = null; // Locking: this TorPlugin(@PluginExecutor Executor pluginExecutor, DuplexPluginCallback callback, long pollingInterval) { @@ -90,13 +91,12 @@ class TorPlugin implements DuplexPlugin { new TorHiddenServicePortPrivateNetAddress(addr, 80); // Connect to Tor NetFactory netFactory = NetFactory.getInstance(); - NetLayer netLayer = netFactory.getNetLayerById(NetLayerIDs.TOR); - netLayer.waitUntilReady(); + NetLayer nl = netFactory.getNetLayerById(NetLayerIDs.TOR); + nl.waitUntilReady(); // Publish the hidden service TorNetServerSocket ss; try { - ss = (TorNetServerSocket) netLayer.createNetServerSocket(null, - addrPort); + ss = (TorNetServerSocket) nl.createNetServerSocket(null, addrPort); } catch(IOException e) { if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString()); return; @@ -107,6 +107,7 @@ class TorPlugin implements DuplexPlugin { return; } socket = ss; + netLayer = nl; } String onion = addr.getPublicOnionHostname(); if(LOG.isLoggable(Level.INFO)) LOG.info("Listening on " + onion); @@ -161,6 +162,10 @@ class TorPlugin implements DuplexPlugin { tryToClose(socket); socket = null; } + if(netLayer != null) { + netLayer.clear(); + netLayer = null; + } } public boolean shouldPoll() { @@ -203,11 +208,9 @@ class TorPlugin implements DuplexPlugin { TransportProperties p = callback.getRemoteProperties().get(c); if(p == null) return null; String onion = p.get("onion"); - String portString = p.get("port"); - if(onion == null || portString == null) return null; + if(onion == null) return null; try { - int port = Integer.parseInt(portString); - TcpipNetAddress addr = new TcpipNetAddress(onion, port); + TcpipNetAddress addr = new TcpipNetAddress(onion, 80); NetFactory netFactory = NetFactory.getInstance(); NetLayer netLayer = netFactory.getNetLayerById(NetLayerIDs.TOR); netLayer.waitUntilReady(); diff --git a/components/net/sf/briar/plugins/tor/TorPluginFactory.java b/components/net/sf/briar/plugins/tor/TorPluginFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e7caf6aa195a70df7ec528e3da811c7d19957a2a --- /dev/null +++ b/components/net/sf/briar/plugins/tor/TorPluginFactory.java @@ -0,0 +1,18 @@ +package net.sf.briar.plugins.tor; + +import java.util.concurrent.Executor; + +import net.sf.briar.api.plugins.PluginExecutor; +import net.sf.briar.api.plugins.duplex.DuplexPlugin; +import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; +import net.sf.briar.api.plugins.duplex.DuplexPluginFactory; + +public class TorPluginFactory implements DuplexPluginFactory { + + private static final long POLLING_INTERVAL = 15L * 60L * 1000L; // 15 mins + + public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, + DuplexPluginCallback callback) { + return new TorPlugin(pluginExecutor, callback, POLLING_INTERVAL); + } +} diff --git a/test/build.xml b/test/build.xml index c28327848121a228f899cc8ce9d502f77410e3e6..f905a6999ff96c149476eed68678fe9010b75ec3 100644 --- a/test/build.xml +++ b/test/build.xml @@ -22,7 +22,6 @@ <test name='net.sf.briar.db.BasicH2Test'/> <test name='net.sf.briar.db.DatabaseCleanerImplTest'/> <test name='net.sf.briar.db.DatabaseComponentImplTest'/> - <test name='net.sf.briar.db.H2DatabaseTest'/> <test name='net.sf.briar.i18n.FontManagerTest'/> <test name='net.sf.briar.i18n.I18nTest'/> <test name='net.sf.briar.invitation.InvitationWorkerTest'/> @@ -64,4 +63,22 @@ <test name='net.sf.briar.util.ZipUtilsTest'/> </junit> </target> + <target name='test-slow' depends='depend'> + <junit printsummary='on' fork='yes' forkmode='once'> + <assertions> + <enable/> + </assertions> + <classpath> + <fileset refid='bundled-jars'/> + <fileset refid='test-jars'/> + <path refid='api-classes'/> + <path refid='component-classes'/> + <path refid='test-classes'/> + <path refid='util-classes'/> + </classpath> + <jvmarg value='-Djava.library.path=../lib'/> + <test name='net.sf.briar.db.H2DatabaseTest'/> + <test name='net.sf.briar.plugins.tor.TorPluginTest'/> + </junit> + </target> </project> diff --git a/test/net/sf/briar/plugins/PluginManagerImplTest.java b/test/net/sf/briar/plugins/PluginManagerImplTest.java index 861eb6593bbffb66adad6c35ccf125ad0fc6061d..feda37c3db7f85a682ca75babf7c4adb15997902 100644 --- a/test/net/sf/briar/plugins/PluginManagerImplTest.java +++ b/test/net/sf/briar/plugins/PluginManagerImplTest.java @@ -6,6 +6,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import net.sf.briar.BriarTestCase; +import net.sf.briar.api.TransportConfig; import net.sf.briar.api.TransportProperties; import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.protocol.TransportId; @@ -35,6 +36,8 @@ public class PluginManagerImplTest extends BriarTestCase { will(returnValue(null)); allowing(db).addTransport(with(any(TransportId.class))); will(returnValue(new TransportIndex(index.getAndIncrement()))); + allowing(db).getConfig(with(any(TransportId.class))); + will(returnValue(new TransportConfig())); allowing(db).getLocalProperties(with(any(TransportId.class))); will(returnValue(new TransportProperties())); allowing(db).getRemoteProperties(with(any(TransportId.class))); @@ -46,7 +49,7 @@ public class PluginManagerImplTest extends BriarTestCase { ExecutorService executor = Executors.newCachedThreadPool(); PluginManagerImpl p = new PluginManagerImpl(executor, db, poller, dispatcher, uiCallback); - // We expect either 2 or 3 plugins to be started, depending on whether + // We expect either 3 or 4 plugins to be started, depending on whether // the test machine has a Bluetooth device int started = p.start(); int stopped = p.stop(); diff --git a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java index 8b7c473e63933b85e2db3d50e345d8e86a9e8faf..cf4cb3fca9b03b8f342f09108584113096d66e17 100644 --- a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java +++ b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.HashMap; +import java.util.Hashtable; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -104,7 +104,7 @@ public class SimpleSocketPluginTest extends BriarTestCase { private static class Callback implements DuplexPluginCallback { private final Map<ContactId, TransportProperties> remote = - new HashMap<ContactId, TransportProperties>(); + new Hashtable<ContactId, TransportProperties>(); private final CountDownLatch latch = new CountDownLatch(1); private TransportConfig config = new TransportConfig(); diff --git a/test/net/sf/briar/plugins/tor/TorPluginTest.java b/test/net/sf/briar/plugins/tor/TorPluginTest.java index aef1f7f6bd8c61b6d60839b60eb792307e7b37b1..9f25e82f697ec9d4a03c4f1395367c46cf0c7926 100644 --- a/test/net/sf/briar/plugins/tor/TorPluginTest.java +++ b/test/net/sf/briar/plugins/tor/TorPluginTest.java @@ -1,6 +1,6 @@ package net.sf.briar.plugins.tor; -import java.util.HashMap; +import java.util.Hashtable; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -18,28 +18,48 @@ import org.junit.Test; public class TorPluginTest extends BriarTestCase { + private final ContactId contactId = new ContactId(1); + @Test - public void testCreateHiddenService() throws Exception { - Callback callback = new Callback(); + public void testHiddenService() throws Exception { Executor e = Executors.newCachedThreadPool(); - TorPlugin plugin = new TorPlugin(e, callback, 0L); - plugin.start(); - // The plugin should have created a hidden service - callback.latch.await(5, TimeUnit.MINUTES); - String onion = callback.local.get("onion"); + // 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 + serverCallback.latch.await(5, 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(); + TransportProperties p = new TransportProperties(); + p.put("onion", onion); + clientCallback.remote.put(contactId, p); + 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); + // Stop the plugins + serverPlugin.stop(); + clientPlugin.stop(); } private static class Callback implements DuplexPluginCallback { private final Map<ContactId, TransportProperties> remote = - new HashMap<ContactId, TransportProperties>(); + new Hashtable<ContactId, TransportProperties>(); private final CountDownLatch latch = new CountDownLatch(1); private TransportConfig config = new TransportConfig(); private TransportProperties local = new TransportProperties(); + private volatile int incomingConnections = 0; + public TransportConfig getConfig() { return config; } @@ -71,7 +91,9 @@ public class TorPluginTest extends BriarTestCase { public void showMessage(String... message) {} - public void incomingConnectionCreated(DuplexTransportConnection d) {} + public void incomingConnectionCreated(DuplexTransportConnection d) { + incomingConnections++; + } public void outgoingConnectionCreated(ContactId c, DuplexTransportConnection d) {}