diff --git a/api/net/sf/briar/api/transport/batch/BatchTransportCallback.java b/api/net/sf/briar/api/transport/batch/BatchTransportCallback.java index 33423e3b72afef1750f237d72a07ac2eab12ed9c..7f335c6068daad41a6d834a1c4dea0217cc24bff 100644 --- a/api/net/sf/briar/api/transport/batch/BatchTransportCallback.java +++ b/api/net/sf/briar/api/transport/batch/BatchTransportCallback.java @@ -1,7 +1,6 @@ package net.sf.briar.api.transport.batch; import net.sf.briar.api.ContactId; -import net.sf.briar.api.TransportId; import net.sf.briar.api.transport.TransportCallback; /** @@ -12,6 +11,5 @@ public interface BatchTransportCallback extends TransportCallback { void readerCreated(BatchTransportReader r); - void writerCreated(ContactId contactId, TransportId t, long connection, - BatchTransportWriter w); + void writerCreated(ContactId contactId, BatchTransportWriter w); } diff --git a/api/net/sf/briar/api/transport/batch/BatchTransportPlugin.java b/api/net/sf/briar/api/transport/batch/BatchTransportPlugin.java index 09482f12bf468780631c87402eeaef3501e28ca7..4bd53dd5be9a85074ca61f5d97281e91f516ee59 100644 --- a/api/net/sf/briar/api/transport/batch/BatchTransportPlugin.java +++ b/api/net/sf/briar/api/transport/batch/BatchTransportPlugin.java @@ -50,10 +50,10 @@ public interface BatchTransportPlugin { boolean shouldPoll(); /** - * Returns the desired interval in seconds between calls to the plugin's - * poll() method. + * Returns the desired interval in milliseconds between calls to the + * plugin's poll() method. */ - int getPollingInterval(); + long getPollingInterval(); /** * Attempts to establish incoming and/or outgoing connections using the diff --git a/api/net/sf/briar/api/transport/stream/StreamTransportCallback.java b/api/net/sf/briar/api/transport/stream/StreamTransportCallback.java index f244160de75b966cce26eeae9bd7a6242aff0a88..2e41f18f1300a38046c6ce5f4026af9f2154236a 100644 --- a/api/net/sf/briar/api/transport/stream/StreamTransportCallback.java +++ b/api/net/sf/briar/api/transport/stream/StreamTransportCallback.java @@ -1,7 +1,6 @@ package net.sf.briar.api.transport.stream; import net.sf.briar.api.ContactId; -import net.sf.briar.api.TransportId; import net.sf.briar.api.transport.TransportCallback; /** @@ -12,6 +11,6 @@ public interface StreamTransportCallback extends TransportCallback { void incomingConnectionCreated(StreamTransportConnection c); - void outgoingConnectionCreated(ContactId contactId, TransportId t, - long connection, StreamTransportConnection c); + void outgoingConnectionCreated(ContactId contactId, + StreamTransportConnection c); } diff --git a/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java b/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java index c66edb69f656eedd7a4d05b68647e8a02ac286a9..aa3c25c81822aa909504114e285735d6a195f727 100644 --- a/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java +++ b/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java @@ -28,5 +28,5 @@ public interface StreamTransportConnection { * connection is not used, or if an exception is thrown while using the * connection. */ - void close() throws IOException; + void dispose() throws IOException; } diff --git a/api/net/sf/briar/api/transport/stream/StreamTransportPlugin.java b/api/net/sf/briar/api/transport/stream/StreamTransportPlugin.java index 970d58b2c4c0e1b0be3d3df210b0e91d8f5a4e7b..ff2c78bb6a25977d48f012a3022df9fdbd766437 100644 --- a/api/net/sf/briar/api/transport/stream/StreamTransportPlugin.java +++ b/api/net/sf/briar/api/transport/stream/StreamTransportPlugin.java @@ -49,10 +49,10 @@ public interface StreamTransportPlugin { boolean shouldPoll(); /** - * Returns the desired interval in seconds between calls to the plugin's - * poll() method. + * Returns the desired interval in milliseconds between calls to the + * plugin's poll() method. */ - int getPollingInterval(); + long getPollingInterval(); /** * Attempts to establish connections using the current transport and diff --git a/components/net/sf/briar/plugins/file/FilePlugin.java b/components/net/sf/briar/plugins/file/FilePlugin.java index 1ca4e7fd87cf9765f1d35520f16ccfc354bf3056..ca0a5c7e2785b4ec175e4dd484941ad1a547b99c 100644 --- a/components/net/sf/briar/plugins/file/FilePlugin.java +++ b/components/net/sf/briar/plugins/file/FilePlugin.java @@ -74,18 +74,6 @@ abstract class FilePlugin implements BatchTransportPlugin { this.config = config; } - public boolean shouldPoll() { - return false; - } - - public int getPollingInterval() { - return 0; - } - - public void poll() { - throw new UnsupportedOperationException(); - } - public BatchTransportReader createReader(ContactId c) { return null; } diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java index e3df83ed704921908396aac37cd925918e561200..8810933439df485d5ff1043198f991f3d7422187 100644 --- a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java +++ b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java @@ -48,6 +48,18 @@ implements RemovableDriveMonitor.Callback { monitor.stop(); } + public boolean shouldPoll() { + return false; + } + + public long getPollingInterval() { + return 0L; + } + + public void poll() { + throw new UnsupportedOperationException(); + } + @Override protected File chooseOutputDirectory() { try { diff --git a/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java b/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..2734a484a340fa33711ede54bfc4ca3793f00164 --- /dev/null +++ b/components/net/sf/briar/plugins/socket/SimpleSocketPlugin.java @@ -0,0 +1,79 @@ +package net.sf.briar.plugins.socket; + +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.util.Map; +import java.util.concurrent.Executor; + +import net.sf.briar.api.ContactId; +import net.sf.briar.api.TransportId; + +public class SimpleSocketPlugin extends SocketPlugin { + + public static final int TRANSPORT_ID = 1; + + private static final TransportId id = new TransportId(TRANSPORT_ID); + + private final long pollingInterval; + + SimpleSocketPlugin(Executor executor, long pollingInterval) { + super(executor); + this.pollingInterval = pollingInterval; + } + + public TransportId getId() { + return id; + } + + public boolean shouldPoll() { + return true; + } + + public long getPollingInterval() { + return pollingInterval; + } + + @Override + protected SocketAddress getLocalSocketAddress() { + Map<String, String> properties; + synchronized(this) { + properties = localProperties; + } + if(properties == null) return null; + return createSocketAddress(properties); + } + + @Override + protected SocketAddress getSocketAddress(ContactId c) { + Map<String, String> properties; + synchronized(this) { + properties = remoteProperties.get(c); + } + if(properties == null) return null; + return createSocketAddress(properties); + } + + private SocketAddress createSocketAddress(Map<String, String> properties) { + String host = properties.get("host"); + String portString = properties.get("port"); + if(host == null || portString == null) return null; + int port; + try { + port = Integer.valueOf(portString); + } catch(NumberFormatException e) { + return null; + } + return InetSocketAddress.createUnresolved(host, port); + } + + @Override + protected Socket createClientSocket() { + return new Socket(); + } + + @Override + protected Socket createServerSocket() { + return new Socket(); + } +} diff --git a/components/net/sf/briar/plugins/socket/SocketPlugin.java b/components/net/sf/briar/plugins/socket/SocketPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..b24fb6556dca406b4eb57b9c00d5ef19fc7e8454 --- /dev/null +++ b/components/net/sf/briar/plugins/socket/SocketPlugin.java @@ -0,0 +1,122 @@ +package net.sf.briar.plugins.socket; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketAddress; +import java.util.Map; +import java.util.concurrent.Executor; + +import net.sf.briar.api.ContactId; +import net.sf.briar.api.transport.InvalidConfigException; +import net.sf.briar.api.transport.InvalidTransportException; +import net.sf.briar.api.transport.stream.StreamTransportCallback; +import net.sf.briar.api.transport.stream.StreamTransportConnection; +import net.sf.briar.api.transport.stream.StreamTransportPlugin; + +abstract class SocketPlugin implements StreamTransportPlugin { + + private final Executor executor; + + protected Map<String, String> localProperties = null; + protected Map<ContactId, Map<String, String>> remoteProperties = null; + protected Map<String, String> config = null; + protected StreamTransportCallback callback = null; + + private volatile boolean started = false; + + protected abstract SocketAddress getLocalSocketAddress(); + protected abstract SocketAddress getSocketAddress(ContactId c); + protected abstract Socket createClientSocket(); + protected abstract Socket createServerSocket(); + + SocketPlugin(Executor executor) { + this.executor = executor; + } + + public synchronized void start(Map<String, String> localProperties, + Map<ContactId, Map<String, String>> remoteProperties, + Map<String, String> config, StreamTransportCallback callback) + throws InvalidTransportException, InvalidConfigException { + if(started) throw new IllegalStateException(); + started = true; + this.localProperties = localProperties; + this.remoteProperties = remoteProperties; + this.config = config; + this.callback = callback; + executor.execute(createBinder()); + } + + protected Runnable createBinder() { + return new Runnable() { + public void run() { + SocketAddress addr = getLocalSocketAddress(); + if(addr == null) return; + Socket s = createServerSocket(); + try { + s.bind(addr); + } catch(IOException e) { + return; + } + } + }; + } + + public synchronized void stop() { + if(!started) throw new IllegalStateException(); + started = false; + } + + public synchronized void setLocalProperties(Map<String, String> properties) + throws InvalidTransportException { + if(!started) throw new IllegalStateException(); + localProperties = properties; + } + + public synchronized void setRemoteProperties(ContactId c, + Map<String, String> properties) + throws InvalidTransportException { + if(!started) throw new IllegalStateException(); + remoteProperties.put(c, properties); + } + + public synchronized void setConfig(Map<String, String> config) + throws InvalidConfigException { + if(!started) throw new IllegalStateException(); + this.config = config; + } + + public synchronized void poll() { + if(!shouldPoll()) throw new UnsupportedOperationException(); + if(!started) throw new IllegalStateException(); + for(ContactId c : remoteProperties.keySet()) { + executor.execute(createConnector(c)); + } + } + + protected Runnable createConnector(final ContactId c) { + return new Runnable() { + public void run() { + StreamTransportConnection conn = createAndConnectSocket(c); + if(conn != null) callback.outgoingConnectionCreated(c, conn); + } + }; + } + + public StreamTransportConnection createConnection(ContactId c) { + if(!started) throw new IllegalStateException(); + return createAndConnectSocket(c); + } + + private StreamTransportConnection createAndConnectSocket(ContactId c) { + if(!started) return null; + SocketAddress addr = getSocketAddress(c); + if(addr == null) return null; + Socket s = createClientSocket(); + try { + s.connect(addr); + } catch(IOException e) { + return null; + } + return new SocketTransportConnection(s); + } +} diff --git a/components/net/sf/briar/plugins/socket/SocketTransportConnection.java b/components/net/sf/briar/plugins/socket/SocketTransportConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..92488fefff7c132fe208b971cdf18d6a553a7bde --- /dev/null +++ b/components/net/sf/briar/plugins/socket/SocketTransportConnection.java @@ -0,0 +1,38 @@ +package net.sf.briar.plugins.socket; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +import net.sf.briar.api.transport.stream.StreamTransportConnection; + +class SocketTransportConnection implements StreamTransportConnection { + + private final Socket socket; + + private boolean streamInUse = false; + + SocketTransportConnection(Socket socket) { + this.socket = socket; + } + + public InputStream getInputStream() throws IOException { + streamInUse = true; + return socket.getInputStream(); + } + + public OutputStream getOutputStream() throws IOException { + streamInUse = true; + return socket.getOutputStream(); + } + + public void finish() throws IOException { + // FIXME: Tell the plugin? + streamInUse = false; + } + + public void dispose() throws IOException { + if(streamInUse) socket.close(); + } +}