forked from I2P_Developers/i2p.i2p
* RouterAddress:
- Deprecate some setters - Add warning about setCost() - Change cost storage from int to short - Cost range checks * NTCP: - Republish even if only changing cost * Transports: - Sort multiple peer addresses by cost, with adjustment for local IPv6 preference - Add default IPv6Config for ease of changing later
This commit is contained in:
@ -14,6 +14,7 @@ import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@ -471,7 +472,8 @@ public abstract class TransportImpl implements Transport {
|
||||
}
|
||||
|
||||
/** Do we increase the advertised cost when approaching conn limits? */
|
||||
public static final boolean ADJUST_COST = true;
|
||||
protected static final boolean ADJUST_COST = true;
|
||||
protected static final int CONGESTION_COST_ADJUSTMENT = 2;
|
||||
|
||||
/**
|
||||
* What addresses are we currently listening to?
|
||||
@ -563,6 +565,67 @@ public abstract class TransportImpl implements Transport {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available address we can use,
|
||||
* shuffled and then sorted by cost/preference.
|
||||
* Lowest cost (most preferred) first.
|
||||
* @return non-null, possibly empty
|
||||
* @since IPv6
|
||||
*/
|
||||
protected List<RouterAddress> getTargetAddresses(RouterInfo target) {
|
||||
List<RouterAddress> rv = target.getTargetAddresses(getStyle());
|
||||
// Shuffle so everybody doesn't use the first one
|
||||
if (rv.size() > 1) {
|
||||
Collections.shuffle(rv, _context.random());
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
int adj;
|
||||
switch (config) {
|
||||
case IPV6_DISABLED:
|
||||
adj = 10; break;
|
||||
case IPV6_NOT_PREFERRED:
|
||||
adj = 1; break;
|
||||
default:
|
||||
case IPV6_ENABLED:
|
||||
adj = 0; break;
|
||||
case IPV6_PREFERRED:
|
||||
adj = -1; break;
|
||||
case IPV6_ONLY:
|
||||
adj = -10; break;
|
||||
}
|
||||
Collections.sort(rv, new AddrComparator(adj));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare based on published cost, adjusting for our IPv6 preference.
|
||||
* Lowest cost (most preferred) first.
|
||||
* @since IPv6
|
||||
*/
|
||||
private static class AddrComparator implements Comparator<RouterAddress> {
|
||||
private final int adj;
|
||||
|
||||
public AddrComparator(int ipv6Adjustment) {
|
||||
adj = ipv6Adjustment;
|
||||
}
|
||||
|
||||
public int compare(RouterAddress l, RouterAddress r) {
|
||||
int lc = l.getCost();
|
||||
int rc = r.getCost();
|
||||
byte[] lip = l.getIP();
|
||||
byte[] rip = r.getIP();
|
||||
if (lip != null && lip.length == 16)
|
||||
lc += adj;
|
||||
if (rip != null && rip.length == 16)
|
||||
rc += adj;
|
||||
if (lc > rc)
|
||||
return 1;
|
||||
if (lc < rc)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify a transport of an external address change.
|
||||
* This may be from a local interface, UPnP, a config change, etc.
|
||||
|
@ -52,6 +52,7 @@ public abstract class TransportUtil {
|
||||
}
|
||||
|
||||
private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>();
|
||||
private static final IPv6Config DEFAULT_IPV6_CONFIG = IPv6Config.IPV6_DISABLED;
|
||||
|
||||
static {
|
||||
for (IPv6Config cfg : IPv6Config.values()) {
|
||||
@ -68,17 +69,17 @@ public abstract class TransportUtil {
|
||||
else if (transportStyle.equals("SSU"))
|
||||
cfg = ctx.getProperty(SSU_IPV6_CONFIG);
|
||||
else
|
||||
return IPv6Config.IPV6_DISABLED;
|
||||
return DEFAULT_IPV6_CONFIG;
|
||||
return getIPv6Config(cfg);
|
||||
}
|
||||
|
||||
public static IPv6Config getIPv6Config(String cfg) {
|
||||
if (cfg == null)
|
||||
return IPv6Config.IPV6_DISABLED;
|
||||
return DEFAULT_IPV6_CONFIG;
|
||||
IPv6Config c = BY_NAME.get(cfg);
|
||||
if (c != null)
|
||||
return c;
|
||||
return IPv6Config.IPV6_DISABLED;
|
||||
return DEFAULT_IPV6_CONFIG;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ package net.i2p.router.transport.ntcp;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
@ -35,6 +36,8 @@ 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.TransportUtil;
|
||||
import static net.i2p.router.transport.TransportUtil.IPv6Config.*;
|
||||
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.util.Addresses;
|
||||
@ -350,7 +353,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
* @since 0.9.6
|
||||
*/
|
||||
private RouterAddress getTargetAddress(RouterInfo target) {
|
||||
List<RouterAddress> addrs = target.getTargetAddresses(STYLE);
|
||||
List<RouterAddress> addrs = getTargetAddresses(target);
|
||||
for (int i = 0; i < addrs.size(); i++) {
|
||||
RouterAddress addr = addrs.get(i);
|
||||
byte[] ip = addr.getIP();
|
||||
@ -501,7 +504,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
OrderedProperties props = new OrderedProperties();
|
||||
props.setProperty(RouterAddress.PROP_HOST, ia.getHostAddress());
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
|
||||
myAddress = new RouterAddress(STYLE, props, DEFAULT_COST);
|
||||
int cost = getDefaultCost(ia instanceof Inet6Address);
|
||||
myAddress = new RouterAddress(STYLE, props, cost);
|
||||
replaceAddress(myAddress);
|
||||
}
|
||||
}
|
||||
@ -604,7 +608,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
OrderedProperties props = new OrderedProperties();
|
||||
props.setProperty(RouterAddress.PROP_HOST, bindTo);
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
|
||||
myAddress = new RouterAddress(STYLE, props, DEFAULT_COST);
|
||||
int cost = getDefaultCost(false);
|
||||
myAddress = new RouterAddress(STYLE, props, cost);
|
||||
}
|
||||
if (!_endpoints.isEmpty()) {
|
||||
// If we are already bound to the new address, OR
|
||||
@ -778,10 +783,23 @@ public class NTCPTransport extends TransportImpl {
|
||||
OrderedProperties props = new OrderedProperties();
|
||||
props.setProperty(RouterAddress.PROP_HOST, name);
|
||||
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(p));
|
||||
RouterAddress addr = new RouterAddress(STYLE, props, DEFAULT_COST);
|
||||
int cost = getDefaultCost(false);
|
||||
RouterAddress addr = new RouterAddress(STYLE, props, cost);
|
||||
return addr;
|
||||
}
|
||||
|
||||
private int getDefaultCost(boolean isIPv6) {
|
||||
int rv = DEFAULT_COST;
|
||||
if (isIPv6) {
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
if (config == IPV6_PREFERRED)
|
||||
rv--;
|
||||
else if (config == IPV6_NOT_PREFERRED)
|
||||
rv++;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP changed addresses, tell NTCP and (possibly) restart
|
||||
*
|
||||
@ -831,7 +849,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
OrderedProperties newProps = new OrderedProperties();
|
||||
int cost;
|
||||
if (oldAddr == null) {
|
||||
cost = DEFAULT_COST;
|
||||
cost = getDefaultCost(ip != null && ip.length == 16);
|
||||
} else {
|
||||
cost = oldAddr.getCost();
|
||||
newProps.putAll(oldAddr.getOptionsMap());
|
||||
@ -930,21 +948,24 @@ public class NTCPTransport extends TransportImpl {
|
||||
|
||||
if (!changed) {
|
||||
if (oldAddr != null) {
|
||||
// change cost only?
|
||||
int oldCost = oldAddr.getCost();
|
||||
int newCost = DEFAULT_COST;
|
||||
if (TransportImpl.ADJUST_COST && !haveCapacity())
|
||||
newCost++;
|
||||
int newCost = getDefaultCost(ohost != null && ohost.contains(":"));
|
||||
if (ADJUST_COST && !haveCapacity())
|
||||
newCost += CONGESTION_COST_ADJUSTMENT;
|
||||
if (newCost != oldCost) {
|
||||
oldAddr.setCost(newCost);
|
||||
newAddr.setCost(newCost);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Changing NTCP cost from " + oldCost + " to " + newCost);
|
||||
// fall thru and republish
|
||||
} else {
|
||||
_log.info("No change to NTCP Address");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
_log.info("No change to NTCP Address");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// stopListening stops the pumper, readers, and writers, so required even if
|
||||
|
@ -38,6 +38,8 @@ 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.TransportUtil;
|
||||
import static net.i2p.router.transport.TransportUtil.IPv6Config.*;
|
||||
import static net.i2p.router.transport.udp.PeerTestState.Role.*;
|
||||
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||
import net.i2p.router.util.RandomIterator;
|
||||
@ -1544,10 +1546,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
* @since 0.9.6
|
||||
*/
|
||||
RouterAddress getTargetAddress(RouterInfo target) {
|
||||
List<RouterAddress> addrs = target.getTargetAddresses(STYLE);
|
||||
// Shuffle so everybody doesn't use the first one
|
||||
if (addrs.size() > 1)
|
||||
Collections.shuffle(addrs, _context.random());
|
||||
List<RouterAddress> addrs = getTargetAddresses(target);
|
||||
for (int i = 0; i < addrs.size(); i++) {
|
||||
RouterAddress addr = addrs.get(i);
|
||||
if (addr.getOption("ihost0") == null) {
|
||||
@ -1821,7 +1820,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
// the whole mechanism is not helpful.
|
||||
int cost = DEFAULT_COST;
|
||||
if (ADJUST_COST && !haveCapacity(91))
|
||||
cost++;
|
||||
cost += CONGESTION_COST_ADJUSTMENT;
|
||||
if (introducersIncluded)
|
||||
cost += 2;
|
||||
if (isIPv6) {
|
||||
TransportUtil.IPv6Config config = getIPv6Config();
|
||||
if (config == IPV6_PREFERRED)
|
||||
cost--;
|
||||
else if (config == IPV6_NOT_PREFERRED)
|
||||
cost++;
|
||||
}
|
||||
RouterAddress addr = new RouterAddress(STYLE, options, cost);
|
||||
|
||||
RouterAddress current = getCurrentAddress(isIPv6);
|
||||
@ -2996,7 +3004,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (peerInfo == null)
|
||||
continue;
|
||||
ip = null;
|
||||
List<RouterAddress> addrs = peerInfo.getTargetAddresses(STYLE);
|
||||
List<RouterAddress> addrs = getTargetAddresses(peerInfo);
|
||||
for (RouterAddress addr : addrs) {
|
||||
ip = addr.getIP();
|
||||
if (ip != null && ip.length == 4)
|
||||
|
Reference in New Issue
Block a user