forked from I2P_Developers/i2p.i2p
Transport: UPnP fixes for Android
This commit is contained in:
@ -52,6 +52,7 @@ import net.i2p.router.startup.StartupJob;
|
||||
import net.i2p.router.startup.WorkingDir;
|
||||
import net.i2p.router.tasks.*;
|
||||
import net.i2p.router.transport.FIFOBandwidthLimiter;
|
||||
import net.i2p.router.transport.UPnPScannerCallback;
|
||||
import net.i2p.router.transport.ntcp.NTCPTransport;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.router.util.EventLog;
|
||||
@ -103,6 +104,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
private FamilyKeyCrypto _familyKeyCrypto;
|
||||
private boolean _familyKeyCryptoFail;
|
||||
public final Object _familyKeyLock = new Object();
|
||||
private UPnPScannerCallback _upnpScannerCallback;
|
||||
|
||||
public final static String PROP_CONFIG_FILE = "router.configLocation";
|
||||
|
||||
@ -384,6 +386,8 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
_networkID = id;
|
||||
// for testing
|
||||
setUPnPScannerCallback(new LoggerCallback());
|
||||
changeState(State.INITIALIZED);
|
||||
// ********* Start no threads before here ********* //
|
||||
}
|
||||
@ -606,6 +610,32 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
*/
|
||||
public RouterContext getContext() { return _context; }
|
||||
|
||||
private class LoggerCallback implements UPnPScannerCallback {
|
||||
public void beforeScan() { _log.info("SSDP beforeScan()"); }
|
||||
public void afterScan() { _log.info("SSDP afterScan()"); }
|
||||
}
|
||||
|
||||
/**
|
||||
* For Android only.
|
||||
* MUST be set before runRouter() is called.
|
||||
*
|
||||
* @param callback the callback or null to clear it
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public synchronized void setUPnPScannerCallback(UPnPScannerCallback callback) {
|
||||
_upnpScannerCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Android only.
|
||||
*
|
||||
* @return the callback or null if none
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public synchronized UPnPScannerCallback getUPnPScannerCallback() {
|
||||
return _upnpScannerCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be called after instantiation.
|
||||
* Starts the threads. Does not install updates.
|
||||
|
@ -341,7 +341,10 @@ public class TransportManager implements TransportEventListener {
|
||||
// Maybe we need a config option to force on? Probably not.
|
||||
// What firewall supports UPnP and is configured with a public address on the LAN side?
|
||||
// Unlikely.
|
||||
if (_upnpManager != null && Addresses.getAnyAddress() == null)
|
||||
// Always start on Android, as we may have a cellular IPv4 address but
|
||||
// are routing all traffic through WiFi.
|
||||
// Also, conditions may change rapidly.
|
||||
if (_upnpManager != null && (SystemVersion.isAndroid() || Addresses.getAnyAddress() == null))
|
||||
_upnpManager.start();
|
||||
configTransports();
|
||||
_log.debug("Starting up the transport manager");
|
||||
|
@ -34,6 +34,8 @@ class UPnPManager {
|
||||
private final RouterContext _context;
|
||||
private final UPnP _upnp;
|
||||
private final UPnPCallback _upnpCallback;
|
||||
private final UPnPScannerCallback _scannerCallback;
|
||||
private final DelayedCallback _delayedCallback;
|
||||
private volatile boolean _isRunning;
|
||||
private volatile boolean _shouldBeRunning;
|
||||
private volatile long _lastRescan;
|
||||
@ -73,6 +75,8 @@ class UPnPManager {
|
||||
Debug.initialize(context);
|
||||
_upnp = new UPnP(context);
|
||||
_upnpCallback = new UPnPCallback();
|
||||
_scannerCallback = _context.router().getUPnPScannerCallback();
|
||||
_delayedCallback = (_scannerCallback != null) ? new DelayedCallback() : null;
|
||||
_rescanner = new Rescanner();
|
||||
}
|
||||
|
||||
@ -91,7 +95,16 @@ class UPnPManager {
|
||||
// and will eventually hit 1024 and then negative
|
||||
_upnp.setHTTPPort(_context.getProperty(PROP_HTTP_PORT, DEFAULT_HTTP_PORT));
|
||||
_upnp.setSSDPPort(_context.getProperty(PROP_SSDP_PORT, DEFAULT_SSDP_PORT));
|
||||
if (_scannerCallback != null) {
|
||||
_scannerCallback.beforeScan();
|
||||
}
|
||||
_isRunning = _upnp.runPlugin();
|
||||
if (_scannerCallback != null) {
|
||||
if (_isRunning)
|
||||
_delayedCallback.reschedule();
|
||||
else
|
||||
_scannerCallback.afterScan();
|
||||
}
|
||||
if (_log.shouldDebug())
|
||||
_log.info("UPnP runPlugin took " + (_context.clock().now() - b));
|
||||
} catch (RuntimeException e) {
|
||||
@ -100,6 +113,9 @@ class UPnPManager {
|
||||
_log.error("UPnP error, please report", e);
|
||||
_errorLogged = true;
|
||||
}
|
||||
if (_scannerCallback != null) {
|
||||
_scannerCallback.afterScan();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_isRunning) {
|
||||
@ -156,6 +172,8 @@ class UPnPManager {
|
||||
return false;
|
||||
_lastRescan = now;
|
||||
if (_isRunning) {
|
||||
if (_scannerCallback != null)
|
||||
_scannerCallback.beforeScan();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("UPnP Rescan");
|
||||
// TODO default search MX (jitter) is 3 seconds... reduce?
|
||||
@ -163,6 +181,8 @@ class UPnPManager {
|
||||
// Adaptive Jitter Control for UPnP M-Search
|
||||
// Kevin Mills and Christopher Dabrowski
|
||||
_upnp.search();
|
||||
if (_scannerCallback != null)
|
||||
_delayedCallback.reschedule();
|
||||
} else {
|
||||
start();
|
||||
}
|
||||
@ -188,6 +208,33 @@ class UPnPManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delayed Callback
|
||||
*
|
||||
* @since 0.9.41
|
||||
*/
|
||||
private class DelayedCallback extends SimpleTimer2.TimedEvent {
|
||||
|
||||
/** caller must reschedule() */
|
||||
public DelayedCallback() {
|
||||
super(_context.simpleTimer2());
|
||||
}
|
||||
|
||||
public void timeReached() {
|
||||
_scannerCallback.afterScan();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes out.
|
||||
* We do it this way because we may have two scans running concurrently,
|
||||
* we only want to call afterScan() once.
|
||||
*/
|
||||
void reschedule() {
|
||||
// false == use latest time
|
||||
reschedule((_upnp.getSearchMx() * 1000) + 500, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when the ports might have changed
|
||||
|
@ -0,0 +1,22 @@
|
||||
package net.i2p.router.transport;
|
||||
|
||||
/**
|
||||
* For Android MulticastLock.
|
||||
*
|
||||
* @since 0.9.41
|
||||
*/
|
||||
public interface UPnPScannerCallback {
|
||||
|
||||
/**
|
||||
* Called before a SSDP search begins.
|
||||
* This may be called more than once before afterScan()
|
||||
* if there are multiple searches in parallel.
|
||||
*/
|
||||
public void beforeScan();
|
||||
|
||||
/**
|
||||
* Called after a SSDP search ends.
|
||||
* This will only be called once after the last scan ends.
|
||||
*/
|
||||
public void afterScan();
|
||||
}
|
Reference in New Issue
Block a user