diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index 81a498bced..eafaad165e 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -529,22 +529,27 @@ public abstract class TransportImpl implements Transport { * Notify a transport of an external address change. * This may be from a local interface, UPnP, a config change, etc. * This should not be called if the ip didn't change - * (from that source's point of view), or is a local address, - * or if the ip is IPv6, but the transport should check anyway. + * (from that source's point of view), or is a local address. + * May be called multiple times for IPv4 or IPv6. * The transport should also do its own checking on whether to accept * notifications from this source. * * This can be called before startListening() to set an initial address, * or after the transport is running. * + * This implementation does nothing. Transports should override if they want notification. + * * @param source defined in Transport.java - * @param ip typ. IPv4 non-local + * @param ip typ. IPv4 or IPv6 non-local * @param port 0 for unknown or unchanged */ public void externalAddressReceived(String source, byte[] ip, int port) {} /** * Notify a transport of the results of trying to forward a port. + * + * This implementation does nothing. Transports should override if they want notification. + * * @param port the internal port * @param externalPort the external port, which for now should always be the same as * the internal port if the forwarding was successful. diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 3c1942ce55..958c0f5508 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -101,19 +101,21 @@ public class TransportManager implements TransportEventListener { return ctx.getBooleanPropertyDefaultTrue(PROP_ENABLE_NTCP); } + /** + * Notify transport of ALL routable local addresses, including IPv6. + * It's the transport's job to ignore what it can't handle. + */ private void initializeAddress(Transport t) { - String ips = Addresses.getAnyAddress(); - if (ips == null) - return; - InetAddress ia; - try { - ia = InetAddress.getByName(ips); - } catch (UnknownHostException e) { - _log.error("UDP failed to bind to local address", e); - return; + Set ipset = Addresses.getAddresses(false, true); // non-local, include IPv6 + for (String ips : ipset) { + try { + InetAddress ia = InetAddress.getByName(ips); + byte[] ip = ia.getAddress(); + t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0); + } catch (UnknownHostException e) { + _log.error("UDP failed to bind to local address", e); + } } - byte[] ip = ia.getAddress(); - t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0); } /** 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 47c822025c..84d3dec852 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -511,11 +511,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _lastInboundReceivedOn = System.currentTimeMillis(); } + // temp prevent multiples + private boolean gotIPv4Addr = false; + private boolean gotIPv6Addr = false; + /** * From config, UPnP, local i/f, ... * * @param source used for logging only - * @param ip publicly routable IPv4 only + * @param ip publicly routable IPv4 or IPv6 * @param port 0 if unknown */ @Override @@ -527,10 +531,22 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES); if (!sources.contains(source)) return; + if (!isValid(ip)) + return; + if (source.equals(Transport.SOURCE_INTERFACE)) { + // temp prevent multiples + if (ip.length == 4 && !gotIPv4Addr) { + gotIPv4Addr = true; + return; + } else if (ip.length == 16 && !gotIPv6Addr) { + gotIPv6Addr = true; + return; + } + } boolean changed = changeAddress(ip, port); // Assume if we have an interface with a public IP that we aren't firewalled. // If this is wrong, the peer test will figure it out and change the status. - if (changed && source.equals(Transport.SOURCE_INTERFACE)) + if (changed && ip.length == 4 && source.equals(Transport.SOURCE_INTERFACE)) setReachabilityStatus(CommSystemFacade.STATUS_OK); } @@ -620,6 +636,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } /** + * @param ourIP MUST have been previously validated with isValid() * @param ourPort >= 1024 or 0 for no change */ private boolean changeAddress(byte ourIP[], int ourPort) {