diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxServiceImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxServiceImpl.java index 9d91f9598c7bee32ccd88534d2b11f501f411883..3dfe1437e62e7c749c931143dbf03888978be972 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxServiceImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxServiceImpl.java @@ -1,18 +1,16 @@ package org.briarproject.bramble.mailbox; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactManager; -import org.briarproject.bramble.api.contact.ContactType; import org.briarproject.bramble.api.contact.PrivateMailbox; import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; 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.lifecycle.IoExecutor; -import org.briarproject.bramble.api.mailbox.MailboxConstants; import org.briarproject.bramble.api.mailbox.MailboxInfo; import org.briarproject.bramble.api.mailbox.MailboxManager; import org.briarproject.bramble.api.mailbox.MailboxService; @@ -20,21 +18,15 @@ import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.LanTcpConstants; import org.briarproject.bramble.api.plugin.PluginManager; import org.briarproject.bramble.api.plugin.TorConstants; -import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; -import org.briarproject.bramble.api.plugin.event.TransportDisabledEvent; -import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.system.Scheduler; import java.security.SecureRandom; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -57,6 +49,7 @@ public class MailboxServiceImpl implements MailboxService, EventListener { Logger.getLogger(MailboxServiceImpl.class.getName()); private final Executor ioExecutor; + private Executor dbExecutor; private final ScheduledExecutorService scheduler; private EventBus eventBus; private ContactManager contactManager; @@ -69,14 +62,12 @@ public class MailboxServiceImpl implements MailboxService, EventListener { private volatile Future mailboxFuture; - private volatile ContactId privateMailboxId = null; - private volatile AtomicBoolean hasPrivateMailbox = new AtomicBoolean(false); - - private ConcurrentHashMap<TransportId, DuplexPlugin> activePlugins = - new ConcurrentHashMap<>(); + private AtomicBoolean hasPrivateMailbox = new AtomicBoolean(false); + private PrivateMailbox privateMailbox; @Inject - MailboxServiceImpl(@IoExecutor Executor ioExecutor, @Scheduler + MailboxServiceImpl(@IoExecutor Executor ioExecutor, + @DatabaseExecutor Executor dbExecutor, @Scheduler ScheduledExecutorService scheduler, EventBus eventBus, ContactManager contactManager, DatabaseComponent db, @@ -85,6 +76,7 @@ public class MailboxServiceImpl implements MailboxService, EventListener { TransportPropertyManager transportPropertyManager, SecureRandom secureRandom) { this.ioExecutor = ioExecutor; + this.dbExecutor = dbExecutor; this.scheduler = scheduler; this.eventBus = eventBus; this.contactManager = contactManager; @@ -101,30 +93,8 @@ public class MailboxServiceImpl implements MailboxService, EventListener { if (LOG.isLoggable(INFO)) LOG.info("Starting Mailbox Service"); - try { - PrivateMailbox mb = contactManager.getPrivateMailbox(); - if (mb != null) - privateMailboxId = mb.getId(); - } catch (DbException e1) { - if (LOG.isLoggable(WARNING)) - LOG.info(e1.toString()); - } - if (privateMailboxId != null) - hasPrivateMailbox.set(true); - - // Get Lan plugin if available - DuplexPlugin plugin = - (DuplexPlugin) pluginManager.getPlugin(LanTcpConstants.ID); - - if (plugin != null && plugin.isRunning()) - activePlugins.put(LanTcpConstants.ID, plugin); - - // Get Tor plugin if available - plugin = (DuplexPlugin) pluginManager.getPlugin(TorConstants.ID); - - if (plugin != null && plugin.isRunning()) - activePlugins.put(TorConstants.ID, plugin); - + // Get private mailbox contact if available + dbExecutor.execute(() -> getPrivateMailbox()); mailboxFuture = schedule(new ConnectMailboxesTask(MIN_POLLING_INTERVALL), @@ -140,48 +110,25 @@ public class MailboxServiceImpl implements MailboxService, EventListener { @Override public void eventOccurred(Event e) { - if (e instanceof TransportEnabledEvent) { - TransportEnabledEvent tee = (TransportEnabledEvent) e; - if (tee.getTransportId().equals(LanTcpConstants.ID) || - tee.getTransportId().equals(TorConstants.ID)) { - DuplexPlugin p = - (DuplexPlugin) pluginManager - .getPlugin(tee.getTransportId()); - activePlugins.put(p.getId(), p); - } - } - - if (e instanceof TransportDisabledEvent) { - if (activePlugins - .containsKey( - ((TransportDisabledEvent) e).getTransportId())) { - activePlugins - .remove(((TransportDisabledEvent) e).getTransportId()); - } - } - if (e instanceof ContactAddedEvent) { if (hasPrivateMailbox.get()) return; - try { - PrivateMailbox mb = contactManager.getPrivateMailbox(); - if (mb != null) - privateMailboxId = mb.getId(); - } catch (DbException e1) { - if (LOG.isLoggable(WARNING)) - LOG.info(e1.toString()); - } - if (privateMailboxId != null) - hasPrivateMailbox.set(true); + dbExecutor.execute(() -> getPrivateMailbox()); } } - private class ConnectMailboxesTask implements Runnable { - // TODO: Try to connect via Lan then Tor (this is debatable but - // surely useful for testing) - ArrayList<TransportId> transportOrder = new ArrayList<>( - Arrays.asList(LanTcpConstants.ID, TorConstants.ID)); + private void getPrivateMailbox() { + try { + privateMailbox = contactManager.getPrivateMailbox(); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.info(e.toString()); + } + if (privateMailbox != null) + hasPrivateMailbox.getAndSet(true); + } + private class ConnectMailboxesTask implements Runnable { private int delay; private ConnectMailboxesTask(int min_interval) { @@ -189,20 +136,32 @@ public class MailboxServiceImpl implements MailboxService, EventListener { secureRandom.nextFloat() * min_interval); } - private void reschedule() { + void reschedule() { mailboxFuture = schedule(this, delay); } - @Override public void run() { + // NOTE: Using Lan then Tor order (this is debatable but + // surely useful for testing) + ArrayList<DuplexPlugin> activePlugins = new ArrayList<>(); + + DuplexPlugin p = + (DuplexPlugin) pluginManager.getPlugin(LanTcpConstants.ID); + if (p != null && p.isRunning()) + activePlugins.add(p); + + p = (DuplexPlugin) pluginManager.getPlugin(TorConstants.ID); + if (p != null && p.isRunning()) + activePlugins.add(p); + // Wait for plugins to become available - if (activePlugins.isEmpty()) { + if (activePlugins.isEmpty()) reschedule(); - } + // Try to connect to private mailbox try { - connectPrivateMailbox(); + connectPrivateMailbox(activePlugins); } catch (DbException e) { logException(LOG, WARNING, e); return; @@ -224,6 +183,7 @@ public class MailboxServiceImpl implements MailboxService, EventListener { } for (MailboxInfo mailboxInfo : contactMailboxes) { + // Don't connect to mailbox if contact is currently connected if (connectionRegistry .isConnected(mailboxInfo.getContactId())) continue; @@ -232,27 +192,28 @@ public class MailboxServiceImpl implements MailboxService, EventListener { // but has been introduced to our mailbox if (mailboxInfo.getMailboxId() == null) { mailboxManager - .handleOwnerContactWithoutMailbox(mailboxInfo); + .handleContactWithoutMailbox(mailboxInfo); continue; } - ioExecutor.execute(() -> connectContactMailbox(mailboxInfo)); + ioExecutor.execute(() -> connectContactMailbox(activePlugins, + mailboxInfo)); } reschedule(); } - private void connectContactMailbox(MailboxInfo mailboxInfo) { - for (TransportId transportId : transportOrder) { - if (!activePlugins.containsKey(transportId)) - continue; + private void connectContactMailbox( + ArrayList<DuplexPlugin> activePlugins, + MailboxInfo mailboxInfo) { - DuplexPlugin plugin = activePlugins.get(transportId); + for (DuplexPlugin plugin : activePlugins) { TransportProperties properties; try { properties = transportPropertyManager - .getRemoteProperties(mailboxInfo.getMailboxId(), transportId); + .getRemoteProperties(mailboxInfo.getMailboxId(), + plugin.getId()); } catch (DbException e) { logException(LOG, WARNING, e); return; @@ -266,25 +227,26 @@ public class MailboxServiceImpl implements MailboxService, EventListener { LOG.info("Contact mailbox connected"); mailboxManager.handleOutgoingContactMailboxConnection( - mailboxInfo.getContactId(), conn, transportId); + mailboxInfo.getContactId(), + mailboxInfo.getMailboxId(), + conn, plugin.getId()); + return; } } } - private void connectPrivateMailbox() throws DbException { + private void connectPrivateMailbox( + ArrayList<DuplexPlugin> activePlugins) throws DbException { // Check if mailbox is available and if it is connected if (!hasPrivateMailbox.get() || - connectionRegistry.isConnected(privateMailboxId)) + connectionRegistry.isConnected(privateMailbox.getId())) return; - for (TransportId transportId : transportOrder) { - if (!activePlugins.containsKey(transportId)) - continue; - - DuplexPlugin plugin = activePlugins.get(transportId); + for (DuplexPlugin plugin : activePlugins) { TransportProperties properties = transportPropertyManager - .getRemoteProperties(privateMailboxId, transportId); + .getRemoteProperties(privateMailbox.getId(), + plugin.getId()); if (LOG.isLoggable(INFO)) LOG.info("Connecting to private mailbox"); @@ -298,8 +260,8 @@ public class MailboxServiceImpl implements MailboxService, EventListener { LOG.info("Connected to private mailbox"); mailboxManager .handleOutgoingPrivateMailboxConnection( - privateMailboxId, conn, - transportId); + privateMailbox.getId(), conn, + plugin.getId()); return; } } @@ -311,8 +273,7 @@ public class MailboxServiceImpl implements MailboxService, EventListener { @Override public void stopService() { - if (mailboxFuture != null && !mailboxFuture.isCancelled()) - mailboxFuture.cancel(true); + mailboxFuture.cancel(true); eventBus.removeListener(this); } }