diff --git a/components/net/sf/briar/plugins/socket/SocketPlugin.java b/components/net/sf/briar/plugins/socket/SocketPlugin.java index abf94d60c90e291de1cc6706b6f1c907917a2899..3a970a517ebbc2e028b6a78aee0c2d2089f21cbe 100644 --- a/components/net/sf/briar/plugins/socket/SocketPlugin.java +++ b/components/net/sf/briar/plugins/socket/SocketPlugin.java @@ -50,30 +50,74 @@ abstract class SocketPlugin implements StreamTransportPlugin { executor.execute(createBinder()); } - protected Runnable createBinder() { + private Runnable createBinder() { return new Runnable() { public void run() { - SocketAddress addr; - ServerSocket s; - try { - synchronized(SocketPlugin.this) { - if(!started) return; - addr = getLocalSocketAddress(); - s = createServerSocket(); + bind(); + } + }; + } + + private void bind() { + SocketAddress addr; + ServerSocket ss; + try { + synchronized(this) { + if(!started) return; + addr = getLocalSocketAddress(); + ss = createServerSocket(); + } + if(addr == null || ss == null) return; + ss.bind(addr); + } catch(IOException e) { + // FIXME: Logging + return; + } + synchronized(this) { + if(!started) return; + socket = ss; + setLocalSocketAddress(ss.getLocalSocketAddress()); + startListener(); + } + } + + private void startListener() { + new Thread() { + @Override + public void run() { + listen(); + } + }.start(); + } + + private void listen() { + while(true) { + ServerSocket ss; + Socket s; + synchronized(this) { + if(!started) return; + ss = socket; + } + try { + s = ss.accept(); + } catch(IOException e) { + // FIXME: Logging + return; + } + synchronized(this) { + if(!started) { + try { + s.close(); + } catch(IOException e) { + // FIXME: Logging } - if(addr == null || s == null) return; - s.bind(addr); - } catch(IOException e) { - // FIXME: Logging return; } - synchronized(SocketPlugin.this) { - if(!started) return; - socket = s; - setLocalSocketAddress(s.getLocalSocketAddress()); - } + SocketTransportConnection conn = + new SocketTransportConnection(s); + callback.incomingConnectionCreated(conn); } - }; + } } public synchronized void stop() throws IOException { @@ -109,20 +153,25 @@ abstract class SocketPlugin implements StreamTransportPlugin { } } - protected Runnable createConnector(final ContactId c) { + private Runnable createConnector(final ContactId c) { return new Runnable() { public void run() { - StreamTransportConnection conn = createAndConnectSocket(c); - if(conn != null) { - synchronized(SocketPlugin.this) { - if(started) callback.outgoingConnectionCreated(c, conn); - } - } + connect(c); } }; } - protected StreamTransportConnection createAndConnectSocket(ContactId c) { + private StreamTransportConnection connect(ContactId c) { + StreamTransportConnection conn = createAndConnectSocket(c); + if(conn != null) { + synchronized(this) { + if(started) callback.outgoingConnectionCreated(c, conn); + } + } + return conn; + } + + private StreamTransportConnection createAndConnectSocket(ContactId c) { SocketAddress addr; Socket s; try { diff --git a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java index aaa0e3b8e80afe31c312940c75dc59c82c1d9e8e..33182d0d3dbc96f894a32cbd956dcb4f99cb5434 100644 --- a/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java +++ b/test/net/sf/briar/plugins/socket/SimpleSocketPluginTest.java @@ -1,5 +1,8 @@ package net.sf.briar.plugins.socket; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; @@ -30,21 +33,34 @@ public class SimpleSocketPluginTest extends TestCase { } @Test - public void testBind() throws Exception { + public void testBindAndAccept() throws Exception { StubCallback callback = new StubCallback(); localProperties.put("host", "127.0.0.1"); localProperties.put("port", "0"); SimpleSocketPlugin plugin = new SimpleSocketPlugin(new ImmediateExecutor(), 10); plugin.start(localProperties, remoteProperties, config, callback); + // The plugin should have bound a socket and stored the port number assertNotNull(callback.localProperties); String host = callback.localProperties.get("host"); assertNotNull(host); assertEquals("127.0.0.1", host); - String port = callback.localProperties.get("port"); - assertNotNull(port); - assertTrue(Integer.valueOf(port) > 0 && Integer.valueOf(port) < 65536); + String portString = callback.localProperties.get("port"); + assertNotNull(portString); + int port = Integer.valueOf(portString); + assertTrue(port > 0 && port < 65536); + // The plugin should be listening on the port + InetSocketAddress addr = new InetSocketAddress(host, port); + Socket s = new Socket(); + s.connect(addr, 100); + s.close(); + // Stop the plugin plugin.stop(); + // The plugin should no longer be listening + try { + s.connect(addr, 100); + fail(); + } catch(IOException expected) {} } private static class ImmediateExecutor implements Executor {