diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index 61f024146..72638f77a 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -55,10 +55,29 @@ public interface Transport { */ public List updateAddress(); - public static final String SOURCE_UPNP = "upnp"; - public static final String SOURCE_INTERFACE = "local"; - public static final String SOURCE_CONFIG = "config"; // unused - public void externalAddressReceived(String source, byte[] ip, int port); + /** + * @since IPv6 + */ + public enum AddressSource { + SOURCE_UPNP("upnp"), + SOURCE_INTERFACE("local"), + /** unused */ + SOURCE_CONFIG("config"), + /** unused */ + SOURCE_SSU_PEER("ssu"); + + private final String cfgstr; + + AddressSource(String cfgstr) { + this.cfgstr = cfgstr; + } + + public String toConfigString() { + return cfgstr; + } + } + + public void externalAddressReceived(AddressSource source, byte[] ip, int port); public void forwardPortStatus(int port, int externalPort, boolean success, String reason); public int getRequestedPort(); public void setListener(TransportEventListener listener); diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java index f56a04da5..44cf01ef0 100644 --- a/router/java/src/net/i2p/router/transport/TransportImpl.java +++ b/router/java/src/net/i2p/router/transport/TransportImpl.java @@ -546,7 +546,7 @@ public abstract class TransportImpl implements Transport { * @param ip typ. IPv4 or IPv6 non-local * @param port 0 for unknown or unchanged */ - public void externalAddressReceived(String source, byte[] ip, int port) {} + public void externalAddressReceived(AddressSource source, byte[] ip, int port) {} /** * Notify a transport of the results of trying to forward a port. diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 67ac3d340..6d9ea36de 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -30,6 +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 net.i2p.router.transport.crypto.DHSessionKeyBuilder; import net.i2p.router.transport.ntcp.NTCPTransport; import net.i2p.router.transport.udp.UDPTransport; @@ -111,7 +112,7 @@ public class TransportManager implements TransportEventListener { try { InetAddress ia = InetAddress.getByName(ips); byte[] ip = ia.getAddress(); - t.externalAddressReceived(Transport.SOURCE_INTERFACE, ip, 0); + t.externalAddressReceived(SOURCE_INTERFACE, ip, 0); } catch (UnknownHostException e) { _log.error("UDP failed to bind to local address", e); } @@ -123,7 +124,7 @@ public class TransportManager implements TransportEventListener { * Only tell SSU, it will tell NTCP * */ - public void externalAddressReceived(String source, byte[] ip, int port) { + public void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port) { Transport t = getTransport(UDPTransport.STYLE); if (t != null) t.externalAddressReceived(source, ip, port); diff --git a/router/java/src/net/i2p/router/transport/UPnPManager.java b/router/java/src/net/i2p/router/transport/UPnPManager.java index 10355f64b..ba4d3df5f 100644 --- a/router/java/src/net/i2p/router/transport/UPnPManager.java +++ b/router/java/src/net/i2p/router/transport/UPnPManager.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Set; import net.i2p.router.RouterContext; +import static net.i2p.router.transport.Transport.AddressSource.SOURCE_UPNP; import net.i2p.util.Addresses; import net.i2p.util.Log; import net.i2p.util.Translate; @@ -161,7 +162,7 @@ class UPnPManager { _log.debug("External address: " + ip.publicAddress + " type: " + ip.natType); if (!ip.publicAddress.equals(_detectedAddress)) { _detectedAddress = ip.publicAddress; - _manager.externalAddressReceived(Transport.SOURCE_UPNP, _detectedAddress.getAddress(), 0); + _manager.externalAddressReceived(SOURCE_UPNP, _detectedAddress.getAddress(), 0); } break; } 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 577ff9eed..4d64e1adf 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -36,6 +36,7 @@ import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; 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 static net.i2p.router.transport.udp.PeerTestState.Role.*; @@ -155,7 +156,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"; + public static final String DEFAULT_SOURCES = SOURCE_INTERFACE.toConfigString() + ',' + + SOURCE_UPNP.toConfigString() + ',' + + SOURCE_SSU_PEER.toConfigString(); /** remember IP changes */ public static final String PROP_IP= "i2np.lastIP"; public static final String PROP_IP_CHANGE = "i2np.lastIPChange"; @@ -547,17 +550,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * @param port 0 if unknown */ @Override - public void externalAddressReceived(String source, byte[] ip, int port) { + 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 (explicitAddressSpecified()) return; String sources = _context.getProperty(PROP_SOURCES, DEFAULT_SOURCES); - if (!sources.contains(source)) + if (!sources.contains(source.toConfigString())) return; if (!isValid(ip)) return; - if (source.equals(Transport.SOURCE_INTERFACE)) { + if (source == SOURCE_INTERFACE) { // temp prevent multiples if (ip.length == 4) { if (gotIPv4Addr) @@ -574,7 +577,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority 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 && ip.length == 4 && source.equals(Transport.SOURCE_INTERFACE)) + if (changed && ip.length == 4 && source == SOURCE_INTERFACE) setReachabilityStatus(CommSystemFacade.STATUS_OK); } @@ -1414,6 +1417,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority */ RouterAddress getTargetAddress(RouterInfo target) { List addrs = target.getTargetAddresses(STYLE); + // Shuffle so everybody doesn't use the first one + if (addrs.size() > 1) + Collections.shuffle(addrs, _context.random()); for (int i = 0; i < addrs.size(); i++) { RouterAddress addr = addrs.get(i); if (addr.getOption("ihost0") == null) {