forked from I2P_Developers/i2p.i2p
Store context in the PeerSelector so we don't have to pass it around
This commit is contained in:
@ -15,8 +15,13 @@ import net.i2p.router.TunnelPoolSettings;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ClientPeerSelector extends TunnelPeerSelector {
|
class ClientPeerSelector extends TunnelPeerSelector {
|
||||||
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
|
||||||
int length = getLength(ctx, settings);
|
public ClientPeerSelector(RouterContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Hash> selectPeers(TunnelPoolSettings settings) {
|
||||||
|
int length = getLength(settings);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return null;
|
return null;
|
||||||
if ( (length == 0) && (settings.getLength()+settings.getLengthVariance() > 0) )
|
if ( (length == 0) && (settings.getLength()+settings.getLengthVariance() > 0) )
|
||||||
@ -26,9 +31,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
if (shouldSelectExplicit(settings))
|
if (shouldSelectExplicit(settings))
|
||||||
return selectExplicit(ctx, settings, length);
|
return selectExplicit(settings, length);
|
||||||
|
|
||||||
Set<Hash> exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
Set<Hash> exclude = getExclude(settings.isInbound(), false);
|
||||||
Set<Hash> matches = new HashSet(length);
|
Set<Hash> matches = new HashSet(length);
|
||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0);
|
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0);
|
||||||
@ -41,6 +46,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
rv = new ArrayList(length + 1);
|
rv = new ArrayList(length + 1);
|
||||||
// OBEP or IB last hop
|
// OBEP or IB last hop
|
||||||
// group 0 or 1 if two hops, otherwise group 0
|
// group 0 or 1 if two hops, otherwise group 0
|
||||||
|
if (!settings.isInbound()) {
|
||||||
|
// exclude existing OBEPs to get some diversity
|
||||||
|
}
|
||||||
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 2 : 4);
|
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 2 : 4);
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
exclude.addAll(matches);
|
exclude.addAll(matches);
|
||||||
@ -64,6 +72,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
// IBGW or OB first hop
|
// IBGW or OB first hop
|
||||||
// group 2 or 3 if two hops, otherwise group 1
|
// group 2 or 3 if two hops, otherwise group 1
|
||||||
|
if (settings.isInbound()) {
|
||||||
|
// exclude existing IBGWs to get some diversity
|
||||||
|
}
|
||||||
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 3 : 5);
|
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 3 : 5);
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
rv.addAll(matches);
|
rv.addAll(matches);
|
||||||
|
@ -18,9 +18,14 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
||||||
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
|
||||||
|
public ExploratoryPeerSelector(RouterContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Hash> selectPeers(TunnelPoolSettings settings) {
|
||||||
Log l = ctx.logManager().getLog(getClass());
|
Log l = ctx.logManager().getLog(getClass());
|
||||||
int length = getLength(ctx, settings);
|
int length = getLength(settings);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
if (l.shouldLog(Log.DEBUG))
|
if (l.shouldLog(Log.DEBUG))
|
||||||
l.debug("Length requested is zero: " + settings);
|
l.debug("Length requested is zero: " + settings);
|
||||||
@ -28,13 +33,13 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (false && shouldSelectExplicit(settings)) {
|
if (false && shouldSelectExplicit(settings)) {
|
||||||
List rv = selectExplicit(ctx, settings, length);
|
List rv = selectExplicit(settings, length);
|
||||||
if (l.shouldLog(Log.DEBUG))
|
if (l.shouldLog(Log.DEBUG))
|
||||||
l.debug("Explicit peers selected: " + rv);
|
l.debug("Explicit peers selected: " + rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Hash> exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
Set<Hash> exclude = getExclude(settings.isInbound(), true);
|
||||||
exclude.add(ctx.routerHash());
|
exclude.add(ctx.routerHash());
|
||||||
// Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores
|
// Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores
|
||||||
// Hmm if they don't get explored they don't get a speed/capacity rating
|
// Hmm if they don't get explored they don't get a speed/capacity rating
|
||||||
@ -42,7 +47,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
// FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
|
// FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
|
||||||
// exclude.addAll(fac.getFloodfillPeers());
|
// exclude.addAll(fac.getFloodfillPeers());
|
||||||
HashSet matches = new HashSet(length);
|
HashSet matches = new HashSet(length);
|
||||||
boolean exploreHighCap = shouldPickHighCap(ctx);
|
boolean exploreHighCap = shouldPickHighCap();
|
||||||
|
|
||||||
//
|
//
|
||||||
// We don't honor IP Restriction here, to be fixed
|
// We don't honor IP Restriction here, to be fixed
|
||||||
@ -84,7 +89,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
* build success rate is much worse, return true so that reliability
|
* build success rate is much worse, return true so that reliability
|
||||||
* is maintained.
|
* is maintained.
|
||||||
*/
|
*/
|
||||||
private static boolean shouldPickHighCap(RouterContext ctx) {
|
private boolean shouldPickHighCap() {
|
||||||
if (ctx.getBooleanProperty("router.exploreHighCapacity"))
|
if (ctx.getBooleanProperty("router.exploreHighCapacity"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -118,7 +123,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
if (ctx.router().getUptime() <= 11*60*1000) {
|
if (ctx.router().getUptime() <= 11*60*1000) {
|
||||||
failPct = 100 - MIN_NONFAILING_PCT;
|
failPct = 100 - MIN_NONFAILING_PCT;
|
||||||
} else {
|
} else {
|
||||||
failPct = getExploratoryFailPercentage(ctx);
|
failPct = getExploratoryFailPercentage();
|
||||||
//Log l = ctx.logManager().getLog(getClass());
|
//Log l = ctx.logManager().getLog(getClass());
|
||||||
//if (l.shouldLog(Log.DEBUG))
|
//if (l.shouldLog(Log.DEBUG))
|
||||||
// l.debug("Normalized Fail pct: " + failPct);
|
// l.debug("Normalized Fail pct: " + failPct);
|
||||||
@ -140,9 +145,9 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
* Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
* Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
||||||
* are often building exploratory tunnels using the HighCapacity pool.
|
* are often building exploratory tunnels using the HighCapacity pool.
|
||||||
*/
|
*/
|
||||||
private static int getExploratoryFailPercentage(RouterContext ctx) {
|
private int getExploratoryFailPercentage() {
|
||||||
int c = getFailPercentage(ctx, "Client");
|
int c = getFailPercentage("Client");
|
||||||
int e = getFailPercentage(ctx, "Exploratory");
|
int e = getFailPercentage("Exploratory");
|
||||||
//Log l = ctx.logManager().getLog(getClass());
|
//Log l = ctx.logManager().getLog(getClass());
|
||||||
//if (l.shouldLog(Log.DEBUG))
|
//if (l.shouldLog(Log.DEBUG))
|
||||||
// l.debug("Client, Expl. Fail pct: " + c + ", " + e);
|
// l.debug("Client, Expl. Fail pct: " + c + ", " + e);
|
||||||
@ -154,11 +159,11 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return (100 * (e-c)) / (100-c);
|
return (100 * (e-c)) / (100-c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getFailPercentage(RouterContext ctx, String t) {
|
private int getFailPercentage(String t) {
|
||||||
String pfx = "tunnel.build" + t;
|
String pfx = "tunnel.build" + t;
|
||||||
int timeout = getEvents(ctx, pfx + "Expire", 10*60*1000);
|
int timeout = getEvents(pfx + "Expire", 10*60*1000);
|
||||||
int reject = getEvents(ctx, pfx + "Reject", 10*60*1000);
|
int reject = getEvents(pfx + "Reject", 10*60*1000);
|
||||||
int accept = getEvents(ctx, pfx + "Success", 10*60*1000);
|
int accept = getEvents(pfx + "Success", 10*60*1000);
|
||||||
if (accept + reject + timeout <= 0)
|
if (accept + reject + timeout <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
double pct = (double)(reject + timeout) / (accept + reject + timeout);
|
double pct = (double)(reject + timeout) / (accept + reject + timeout);
|
||||||
@ -166,7 +171,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Use current + last to get more recent and smoother data */
|
/** Use current + last to get more recent and smoother data */
|
||||||
private static int getEvents(RouterContext ctx, String stat, long period) {
|
private int getEvents(String stat, long period) {
|
||||||
RateStat rs = ctx.statManager().getRate(stat);
|
RateStat rs = ctx.statManager().getRate(stat);
|
||||||
if (rs == null)
|
if (rs == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -31,6 +31,12 @@ import net.i2p.util.VersionComparator;
|
|||||||
* Todo: there's nothing non-static in here
|
* Todo: there's nothing non-static in here
|
||||||
*/
|
*/
|
||||||
public abstract class TunnelPeerSelector {
|
public abstract class TunnelPeerSelector {
|
||||||
|
protected final RouterContext ctx;
|
||||||
|
|
||||||
|
protected TunnelPeerSelector(RouterContext context) {
|
||||||
|
ctx = context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which peers should go into the next tunnel for the given settings?
|
* Which peers should go into the next tunnel for the given settings?
|
||||||
*
|
*
|
||||||
@ -40,12 +46,12 @@ public abstract class TunnelPeerSelector {
|
|||||||
* to build through, and the settings reject 0 hop tunnels, this will
|
* to build through, and the settings reject 0 hop tunnels, this will
|
||||||
* return null.
|
* return null.
|
||||||
*/
|
*/
|
||||||
public abstract List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings);
|
public abstract List<Hash> selectPeers(TunnelPoolSettings settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return randomized number of hops 0-7, not including ourselves
|
* @return randomized number of hops 0-7, not including ourselves
|
||||||
*/
|
*/
|
||||||
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
|
protected int getLength(TunnelPoolSettings settings) {
|
||||||
int length = settings.getLength();
|
int length = settings.getLength();
|
||||||
int override = settings.getLengthOverride();
|
int override = settings.getLengthOverride();
|
||||||
if (override >= 0) {
|
if (override >= 0) {
|
||||||
@ -109,7 +115,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
* Needs analysis and testing
|
* Needs analysis and testing
|
||||||
* @return should always be false
|
* @return should always be false
|
||||||
*/
|
*/
|
||||||
protected List<Hash> selectExplicit(RouterContext ctx, TunnelPoolSettings settings, int length) {
|
protected List<Hash> selectExplicit(TunnelPoolSettings settings, int length) {
|
||||||
String peers = null;
|
String peers = null;
|
||||||
Properties opts = settings.getUnknownOptions();
|
Properties opts = settings.getUnknownOptions();
|
||||||
if (opts != null)
|
if (opts != null)
|
||||||
@ -173,7 +179,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
/**
|
/**
|
||||||
* Pick peers that we want to avoid
|
* Pick peers that we want to avoid
|
||||||
*/
|
*/
|
||||||
public Set<Hash> getExclude(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
public Set<Hash> getExclude(boolean isInbound, boolean isExploratory) {
|
||||||
// we may want to update this to skip 'hidden' or 'unreachable' peers, but that
|
// we may want to update this to skip 'hidden' or 'unreachable' peers, but that
|
||||||
// isn't safe, since they may publish one set of routerInfo to us and another to
|
// isn't safe, since they may publish one set of routerInfo to us and another to
|
||||||
// other peers. the defaults for filterUnreachable has always been to return false,
|
// other peers. the defaults for filterUnreachable has always been to return false,
|
||||||
@ -196,7 +202,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting());
|
peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting());
|
||||||
peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
|
peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
|
||||||
// if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
|
// if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
|
||||||
if (filterUnreachable(ctx, isInbound, isExploratory)) {
|
if (filterUnreachable(isInbound, isExploratory)) {
|
||||||
// NOTE: filterUnreachable returns true for inbound, false for outbound
|
// NOTE: filterUnreachable returns true for inbound, false for outbound
|
||||||
// This is the only use for getPeersByCapability? And the whole set of datastructures in PeerManager?
|
// This is the only use for getPeersByCapability? And the whole set of datastructures in PeerManager?
|
||||||
Collection<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
|
Collection<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
|
||||||
@ -439,7 +445,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
* do we want to skip peers who haven't been up for long?
|
* do we want to skip peers who haven't been up for long?
|
||||||
* @return true for inbound, false for outbound, unless configured otherwise
|
* @return true for inbound, false for outbound, unless configured otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean filterUnreachable(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
protected boolean filterUnreachable(boolean isInbound, boolean isExploratory) {
|
||||||
boolean def = false;
|
boolean def = false;
|
||||||
String val = null;
|
String val = null;
|
||||||
|
|
||||||
|
@ -1093,7 +1093,7 @@ public class TunnelPool {
|
|||||||
}
|
}
|
||||||
if (peers == null) {
|
if (peers == null) {
|
||||||
setLengthOverride();
|
setLengthOverride();
|
||||||
peers = _peerSelector.selectPeers(_context, settings);
|
peers = _peerSelector.selectPeers(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (peers == null) || (peers.isEmpty()) ) {
|
if ( (peers == null) || (peers.isEmpty()) ) {
|
||||||
|
@ -61,7 +61,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
|||||||
|
|
||||||
_clientInboundPools = new ConcurrentHashMap(4);
|
_clientInboundPools = new ConcurrentHashMap(4);
|
||||||
_clientOutboundPools = new ConcurrentHashMap(4);
|
_clientOutboundPools = new ConcurrentHashMap(4);
|
||||||
_clientPeerSelector = new ClientPeerSelector();
|
_clientPeerSelector = new ClientPeerSelector(ctx);
|
||||||
|
|
||||||
_executor = new BuildExecutor(ctx, this);
|
_executor = new BuildExecutor(ctx, this);
|
||||||
I2PThread execThread = new I2PThread(_executor, "BuildExecutor", true);
|
I2PThread execThread = new I2PThread(_executor, "BuildExecutor", true);
|
||||||
@ -511,7 +511,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
|||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
ExploratoryPeerSelector selector = new ExploratoryPeerSelector();
|
ExploratoryPeerSelector selector = new ExploratoryPeerSelector(_context);
|
||||||
|
|
||||||
TunnelPoolSettings inboundSettings = new TunnelPoolSettings();
|
TunnelPoolSettings inboundSettings = new TunnelPoolSettings();
|
||||||
inboundSettings.setIsExploratory(true);
|
inboundSettings.setIsExploratory(true);
|
||||||
|
Reference in New Issue
Block a user