mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Start the port-mapper on demand, delete mappings at shutdown.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,5 @@ package net.sf.briar.plugins.tcp;
|
||||
|
||||
interface PortMapper {
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
MappingResult map(int port);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user