Start the port-mapper on demand, delete mappings at shutdown.

This commit is contained in:
akwizgran
2012-11-05 15:08:48 +00:00
parent fdfb3fee87
commit 42383001f1
14 changed files with 77 additions and 94 deletions

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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()

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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()) {

View File

@@ -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);
}
}

View File

@@ -2,9 +2,5 @@ package net.sf.briar.plugins.tcp;
interface PortMapper {
void start();
void stop();
MappingResult map(int port);
}

View File

@@ -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,13 +21,46 @@ 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() {
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 {
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());
}
return new MappingResult(internal, external, port, succeeded);
}
private void start() {
GatewayDiscover d = new GatewayDiscover();
try {
d.discover();
@@ -39,53 +72,17 @@ class PortMapperImpl implements PortMapper {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
}
gateway = d.getValidGateway();
started.countDown();
}
public void stop() {
if(gateway == null) return;
private void deleteMapping(int port) {
try {
for(Integer port: ports) {
gateway.deletePortMapping(port, "TCP");
if(LOG.isLoggable(INFO))
LOG.info("Deleted mapping for port " + port);
}
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());
}
}
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;
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");
}
} 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);
}
}

View File

@@ -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>();

View File

@@ -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));
}
}

View File

@@ -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);
}
}