diff --git a/router/java/src/net/i2p/router/transport/Addresses.java b/router/java/src/net/i2p/router/transport/Addresses.java index 53278af78..c8c2b6518 100644 --- a/router/java/src/net/i2p/router/transport/Addresses.java +++ b/router/java/src/net/i2p/router/transport/Addresses.java @@ -9,6 +9,7 @@ import java.net.Inet4Address; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -54,7 +55,9 @@ public class Addresses { } } catch (SocketException e) {} - return rv.toArray(new String[rv.size()]); + String[] rva = rv.toArray(new String[rv.size()]); + Arrays.sort(rva); + return rva; } private static void add(Set set, InetAddress ia) { diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 8fe45ee41..c20fc2548 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -25,6 +25,7 @@ import org.cybergarage.upnp.ServiceList; import org.cybergarage.upnp.ServiceStateTable; import org.cybergarage.upnp.StateVariable; import org.cybergarage.upnp.device.DeviceChangeListener; +import org.cybergarage.upnp.event.EventListener; import org.freenetproject.DetectedIP; import org.freenetproject.ForwardPort; import org.freenetproject.ForwardPortCallback; @@ -53,7 +54,7 @@ import org.freenetproject.ForwardPortStatus; * TODO: Advertise the node like the MDNS plugin does * TODO: Implement EventListener and react on ip-change */ -public class UPnP extends ControlPoint implements DeviceChangeListener { +public class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { private Log _log; private I2PAppContext _context; @@ -86,8 +87,8 @@ public class UPnP extends ControlPoint implements DeviceChangeListener { addDeviceChangeListener(this); } - public void runPlugin() { - super.start(); + public boolean runPlugin() { + return super.start(); } public void terminate() { @@ -160,7 +161,7 @@ public class UPnP extends ControlPoint implements DeviceChangeListener { return; } - _log.warn("UP&P IGD found : " + dev.getFriendlyName() + " UDN: " + dev.getUDN()); + _log.warn("UP&P IGD found : " + dev.getFriendlyName() + " UDN: " + dev.getUDN() + " lease time: " + dev.getLeaseTime()); synchronized(lock) { _router = dev; } @@ -177,6 +178,7 @@ public class UPnP extends ControlPoint implements DeviceChangeListener { _router = null; return; } + subscribe(_service); } registerPortMappings(); } @@ -261,6 +263,11 @@ public class UPnP extends ControlPoint implements DeviceChangeListener { } } + /** event callback */ + public void eventNotifyReceived(String uuid, long seq, String varName, String value) { + _log.error("Event: " + uuid + ' ' + seq + ' ' + varName + '=' + value); + } + /** compare two strings, either of which could be null */ private static boolean stringEquals(String a, String b) { if (a != null) @@ -459,7 +466,7 @@ public class UPnP extends ControlPoint implements DeviceChangeListener { if(portsForwarded.contains(port)) sb.append(" has been forwarded successfully by UPnP.\n"); else - sb.append(" has not been forwarded UPnP.\n"); + sb.append(" has not been forwarded by UPnP.\n"); } } } diff --git a/router/java/src/net/i2p/router/transport/UPnPManager.java b/router/java/src/net/i2p/router/transport/UPnPManager.java index 64f8acffa..7b9bb563a 100644 --- a/router/java/src/net/i2p/router/transport/UPnPManager.java +++ b/router/java/src/net/i2p/router/transport/UPnPManager.java @@ -51,8 +51,9 @@ public class UPnPManager { Debug.on(); // UPnP stuff -> wrapper log } if (!_isRunning) - _upnp.runPlugin(); - _isRunning = true; + _isRunning = _upnp.runPlugin(); + if (!_isRunning) + _log.error("UPnP start failed - port conflict?"); } public synchronized void stop() { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index df30f5d75..ee9c7d9b7 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -126,6 +126,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority /** allowed sources of address updates */ public static final String PROP_SOURCES = "i2np.udp.addressSources"; public static final String DEFAULT_SOURCES = "local,upnp,ssu"; + /** remember IP changes */ + public static final String PROP_IP= "i2np.lastIP"; + public static final String PROP_IP_CHANGE = "i2np.lastIPChange"; /** do we require introducers, regardless of our status? */ public static final String PROP_FORCE_INTRODUCERS = "i2np.udp.forceIntroducers"; @@ -462,17 +465,18 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (fireTest) { _context.statManager().addRateData("udp.addressTestInsteadOfUpdate", 1, 0); - _testEvent.forceRun(); - SimpleTimer.getInstance().addEvent(_testEvent, 5*1000); } else if (updated) { _context.statManager().addRateData("udp.addressUpdated", 1, 0); if (!fixedPort) _context.router().setConfigSetting(PROP_EXTERNAL_PORT, ourPort+""); + // store these for laptop-mode (change ident on restart... or every time... when IP changes) + _context.router().setConfigSetting(PROP_IP, _externalListenHost.getHostAddress()); + _context.router().setConfigSetting(PROP_IP_CHANGE, "" + _context.clock().now()); _context.router().saveConfig(); _context.router().rebuildRouterInfo(); - _testEvent.forceRun(); - SimpleTimer.getInstance().addEvent(_testEvent, 5*1000); } + _testEvent.forceRun(); + SimpleTimer.getInstance().addEvent(_testEvent, 5*1000); return updated; } @@ -485,7 +489,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (addr.length < 4) return false; if (isPubliclyRoutable(addr)) return true; - return Boolean.valueOf(_context.getProperty("i2np.udp.allowLocal", "false")).booleanValue(); + return Boolean.valueOf(_context.getProperty("i2np.udp.allowLocal")).booleanValue(); } private boolean getIsPortFixed() {