* Tunnels:
- Don't use peers < 0.7.9 for tunnels due to the old message corruption bugs - Javadoc - Cleanups
This commit is contained in:
@ -24,7 +24,7 @@ public class BuildMessageProcessor {
|
|||||||
|
|
||||||
public BuildMessageProcessor(I2PAppContext ctx) {
|
public BuildMessageProcessor(I2PAppContext ctx) {
|
||||||
_filter = new DecayingHashSet(ctx, 60*1000, 32, "TunnelBMP");
|
_filter = new DecayingHashSet(ctx, 60*1000, 32, "TunnelBMP");
|
||||||
ctx.statManager().createRateStat("tunnel.buildRequestDup", "How frequently we get dup build request messages", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
ctx.statManager().createRateStat("tunnel.buildRequestDup", "How frequently we get dup build request messages", "Tunnels", new long[] { 60*60*1000 });
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Decrypt the record targetting us, encrypting all of the other records with the included
|
* Decrypt the record targetting us, encrypting all of the other records with the included
|
||||||
|
@ -15,17 +15,19 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InboundEndpointProcessor {
|
public class InboundEndpointProcessor {
|
||||||
private RouterContext _context;
|
private final RouterContext _context;
|
||||||
private Log _log;
|
private final Log _log;
|
||||||
private TunnelCreatorConfig _config;
|
private final TunnelCreatorConfig _config;
|
||||||
private IVValidator _validator;
|
private final IVValidator _validator;
|
||||||
|
|
||||||
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
||||||
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
|
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
|
||||||
|
|
||||||
|
/** @deprecated unused */
|
||||||
public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg) {
|
public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg) {
|
||||||
this(ctx, cfg, DummyValidator.getInstance());
|
this(ctx, cfg, DummyValidator.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg, IVValidator validator) {
|
public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg, IVValidator validator) {
|
||||||
_context = ctx;
|
_context = ctx;
|
||||||
_log = ctx.logManager().getLog(InboundEndpointProcessor.class);
|
_log = ctx.logManager().getLog(InboundEndpointProcessor.class);
|
||||||
@ -84,6 +86,9 @@ public class InboundEndpointProcessor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iteratively undo the crypto that the various layers in the tunnel added.
|
||||||
|
*/
|
||||||
private void decrypt(RouterContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
|
private void decrypt(RouterContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
|
||||||
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
||||||
ByteArray ba = _cache.acquire();
|
ByteArray ba = _cache.acquire();
|
||||||
|
@ -14,9 +14,9 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class OutboundGatewayProcessor {
|
public class OutboundGatewayProcessor {
|
||||||
private I2PAppContext _context;
|
private final I2PAppContext _context;
|
||||||
private Log _log;
|
private final Log _log;
|
||||||
private TunnelCreatorConfig _config;
|
private final TunnelCreatorConfig _config;
|
||||||
|
|
||||||
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
||||||
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
|
private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH);
|
||||||
@ -54,10 +54,8 @@ public class OutboundGatewayProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undo the crypto that the various layers in the tunnel added. This is used
|
* Iteratively undo the crypto that the various layers in the tunnel added. This is used
|
||||||
* by both the outbound gateway (preemptively undoing the crypto peers will add)
|
* by the outbound gateway (preemptively undoing the crypto peers will add).
|
||||||
* and by the inbound endpoint.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void decrypt(I2PAppContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
|
private void decrypt(I2PAppContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) {
|
||||||
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
||||||
@ -73,6 +71,11 @@ public class OutboundGatewayProcessor {
|
|||||||
_cache.release(ba);
|
_cache.release(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo the crypto for a single hop. This is used
|
||||||
|
* by both the outbound gateway (preemptively undoing the crypto peers will add)
|
||||||
|
* and by the inbound endpoint.
|
||||||
|
*/
|
||||||
static void decrypt(I2PAppContext ctx, byte iv[], byte orig[], int offset, int length, byte cur[], HopConfig config) {
|
static void decrypt(I2PAppContext ctx, byte iv[], byte orig[], int offset, int length, byte cur[], HopConfig config) {
|
||||||
// update the IV for the previous (next?) hop
|
// update the IV for the previous (next?) hop
|
||||||
ctx.aes().decryptBlock(orig, offset, config.getIVKey(), orig, offset);
|
ctx.aes().decryptBlock(orig, offset, config.getIVKey(), orig, offset);
|
||||||
|
@ -60,7 +60,6 @@ public class TunnelGateway {
|
|||||||
_preprocessor = preprocessor;
|
_preprocessor = preprocessor;
|
||||||
_sender = sender;
|
_sender = sender;
|
||||||
_receiver = receiver;
|
_receiver = receiver;
|
||||||
_messagesSent = 0;
|
|
||||||
_flushFrequency = 500;
|
_flushFrequency = 500;
|
||||||
_delayedFlush = new DelayedFlush();
|
_delayedFlush = new DelayedFlush();
|
||||||
_lastFlush = _context.clock().now();
|
_lastFlush = _context.clock().now();
|
||||||
@ -128,8 +127,8 @@ public class TunnelGateway {
|
|||||||
FlushTimer.getInstance().addEvent(_delayedFlush, delayAmount);
|
FlushTimer.getInstance().addEvent(_delayedFlush, delayAmount);
|
||||||
}
|
}
|
||||||
_context.statManager().addRateData("tunnel.lockedGatewayAdd", afterAdded-beforeLock, remaining);
|
_context.statManager().addRateData("tunnel.lockedGatewayAdd", afterAdded-beforeLock, remaining);
|
||||||
long complete = System.currentTimeMillis();
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
long complete = System.currentTimeMillis();
|
||||||
_log.debug("Time to add the message " + msg.getUniqueId() + ": " + (complete-startAdd)
|
_log.debug("Time to add the message " + msg.getUniqueId() + ": " + (complete-startAdd)
|
||||||
+ " delayed? " + delayedFlush + " remaining: " + remaining
|
+ " delayed? " + delayedFlush + " remaining: " + remaining
|
||||||
+ " prepare: " + (beforeLock-startAdd)
|
+ " prepare: " + (beforeLock-startAdd)
|
||||||
@ -137,6 +136,7 @@ public class TunnelGateway {
|
|||||||
+ " preprocess: " + (afterPreprocess-afterAdded)
|
+ " preprocess: " + (afterPreprocess-afterAdded)
|
||||||
+ " expire: " + (afterExpire-afterPreprocess)
|
+ " expire: " + (afterExpire-afterPreprocess)
|
||||||
+ " queue flush: " + (complete-afterExpire));
|
+ " queue flush: " + (complete-afterExpire));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMessagesSent() { return _messagesSent; }
|
public int getMessagesSent() { return _messagesSent; }
|
||||||
@ -202,10 +202,7 @@ public class TunnelGateway {
|
|||||||
_messageId = message.getUniqueId();
|
_messageId = message.getUniqueId();
|
||||||
_expiration = message.getMessageExpiration();
|
_expiration = message.getMessageExpiration();
|
||||||
_remaining = message.toByteArray();
|
_remaining = message.toByteArray();
|
||||||
_offset = 0;
|
|
||||||
_fragmentNumber = 0;
|
|
||||||
_created = now;
|
_created = now;
|
||||||
_messageIds = null;
|
|
||||||
}
|
}
|
||||||
/** may be null */
|
/** may be null */
|
||||||
public Hash getToRouter() { return _toRouter; }
|
public Hash getToRouter() { return _toRouter; }
|
||||||
|
@ -5,6 +5,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import net.i2p.router.TunnelPoolSettings;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ClientPeerSelector extends TunnelPeerSelector {
|
class ClientPeerSelector extends TunnelPeerSelector {
|
||||||
public List selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
||||||
int length = getLength(ctx, settings);
|
int length = getLength(ctx, settings);
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
return null;
|
return null;
|
||||||
@ -31,7 +32,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, settings.getIPRestriction());
|
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, settings.getIPRestriction());
|
||||||
|
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
ArrayList rv = new ArrayList(matches);
|
ArrayList<Hash> rv = new ArrayList(matches);
|
||||||
if (rv.size() > 1)
|
if (rv.size() > 1)
|
||||||
orderPeers(rv, settings.getRandomKey());
|
orderPeers(rv, settings.getRandomKey());
|
||||||
if (settings.isInbound())
|
if (settings.isInbound())
|
||||||
|
@ -5,6 +5,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import net.i2p.stat.Rate;
|
import net.i2p.stat.Rate;
|
||||||
@ -17,7 +18,7 @@ import net.i2p.util.Log;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
class ExploratoryPeerSelector extends TunnelPeerSelector {
|
||||||
public List selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
|
||||||
Log l = ctx.logManager().getLog(getClass());
|
Log l = ctx.logManager().getLog(getClass());
|
||||||
int length = getLength(ctx, settings);
|
int length = getLength(ctx, settings);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
@ -33,7 +34,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
Set<Hash> exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory());
|
||||||
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
|
||||||
@ -56,7 +57,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
l.debug("profileOrganizer.selectNotFailing(" + length + ") found " + matches);
|
l.debug("profileOrganizer.selectNotFailing(" + length + ") found " + matches);
|
||||||
|
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
ArrayList rv = new ArrayList(matches);
|
ArrayList<Hash> rv = new ArrayList(matches);
|
||||||
if (rv.size() > 1)
|
if (rv.size() > 1)
|
||||||
orderPeers(rv, settings.getRandomKey());
|
orderPeers(rv, settings.getRandomKey());
|
||||||
if (settings.isInbound())
|
if (settings.isInbound())
|
||||||
@ -67,7 +68,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int MIN_NONFAILING_PCT = 25;
|
private static final int MIN_NONFAILING_PCT = 25;
|
||||||
private boolean shouldPickHighCap(RouterContext ctx) {
|
private static boolean shouldPickHighCap(RouterContext ctx) {
|
||||||
if (Boolean.valueOf(ctx.getProperty("router.exploreHighCapacity", "false")).booleanValue())
|
if (Boolean.valueOf(ctx.getProperty("router.exploreHighCapacity", "false")).booleanValue())
|
||||||
return true;
|
return true;
|
||||||
// no need to explore too wildly at first
|
// no need to explore too wildly at first
|
||||||
@ -86,9 +87,9 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
failPct = 100 - MIN_NONFAILING_PCT;
|
failPct = 100 - MIN_NONFAILING_PCT;
|
||||||
} else {
|
} else {
|
||||||
failPct = getExploratoryFailPercentage(ctx);
|
failPct = getExploratoryFailPercentage(ctx);
|
||||||
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);
|
||||||
// always try a little, this helps keep the failPct stat accurate too
|
// always try a little, this helps keep the failPct stat accurate too
|
||||||
if (failPct > 100 - MIN_NONFAILING_PCT)
|
if (failPct > 100 - MIN_NONFAILING_PCT)
|
||||||
failPct = 100 - MIN_NONFAILING_PCT;
|
failPct = 100 - MIN_NONFAILING_PCT;
|
||||||
@ -96,21 +97,23 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return (failPct >= ctx.random().nextInt(100));
|
return (failPct >= ctx.random().nextInt(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should really use the difference between the exploratory fail rate
|
/**
|
||||||
// and the high capacity fail rate - but we don't have a stat for high cap,
|
* We should really use the difference between the exploratory fail rate
|
||||||
// so use the fast (== client) fail rate, it should be close
|
* and the high capacity fail rate - but we don't have a stat for high cap,
|
||||||
// if the expl. and client tunnel lengths aren't too different.
|
* so use the fast (== client) fail rate, it should be close
|
||||||
// So calculate the difference between the exploratory fail rate
|
* if the expl. and client tunnel lengths aren't too different.
|
||||||
// and the client fail rate, normalized to 100:
|
* So calculate the difference between the exploratory fail rate
|
||||||
// 100 * ((Efail - Cfail) / (100 - Cfail))
|
* and the client fail rate, normalized to 100:
|
||||||
// Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
* 100 * ((Efail - Cfail) / (100 - Cfail))
|
||||||
// are often building exploratory tunnels using the HighCapacity pool.
|
* Even this isn't the "true" rate for the NonFailingPeers pool, since we
|
||||||
private int getExploratoryFailPercentage(RouterContext ctx) {
|
* are often building exploratory tunnels using the HighCapacity pool.
|
||||||
|
*/
|
||||||
|
private static int getExploratoryFailPercentage(RouterContext ctx) {
|
||||||
int c = getFailPercentage(ctx, "Client");
|
int c = getFailPercentage(ctx, "Client");
|
||||||
int e = getFailPercentage(ctx, "Exploratory");
|
int e = getFailPercentage(ctx, "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);
|
||||||
if (e <= c || e <= 25) // doing very well (unlikely)
|
if (e <= c || e <= 25) // doing very well (unlikely)
|
||||||
return 0;
|
return 0;
|
||||||
if (c >= 90) // doing very badly
|
if (c >= 90) // doing very badly
|
||||||
@ -118,7 +121,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return (100 * (e-c)) / (100-c);
|
return (100 * (e-c)) / (100-c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getFailPercentage(RouterContext ctx, String t) {
|
private static int getFailPercentage(RouterContext ctx, String t) {
|
||||||
String pfx = "tunnel.build" + t;
|
String pfx = "tunnel.build" + t;
|
||||||
int timeout = getEvents(ctx, pfx + "Expire", 10*60*1000);
|
int timeout = getEvents(ctx, pfx + "Expire", 10*60*1000);
|
||||||
int reject = getEvents(ctx, pfx + "Reject", 10*60*1000);
|
int reject = getEvents(ctx, pfx + "Reject", 10*60*1000);
|
||||||
@ -129,8 +132,8 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
return (int)(100 * pct);
|
return (int)(100 * pct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use current + last to get more recent and smoother data
|
/** Use current + last to get more recent and smoother data */
|
||||||
private int getEvents(RouterContext ctx, String stat, long period) {
|
private static int getEvents(RouterContext ctx, 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;
|
||||||
|
@ -12,7 +12,7 @@ import net.i2p.util.Log;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
|
class PooledTunnelCreatorConfig extends TunnelCreatorConfig {
|
||||||
private TunnelPool _pool;
|
private TunnelPool _pool;
|
||||||
private TestJob _testJob;
|
private TestJob _testJob;
|
||||||
// private Job _expireJob;
|
// private Job _expireJob;
|
||||||
|
@ -21,10 +21,13 @@ import net.i2p.router.TunnelPoolSettings;
|
|||||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||||
import net.i2p.router.networkdb.kademlia.HashDistance;
|
import net.i2p.router.networkdb.kademlia.HashDistance;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.VersionComparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coordinate the selection of peers to go into a tunnel for one particular
|
* Coordinate the selection of peers to go into a tunnel for one particular
|
||||||
* pool.
|
* pool.
|
||||||
|
*
|
||||||
|
* Todo: there's nothing non-static in here
|
||||||
*/
|
*/
|
||||||
public abstract class TunnelPeerSelector {
|
public abstract class TunnelPeerSelector {
|
||||||
/**
|
/**
|
||||||
@ -36,7 +39,7 @@ 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 selectPeers(RouterContext ctx, TunnelPoolSettings settings);
|
public abstract List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings);
|
||||||
|
|
||||||
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
|
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
|
||||||
int length = settings.getLength();
|
int length = settings.getLength();
|
||||||
@ -79,6 +82,11 @@ public abstract class TunnelPeerSelector {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For debugging, also possibly for restricted routes?
|
||||||
|
* Needs analysis and testing
|
||||||
|
* @return should always be false
|
||||||
|
*/
|
||||||
protected boolean shouldSelectExplicit(TunnelPoolSettings settings) {
|
protected boolean shouldSelectExplicit(TunnelPoolSettings settings) {
|
||||||
if (settings.isExploratory()) return false;
|
if (settings.isExploratory()) return false;
|
||||||
Properties opts = settings.getUnknownOptions();
|
Properties opts = settings.getUnknownOptions();
|
||||||
@ -92,7 +100,12 @@ public abstract class TunnelPeerSelector {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List selectExplicit(RouterContext ctx, TunnelPoolSettings settings, int length) {
|
/**
|
||||||
|
* For debugging, also possibly for restricted routes?
|
||||||
|
* Needs analysis and testing
|
||||||
|
* @return should always be false
|
||||||
|
*/
|
||||||
|
protected List<Hash> selectExplicit(RouterContext ctx, TunnelPoolSettings settings, int length) {
|
||||||
String peers = null;
|
String peers = null;
|
||||||
Properties opts = settings.getUnknownOptions();
|
Properties opts = settings.getUnknownOptions();
|
||||||
if (opts != null)
|
if (opts != null)
|
||||||
@ -102,7 +115,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
peers = I2PAppContext.getGlobalContext().getProperty("explicitPeers");
|
peers = I2PAppContext.getGlobalContext().getProperty("explicitPeers");
|
||||||
|
|
||||||
Log log = ctx.logManager().getLog(ClientPeerSelector.class);
|
Log log = ctx.logManager().getLog(ClientPeerSelector.class);
|
||||||
List rv = new ArrayList();
|
List<Hash> rv = new ArrayList();
|
||||||
StringTokenizer tok = new StringTokenizer(peers, ",");
|
StringTokenizer tok = new StringTokenizer(peers, ",");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String peerStr = tok.nextToken();
|
String peerStr = tok.nextToken();
|
||||||
@ -156,7 +169,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
/**
|
/**
|
||||||
* Pick peers that we want to avoid
|
* Pick peers that we want to avoid
|
||||||
*/
|
*/
|
||||||
public Set getExclude(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
public Set<Hash> getExclude(RouterContext ctx, 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,
|
||||||
@ -175,11 +188,12 @@ public abstract class TunnelPeerSelector {
|
|||||||
//
|
//
|
||||||
// Defaults changed to true for inbound only in filterUnreachable below.
|
// Defaults changed to true for inbound only in filterUnreachable below.
|
||||||
|
|
||||||
Set peers = new HashSet(1);
|
Set<Hash> peers = new HashSet(1);
|
||||||
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(ctx, isInbound, isExploratory)) {
|
||||||
|
// 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?
|
||||||
List<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
|
List<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
|
||||||
if (caps != null)
|
if (caps != null)
|
||||||
@ -189,6 +203,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
peers.addAll(caps);
|
peers.addAll(caps);
|
||||||
}
|
}
|
||||||
if (filterSlow(ctx, isInbound, isExploratory)) {
|
if (filterSlow(ctx, isInbound, isExploratory)) {
|
||||||
|
// NOTE: filterSlow always returns true
|
||||||
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
||||||
char excl[] = getExcludeCaps(ctx);
|
char excl[] = getExcludeCaps(ctx);
|
||||||
if (excl != null) {
|
if (excl != null) {
|
||||||
@ -301,6 +316,7 @@ public abstract class TunnelPeerSelector {
|
|||||||
return peers;
|
return peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** warning, this is also called by ProfileOrganizer.isSelectable() */
|
||||||
public static boolean shouldExclude(RouterContext ctx, RouterInfo peer) {
|
public static boolean shouldExclude(RouterContext ctx, RouterInfo peer) {
|
||||||
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
||||||
return shouldExclude(ctx, log, peer, getExcludeCaps(ctx));
|
return shouldExclude(ctx, log, peer, getExcludeCaps(ctx));
|
||||||
@ -318,6 +334,10 @@ public abstract class TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final long DONT_EXCLUDE_PERIOD = 15*60*1000;
|
private static final long DONT_EXCLUDE_PERIOD = 15*60*1000;
|
||||||
|
/** 0.7.8 and earlier had major message corruption bugs */
|
||||||
|
private static final String MIN_VERSION = "0.7.9";
|
||||||
|
private static final VersionComparator _versionComparator = new VersionComparator();
|
||||||
|
|
||||||
private static boolean shouldExclude(RouterContext ctx, Log log, RouterInfo peer, char excl[]) {
|
private static boolean shouldExclude(RouterContext ctx, Log log, RouterInfo peer, char excl[]) {
|
||||||
String cap = peer.getCapabilities();
|
String cap = peer.getCapabilities();
|
||||||
if (cap == null) {
|
if (cap == null) {
|
||||||
@ -340,6 +360,13 @@ public abstract class TunnelPeerSelector {
|
|||||||
// otherwise, it contains flags we aren't trying to focus on,
|
// otherwise, it contains flags we aren't trying to focus on,
|
||||||
// so don't exclude it based on published capacity
|
// so don't exclude it based on published capacity
|
||||||
|
|
||||||
|
// minimum version check
|
||||||
|
String v = peer.getOption("router.version");
|
||||||
|
if (v == null || _versionComparator.compare(v, MIN_VERSION) < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// uptime is always spoofed to 90m, so just remove all this
|
||||||
|
/******
|
||||||
String val = peer.getOption("stat_uptime");
|
String val = peer.getOption("stat_uptime");
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
long uptimeMs = 0;
|
long uptimeMs = 0;
|
||||||
@ -390,6 +417,8 @@ public abstract class TunnelPeerSelector {
|
|||||||
// not publishing an uptime, so exclude it
|
// not publishing an uptime, so exclude it
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
******/
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.outboundExploratoryExcludeUnreachable";
|
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.outboundExploratoryExcludeUnreachable";
|
||||||
@ -403,6 +432,10 @@ public abstract class TunnelPeerSelector {
|
|||||||
private static final String DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "true";
|
private static final String DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "true";
|
||||||
private static final String DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "true";
|
private static final String DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "true";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* do we want to skip peers who haven't been up for long?
|
||||||
|
* @return true for inbound, false for outbound, unless configured otherwise
|
||||||
|
*/
|
||||||
protected boolean filterUnreachable(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
protected boolean filterUnreachable(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
||||||
boolean def = false;
|
boolean def = false;
|
||||||
String val = null;
|
String val = null;
|
||||||
@ -429,6 +462,10 @@ public abstract class TunnelPeerSelector {
|
|||||||
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.inboundExploratoryExcludeSlow";
|
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.inboundExploratoryExcludeSlow";
|
||||||
private static final String PROP_INBOUND_CLIENT_EXCLUDE_SLOW = "router.inboundClientExcludeSlow";
|
private static final String PROP_INBOUND_CLIENT_EXCLUDE_SLOW = "router.inboundClientExcludeSlow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* do we want to skip peers that are slow?
|
||||||
|
* @return true unless configured otherwise
|
||||||
|
*/
|
||||||
protected boolean filterSlow(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
protected boolean filterSlow(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
||||||
boolean def = true;
|
boolean def = true;
|
||||||
String val = null;
|
String val = null;
|
||||||
@ -454,7 +491,10 @@ public abstract class TunnelPeerSelector {
|
|||||||
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.inboundExploratoryExcludeUptime";
|
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.inboundExploratoryExcludeUptime";
|
||||||
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UPTIME = "router.inboundClientExcludeUptime";
|
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UPTIME = "router.inboundClientExcludeUptime";
|
||||||
|
|
||||||
/** 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 unless configured otherwise
|
||||||
|
*/
|
||||||
protected boolean filterUptime(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
protected boolean filterUptime(RouterContext ctx, boolean isInbound, boolean isExploratory) {
|
||||||
boolean def = true;
|
boolean def = true;
|
||||||
String val = null;
|
String val = null;
|
||||||
|
Reference in New Issue
Block a user