diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionManager.java similarity index 85% rename from bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionManager.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionManager.java index c7c8113f9..e08a73e9b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionManager.java @@ -1,8 +1,11 @@ -package org.briarproject.bramble.api.plugin; +package org.briarproject.bramble.api.connection; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; @NotNullByDefault diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionRegistry.java b/bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionRegistry.java similarity index 95% rename from bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionRegistry.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionRegistry.java index 7f0adec36..715a4da9e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionRegistry.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/connection/ConnectionRegistry.java @@ -1,8 +1,9 @@ -package org.briarproject.bramble.api.plugin; +package org.briarproject.bramble.api.connection; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent; import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent; import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java index d95b07e0a..e2b7deae8 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/BrambleCoreModule.java @@ -1,6 +1,7 @@ package org.briarproject.bramble; import org.briarproject.bramble.client.ClientModule; +import org.briarproject.bramble.connection.ConnectionModule; import org.briarproject.bramble.contact.ContactModule; import org.briarproject.bramble.crypto.CryptoExecutorModule; import org.briarproject.bramble.crypto.CryptoModule; @@ -28,6 +29,7 @@ import dagger.Module; @Module(includes = { ClientModule.class, + ConnectionModule.class, ContactModule.class, CryptoModule.class, CryptoExecutorModule.class, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/Connection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/Connection.java new file mode 100644 index 000000000..1efe2d480 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/Connection.java @@ -0,0 +1,79 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Logger; + +import javax.annotation.Nullable; + +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; +import static org.briarproject.bramble.util.IoUtils.read; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +abstract class Connection { + + protected static final Logger LOG = getLogger(Connection.class.getName()); + + final KeyManager keyManager; + final ConnectionRegistry connectionRegistry; + final StreamReaderFactory streamReaderFactory; + final StreamWriterFactory streamWriterFactory; + + Connection(KeyManager keyManager, ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory) { + this.keyManager = keyManager; + this.connectionRegistry = connectionRegistry; + this.streamReaderFactory = streamReaderFactory; + this.streamWriterFactory = streamWriterFactory; + } + + @Nullable + StreamContext recogniseTag(TransportConnectionReader reader, + TransportId transportId) { + StreamContext ctx; + try { + byte[] tag = readTag(reader.getInputStream()); + return keyManager.getStreamContext(transportId, tag); + } catch (IOException | DbException e) { + logException(LOG, WARNING, e); + return null; + } + } + + private byte[] readTag(InputStream in) throws IOException { + byte[] tag = new byte[TAG_LENGTH]; + read(in, tag); + return tag; + } + + void disposeOnError(TransportConnectionReader reader, boolean recognised) { + try { + reader.dispose(true, recognised); + } catch (IOException e) { + logException(LOG, WARNING, e); + } + } + + void disposeOnError(TransportConnectionWriter writer) { + try { + writer.dispose(true); + } catch (IOException e) { + logException(LOG, WARNING, e); + } + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionManagerImpl.java new file mode 100644 index 000000000..7df9b1074 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionManagerImpl.java @@ -0,0 +1,110 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactExchangeManager; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.contact.HandshakeManager; +import org.briarproject.bramble.api.contact.PendingContactId; +import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.util.concurrent.Executor; + +import javax.annotation.concurrent.Immutable; +import javax.inject.Inject; + +@Immutable +@NotNullByDefault +class ConnectionManagerImpl implements ConnectionManager { + + private final Executor ioExecutor; + private final KeyManager keyManager; + private final StreamReaderFactory streamReaderFactory; + private final StreamWriterFactory streamWriterFactory; + private final SyncSessionFactory syncSessionFactory; + private final HandshakeManager handshakeManager; + private final ContactExchangeManager contactExchangeManager; + private final ConnectionRegistry connectionRegistry; + private final TransportPropertyManager transportPropertyManager; + + @Inject + ConnectionManagerImpl(@IoExecutor Executor ioExecutor, + KeyManager keyManager, StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + HandshakeManager handshakeManager, + ContactExchangeManager contactExchangeManager, + ConnectionRegistry connectionRegistry, + TransportPropertyManager transportPropertyManager) { + this.ioExecutor = ioExecutor; + this.keyManager = keyManager; + this.streamReaderFactory = streamReaderFactory; + this.streamWriterFactory = streamWriterFactory; + this.syncSessionFactory = syncSessionFactory; + this.handshakeManager = handshakeManager; + this.contactExchangeManager = contactExchangeManager; + this.connectionRegistry = connectionRegistry; + this.transportPropertyManager = transportPropertyManager; + } + + + @Override + public void manageIncomingConnection(TransportId t, + TransportConnectionReader r) { + ioExecutor.execute(new IncomingSimplexSyncConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + syncSessionFactory, transportPropertyManager, t, r)); + } + + @Override + public void manageIncomingConnection(TransportId t, + DuplexTransportConnection d) { + ioExecutor.execute(new IncomingDuplexSyncConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + syncSessionFactory, transportPropertyManager, ioExecutor, + t, d)); + } + + @Override + public void manageIncomingConnection(PendingContactId p, TransportId t, + DuplexTransportConnection d) { + ioExecutor.execute(new IncomingHandshakeConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + handshakeManager, contactExchangeManager, this, p, t, d)); + } + + @Override + public void manageOutgoingConnection(ContactId c, TransportId t, + TransportConnectionWriter w) { + ioExecutor.execute(new OutgoingSimplexSyncConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + syncSessionFactory, transportPropertyManager, c, t, w)); + } + + @Override + public void manageOutgoingConnection(ContactId c, TransportId t, + DuplexTransportConnection d) { + ioExecutor.execute(new OutgoingDuplexSyncConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + syncSessionFactory, transportPropertyManager, ioExecutor, + c, t, d)); + } + + @Override + public void manageOutgoingConnection(PendingContactId p, TransportId t, + DuplexTransportConnection d) { + ioExecutor.execute(new OutgoingHandshakeConnection(keyManager, + connectionRegistry, streamReaderFactory, streamWriterFactory, + handshakeManager, contactExchangeManager, this, p, t, d)); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionModule.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionModule.java new file mode 100644 index 000000000..e6b8fee3a --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionModule.java @@ -0,0 +1,26 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class ConnectionModule { + + @Provides + ConnectionManager provideConnectionManager( + ConnectionManagerImpl connectionManager) { + return connectionManager; + } + + @Provides + @Singleton + ConnectionRegistry provideConnectionRegistry( + ConnectionRegistryImpl connectionRegistry) { + return connectionRegistry; + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionRegistryImpl.java similarity index 97% rename from bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java rename to bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionRegistryImpl.java index 06056f960..1bba22593 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionRegistryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/ConnectionRegistryImpl.java @@ -1,11 +1,11 @@ -package org.briarproject.bramble.plugin; +package org.briarproject.bramble.connection; import org.briarproject.bramble.api.Multiset; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent; import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/DuplexSyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/DuplexSyncConnection.java new file mode 100644 index 000000000..0ed62ab0b --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/DuplexSyncConnection.java @@ -0,0 +1,78 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriter; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.util.concurrent.Executor; + +import javax.annotation.Nullable; + +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; + +@NotNullByDefault +abstract class DuplexSyncConnection extends SyncConnection { + + final Executor ioExecutor; + final TransportId transportId; + final TransportConnectionReader reader; + final TransportConnectionWriter writer; + final TransportProperties remote; + + @Nullable + volatile SyncSession outgoingSession = null; + + DuplexSyncConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager, + Executor ioExecutor, TransportId transportId, + DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, syncSessionFactory, + transportPropertyManager); + this.ioExecutor = ioExecutor; + this.transportId = transportId; + reader = connection.getReader(); + writer = connection.getWriter(); + remote = connection.getRemoteProperties(); + } + + void onReadError(boolean recognised) { + disposeOnError(reader, recognised); + disposeOnError(writer); + // Interrupt the outgoing session so it finishes + SyncSession out = outgoingSession; + if (out != null) out.interrupt(); + } + + void onWriteError() { + disposeOnError(reader, true); + disposeOnError(writer); + } + + SyncSession createDuplexOutgoingSession(StreamContext ctx, + TransportConnectionWriter w) throws IOException { + StreamWriter streamWriter = streamWriterFactory.createStreamWriter( + w.getOutputStream(), ctx); + ContactId c = requireNonNull(ctx.getContactId()); + return syncSessionFactory.createDuplexOutgoingSession(c, + w.getMaxLatency(), w.getMaxIdleTime(), streamWriter); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/HandshakeConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/HandshakeConnection.java new file mode 100644 index 000000000..7405bbe2e --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/HandshakeConnection.java @@ -0,0 +1,72 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactExchangeManager; +import org.briarproject.bramble.api.contact.HandshakeManager; +import org.briarproject.bramble.api.contact.PendingContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import javax.annotation.Nullable; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +abstract class HandshakeConnection extends Connection { + + final HandshakeManager handshakeManager; + final ContactExchangeManager contactExchangeManager; + final ConnectionManager connectionManager; + final PendingContactId pendingContactId; + final TransportId transportId; + final DuplexTransportConnection connection; + final TransportConnectionReader reader; + final TransportConnectionWriter writer; + + HandshakeConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + HandshakeManager handshakeManager, + ContactExchangeManager contactExchangeManager, + ConnectionManager connectionManager, + PendingContactId pendingContactId, + TransportId transportId, DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory); + this.handshakeManager = handshakeManager; + this.contactExchangeManager = contactExchangeManager; + this.connectionManager = connectionManager; + this.pendingContactId = pendingContactId; + this.transportId = transportId; + this.connection = connection; + reader = connection.getReader(); + writer = connection.getWriter(); + } + + @Nullable + StreamContext allocateStreamContext(PendingContactId pendingContactId, + TransportId transportId) { + try { + return keyManager.getStreamContext(pendingContactId, transportId); + } catch (DbException e) { + logException(LOG, WARNING, e); + return null; + } + } + + void onError(boolean recognised) { + disposeOnError(reader, recognised); + disposeOnError(writer); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingDuplexSyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingDuplexSyncConnection.java new file mode 100644 index 000000000..382b17a50 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingDuplexSyncConnection.java @@ -0,0 +1,103 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.util.concurrent.Executor; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class IncomingDuplexSyncConnection extends DuplexSyncConnection + implements Runnable { + + IncomingDuplexSyncConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager, + Executor ioExecutor, TransportId transportId, + DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, syncSessionFactory, + transportPropertyManager, ioExecutor, transportId, connection); + } + + @Override + public void run() { + // Read and recognise the tag + StreamContext ctx = recogniseTag(reader, transportId); + if (ctx == null) { + LOG.info("Unrecognised tag"); + onReadError(false); + return; + } + ContactId contactId = ctx.getContactId(); + if (contactId == null) { + LOG.warning("Expected contact tag, got rendezvous tag"); + onReadError(true); + return; + } + if (ctx.isHandshakeMode()) { + // TODO: Support handshake mode for contacts + LOG.warning("Received handshake tag, expected rotation mode"); + onReadError(true); + return; + } + connectionRegistry.registerConnection(contactId, transportId, true); + // Start the outgoing session on another thread + ioExecutor.execute(() -> runOutgoingSession(contactId)); + try { + // Store any transport properties discovered from the connection + transportPropertyManager.addRemotePropertiesFromConnection( + contactId, transportId, remote); + // Create and run the incoming session + createIncomingSession(ctx, reader).run(); + reader.dispose(false, true); + // Interrupt the outgoing session so it finishes cleanly + SyncSession out = outgoingSession; + if (out != null) out.interrupt(); + } catch (DbException | IOException e) { + logException(LOG, WARNING, e); + onReadError(true); + } finally { + connectionRegistry.unregisterConnection(contactId, transportId, + true); + } + } + + private void runOutgoingSession(ContactId contactId) { + // Allocate a stream context + StreamContext ctx = allocateStreamContext(contactId, transportId); + if (ctx == null) { + LOG.warning("Could not allocate stream context"); + onWriteError(); + return; + } + try { + // Create and run the outgoing session + SyncSession out = createDuplexOutgoingSession(ctx, writer); + outgoingSession = out; + out.run(); + writer.dispose(false); + } catch (IOException e) { + logException(LOG, WARNING, e); + onWriteError(); + } + } +} + diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingHandshakeConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingHandshakeConnection.java new file mode 100644 index 000000000..d919c1bd4 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingHandshakeConnection.java @@ -0,0 +1,93 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactExchangeManager; +import org.briarproject.bramble.api.contact.HandshakeManager; +import org.briarproject.bramble.api.contact.HandshakeManager.HandshakeResult; +import org.briarproject.bramble.api.contact.PendingContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriter; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.io.InputStream; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class IncomingHandshakeConnection extends HandshakeConnection + implements Runnable { + + IncomingHandshakeConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + HandshakeManager handshakeManager, + ContactExchangeManager contactExchangeManager, + ConnectionManager connectionManager, + PendingContactId pendingContactId, + TransportId transportId, DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, handshakeManager, contactExchangeManager, + connectionManager, pendingContactId, transportId, connection); + } + + @Override + public void run() { + // Read and recognise the tag + StreamContext ctxIn = recogniseTag(reader, transportId); + if (ctxIn == null) { + LOG.info("Unrecognised tag"); + onError(false); + return; + } + PendingContactId inPendingContactId = ctxIn.getPendingContactId(); + if (inPendingContactId == null) { + LOG.warning("Expected rendezvous tag, got contact tag"); + onError(true); + return; + } + // Allocate the outgoing stream context + StreamContext ctxOut = + allocateStreamContext(pendingContactId, transportId); + if (ctxOut == null) { + LOG.warning("Could not allocate stream context"); + onError(true); + return; + } + // Close the connection if it's redundant + if (!connectionRegistry.registerConnection(pendingContactId)) { + LOG.info("Redundant rendezvous connection"); + onError(true); + return; + } + // Handshake and exchange contacts + try { + InputStream in = streamReaderFactory.createStreamReader( + reader.getInputStream(), ctxIn); + // Flush the output stream to send the outgoing stream header + StreamWriter out = streamWriterFactory.createStreamWriter( + writer.getOutputStream(), ctxOut); + out.getOutputStream().flush(); + HandshakeResult result = + handshakeManager.handshake(pendingContactId, in, out); + contactExchangeManager.exchangeContacts(pendingContactId, + connection, result.getMasterKey(), result.isAlice(), false); + connectionRegistry.unregisterConnection(pendingContactId, true); + // Reuse the connection as a transport connection + connectionManager.manageIncomingConnection(transportId, connection); + } catch (IOException | DbException e) { + logException(LOG, WARNING, e); + onError(true); + connectionRegistry.unregisterConnection(pendingContactId, false); + } + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingSimplexSyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingSimplexSyncConnection.java new file mode 100644 index 000000000..9bf5980f8 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/IncomingSimplexSyncConnection.java @@ -0,0 +1,79 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class IncomingSimplexSyncConnection extends SyncConnection implements Runnable { + + private final TransportId transportId; + private final TransportConnectionReader reader; + + IncomingSimplexSyncConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager, + TransportId transportId, TransportConnectionReader reader) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, syncSessionFactory, + transportPropertyManager); + this.transportId = transportId; + this.reader = reader; + } + + @Override + public void run() { + // Read and recognise the tag + StreamContext ctx = recogniseTag(reader, transportId); + if (ctx == null) { + LOG.info("Unrecognised tag"); + onError(false); + return; + } + ContactId contactId = ctx.getContactId(); + if (contactId == null) { + LOG.warning("Received rendezvous stream, expected contact"); + onError(true); + return; + } + if (ctx.isHandshakeMode()) { + // TODO: Support handshake mode for contacts + LOG.warning("Received handshake tag, expected rotation mode"); + onError(true); + return; + } + connectionRegistry.registerConnection(contactId, transportId, true); + try { + // Create and run the incoming session + createIncomingSession(ctx, reader).run(); + reader.dispose(false, true); + } catch (IOException e) { + logException(LOG, WARNING, e); + onError(true); + } finally { + connectionRegistry.unregisterConnection(contactId, transportId, + true); + } + } + + private void onError(boolean recognised) { + disposeOnError(reader, recognised); + } +} + diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingDuplexSyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingDuplexSyncConnection.java new file mode 100644 index 000000000..0c8f464fb --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingDuplexSyncConnection.java @@ -0,0 +1,123 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.util.concurrent.Executor; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class OutgoingDuplexSyncConnection extends DuplexSyncConnection + implements Runnable { + + private final ContactId contactId; + + OutgoingDuplexSyncConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager, + Executor ioExecutor, ContactId contactId, TransportId transportId, + DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, syncSessionFactory, + transportPropertyManager, ioExecutor, transportId, connection); + this.contactId = contactId; + } + + @Override + public void run() { + // Allocate a stream context + StreamContext ctx = allocateStreamContext(contactId, transportId); + if (ctx == null) { + LOG.warning("Could not allocate stream context"); + onWriteError(); + return; + } + if (ctx.isHandshakeMode()) { + // TODO: Support handshake mode for contacts + LOG.warning("Cannot use handshake mode stream context"); + onWriteError(); + return; + } + // Start the incoming session on another thread + ioExecutor.execute(this::runIncomingSession); + try { + // Create and run the outgoing session + SyncSession out = createDuplexOutgoingSession(ctx, writer); + outgoingSession = out; + out.run(); + writer.dispose(false); + } catch (IOException e) { + logException(LOG, WARNING, e); + onWriteError(); + } + } + + private void runIncomingSession() { + // Read and recognise the tag + StreamContext ctx = recogniseTag(reader, transportId); + // Unrecognised tags are suspicious in this case + if (ctx == null) { + LOG.warning("Unrecognised tag for returning stream"); + onReadError(); + return; + } + // Check that the stream comes from the expected contact + ContactId inContactId = ctx.getContactId(); + if (inContactId == null) { + LOG.warning("Expected contact tag, got rendezvous tag"); + onReadError(); + return; + } + if (!contactId.equals(inContactId)) { + LOG.warning("Wrong contact ID for returning stream"); + onReadError(); + return; + } + if (ctx.isHandshakeMode()) { + // TODO: Support handshake mode for contacts + LOG.warning("Received handshake tag, expected rotation mode"); + onReadError(); + return; + } + connectionRegistry.registerConnection(contactId, transportId, false); + try { + // Store any transport properties discovered from the connection + transportPropertyManager.addRemotePropertiesFromConnection( + contactId, transportId, remote); + // Create and run the incoming session + createIncomingSession(ctx, reader).run(); + reader.dispose(false, true); + // Interrupt the outgoing session so it finishes cleanly + SyncSession out = outgoingSession; + if (out != null) out.interrupt(); + } catch (DbException | IOException e) { + logException(LOG, WARNING, e); + onReadError(); + } finally { + connectionRegistry.unregisterConnection(contactId, transportId, + false); + } + } + + private void onReadError() { + // 'Recognised' is always true for outgoing connections + onReadError(true); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingHandshakeConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingHandshakeConnection.java new file mode 100644 index 000000000..7a2e5264e --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingHandshakeConnection.java @@ -0,0 +1,115 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.contact.ContactExchangeManager; +import org.briarproject.bramble.api.contact.HandshakeManager; +import org.briarproject.bramble.api.contact.HandshakeManager.HandshakeResult; +import org.briarproject.bramble.api.contact.PendingContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriter; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.io.InputStream; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class OutgoingHandshakeConnection extends HandshakeConnection + implements Runnable { + + OutgoingHandshakeConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + HandshakeManager handshakeManager, + ContactExchangeManager contactExchangeManager, + ConnectionManager connectionManager, + PendingContactId pendingContactId, + TransportId transportId, DuplexTransportConnection connection) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, handshakeManager, contactExchangeManager, + connectionManager, pendingContactId, transportId, connection); + } + + @Override + public void run() { + // Allocate the outgoing stream context + StreamContext ctxOut = + allocateStreamContext(pendingContactId, transportId); + if (ctxOut == null) { + LOG.warning("Could not allocate stream context"); + onError(); + return; + } + // Flush the output stream to send the outgoing stream header + StreamWriter out; + try { + out = streamWriterFactory.createStreamWriter( + writer.getOutputStream(), ctxOut); + out.getOutputStream().flush(); + } catch (IOException e) { + logException(LOG, WARNING, e); + onError(); + return; + } + // Read and recognise the tag + StreamContext ctxIn = recogniseTag(reader, transportId); + // Unrecognised tags are suspicious in this case + if (ctxIn == null) { + LOG.warning("Unrecognised tag for returning stream"); + onError(); + return; + } + // Check that the stream comes from the expected pending contact + PendingContactId inPendingContactId = ctxIn.getPendingContactId(); + if (inPendingContactId == null) { + LOG.warning("Expected rendezvous tag, got contact tag"); + onError(); + return; + } + if (!inPendingContactId.equals(pendingContactId)) { + LOG.warning("Wrong pending contact ID for returning stream"); + onError(); + return; + } + // Close the connection if it's redundant + if (!connectionRegistry.registerConnection(pendingContactId)) { + LOG.info("Redundant rendezvous connection"); + onError(); + return; + } + // Handshake and exchange contacts + try { + InputStream in = streamReaderFactory.createStreamReader( + reader.getInputStream(), ctxIn); + HandshakeResult result = + handshakeManager.handshake(pendingContactId, in, out); + Contact contact = contactExchangeManager.exchangeContacts( + pendingContactId, connection, result.getMasterKey(), + result.isAlice(), false); + connectionRegistry.unregisterConnection(pendingContactId, true); + // Reuse the connection as a transport connection + connectionManager.manageOutgoingConnection(contact.getId(), + transportId, connection); + } catch (IOException | DbException e) { + logException(LOG, WARNING, e); + onError(); + connectionRegistry.unregisterConnection(pendingContactId, false); + } + } + + private void onError() { + // 'Recognised' is always true for outgoing connections + onError(true); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingSimplexSyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingSimplexSyncConnection.java new file mode 100644 index 000000000..7136c818f --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/OutgoingSimplexSyncConnection.java @@ -0,0 +1,82 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriter; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class OutgoingSimplexSyncConnection extends SyncConnection implements Runnable { + + private final ContactId contactId; + private final TransportId transportId; + private final TransportConnectionWriter writer; + + OutgoingSimplexSyncConnection(KeyManager keyManager, + ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager, + ContactId contactId, TransportId transportId, + TransportConnectionWriter writer) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory, syncSessionFactory, + transportPropertyManager); + this.contactId = contactId; + this.transportId = transportId; + this.writer = writer; + } + + @Override + public void run() { + // Allocate a stream context + StreamContext ctx = allocateStreamContext(contactId, transportId); + if (ctx == null) { + LOG.warning("Could not allocate stream context"); + onError(); + return; + } + connectionRegistry.registerConnection(contactId, transportId, false); + try { + // Create and run the outgoing session + createSimplexOutgoingSession(ctx, writer).run(); + writer.dispose(false); + } catch (IOException e) { + logException(LOG, WARNING, e); + onError(); + } finally { + connectionRegistry.unregisterConnection(contactId, transportId, + false); + } + } + + private void onError() { + disposeOnError(writer); + } + + private SyncSession createSimplexOutgoingSession(StreamContext ctx, + TransportConnectionWriter w) throws IOException { + StreamWriter streamWriter = streamWriterFactory.createStreamWriter( + w.getOutputStream(), ctx); + ContactId c = requireNonNull(ctx.getContactId()); + return syncSessionFactory.createSimplexOutgoingSession(c, + w.getMaxLatency(), streamWriter); + } +} + diff --git a/bramble-core/src/main/java/org/briarproject/bramble/connection/SyncConnection.java b/bramble-core/src/main/java/org/briarproject/bramble/connection/SyncConnection.java new file mode 100644 index 000000000..40ac2cac2 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/connection/SyncConnection.java @@ -0,0 +1,61 @@ +package org.briarproject.bramble.connection; + +import org.briarproject.bramble.api.connection.ConnectionRegistry; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.sync.SyncSession; +import org.briarproject.bramble.api.sync.SyncSessionFactory; +import org.briarproject.bramble.api.transport.KeyManager; +import org.briarproject.bramble.api.transport.StreamContext; +import org.briarproject.bramble.api.transport.StreamReaderFactory; +import org.briarproject.bramble.api.transport.StreamWriterFactory; + +import java.io.IOException; +import java.io.InputStream; + +import javax.annotation.Nullable; + +import static java.util.logging.Level.WARNING; +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; +import static org.briarproject.bramble.util.LogUtils.logException; + +@NotNullByDefault +class SyncConnection extends Connection { + + final SyncSessionFactory syncSessionFactory; + final TransportPropertyManager transportPropertyManager; + + SyncConnection(KeyManager keyManager, ConnectionRegistry connectionRegistry, + StreamReaderFactory streamReaderFactory, + StreamWriterFactory streamWriterFactory, + SyncSessionFactory syncSessionFactory, + TransportPropertyManager transportPropertyManager) { + super(keyManager, connectionRegistry, streamReaderFactory, + streamWriterFactory); + this.syncSessionFactory = syncSessionFactory; + this.transportPropertyManager = transportPropertyManager; + } + + @Nullable + StreamContext allocateStreamContext(ContactId contactId, + TransportId transportId) { + try { + return keyManager.getStreamContext(contactId, transportId); + } catch (DbException e) { + logException(LOG, WARNING, e); + return null; + } + } + + SyncSession createIncomingSession(StreamContext ctx, + TransportConnectionReader r) throws IOException { + InputStream streamReader = streamReaderFactory.createStreamReader( + r.getInputStream(), ctx); + ContactId c = requireNonNull(ctx.getContactId()); + return syncSessionFactory.createIncomingSession(c, streamReader); + } +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java deleted file mode 100644 index ba45b6e1a..000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java +++ /dev/null @@ -1,709 +0,0 @@ -package org.briarproject.bramble.plugin; - -import org.briarproject.bramble.api.contact.Contact; -import org.briarproject.bramble.api.contact.ContactExchangeManager; -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.contact.HandshakeManager; -import org.briarproject.bramble.api.contact.HandshakeManager.HandshakeResult; -import org.briarproject.bramble.api.contact.PendingContactId; -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.lifecycle.IoExecutor; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; -import org.briarproject.bramble.api.plugin.TransportConnectionReader; -import org.briarproject.bramble.api.plugin.TransportConnectionWriter; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; -import org.briarproject.bramble.api.properties.TransportProperties; -import org.briarproject.bramble.api.properties.TransportPropertyManager; -import org.briarproject.bramble.api.sync.SyncSession; -import org.briarproject.bramble.api.sync.SyncSessionFactory; -import org.briarproject.bramble.api.transport.KeyManager; -import org.briarproject.bramble.api.transport.StreamContext; -import org.briarproject.bramble.api.transport.StreamReaderFactory; -import org.briarproject.bramble.api.transport.StreamWriter; -import org.briarproject.bramble.api.transport.StreamWriterFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.Executor; -import java.util.logging.Logger; - -import javax.annotation.Nullable; -import javax.inject.Inject; - -import static java.util.logging.Level.WARNING; -import static java.util.logging.Logger.getLogger; -import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; -import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; -import static org.briarproject.bramble.util.IoUtils.read; -import static org.briarproject.bramble.util.LogUtils.logException; - -@NotNullByDefault -class ConnectionManagerImpl implements ConnectionManager { - - private static final Logger LOG = - getLogger(ConnectionManagerImpl.class.getName()); - - private final Executor ioExecutor; - private final KeyManager keyManager; - private final StreamReaderFactory streamReaderFactory; - private final StreamWriterFactory streamWriterFactory; - private final SyncSessionFactory syncSessionFactory; - private final HandshakeManager handshakeManager; - private final ContactExchangeManager contactExchangeManager; - private final ConnectionRegistry connectionRegistry; - private final TransportPropertyManager transportPropertyManager; - - @Inject - ConnectionManagerImpl(@IoExecutor Executor ioExecutor, - KeyManager keyManager, StreamReaderFactory streamReaderFactory, - StreamWriterFactory streamWriterFactory, - SyncSessionFactory syncSessionFactory, - HandshakeManager handshakeManager, - ContactExchangeManager contactExchangeManager, - ConnectionRegistry connectionRegistry, - TransportPropertyManager transportPropertyManager) { - this.ioExecutor = ioExecutor; - this.keyManager = keyManager; - this.streamReaderFactory = streamReaderFactory; - this.streamWriterFactory = streamWriterFactory; - this.syncSessionFactory = syncSessionFactory; - this.handshakeManager = handshakeManager; - this.contactExchangeManager = contactExchangeManager; - this.connectionRegistry = connectionRegistry; - this.transportPropertyManager = transportPropertyManager; - } - - @Override - public void manageIncomingConnection(TransportId t, - TransportConnectionReader r) { - ioExecutor.execute(new ManageIncomingSimplexConnection(t, r)); - } - - @Override - public void manageIncomingConnection(TransportId t, - DuplexTransportConnection d) { - ioExecutor.execute(new ManageIncomingDuplexConnection(t, d)); - } - - @Override - public void manageIncomingConnection(PendingContactId p, TransportId t, - DuplexTransportConnection d) { - ioExecutor.execute(new ManageIncomingHandshakeConnection(p, t, d)); - } - - @Override - public void manageOutgoingConnection(ContactId c, TransportId t, - TransportConnectionWriter w) { - ioExecutor.execute(new ManageOutgoingSimplexConnection(c, t, w)); - } - - @Override - public void manageOutgoingConnection(ContactId c, TransportId t, - DuplexTransportConnection d) { - ioExecutor.execute(new ManageOutgoingDuplexConnection(c, t, d)); - } - - @Override - public void manageOutgoingConnection(PendingContactId p, TransportId t, - DuplexTransportConnection d) { - ioExecutor.execute(new ManageOutgoingHandshakeConnection(p, t, d)); - } - - private byte[] readTag(InputStream in) throws IOException { - byte[] tag = new byte[TAG_LENGTH]; - read(in, tag); - return tag; - } - - private SyncSession createIncomingSession(StreamContext ctx, - TransportConnectionReader r) throws IOException { - InputStream streamReader = streamReaderFactory.createStreamReader( - r.getInputStream(), ctx); - ContactId c = requireNonNull(ctx.getContactId()); - return syncSessionFactory.createIncomingSession(c, streamReader); - } - - private SyncSession createSimplexOutgoingSession(StreamContext ctx, - TransportConnectionWriter w) throws IOException { - StreamWriter streamWriter = streamWriterFactory.createStreamWriter( - w.getOutputStream(), ctx); - ContactId c = requireNonNull(ctx.getContactId()); - return syncSessionFactory.createSimplexOutgoingSession(c, - w.getMaxLatency(), streamWriter); - } - - private SyncSession createDuplexOutgoingSession(StreamContext ctx, - TransportConnectionWriter w) throws IOException { - StreamWriter streamWriter = streamWriterFactory.createStreamWriter( - w.getOutputStream(), ctx); - ContactId c = requireNonNull(ctx.getContactId()); - return syncSessionFactory.createDuplexOutgoingSession(c, - w.getMaxLatency(), w.getMaxIdleTime(), streamWriter); - } - - private void disposeOnError(TransportConnectionReader reader, - boolean recognised) { - try { - reader.dispose(true, recognised); - } catch (IOException e) { - logException(LOG, WARNING, e); - } - } - - private void disposeOnError(TransportConnectionWriter writer) { - try { - writer.dispose(true); - } catch (IOException e) { - logException(LOG, WARNING, e); - } - } - - private class ManageIncomingSimplexConnection implements Runnable { - - private final TransportId transportId; - private final TransportConnectionReader reader; - - private ManageIncomingSimplexConnection(TransportId transportId, - TransportConnectionReader reader) { - this.transportId = transportId; - this.reader = reader; - } - - @Override - public void run() { - // Read and recognise the tag - StreamContext ctx; - try { - byte[] tag = readTag(reader.getInputStream()); - ctx = keyManager.getStreamContext(transportId, tag); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onError(false); - return; - } - if (ctx == null) { - LOG.info("Unrecognised tag"); - onError(false); - return; - } - ContactId contactId = ctx.getContactId(); - if (contactId == null) { - LOG.warning("Received rendezvous stream, expected contact"); - onError(true); - return; - } - if (ctx.isHandshakeMode()) { - // TODO: Support handshake mode for contacts - LOG.warning("Received handshake tag, expected rotation mode"); - onError(true); - return; - } - connectionRegistry.registerConnection(contactId, transportId, true); - try { - // Create and run the incoming session - createIncomingSession(ctx, reader).run(); - reader.dispose(false, true); - } catch (IOException e) { - logException(LOG, WARNING, e); - onError(true); - } finally { - connectionRegistry.unregisterConnection(contactId, transportId, - true); - } - } - - private void onError(boolean recognised) { - disposeOnError(reader, recognised); - } - } - - private class ManageOutgoingSimplexConnection implements Runnable { - - private final ContactId contactId; - private final TransportId transportId; - private final TransportConnectionWriter writer; - - private ManageOutgoingSimplexConnection(ContactId contactId, - TransportId transportId, TransportConnectionWriter writer) { - this.contactId = contactId; - this.transportId = transportId; - this.writer = writer; - } - - @Override - public void run() { - // Allocate a stream context - StreamContext ctx; - try { - ctx = keyManager.getStreamContext(contactId, transportId); - } catch (DbException e) { - logException(LOG, WARNING, e); - onError(); - return; - } - if (ctx == null) { - LOG.warning("Could not allocate stream context"); - onError(); - return; - } - connectionRegistry.registerConnection(contactId, transportId, - false); - try { - // Create and run the outgoing session - createSimplexOutgoingSession(ctx, writer).run(); - writer.dispose(false); - } catch (IOException e) { - logException(LOG, WARNING, e); - onError(); - } finally { - connectionRegistry.unregisterConnection(contactId, transportId, - false); - } - } - - private void onError() { - disposeOnError(writer); - } - } - - private class ManageIncomingDuplexConnection implements Runnable { - - private final TransportId transportId; - private final TransportConnectionReader reader; - private final TransportConnectionWriter writer; - private final TransportProperties remote; - - @Nullable - private volatile SyncSession outgoingSession = null; - - private ManageIncomingDuplexConnection(TransportId transportId, - DuplexTransportConnection connection) { - this.transportId = transportId; - reader = connection.getReader(); - writer = connection.getWriter(); - remote = connection.getRemoteProperties(); - } - - @Override - public void run() { - // Read and recognise the tag - StreamContext ctx; - try { - byte[] tag = readTag(reader.getInputStream()); - ctx = keyManager.getStreamContext(transportId, tag); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onReadError(false); - return; - } - if (ctx == null) { - LOG.info("Unrecognised tag"); - onReadError(false); - return; - } - ContactId contactId = ctx.getContactId(); - if (contactId == null) { - LOG.warning("Expected contact tag, got rendezvous tag"); - onReadError(true); - return; - } - if (ctx.isHandshakeMode()) { - // TODO: Support handshake mode for contacts - LOG.warning("Received handshake tag, expected rotation mode"); - onReadError(true); - return; - } - connectionRegistry.registerConnection(contactId, transportId, true); - // Start the outgoing session on another thread - ioExecutor.execute(() -> runOutgoingSession(contactId)); - try { - // Store any transport properties discovered from the connection - transportPropertyManager.addRemotePropertiesFromConnection( - contactId, transportId, remote); - // Create and run the incoming session - createIncomingSession(ctx, reader).run(); - reader.dispose(false, true); - // Interrupt the outgoing session so it finishes cleanly - SyncSession out = outgoingSession; - if (out != null) out.interrupt(); - } catch (DbException | IOException e) { - logException(LOG, WARNING, e); - onReadError(true); - } finally { - connectionRegistry.unregisterConnection(contactId, transportId, - true); - } - } - - private void runOutgoingSession(ContactId contactId) { - // Allocate a stream context - StreamContext ctx; - try { - ctx = keyManager.getStreamContext(contactId, transportId); - } catch (DbException e) { - logException(LOG, WARNING, e); - onWriteError(); - return; - } - if (ctx == null) { - LOG.warning("Could not allocate stream context"); - onWriteError(); - return; - } - try { - // Create and run the outgoing session - SyncSession out = createDuplexOutgoingSession(ctx, writer); - outgoingSession = out; - out.run(); - writer.dispose(false); - } catch (IOException e) { - logException(LOG, WARNING, e); - onWriteError(); - } - } - - private void onReadError(boolean recognised) { - disposeOnError(reader, recognised); - disposeOnError(writer); - // Interrupt the outgoing session so it finishes - SyncSession out = outgoingSession; - if (out != null) out.interrupt(); - } - - private void onWriteError() { - disposeOnError(reader, true); - disposeOnError(writer); - } - } - - private class ManageOutgoingDuplexConnection implements Runnable { - - private final ContactId contactId; - private final TransportId transportId; - private final TransportConnectionReader reader; - private final TransportConnectionWriter writer; - private final TransportProperties remote; - - @Nullable - private volatile SyncSession outgoingSession = null; - - private ManageOutgoingDuplexConnection(ContactId contactId, - TransportId transportId, DuplexTransportConnection connection) { - this.contactId = contactId; - this.transportId = transportId; - reader = connection.getReader(); - writer = connection.getWriter(); - remote = connection.getRemoteProperties(); - } - - @Override - public void run() { - // Allocate a stream context - StreamContext ctx; - try { - ctx = keyManager.getStreamContext(contactId, transportId); - } catch (DbException e) { - logException(LOG, WARNING, e); - onWriteError(); - return; - } - if (ctx == null) { - LOG.warning("Could not allocate stream context"); - onWriteError(); - return; - } - if (ctx.isHandshakeMode()) { - // TODO: Support handshake mode for contacts - LOG.warning("Cannot use handshake mode stream context"); - onWriteError(); - return; - } - // Start the incoming session on another thread - ioExecutor.execute(this::runIncomingSession); - try { - // Create and run the outgoing session - SyncSession out = createDuplexOutgoingSession(ctx, writer); - outgoingSession = out; - out.run(); - writer.dispose(false); - } catch (IOException e) { - logException(LOG, WARNING, e); - onWriteError(); - } - } - - private void runIncomingSession() { - // Read and recognise the tag - StreamContext ctx; - try { - byte[] tag = readTag(reader.getInputStream()); - ctx = keyManager.getStreamContext(transportId, tag); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onReadError(); - return; - } - // Unrecognised tags are suspicious in this case - if (ctx == null) { - LOG.warning("Unrecognised tag for returning stream"); - onReadError(); - return; - } - // Check that the stream comes from the expected contact - ContactId inContactId = ctx.getContactId(); - if (inContactId == null) { - LOG.warning("Expected contact tag, got rendezvous tag"); - onReadError(); - return; - } - if (!contactId.equals(inContactId)) { - LOG.warning("Wrong contact ID for returning stream"); - onReadError(); - return; - } - if (ctx.isHandshakeMode()) { - // TODO: Support handshake mode for contacts - LOG.warning("Received handshake tag, expected rotation mode"); - onReadError(); - return; - } - connectionRegistry.registerConnection(contactId, transportId, - false); - try { - // Store any transport properties discovered from the connection - transportPropertyManager.addRemotePropertiesFromConnection( - contactId, transportId, remote); - // Create and run the incoming session - createIncomingSession(ctx, reader).run(); - reader.dispose(false, true); - // Interrupt the outgoing session so it finishes cleanly - SyncSession out = outgoingSession; - if (out != null) out.interrupt(); - } catch (DbException | IOException e) { - logException(LOG, WARNING, e); - onReadError(); - } finally { - connectionRegistry.unregisterConnection(contactId, transportId, - false); - } - } - - private void onReadError() { - // 'Recognised' is always true for outgoing connections - disposeOnError(reader, true); - disposeOnError(writer); - // Interrupt the outgoing session so it finishes - SyncSession out = outgoingSession; - if (out != null) out.interrupt(); - } - - private void onWriteError() { - disposeOnError(reader, true); - disposeOnError(writer); - } - } - - private class ManageIncomingHandshakeConnection implements Runnable { - - private final PendingContactId pendingContactId; - private final TransportId transportId; - private final DuplexTransportConnection connection; - private final TransportConnectionReader reader; - private final TransportConnectionWriter writer; - - private ManageIncomingHandshakeConnection( - PendingContactId pendingContactId, TransportId transportId, - DuplexTransportConnection connection) { - this.pendingContactId = pendingContactId; - this.transportId = transportId; - this.connection = connection; - reader = connection.getReader(); - writer = connection.getWriter(); - } - - @Override - public void run() { - // Read and recognise the tag - StreamContext ctxIn; - try { - byte[] tag = readTag(reader.getInputStream()); - ctxIn = keyManager.getStreamContext(transportId, tag); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onError(false); - return; - } - if (ctxIn == null) { - LOG.info("Unrecognised tag"); - onError(false); - return; - } - PendingContactId inPendingContactId = ctxIn.getPendingContactId(); - if (inPendingContactId == null) { - LOG.warning("Expected rendezvous tag, got contact tag"); - onError(true); - return; - } - // Allocate the outgoing stream context - StreamContext ctxOut; - try { - ctxOut = keyManager.getStreamContext(pendingContactId, - transportId); - } catch (DbException e) { - logException(LOG, WARNING, e); - onError(true); - return; - } - if (ctxOut == null) { - LOG.warning("Could not allocate stream context"); - onError(true); - return; - } - // Close the connection if it's redundant - if (!connectionRegistry.registerConnection(pendingContactId)) { - LOG.info("Redundant rendezvous connection"); - onError(true); - return; - } - // Handshake and exchange contacts - try { - InputStream in = streamReaderFactory.createStreamReader( - reader.getInputStream(), ctxIn); - // Flush the output stream to send the outgoing stream header - StreamWriter out = streamWriterFactory.createStreamWriter( - writer.getOutputStream(), ctxOut); - out.getOutputStream().flush(); - HandshakeResult result = handshakeManager.handshake( - pendingContactId, in, out); - Contact contact = contactExchangeManager.exchangeContacts( - pendingContactId, connection, result.getMasterKey(), - result.isAlice(), false); - connectionRegistry.unregisterConnection(pendingContactId, true); - // Reuse the connection as a transport connection - manageOutgoingConnection(contact.getId(), transportId, - connection); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onError(true); - connectionRegistry.unregisterConnection(pendingContactId, - false); - } - } - - private void onError(boolean recognised) { - disposeOnError(reader, recognised); - disposeOnError(writer); - } - } - - private class ManageOutgoingHandshakeConnection implements Runnable { - - private final PendingContactId pendingContactId; - private final TransportId transportId; - private final DuplexTransportConnection connection; - private final TransportConnectionReader reader; - private final TransportConnectionWriter writer; - - private ManageOutgoingHandshakeConnection( - PendingContactId pendingContactId, TransportId transportId, - DuplexTransportConnection connection) { - this.pendingContactId = pendingContactId; - this.transportId = transportId; - this.connection = connection; - reader = connection.getReader(); - writer = connection.getWriter(); - } - - @Override - public void run() { - // Allocate the outgoing stream context - StreamContext ctxOut; - try { - ctxOut = keyManager.getStreamContext(pendingContactId, - transportId); - } catch (DbException e) { - logException(LOG, WARNING, e); - onError(); - return; - } - if (ctxOut == null) { - LOG.warning("Could not allocate stream context"); - onError(); - return; - } - // Flush the output stream to send the outgoing stream header - StreamWriter out; - try { - out = streamWriterFactory.createStreamWriter( - writer.getOutputStream(), ctxOut); - out.getOutputStream().flush(); - } catch (IOException e) { - logException(LOG, WARNING, e); - onError(); - return; - } - // Read and recognise the tag - StreamContext ctxIn; - try { - byte[] tag = readTag(reader.getInputStream()); - ctxIn = keyManager.getStreamContext(transportId, tag); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onError(); - return; - } - // Unrecognised tags are suspicious in this case - if (ctxIn == null) { - LOG.warning("Unrecognised tag for returning stream"); - onError(); - return; - } - // Check that the stream comes from the expected pending contact - PendingContactId inPendingContactId = ctxIn.getPendingContactId(); - if (inPendingContactId == null) { - LOG.warning("Expected rendezvous tag, got contact tag"); - onError(); - return; - } - if (!inPendingContactId.equals(pendingContactId)) { - LOG.warning("Wrong pending contact ID for returning stream"); - onError(); - return; - } - // Close the connection if it's redundant - if (!connectionRegistry.registerConnection(pendingContactId)) { - LOG.info("Redundant rendezvous connection"); - onError(); - return; - } - // Handshake and exchange contacts - try { - InputStream in = streamReaderFactory.createStreamReader( - reader.getInputStream(), ctxIn); - HandshakeResult result = handshakeManager.handshake( - pendingContactId, in, out); - Contact contact = contactExchangeManager.exchangeContacts( - pendingContactId, connection, result.getMasterKey(), - result.isAlice(), false); - connectionRegistry.unregisterConnection(pendingContactId, true); - // Reuse the connection as a transport connection - manageOutgoingConnection(contact.getId(), transportId, - connection); - } catch (IOException | DbException e) { - logException(LOG, WARNING, e); - onError(); - connectionRegistry.unregisterConnection(pendingContactId, - false); - } - } - - private void onError() { - // 'Recognised' is always true for outgoing connections - disposeOnError(reader, true); - disposeOnError(writer); - } - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java index d4d69ca56..c7b33692a 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java @@ -1,12 +1,12 @@ package org.briarproject.bramble.plugin; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java index bca57cc1e..ff5e2299a 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java @@ -3,8 +3,6 @@ package org.briarproject.bramble.plugin; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.plugin.BackoffFactory; -import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.PluginManager; @@ -29,20 +27,6 @@ public class PluginModule { return new BackoffFactoryImpl(); } - @Provides - @Singleton - ConnectionManager provideConnectionManager( - ConnectionManagerImpl connectionManager) { - return connectionManager; - } - - @Provides - @Singleton - ConnectionRegistry provideConnectionRegistry( - ConnectionRegistryImpl connectionRegistry) { - return connectionRegistry; - } - @Provides @Singleton PluginManager providePluginManager(LifecycleManager lifecycleManager, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java index 256bf215e..c42e49a8c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java @@ -1,6 +1,8 @@ package org.briarproject.bramble.plugin; import org.briarproject.bramble.api.Pair; +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.db.DbException; @@ -9,8 +11,6 @@ import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.ConnectionHandler; -import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TransportConnectionReader; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java index d16317bff..8e41e9b64 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/rendezvous/RendezvousPollerImpl.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.rendezvous; import org.briarproject.bramble.PoliteExecutor; import org.briarproject.bramble.api.Pair; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.contact.PendingContactState; @@ -23,7 +24,6 @@ import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.ConnectionHandler; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TransportConnectionReader; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/connection/ConnectionRegistryImplTest.java similarity index 98% rename from bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/connection/ConnectionRegistryImplTest.java index 13c0466e8..3edf4ddc8 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/ConnectionRegistryImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/connection/ConnectionRegistryImplTest.java @@ -1,9 +1,9 @@ -package org.briarproject.bramble.plugin; +package org.briarproject.bramble.connection; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.event.EventBus; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent; import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java index dd47cfbbd..7f91988a0 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactExchangeIntegrationTestComponent.java @@ -2,13 +2,13 @@ package org.briarproject.bramble.contact; import org.briarproject.bramble.BrambleCoreEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.ContactExchangeManager; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import java.util.concurrent.Executor; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java index 93f649db8..02e896f27 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java @@ -1,7 +1,7 @@ package org.briarproject.bramble.plugin; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.event.EventBus; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.PluginException; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java index 255635a13..522c9aad9 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java @@ -1,10 +1,10 @@ package org.briarproject.bramble.plugin; +import org.briarproject.bramble.api.connection.ConnectionManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.plugin.ConnectionHandler; -import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TransportConnectionWriter; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java index 0f65d9adf..eddaacce4 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/rendezvous/RendezvousPollerImplTest.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.rendezvous; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactState; import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent; @@ -13,7 +14,6 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.plugin.ConnectionHandler; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/ScreenshotTest.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/ScreenshotTest.java index c1d040235..84fef39b2 100644 --- a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/ScreenshotTest.java +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/ScreenshotTest.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android; import android.app.Activity; import android.util.Log; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.system.Clock; import org.briarproject.briar.api.test.TestDataCreator; import org.junit.ClassRule; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java index ce30c42e5..5a9092582 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java @@ -7,6 +7,7 @@ import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.account.BriarAccountModule; import org.briarproject.bramble.api.FeatureFlags; import org.briarproject.bramble.api.account.AccountManager; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactExchangeManager; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.CryptoExecutor; @@ -19,7 +20,6 @@ import org.briarproject.bramble.api.keyagreement.PayloadEncoder; import org.briarproject.bramble.api.keyagreement.PayloadParser; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.settings.SettingsManager; import org.briarproject.bramble.api.system.AndroidExecutor; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java index a2adf44de..f76a05cac 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java @@ -10,6 +10,7 @@ import android.widget.TextView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactManager; @@ -24,7 +25,6 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent; import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent; import org.briarproject.briar.R; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java index 2d22db901..858c94c53 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java @@ -1,11 +1,11 @@ package org.briarproject.briar.android.controller; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent; import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index 6aa6986c7..1e4a8c416 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -21,6 +21,7 @@ import com.google.android.material.snackbar.Snackbar; import org.briarproject.bramble.api.FeatureFlags; import org.briarproject.bramble.api.Pair; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.event.ContactRemovedEvent; @@ -33,7 +34,6 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent; import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent; import org.briarproject.bramble.api.sync.ClientId; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java index 19c982029..176fde641 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java @@ -5,13 +5,13 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.contact.BaseContactListAdapter.OnContactClickListener; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeViewModel.java index d37a19b84..054121cac 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ContactExchangeViewModel.java @@ -2,6 +2,7 @@ package org.briarproject.briar.android.keyagreement; import android.app.Application; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactExchangeManager; import org.briarproject.bramble.api.crypto.SecretKey; @@ -10,7 +11,6 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java index 92f6343ef..13b7ba346 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java @@ -1,10 +1,10 @@ package org.briarproject.briar.android.privategroup.memberlist; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.android.controller.DbControllerImpl; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java index a6dcd9516..ab8e0e1ae 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.view.MenuItem; import android.widget.TextView; +import org.briarproject.bramble.api.connection.ConnectionRegistry; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DbException; @@ -13,7 +14,6 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.event.GroupRemovedEvent; import org.briarproject.briar.R; diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java index 9551ba793..1096b4314 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTestComponent.java @@ -2,11 +2,11 @@ package org.briarproject.briar.messaging; import org.briarproject.bramble.BrambleCoreEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.briar.api.messaging.MessagingManager; import org.briarproject.briar.api.messaging.PrivateMessageFactory; diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java index b998882ff..337303db4 100644 --- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java +++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTestComponent.java @@ -3,13 +3,13 @@ package org.briarproject.briar.test; import org.briarproject.bramble.BrambleCoreEagerSingletons; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.api.client.ClientHelper; +import org.briarproject.bramble.api.connection.ConnectionManager; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule; import org.briarproject.briar.api.blog.BlogFactory;