From 42383001f1fd2722cb516ec21f93eb713328e08c Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Mon, 5 Nov 2012 15:08:48 +0000 Subject: [PATCH] Start the port-mapper on demand, delete mappings at shutdown. --- .../plugins/duplex/DuplexPluginFactory.java | 3 +- .../plugins/simplex/SimplexPluginFactory.java | 3 +- .../lifecycle/WindowsShutdownManagerImpl.java | 13 ++- .../sf/briar/plugins/PluginManagerImpl.java | 13 +-- .../bluetooth/BluetoothPluginFactory.java | 3 +- .../droidtooth/DroidtoothPluginFactory.java | 3 +- .../plugins/email/GmailPluginFactory.java | 3 +- .../file/RemovableDrivePluginFactory.java | 3 +- .../plugins/tcp/LanTcpPluginFactory.java | 3 +- src/net/sf/briar/plugins/tcp/PortMapper.java | 4 - .../sf/briar/plugins/tcp/PortMapperImpl.java | 85 +++++++++---------- .../sf/briar/plugins/tcp/WanTcpPlugin.java | 21 ----- .../plugins/tcp/WanTcpPluginFactory.java | 5 +- .../briar/plugins/tor/TorPluginFactory.java | 3 +- 14 files changed, 74 insertions(+), 91 deletions(-) diff --git a/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java b/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java index daf39c1550..047e458461 100644 --- a/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java +++ b/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.api.plugins.duplex; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import android.content.Context; @@ -10,5 +11,5 @@ public interface DuplexPluginFactory { DuplexPlugin createPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback); + ShutdownManager shutdownManager, DuplexPluginCallback callback); } diff --git a/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java b/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java index 06e4df03c8..6460d45a21 100644 --- a/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java +++ b/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.api.plugins.simplex; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import android.content.Context; @@ -10,5 +11,5 @@ public interface SimplexPluginFactory { SimplexPlugin createPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - SimplexPluginCallback callback); + ShutdownManager shutdownManager, SimplexPluginCallback callback); } diff --git a/src/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java b/src/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java index 38f66ce61f..d603975fe1 100644 --- a/src/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java +++ b/src/net/sf/briar/lifecycle/WindowsShutdownManagerImpl.java @@ -1,5 +1,8 @@ package net.sf.briar.lifecycle; +import static com.sun.jna.Library.OPTION_FUNCTION_MAPPER; +import static com.sun.jna.Library.OPTION_TYPE_MAPPER; +import static com.sun.jna.win32.W32APIFunctionMapper.UNICODE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; @@ -11,7 +14,6 @@ import java.util.logging.Logger; import net.sf.briar.util.OsUtils; -import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef.HINSTANCE; @@ -23,13 +25,11 @@ import com.sun.jna.platform.win32.WinDef.WPARAM; import com.sun.jna.platform.win32.WinUser.MSG; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.StdCallLibrary.StdCallCallback; -import com.sun.jna.win32.W32APIFunctionMapper; -import com.sun.jna.win32.W32APITypeMapper; class WindowsShutdownManagerImpl extends ShutdownManagerImpl { private static final Logger LOG = - Logger.getLogger(WindowsShutdownManagerImpl.class.getName()); + Logger.getLogger(WindowsShutdownManagerImpl.class.getName()); private static final int WM_QUERYENDSESSION = 17; private static final int GWL_WNDPROC = -4; @@ -42,9 +42,8 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl { WindowsShutdownManagerImpl() { // Use the Unicode versions of Win32 API calls Map<String, Object> m = new HashMap<String, Object>(); - m.put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); - m.put(Library.OPTION_FUNCTION_MAPPER, - W32APIFunctionMapper.UNICODE); + m.put(OPTION_TYPE_MAPPER, UNICODE); + m.put(OPTION_FUNCTION_MAPPER, UNICODE); options = Collections.unmodifiableMap(m); } diff --git a/src/net/sf/briar/plugins/PluginManagerImpl.java b/src/net/sf/briar/plugins/PluginManagerImpl.java index a0e2e4111b..4fb2748895 100644 --- a/src/net/sf/briar/plugins/PluginManagerImpl.java +++ b/src/net/sf/briar/plugins/PluginManagerImpl.java @@ -20,6 +20,7 @@ import net.sf.briar.api.TransportProperties; import net.sf.briar.api.android.AndroidExecutor; import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DbException; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.Plugin; import net.sf.briar.api.plugins.PluginCallback; import net.sf.briar.api.plugins.PluginExecutor; @@ -67,6 +68,7 @@ class PluginManagerImpl implements PluginManager { private final ExecutorService pluginExecutor; private final AndroidExecutor androidExecutor; + private final ShutdownManager shutdownManager; private final DatabaseComponent db; private final Poller poller; private final ConnectionDispatcher dispatcher; @@ -76,11 +78,12 @@ class PluginManagerImpl implements PluginManager { @Inject PluginManagerImpl(@PluginExecutor ExecutorService pluginExecutor, - AndroidExecutor androidExecutor, DatabaseComponent db, - Poller poller, ConnectionDispatcher dispatcher, - UiCallback uiCallback) { + AndroidExecutor androidExecutor, ShutdownManager shutdownManager, + DatabaseComponent db, Poller poller, + ConnectionDispatcher dispatcher, UiCallback uiCallback) { this.pluginExecutor = pluginExecutor; this.androidExecutor = androidExecutor; + this.shutdownManager = shutdownManager; this.db = db; this.poller = poller; this.dispatcher = dispatcher; @@ -99,7 +102,7 @@ class PluginManagerImpl implements PluginManager { (SimplexPluginFactory) c.newInstance(); SimplexCallback callback = new SimplexCallback(); SimplexPlugin plugin = factory.createPlugin(pluginExecutor, - androidExecutor, appContext, callback); + androidExecutor, appContext, shutdownManager, callback); if(plugin == null) { if(LOG.isLoggable(INFO)) { LOG.info(factory.getClass().getSimpleName() @@ -132,7 +135,7 @@ class PluginManagerImpl implements PluginManager { (DuplexPluginFactory) c.newInstance(); DuplexCallback callback = new DuplexCallback(); DuplexPlugin plugin = factory.createPlugin(pluginExecutor, - androidExecutor, appContext, callback); + androidExecutor, appContext, shutdownManager, callback); if(plugin == null) { if(LOG.isLoggable(INFO)) { LOG.info(factory.getClass().getSimpleName() diff --git a/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java b/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java index f3edf599c2..2d9754fde9 100644 --- a/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java +++ b/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java @@ -4,6 +4,7 @@ import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; import net.sf.briar.api.clock.SystemClock; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; @@ -16,7 +17,7 @@ public class BluetoothPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback) { + ShutdownManager shutdownManager, DuplexPluginCallback callback) { return new BluetoothPlugin(pluginExecutor, new SystemClock(), callback, POLLING_INTERVAL); } diff --git a/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java b/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java index e1634e102a..7e438c5483 100644 --- a/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java +++ b/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.droidtooth; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; @@ -15,7 +16,7 @@ public class DroidtoothPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback) { + ShutdownManager shutdownManager, DuplexPluginCallback callback) { return new DroidtoothPlugin(pluginExecutor, androidExecutor, appContext, callback, POLLING_INTERVAL); } diff --git a/src/net/sf/briar/plugins/email/GmailPluginFactory.java b/src/net/sf/briar/plugins/email/GmailPluginFactory.java index 192e0d412e..1057b80c03 100644 --- a/src/net/sf/briar/plugins/email/GmailPluginFactory.java +++ b/src/net/sf/briar/plugins/email/GmailPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.email; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.simplex.SimplexPlugin; import net.sf.briar.api.plugins.simplex.SimplexPluginCallback; import net.sf.briar.api.plugins.simplex.SimplexPluginFactory; @@ -12,7 +13,7 @@ public class GmailPluginFactory implements SimplexPluginFactory { public SimplexPlugin createPlugin(Executor pluginExecutor, AndroidExecutor androidExecutor, Context context, - SimplexPluginCallback callback) { + ShutdownManager shutdownManager, SimplexPluginCallback callback) { return new GmailPlugin(pluginExecutor, callback); } } diff --git a/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java b/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java index 0dfee33b7e..26ecec3675 100644 --- a/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java +++ b/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.file; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.simplex.SimplexPlugin; import net.sf.briar.api.plugins.simplex.SimplexPluginCallback; @@ -16,7 +17,7 @@ public class RemovableDrivePluginFactory implements SimplexPluginFactory { public SimplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - SimplexPluginCallback callback) { + ShutdownManager shutdownManager, SimplexPluginCallback callback) { RemovableDriveFinder finder; RemovableDriveMonitor monitor; if(OsUtils.isLinux()) { diff --git a/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java b/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java index fb5c8f560e..6abcba8997 100644 --- a/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java +++ b/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.tcp; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; @@ -15,7 +16,7 @@ public class LanTcpPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback) { + ShutdownManager shutdownManager, DuplexPluginCallback callback) { return new LanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL); } } diff --git a/src/net/sf/briar/plugins/tcp/PortMapper.java b/src/net/sf/briar/plugins/tcp/PortMapper.java index 5bd226329d..d7ad7d6fba 100644 --- a/src/net/sf/briar/plugins/tcp/PortMapper.java +++ b/src/net/sf/briar/plugins/tcp/PortMapper.java @@ -2,9 +2,5 @@ package net.sf.briar.plugins.tcp; interface PortMapper { - void start(); - - void stop(); - MappingResult map(int port); } diff --git a/src/net/sf/briar/plugins/tcp/PortMapperImpl.java b/src/net/sf/briar/plugins/tcp/PortMapperImpl.java index d3da9eb63c..bb7606e8aa 100644 --- a/src/net/sf/briar/plugins/tcp/PortMapperImpl.java +++ b/src/net/sf/briar/plugins/tcp/PortMapperImpl.java @@ -5,13 +5,13 @@ import static java.util.logging.Level.WARNING; import java.io.IOException; import java.net.InetAddress; -import java.util.Collection; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; +import net.sf.briar.api.lifecycle.ShutdownManager; + import org.wetorrent.upnp.GatewayDevice; import org.wetorrent.upnp.GatewayDiscover; import org.xml.sax.SAXException; @@ -21,71 +21,68 @@ class PortMapperImpl implements PortMapper { private static final Logger LOG = Logger.getLogger(PortMapperImpl.class.getName()); - private final CountDownLatch started = new CountDownLatch(1); - private final Collection<Integer> ports = - new CopyOnWriteArrayList<Integer>(); + private final ShutdownManager shutdownManager; + private final AtomicBoolean started = new AtomicBoolean(false); private volatile GatewayDevice gateway = null; - public void start() { - GatewayDiscover d = new GatewayDiscover(); + PortMapperImpl(ShutdownManager shutdownManager) { + this.shutdownManager = shutdownManager; + } + + public MappingResult map(final int port) { + if(!started.getAndSet(true)) start(); + if(gateway == null) return null; + InetAddress internal = gateway.getLocalAddress(); + if(internal == null) return null; + boolean succeeded = false; + InetAddress external = null; try { - d.discover(); + succeeded = gateway.addPortMapping(port, port, + internal.getHostAddress(), "TCP", "TCP"); + if(succeeded) { + shutdownManager.addShutdownHook(new Runnable() { + public void run() { + deleteMapping(port); + } + }); + } + String externalString = gateway.getExternalIPAddress(); + if(LOG.isLoggable(INFO)) + LOG.info("External address " + externalString); + if(externalString != null) + external = InetAddress.getByName(externalString); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } catch(SAXException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); - } catch(ParserConfigurationException e) { - if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } - gateway = d.getValidGateway(); - started.countDown(); + return new MappingResult(internal, external, port, succeeded); } - public void stop() { - if(gateway == null) return; + private void start() { + GatewayDiscover d = new GatewayDiscover(); try { - for(Integer port: ports) { - gateway.deletePortMapping(port, "TCP"); - if(LOG.isLoggable(INFO)) - LOG.info("Deleted mapping for port " + port); - } + d.discover(); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } catch(SAXException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); + } catch(ParserConfigurationException e) { + if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } + gateway = d.getValidGateway(); } - public MappingResult map(int port) { - try { - started.await(); - } catch(InterruptedException e) { - if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); - Thread.currentThread().interrupt(); - return null; - } - if(gateway == null) return null; - InetAddress internal = gateway.getLocalAddress(); - if(internal == null) return null; - boolean succeeded = false; - InetAddress external = null; + private void deleteMapping(int port) { try { - succeeded = gateway.addPortMapping(port, port, - internal.getHostAddress(), "TCP", "TCP"); - String externalString = gateway.getExternalIPAddress(); - if(externalString != null) - external = InetAddress.getByName(externalString); - if(LOG.isLoggable(INFO)) { - if(succeeded) LOG.info("External address " + externalString); - else LOG.info("Could not create port mapping"); - } + gateway.deletePortMapping(port, "TCP"); + if(LOG.isLoggable(INFO)) + LOG.info("Deleted mapping for port " + port); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } catch(SAXException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); } - if(succeeded) ports.add(port); - return new MappingResult(internal, external, port, succeeded); } } diff --git a/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java b/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java index c0849cf927..471b03d29f 100644 --- a/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java +++ b/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java @@ -2,7 +2,6 @@ package net.sf.briar.plugins.tcp; import static java.util.logging.Level.WARNING; -import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; @@ -49,26 +48,6 @@ class WanTcpPlugin extends TcpPlugin { return ID; } - @Override - public void start() throws IOException { - super.start(); - pluginExecutor.execute(new Runnable() { - public void run() { - portMapper.start(); - } - }); - } - - @Override - public void stop() throws IOException { - super.stop(); - pluginExecutor.execute(new Runnable() { - public void run() { - portMapper.stop(); - } - }); - } - @Override protected List<SocketAddress> getLocalSocketAddresses() { List<SocketAddress> addrs = new ArrayList<SocketAddress>(); diff --git a/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java b/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java index f976e22cf5..d4f89475bc 100644 --- a/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java +++ b/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.tcp; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; @@ -15,8 +16,8 @@ public class WanTcpPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback) { + ShutdownManager shutdownManager, DuplexPluginCallback callback) { return new WanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL, - new PortMapperImpl()); + new PortMapperImpl(shutdownManager)); } } diff --git a/src/net/sf/briar/plugins/tor/TorPluginFactory.java b/src/net/sf/briar/plugins/tor/TorPluginFactory.java index bb43a6d3b4..2d213209cc 100644 --- a/src/net/sf/briar/plugins/tor/TorPluginFactory.java +++ b/src/net/sf/briar/plugins/tor/TorPluginFactory.java @@ -3,6 +3,7 @@ package net.sf.briar.plugins.tor; import java.util.concurrent.Executor; import net.sf.briar.api.android.AndroidExecutor; +import net.sf.briar.api.lifecycle.ShutdownManager; import net.sf.briar.api.plugins.PluginExecutor; import net.sf.briar.api.plugins.duplex.DuplexPlugin; import net.sf.briar.api.plugins.duplex.DuplexPluginCallback; @@ -15,7 +16,7 @@ public class TorPluginFactory implements DuplexPluginFactory { public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor, AndroidExecutor androidExecutor, Context appContext, - DuplexPluginCallback callback) { + ShutdownManager shutdownManager, DuplexPluginCallback callback) { return new TorPlugin(pluginExecutor, callback, POLLING_INTERVAL); } } -- GitLab