diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 3b69e9b090..c8cc315772 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -194,249 +194,26 @@ public class CommSystemFacadeImpl extends CommSystemFacade { //if (_context.router().isHidden()) // return Collections.EMPTY_SET; List addresses = new ArrayList(_manager.getAddresses()); - - Transport ntcp = _manager.getTransport(NTCPTransport.STYLE); - boolean hasNTCP = ntcp != null && ntcp.hasCurrentAddress(); - - boolean newCreated = false; - if (!hasNTCP) { - RouterAddress addr = createNTCPAddress(_context); - if (_log.shouldLog(Log.INFO)) - _log.info("NTCP address: " + addr); - if (addr != null) { - addresses.add(addr); - newCreated = true; - } - } - if (_log.shouldLog(Log.INFO)) - _log.info("Creating addresses: " + addresses + " isNew? " + newCreated, new Exception("creator")); + _log.info("Creating addresses: " + addresses, new Exception("creator")); return addresses; } - public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname"; - public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port"; - public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport"; - public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip"; - - /** - * This only creates an address if the hostname AND port are set in router.config, - * which should be rare. - * Otherwise, notifyReplaceAddress() below takes care of it. - * Note this is called both from above and from NTCPTransport.startListening() - * - * This should really be moved to ntcp/NTCPTransport.java, why is it here? - */ - public static RouterAddress createNTCPAddress(RouterContext ctx) { - if (!TransportManager.isNTCPEnabled(ctx)) return null; - String name = ctx.router().getConfigSetting(PROP_I2NP_NTCP_HOSTNAME); - String port = ctx.router().getConfigSetting(PROP_I2NP_NTCP_PORT); - /* - boolean isNew = false; - if (name == null) { - name = "localhost"; - isNew = true; - } - if (port == null) { - port = String.valueOf(ctx.random().nextInt(10240)+1024); - isNew = true; - } - */ - if ( (name == null) || (port == null) || (name.trim().length() <= 0) || ("null".equals(name)) ) - return null; - try { - int p = Integer.parseInt(port); - if ( (p <= 0) || (p > 64*1024) ) - return null; - } catch (NumberFormatException nfe) { - return null; - } - Properties props = new Properties(); - props.setProperty(NTCPAddress.PROP_HOST, name); - props.setProperty(NTCPAddress.PROP_PORT, port); - RouterAddress addr = new RouterAddress(); - addr.setCost(NTCPAddress.DEFAULT_COST); - //addr.setExpiration(null); - addr.setOptions(props); - addr.setTransportStyle(NTCPTransport.STYLE); - //if (isNew) { - // why save the same thing? - Map changes = new HashMap(); - changes.put(PROP_I2NP_NTCP_HOSTNAME, name); - changes.put(PROP_I2NP_NTCP_PORT, port); - ctx.router().saveConfig(changes, null); - //} - return addr; - } - /** * UDP changed addresses, tell NTCP and restart - * This should really be moved to ntcp/NTCPTransport.java, why is it here? + * + * All the work moved to NTCPTransport.externalAddressReceived() */ @Override - public synchronized void notifyReplaceAddress(RouterAddress udpAddr) { - if (udpAddr == null) - return; - NTCPTransport t = (NTCPTransport) _manager.getTransport(NTCPTransport.STYLE); - if (t == null) - return; - - //////// FIXME just take first IPv4 address for now - List oldAddrs = t.getCurrentAddresses(); - RouterAddress oldAddr = null; - for (RouterAddress ra : oldAddrs) { - byte[] ipx = ra.getIP(); - if (ipx != null && ipx.length == 4) { - oldAddr = ra; - break; - } - } - if (_log.shouldLog(Log.INFO)) - _log.info("Changing NTCP Address? was " + oldAddr); - - RouterAddress newAddr = new RouterAddress(); - newAddr.setTransportStyle(NTCPTransport.STYLE); - Properties newProps = new Properties(); - if (oldAddr == null) { - newAddr.setCost(NTCPAddress.DEFAULT_COST); - } else { - newAddr.setCost(oldAddr.getCost()); - newProps.putAll(oldAddr.getOptionsMap()); - } - - boolean changed = false; - - // Auto Port Setting - // old behavior (<= 0.7.3): auto-port defaults to false, and true trumps explicit setting - // new behavior (>= 0.7.4): auto-port defaults to true, but explicit setting trumps auto - // TODO rewrite this to operate on ints instead of strings - String oport = newProps.getProperty(NTCPAddress.PROP_PORT); - String nport = null; - String cport = _context.getProperty(PROP_I2NP_NTCP_PORT); - if (cport != null && cport.length() > 0) { - nport = cport; - } else if (_context.getBooleanPropertyDefaultTrue(PROP_I2NP_NTCP_AUTO_PORT)) { - // 0.9.6 change - // This wasn't quite right, as udpAddr is the EXTERNAL port and we really - // want NTCP to bind to the INTERNAL port the first time, - // because if they are different, the NAT is changing them, and - // it probably isn't mapping UDP and TCP the same. + public void notifyReplaceAddress(RouterAddress udpAddr) { + byte[] ip = udpAddr != null ? udpAddr.getIP() : null; + int port = udpAddr != null ? udpAddr.getPort() : 0; + if (port < 0) { Transport udp = _manager.getTransport(UDPTransport.STYLE); - if (udp != null) { - int udpIntPort = udp.getRequestedPort(); - if (udpIntPort > 0) - // should always be true - nport = Integer.toString(udpIntPort); - } - if (nport == null) - // fallback - nport = udpAddr.getOption(UDPAddress.PROP_PORT); + if (udp != null) + port = udp.getRequestedPort(); } - if (_log.shouldLog(Log.INFO)) - _log.info("old: " + oport + " config: " + cport + " new: " + nport); - if (nport == null || nport.length() <= 0) - return; - // 0.9.6 change - // Don't have NTCP "chase" SSU's external port, - // as it may change, possibly frequently. - //if (oport == null || ! oport.equals(nport)) { - if (oport == null) { - newProps.setProperty(NTCPAddress.PROP_PORT, nport); - changed = true; - } - - // Auto IP Setting - // old behavior (<= 0.7.3): auto-ip defaults to false, and trumps configured hostname, - // and ignores reachability status - leading to - // "firewalled with inbound TCP enabled" warnings. - // new behavior (>= 0.7.4): auto-ip defaults to true, and explicit setting trumps auto, - // and only takes effect if reachability is OK. - // And new "always" setting ignores reachability status, like - // "true" was in 0.7.3 - String ohost = newProps.getProperty(NTCPAddress.PROP_HOST); - String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "true").toLowerCase(Locale.US); - String name = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME); - // hostname config trumps auto config - if (name != null && name.length() > 0) - enabled = "false"; - Transport udp = _manager.getTransport(UDPTransport.STYLE); - short status = STATUS_UNKNOWN; - if (udp != null) - status = udp.getReachabilityStatus(); - if (_log.shouldLog(Log.INFO)) - _log.info("old: " + ohost + " config: " + name + " auto: " + enabled + " status: " + status); - if (enabled.equals("always") || - (Boolean.parseBoolean(enabled) && status == STATUS_OK)) { - String nhost = udpAddr.getOption(UDPAddress.PROP_HOST); - if (_log.shouldLog(Log.INFO)) - _log.info("old: " + ohost + " config: " + name + " new: " + nhost); - if (nhost == null || nhost.length() <= 0) - return; - if (ohost == null || ! ohost.equalsIgnoreCase(nhost)) { - newProps.setProperty(NTCPAddress.PROP_HOST, nhost); - changed = true; - } - } else if (enabled.equals("false") && - name != null && name.length() > 0 && - !name.equals(ohost) && - nport != null) { - // Host name is configured, and we have a port (either auto or configured) - // but we probably only get here if the port is auto, - // otherwise createNTCPAddress() would have done it already - if (_log.shouldLog(Log.INFO)) - _log.info("old: " + ohost + " config: " + name + " new: " + name); - newProps.setProperty(NTCPAddress.PROP_HOST, name); - changed = true; - } else if (ohost == null || ohost.length() <= 0) { - return; - } else if (Boolean.parseBoolean(enabled) && status != STATUS_OK) { - // UDP transitioned to not-OK, turn off NTCP address - // This will commonly happen at startup if we were initially OK - // because UPnP was successful, but a subsequent SSU Peer Test determines - // we are still firewalled (SW firewall, bad UPnP indication, etc.) - if (_log.shouldLog(Log.INFO)) - _log.info("old: " + ohost + " config: " + name + " new: null"); - newAddr = null; - changed = true; - } - - if (!changed) { - if (oldAddr != null) { - int oldCost = oldAddr.getCost(); - int newCost = NTCPAddress.DEFAULT_COST; - if (TransportImpl.ADJUST_COST && !t.haveCapacity()) - newCost++; - if (newCost != oldCost) { - oldAddr.setCost(newCost); - if (_log.shouldLog(Log.WARN)) - _log.warn("Changing NTCP cost from " + oldCost + " to " + newCost); - } else { - _log.info("No change to NTCP Address"); - } - } else { - _log.info("No change to NTCP Address"); - } - return; - } - - // stopListening stops the pumper, readers, and writers, so required even if - // oldAddr == null since startListening starts them all again - // - // really need to fix this so that we can change or create an inbound address - // without tearing down everything - // Especially on disabling the address, we shouldn't tear everything down. - // - _log.warn("Halting NTCP to change address"); - t.stopListening(); - if (newAddr != null) - newAddr.setOptions(newProps); - // Wait for NTCP Pumper to stop so we don't end up with two... - while (t.isAlive()) { - try { Thread.sleep(5*1000); } catch (InterruptedException ie) {} - } - t.restartListening(newAddr); - _log.warn("Changed NTCP Address and started up, address is now " + newAddr); - return; + _manager.externalAddressReceived(Transport.AddressSource.SOURCE_SSU, ip, port); } /* diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index 72638f77a7..ffcf0b4ebb 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -63,8 +63,7 @@ public interface Transport { SOURCE_INTERFACE("local"), /** unused */ SOURCE_CONFIG("config"), - /** unused */ - SOURCE_SSU_PEER("ssu"); + SOURCE_SSU("ssu"); private final String cfgstr; diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 430b57d41f..153e4b358d 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -552,7 +552,7 @@ public abstract class TransportImpl implements Transport { * This implementation does nothing. Transports should override if they want notification. * * @param source defined in Transport.java - * @param ip typ. IPv4 or IPv6 non-local + * @param ip typ. IPv4 or IPv6 non-local; may be null to indicate IPv4 failure or port info only * @param port 0 for unknown or unchanged */ public void externalAddressReceived(AddressSource source, byte[] ip, int port) {} diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index e0fdcc0cfe..6575447003 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -30,7 +30,7 @@ import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.CommSystemFacade; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; -import static net.i2p.router.transport.Transport.AddressSource.SOURCE_INTERFACE; +import static net.i2p.router.transport.Transport.AddressSource.*; import net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.ntcp.NTCPTransport; import net.i2p.router.transport.udp.UDPTransport; @@ -120,14 +120,16 @@ public class TransportManager implements TransportEventListener { } /** - * callback from UPnP + * callback from UPnP or SSU * Only tell SSU, it will tell NTCP * */ public void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port) { - Transport t = getTransport(UDPTransport.STYLE); - if (t != null) - t.externalAddressReceived(source, ip, port); + for (Transport t : _transports.values()) { + // don't loop + if (!(source == SOURCE_SSU && t.getStyle().equals(UDPTransport.STYLE))) + t.externalAddressReceived(source, ip, port); + } } /** @@ -385,7 +387,7 @@ public class TransportManager implements TransportEventListener { int port = t.getRequestedPort(); // Use UDP port for NTCP too - see comment in NTCPTransport.getRequestedPort() for why this is here if (t.getStyle().equals(NTCPTransport.STYLE) && port <= 0 && - _context.getBooleanProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)) { + _context.getBooleanProperty(NTCPTransport.PROP_I2NP_NTCP_AUTO_PORT)) { Transport udp = getTransport(UDPTransport.STYLE); if (udp != null) port = t.getRequestedPort(); diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 22a0d43ff5..c722c34bd3 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -30,12 +30,15 @@ import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.router.transport.CommSystemFacadeImpl; import net.i2p.router.transport.Transport; +import static net.i2p.router.transport.Transport.AddressSource.*; import net.i2p.router.transport.TransportBid; import net.i2p.router.transport.TransportImpl; import net.i2p.router.transport.crypto.DHSessionKeyBuilder; +import net.i2p.router.transport.udp.UDPTransport; import net.i2p.util.Addresses; import net.i2p.util.ConcurrentHashSet; import net.i2p.util.Log; +import net.i2p.util.OrderedProperties; import net.i2p.util.Translate; /** @@ -62,6 +65,11 @@ public class NTCPTransport extends TransportImpl { */ private final Set _establishing; + public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname"; + public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port"; + public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport"; + public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip"; + /** this is rarely if ever used, default is to bind to wildcard address */ public static final String PROP_BIND_INTERFACE = "i2np.ntcp.bindInterface"; @@ -471,11 +479,11 @@ public class NTCPTransport extends TransportImpl { } /** - * Only called by CSFI. + * Only called by externalAddressReceived(). * Caller should stop the transport first, then * verify stopped with isAlive() */ - public synchronized void restartListening(RouterAddress addr) { + private synchronized void restartListening(RouterAddress addr) { // try once again to prevent two pumpers which is fatal // we could just return null since the return value is ignored if (_pumper.isAlive()) @@ -528,9 +536,9 @@ public class NTCPTransport extends TransportImpl { // If we are configured with a fixed IP address, // AND it's one of our local interfaces, // bind only to that. - boolean isFixed = _context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_IP, "true") + boolean isFixed = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "true") .toLowerCase(Locale.US).equals("false"); - String fixedHost = _context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_HOSTNAME); + String fixedHost = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME); if (isFixed && fixedHost != null) { try { String testAddr = InetAddress.getByName(fixedHost).getHostAddress(); @@ -638,12 +646,8 @@ public class NTCPTransport extends TransportImpl { /** caller must synch on this */ private void configureLocalAddress() { - RouterContext ctx = getContext(); - if (ctx == null) { - System.err.println("NIO transport has no context?"); - } else { // this generally returns null -- see javadoc - RouterAddress ra = CommSystemFacadeImpl.createNTCPAddress(ctx); + RouterAddress ra = createNTCPAddress(); if (ra != null) { NTCPAddress addr = new NTCPAddress(ra); if (addr.getPort() <= 0) { @@ -660,9 +664,200 @@ public class NTCPTransport extends TransportImpl { if (_log.shouldLog(Log.INFO)) _log.info("NTCP address is outbound only"); } - } } + /** + * This only creates an address if the hostname AND port are set in router.config, + * which should be rare. + * Otherwise, notifyReplaceAddress() below takes care of it. + * Note this is called both from above and from NTCPTransport.startListening() + * + * @since IPv6 moved from CSFI + */ + private RouterAddress createNTCPAddress() { + String name = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME); + if ( (name == null) || (name.trim().length() <= 0) || ("null".equals(name)) ) + return null; + int p = _context.getProperty(PROP_I2NP_NTCP_PORT, -1); + if (p <= 0 || p >= 64*1024) + return null; + OrderedProperties props = new OrderedProperties(); + props.setProperty(NTCPAddress.PROP_HOST, name); + props.setProperty(NTCPAddress.PROP_PORT, Integer.toString(p)); + RouterAddress addr = new RouterAddress(STYLE, props, NTCPAddress.DEFAULT_COST); + return addr; + } + + /** + * UDP changed addresses, tell NTCP and restart + * + * @since IPv6 moved from CSFI.notifyReplaceAddress() + */ + @Override + public void externalAddressReceived(AddressSource source, byte[] ip, int port) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Received address: " + Addresses.toString(ip, port) + " from: " + source); + // ignore UPnP for now, get everything from SSU + if (source != SOURCE_SSU) + return; + externalAddressReceived(ip, port); + } + + /** + * UDP changed addresses, tell NTCP and restart + * Port may be set to indicate requested port even if ip is null; + * see CSFI.notifyReplaceAddress() + * + * @since IPv6 moved from CSFI.notifyReplaceAddress() + */ + private synchronized void externalAddressReceived(byte[] ip, int port) { + // FIXME just take first IPv4 address for now + // FIXME if SSU set to hostname, NTCP will be set to IP + RouterAddress oldAddr = getCurrentAddress(false); + if (_log.shouldLog(Log.INFO)) + _log.info("Changing NTCP Address? was " + oldAddr); + + OrderedProperties newProps = new OrderedProperties(); + int cost; + if (oldAddr == null) { + cost = NTCPAddress.DEFAULT_COST; + } else { + cost = oldAddr.getCost(); + newProps.putAll(oldAddr.getOptionsMap()); + } + RouterAddress newAddr = new RouterAddress(STYLE, newProps, cost); + + boolean changed = false; + + // Auto Port Setting + // old behavior (<= 0.7.3): auto-port defaults to false, and true trumps explicit setting + // new behavior (>= 0.7.4): auto-port defaults to true, but explicit setting trumps auto + // TODO rewrite this to operate on ints instead of strings + String oport = newProps.getProperty(NTCPAddress.PROP_PORT); + String nport = null; + String cport = _context.getProperty(PROP_I2NP_NTCP_PORT); + if (cport != null && cport.length() > 0) { + nport = cport; + } else if (_context.getBooleanPropertyDefaultTrue(PROP_I2NP_NTCP_AUTO_PORT)) { + // 0.9.6 change + // This wasn't quite right, as udpAddr is the EXTERNAL port and we really + // want NTCP to bind to the INTERNAL port the first time, + // because if they are different, the NAT is changing them, and + // it probably isn't mapping UDP and TCP the same. + if (port > 0) + // should always be true + nport = Integer.toString(port); + } + if (_log.shouldLog(Log.INFO)) + _log.info("old: " + oport + " config: " + cport + " new: " + nport); + if (nport == null || nport.length() <= 0) + return; + // 0.9.6 change + // Don't have NTCP "chase" SSU's external port, + // as it may change, possibly frequently. + //if (oport == null || ! oport.equals(nport)) { + if (oport == null) { + newProps.setProperty(NTCPAddress.PROP_PORT, nport); + changed = true; + } + + // Auto IP Setting + // old behavior (<= 0.7.3): auto-ip defaults to false, and trumps configured hostname, + // and ignores reachability status - leading to + // "firewalled with inbound TCP enabled" warnings. + // new behavior (>= 0.7.4): auto-ip defaults to true, and explicit setting trumps auto, + // and only takes effect if reachability is OK. + // And new "always" setting ignores reachability status, like + // "true" was in 0.7.3 + String ohost = newProps.getProperty(NTCPAddress.PROP_HOST); + String enabled = _context.getProperty(PROP_I2NP_NTCP_AUTO_IP, "true").toLowerCase(Locale.US); + String name = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME); + // hostname config trumps auto config + if (name != null && name.length() > 0) + enabled = "false"; + + // assume SSU is happy if the address is non-null + // TODO is this sufficient? + boolean ssuOK = ip != null; + if (_log.shouldLog(Log.INFO)) + _log.info("old: " + ohost + " config: " + name + " auto: " + enabled + " ssuOK? " + ssuOK); + if (enabled.equals("always") || + (Boolean.parseBoolean(enabled) && ssuOK)) { + // ip non-null + String nhost = Addresses.toString(ip); + if (_log.shouldLog(Log.INFO)) + _log.info("old: " + ohost + " config: " + name + " new: " + nhost); + if (nhost == null || nhost.length() <= 0) + return; + if (ohost == null || ! ohost.equalsIgnoreCase(nhost)) { + newProps.setProperty(NTCPAddress.PROP_HOST, nhost); + changed = true; + } + } else if (enabled.equals("false") && + name != null && name.length() > 0 && + !name.equals(ohost) && + nport != null) { + // Host name is configured, and we have a port (either auto or configured) + // but we probably only get here if the port is auto, + // otherwise createNTCPAddress() would have done it already + if (_log.shouldLog(Log.INFO)) + _log.info("old: " + ohost + " config: " + name + " new: " + name); + newProps.setProperty(NTCPAddress.PROP_HOST, name); + changed = true; + } else if (ohost == null || ohost.length() <= 0) { + return; + } else if (Boolean.parseBoolean(enabled) && !ssuOK) { + // UDP transitioned to not-OK, turn off NTCP address + // This will commonly happen at startup if we were initially OK + // because UPnP was successful, but a subsequent SSU Peer Test determines + // we are still firewalled (SW firewall, bad UPnP indication, etc.) + if (_log.shouldLog(Log.INFO)) + _log.info("old: " + ohost + " config: " + name + " new: null"); + newAddr = null; + changed = true; + } + + if (!changed) { + if (oldAddr != null) { + int oldCost = oldAddr.getCost(); + int newCost = NTCPAddress.DEFAULT_COST; + if (TransportImpl.ADJUST_COST && !haveCapacity()) + newCost++; + if (newCost != oldCost) { + oldAddr.setCost(newCost); + if (_log.shouldLog(Log.WARN)) + _log.warn("Changing NTCP cost from " + oldCost + " to " + newCost); + } else { + _log.info("No change to NTCP Address"); + } + } else { + _log.info("No change to NTCP Address"); + } + return; + } + + // stopListening stops the pumper, readers, and writers, so required even if + // oldAddr == null since startListening starts them all again + // + // really need to fix this so that we can change or create an inbound address + // without tearing down everything + // Especially on disabling the address, we shouldn't tear everything down. + // + _log.warn("Halting NTCP to change address"); + stopListening(); + if (newAddr != null) + newAddr.setOptions(newProps); + // Wait for NTCP Pumper to stop so we don't end up with two... + while (isAlive()) { + try { Thread.sleep(5*1000); } catch (InterruptedException ie) {} + } + restartListening(newAddr); + _log.warn("Changed NTCP Address and started up, address is now " + newAddr); + return; + } + + + /** * If we didn't used to be forwarded, and we have an address, * and we are configured to use UPnP, update our RouterAddress @@ -698,7 +893,7 @@ public class NTCPTransport extends TransportImpl { // from here, so we do it in TransportManager. // if (Boolean.valueOf(_context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)).booleanValue()) // return foo; - return _context.getProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_PORT, -1); + return _context.getProperty(PROP_I2NP_NTCP_PORT, -1); } /** 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 1751bf453e..983b4f5907 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -155,7 +155,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority public static final String PROP_SOURCES = "i2np.udp.addressSources"; public static final String DEFAULT_SOURCES = SOURCE_INTERFACE.toConfigString() + ',' + SOURCE_UPNP.toConfigString() + ',' + - SOURCE_SSU_PEER.toConfigString(); + SOURCE_SSU.toConfigString(); /** remember IP changes */ public static final String PROP_IP= "i2np.lastIP"; public static final String PROP_IP_CHANGE = "i2np.lastIPChange"; @@ -563,13 +563,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * Not for info received from peers - see externalAddressReceived(Hash, ip, port) * * @param source as defined in Transport.SOURCE_xxx - * @param ip publicly routable IPv4 or IPv6 + * @param ip publicly routable IPv4 or IPv6, null ok * @param port 0 if unknown */ @Override public void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port) { if (_log.shouldLog(Log.WARN)) _log.warn("Received address: " + Addresses.toString(ip, port) + " from: " + source); + if (ip == null) + return; if (source == SOURCE_INTERFACE && ip.length == 16) { // must be set before isValid() call _haveIPv6Address = true;