diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/AbstractMailboxSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/AbstractMailboxSession.java index b1adf524833688d882cb69e0402692328829aa25..013fd0e1788b668daf062c40e3394531f183d149 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/AbstractMailboxSession.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/AbstractMailboxSession.java @@ -1,7 +1,9 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.mailbox.MailboxConstants; import org.briarproject.bramble.api.sync.SyncSession; import org.briarproject.bramble.api.sync.SyncSessionFactory; @@ -38,6 +40,7 @@ public abstract class AbstractMailboxSession implements Runnable { Logger.getLogger(AbstractMailboxSession.class.getName()); private final Executor ioExecutor; private final ContactId contactId; + private DatabaseComponent db; private KeyManager keyManager; private SyncSessionFactory syncSessionFactory; private final StreamWriterFactory streamWriterFactory; @@ -54,6 +57,7 @@ public abstract class AbstractMailboxSession implements Runnable { public AbstractMailboxSession(Executor ioExecutor, + DatabaseComponent db, KeyManager keyManager, SyncSessionFactory syncSessionFactory, StreamWriterFactory streamWriterFactory, @@ -64,6 +68,7 @@ public abstract class AbstractMailboxSession implements Runnable { ContactId contactId) { this.ioExecutor = ioExecutor; + this.db = db; this.keyManager = keyManager; this.syncSessionFactory = syncSessionFactory; this.streamWriterFactory = streamWriterFactory; @@ -221,14 +226,30 @@ public abstract class AbstractMailboxSession implements Runnable { * Get an encrypted Sync stream which can be stored on the mailbox by * issuing a STORE request * - * @param targetContactId The encrypted sync stream is generated for the given + * @param c The encrypted sync stream is generated for the given * contactId - * @return Encrypted Sync stream + * @return Encrypted Sync stream or Null if no data is available to send * @throws DbException * @throws IOException */ - protected byte[] getSyncStreamToStore(ContactId targetContactId) + @Nullable + protected byte[] getSyncStreamToStore(ContactId c) throws DbException, IOException { + Transaction txn = null; + boolean hasMessages; + + try { + txn = db.startTransaction(true); + hasMessages = db.hasMessagesOrAcksToSend(txn, c); + db.commitTransaction(txn); + } finally { + if (txn != null) + db.endTransaction(txn); + } + + if (!hasMessages) + return null; + StreamContext ctx = keyManager .getStreamContext(targetContactId, MailboxConstants.ID); @@ -241,12 +262,15 @@ public abstract class AbstractMailboxSession implements Runnable { StreamWriter streamWriter = streamWriterFactory .createStreamWriter(os, ctx); - syncSessionFactory.createSimplexOutgoingSession(targetContactId, - MailboxConstants.MAX_LATENCY, streamWriter); + syncSessionFactory.createSimplexOutgoingSession(c, + MailboxConstants.MAX_LATENCY, streamWriter).run(); + byte [] buf = os.toByteArray(); - return os.toByteArray(); - } + if (buf.length <= 0) + return null; + return buf; + } /** * Reads a Tag from the given InputStream and returns the matching StreamContext diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ContactMailboxSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ContactMailboxSession.java index 60785ad44b410718e0ebf3ca35712c635b3ab121..78b5da37e781c5abcaff31036c609b3791e37e94 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ContactMailboxSession.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/ContactMailboxSession.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.transport.KeyManager; @@ -33,7 +34,6 @@ import static org.briarproject.bramble.util.LogUtils.logException; public class ContactMailboxSession extends AbstractMailboxSession { private static final Logger LOG = Logger.getLogger(ContactMailboxSession.class.getName()); - private final KeyManager keyManager; private final SyncSessionFactory syncSessionFactory; private final StreamReaderFactory streamReaderFactory; private final MailboxProtocol mailboxProtocol; @@ -45,11 +45,12 @@ public class ContactMailboxSession extends AbstractMailboxSession { StreamWriterFactory streamWriterFactory, StreamReaderFactory streamReaderFactory, MailboxProtocol mailboxProtocol, - int transportMaxLatency, int transportMaxIdleTime) { - super(ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, + int transportMaxLatency, int transportMaxIdleTime, + DatabaseComponent db) { + super(ioExecutor, db, keyManager, syncSessionFactory, + streamWriterFactory, streamReaderFactory, mailboxProtocol, transportMaxLatency, transportMaxIdleTime, contactId); - this.keyManager = keyManager; this.syncSessionFactory = syncSessionFactory; this.streamReaderFactory = streamReaderFactory; this.mailboxProtocol = mailboxProtocol; @@ -62,13 +63,29 @@ public class ContactMailboxSession extends AbstractMailboxSession { @Override public void run() { // Get messages to send and formulate a STORE request + byte[] encryptedStream; try { - sendStreamsToStore(); - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) - LOG.warning(e.toString()); - } catch (DbException | InterruptedException e) { + // Get sync stream if available + encryptedStream = getSyncStreamToStore(contactId); + } catch (IOException | DbException e) { logException(LOG, WARNING, e); + return; + } + + if (encryptedStream == null) + return; + + // Send a STORE request and wait for a response + MailboxRequestStore req = new MailboxRequestStore(encryptedStream); + try { + mailboxProtocol.writeRequest(req); + if (!req.awaitAndGetResponse()) + throw new ProtocolException(req.getError()); + } catch (InterruptedException | IOException e) { + // TODO: Handle STORE request error! + if (LOG.isLoggable(WARNING)) + LOG.info(e.toString()); + return; } // End the session by issuing and END request and wait for peer @@ -81,24 +98,6 @@ public class ContactMailboxSession extends AbstractMailboxSession { } } - void sendStreamsToStore() - throws IOException, DbException, InterruptedException { - - // Get sync stream if available - byte[] encryptedStream = getSyncStreamToStore(contactId); - - while (encryptedStream != null || encryptedStream.length > 0) { - // Send a STORE request and wait for a response - MailboxRequestStore req = new MailboxRequestStore(encryptedStream); - mailboxProtocol.writeRequest(req); - if (!req.awaitAndGetResponse()) - // TODO: Handle STORE request error! - throw new ProtocolException(req.getError()); - - // Get next sync stream if available - encryptedStream = getSyncStreamToStore(contactId); - } - } /** * Handles an incoming TAKE request. The request contains an encrypted BSP diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxContactSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxContactSession.java index 447496fa4c0cbba06ca85e14237866a5d82cbdb3..4d8d3a3588d9aeb3f6a8beb65ad5f47831dd3711 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxContactSession.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxContactSession.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.api.transport.StreamReaderFactory; @@ -39,8 +40,8 @@ public class MailboxContactSession extends AbstractMailboxSession { StreamWriterFactory streamWriterFactory, StreamReaderFactory streamReaderFactory, MailboxProtocol mailboxProtocol, int transportMaxLatency, - int transportMaxIdleTime, MailboxStorage mailboxStorage) { - super(ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, + int transportMaxIdleTime, MailboxStorage mailboxStorage, DatabaseComponent db) { + super(ioExecutor, db, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, transportMaxLatency, transportMaxIdleTime, contactId); this.mailboxProtocol = mailboxProtocol; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxOwnerSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxOwnerSession.java index 8101f4c0c9e257719415d5516ce158c169123215..257eb884d7b0ee4df2cd5ce09d5282ee45423713 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxOwnerSession.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxOwnerSession.java @@ -1,6 +1,8 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.mailbox.MailboxConstants; import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.api.transport.StreamReaderFactory; @@ -10,7 +12,9 @@ import org.briarproject.bramble.mailbox.protocol.MailboxProtocol; import org.briarproject.bramble.mailbox.protocol.MailboxRequest; import org.briarproject.bramble.mailbox.protocol.MailboxRequestHandler; import org.briarproject.bramble.mailbox.protocol.MailboxRequestStore; +import org.briarproject.bramble.mailbox.protocol.MailboxRequestTake; +import java.io.IOException; import java.net.ProtocolException; import java.util.concurrent.Executor; import java.util.logging.Logger; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSessionFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSessionFactoryImpl.java index b5a93bff5db733a624fc559de0cfcc6fe184efdd..65e39e385b90abca80fba55dc595a45649362bb7 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSessionFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSessionFactoryImpl.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactType; +import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.transport.KeyManager; @@ -21,17 +22,20 @@ public class MailboxSessionFactoryImpl implements MailboxSessionFactory { private final SyncSessionFactory syncSessionFactory; private final StreamWriterFactory streamWriterFactory; private final StreamReaderFactory streamReaderFactory; + private DatabaseComponent db; + @Inject public MailboxSessionFactoryImpl(@IoExecutor Executor ioExecutor, KeyManager keyManager, SyncSessionFactory syncSessionFactory, StreamWriterFactory streamWriterFactory, - StreamReaderFactory streamReaderFactory) { + StreamReaderFactory streamReaderFactory, DatabaseComponent db) { this.ioExecutor = ioExecutor; this.keyManager = keyManager; this.syncSessionFactory = syncSessionFactory; this.streamWriterFactory = streamWriterFactory; this.streamReaderFactory = streamReaderFactory; + this.db = db; // FIXME: using temporary storage for now this.mailboxStorage = new MailboxStorage(); @@ -51,22 +55,22 @@ public class MailboxSessionFactoryImpl implements MailboxSessionFactory { return new PrivateMailboxSession(contactId, ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, - transportMaxLatency, transportMaxIdleTime); + transportMaxLatency, transportMaxIdleTime, db); case CONTACT_MAILBOX: return new ContactMailboxSession(contactId, ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, - transportMaxLatency, transportMaxIdleTime); + transportMaxLatency, transportMaxIdleTime, db); case MAILBOX_OWNER: return new MailboxOwnerSession(contactId, ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, - transportMaxLatency, transportMaxIdleTime, mailboxStorage); + transportMaxLatency, transportMaxIdleTime, mailboxStorage, db); case MAILBOX_CONTACT: return new MailboxContactSession(contactId, ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, - transportMaxLatency, transportMaxIdleTime, mailboxStorage); + transportMaxLatency, transportMaxIdleTime, mailboxStorage, db); } return null; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java index 933a686ffb18b87c488519202f464f25d3b1e25f..0ef05af610d21df8386940f205fe48d761331f47 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/PrivateMailboxSession.java @@ -1,9 +1,8 @@ package org.briarproject.bramble.mailbox; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.mailbox.MailboxConstants; -import org.briarproject.bramble.api.mailbox.MailboxInfo; import org.briarproject.bramble.api.sync.SyncSessionFactory; import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.api.transport.StreamContext; @@ -17,17 +16,14 @@ import org.briarproject.bramble.mailbox.protocol.MailboxRequestStore; import org.briarproject.bramble.mailbox.protocol.MailboxRequestTake; import java.io.ByteArrayInputStream; -import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.net.ProtocolException; import java.util.concurrent.Executor; import java.util.logging.Logger; -import java.util.stream.Stream; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.bramble.mailbox.protocol.MailboxMessage.TYPE.TAKE; import static org.briarproject.bramble.util.LogUtils.logException; @@ -49,9 +45,9 @@ public class PrivateMailboxSession extends AbstractMailboxSession { StreamWriterFactory streamWriterFactory, StreamReaderFactory streamReaderFactory, MailboxProtocol mailboxProtocol, int transportMaxLatency, - int transportMaxIdleTime) { + int transportMaxIdleTime, DatabaseComponent db) { - super(ioExecutor, keyManager, syncSessionFactory, streamWriterFactory, + super(ioExecutor, db, keyManager, syncSessionFactory, streamWriterFactory, streamReaderFactory, mailboxProtocol, transportMaxLatency, transportMaxIdleTime, contactId); this.keyManager = keyManager;