forked from I2P_Developers/i2p.i2p
* Tunnels:
- Make most classes package private - Final, static, logs, cleanups - Consolideate createRateStat calls - Add getTotalLength() - Remove unused lengthOverride()
This commit is contained in:
@ -63,6 +63,7 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
private static final int MAX_BACKUP_QUANTITY = 3;
|
||||
private static final int MAX_VARIANCE = 2;
|
||||
private static final int MIN_NEG_VARIANCE = -1;
|
||||
|
||||
private void renderForm(StringBuilder buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
||||
|
||||
buf.append("<tr><th colspan=\"3\"><a name=\"").append(prefix).append("\">");
|
||||
@ -80,8 +81,8 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
if (in.getLength() + Math.abs(in.getLengthVariance()) >= WARN_LENGTH ||
|
||||
out.getLength() + Math.abs(out.getLengthVariance()) >= WARN_LENGTH)
|
||||
buf.append("<tr><th colspan=\"3\"><font color=\"red\">" + _("PERFORMANCE WARNING - Settings include very long tunnels.") + "</font></th></tr>");
|
||||
if (in.getQuantity() + in.getBackupQuantity() >= WARN_QUANTITY ||
|
||||
out.getQuantity() + out.getBackupQuantity() >= WARN_QUANTITY)
|
||||
if (in.getTotalQuantity() >= WARN_QUANTITY ||
|
||||
out.getTotalQuantity() >= WARN_QUANTITY)
|
||||
buf.append("<tr><th colspan=\"3\"><font color=\"red\">" + _("PERFORMANCE WARNING - Settings include high tunnel quantities.") + "</font></th></tr>");
|
||||
|
||||
buf.append("<tr><th></th><th><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"Inbound Tunnels\"> " + _("Inbound") + "</th><th><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound Tunnels\" title=\"Outbound\"> " + _("Outbound") + "</th></tr>\n");
|
||||
|
12
history.txt
12
history.txt
@ -1,3 +1,15 @@
|
||||
2011-10-25 zzz
|
||||
* BloomSHA1, DecayingBloomFilter:
|
||||
- Refactor for concurrent, at some small risk of false negatives
|
||||
- Optimizations to cache objects and reuse offsets
|
||||
* Tunnels:
|
||||
- Make most classes package private
|
||||
- Final, static, logs, cleanups
|
||||
- Consolideate createRateStat calls
|
||||
- Add getTotalLength()
|
||||
- Remove unused lengthOverride()
|
||||
* UDP: Mark only first fragment as a duplicate
|
||||
|
||||
* 2011-10-20 0.8.10 released
|
||||
|
||||
2011-10-19 kytv
|
||||
|
@ -43,6 +43,9 @@ class RouterThrottleImpl implements RouterThrottle {
|
||||
/** tunnel acceptance */
|
||||
public static final int TUNNEL_ACCEPT = 0;
|
||||
|
||||
/** = TrivialPreprocessor.PREPROCESSED_SIZE */
|
||||
private static final int PREPROCESSED_SIZE = 1024;
|
||||
|
||||
public RouterThrottleImpl(RouterContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(RouterThrottleImpl.class);
|
||||
@ -265,7 +268,7 @@ class RouterThrottleImpl implements RouterThrottle {
|
||||
if (messagesPerTunnel < DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE)
|
||||
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
|
||||
|
||||
double bytesAllocated = messagesPerTunnel * numTunnels * net.i2p.router.tunnel.TrivialPreprocessor.PREPROCESSED_SIZE;
|
||||
double bytesAllocated = messagesPerTunnel * numTunnels * PREPROCESSED_SIZE;
|
||||
|
||||
if (!allowTunnel(bytesAllocated, numTunnels)) {
|
||||
_context.statManager().addRateData("router.throttleTunnelBandwidthExceeded", (long)bytesAllocated, 0);
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 0;
|
||||
public final static long BUILD = 1;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@ -7,7 +7,7 @@ import net.i2p.data.Hash;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
/**
|
||||
* Wrap up the settings for a pool of tunnels (duh)
|
||||
* Wrap up the settings for a pool of tunnels.
|
||||
*
|
||||
*/
|
||||
public class TunnelPoolSettings {
|
||||
@ -19,7 +19,7 @@ public class TunnelPoolSettings {
|
||||
//private int _duration;
|
||||
private int _length;
|
||||
private int _lengthVariance;
|
||||
private int _lengthOverride;
|
||||
//private int _lengthOverride;
|
||||
private boolean _isInbound;
|
||||
private boolean _isExploratory;
|
||||
private boolean _allowZeroHop;
|
||||
@ -74,6 +74,15 @@ public class TunnelPoolSettings {
|
||||
public int getBackupQuantity() { return _backupQuantity; }
|
||||
public void setBackupQuantity(int quantity) { _backupQuantity = quantity; }
|
||||
|
||||
/**
|
||||
* Convenience
|
||||
* @return getQuantity() + getBackupQuantity()
|
||||
* @since 0.8.11
|
||||
*/
|
||||
public int getTotalQuantity() {
|
||||
return _quantity + _backupQuantity;
|
||||
}
|
||||
|
||||
/** how long before tunnel expiration should new tunnels be built */
|
||||
// public int getRebuildPeriod() { return _rebuildPeriod; }
|
||||
// public void setRebuildPeriod(int periodMs) { _rebuildPeriod = periodMs; }
|
||||
@ -95,9 +104,9 @@ public class TunnelPoolSettings {
|
||||
public int getLengthVariance() { return _lengthVariance; }
|
||||
public void setLengthVariance(int variance) { _lengthVariance = variance; }
|
||||
|
||||
/* Set to a nonzero value to override the length setting */
|
||||
public int getLengthOverride() { return _lengthOverride; }
|
||||
public void setLengthOverride(int variance) { _lengthOverride = variance; }
|
||||
/* UNUSED Set to a nonzero value to override the length setting */
|
||||
//public int getLengthOverride() { return _lengthOverride; }
|
||||
//public void setLengthOverride(int variance) { _lengthOverride = variance; }
|
||||
|
||||
/** is this an inbound tunnel? */
|
||||
public boolean isInbound() { return _isInbound; }
|
||||
@ -200,7 +209,7 @@ public class TunnelPoolSettings {
|
||||
}
|
||||
|
||||
// used for strict peer ordering
|
||||
private Hash generateRandomKey() {
|
||||
private static Hash generateRandomKey() {
|
||||
byte hash[] = new byte[Hash.HASH_LENGTH];
|
||||
RandomSource.getInstance().nextBytes(hash);
|
||||
return new Hash(hash);
|
||||
@ -211,7 +220,9 @@ public class TunnelPoolSettings {
|
||||
boolean v = "TRUE".equalsIgnoreCase(str) || "YES".equalsIgnoreCase(str);
|
||||
return v;
|
||||
}
|
||||
|
||||
private static final int getInt(String str, int defaultValue) { return (int)getLong(str, defaultValue); }
|
||||
|
||||
private static final long getLong(String str, long defaultValue) {
|
||||
if (str == null) return defaultValue;
|
||||
try {
|
||||
|
@ -108,12 +108,13 @@ class OutboundClientMessageJobHelper {
|
||||
|
||||
DeliveryInstructions instructions = new DeliveryInstructions();
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
|
||||
instructions.setDelayRequested(false);
|
||||
instructions.setDelaySeconds(0);
|
||||
instructions.setEncrypted(false);
|
||||
instructions.setEncryptionKey(null);
|
||||
instructions.setRouter(null);
|
||||
instructions.setTunnelId(null);
|
||||
// defaults
|
||||
//instructions.setDelayRequested(false);
|
||||
//instructions.setDelaySeconds(0);
|
||||
//instructions.setEncrypted(false);
|
||||
//instructions.setEncryptionKey(null);
|
||||
//instructions.setRouter(null);
|
||||
//instructions.setTunnelId(null);
|
||||
|
||||
config.setCertificate(Certificate.NULL_CERT);
|
||||
config.setDeliveryInstructions(instructions);
|
||||
@ -155,9 +156,10 @@ class OutboundClientMessageJobHelper {
|
||||
ackInstructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_TUNNEL);
|
||||
ackInstructions.setRouter(replyToTunnelRouter);
|
||||
ackInstructions.setTunnelId(replyToTunnelId);
|
||||
ackInstructions.setDelayRequested(false);
|
||||
ackInstructions.setDelaySeconds(0);
|
||||
ackInstructions.setEncrypted(false);
|
||||
// defaults
|
||||
//ackInstructions.setDelayRequested(false);
|
||||
//ackInstructions.setDelaySeconds(0);
|
||||
//ackInstructions.setEncrypted(false);
|
||||
|
||||
DeliveryStatusMessage msg = new DeliveryStatusMessage(ctx);
|
||||
msg.setArrival(ctx.clock().now());
|
||||
@ -192,9 +194,10 @@ class OutboundClientMessageJobHelper {
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_DESTINATION);
|
||||
instructions.setDestination(dest.calculateHash());
|
||||
|
||||
instructions.setDelayRequested(false);
|
||||
instructions.setDelaySeconds(0);
|
||||
instructions.setEncrypted(false);
|
||||
// defaults
|
||||
//instructions.setDelayRequested(false);
|
||||
//instructions.setDelaySeconds(0);
|
||||
//instructions.setEncrypted(false);
|
||||
|
||||
clove.setCertificate(Certificate.NULL_CERT);
|
||||
clove.setDeliveryInstructions(instructions);
|
||||
@ -218,9 +221,10 @@ class OutboundClientMessageJobHelper {
|
||||
|
||||
DeliveryInstructions instructions = new DeliveryInstructions();
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
|
||||
instructions.setDelayRequested(false);
|
||||
instructions.setDelaySeconds(0);
|
||||
instructions.setEncrypted(false);
|
||||
// defaults
|
||||
//instructions.setDelayRequested(false);
|
||||
//instructions.setDelaySeconds(0);
|
||||
//instructions.setEncrypted(false);
|
||||
|
||||
clove.setCertificate(Certificate.NULL_CERT);
|
||||
clove.setDeliveryInstructions(instructions);
|
||||
|
@ -891,9 +891,10 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_DESTINATION);
|
||||
instructions.setDestination(_to.calculateHash());
|
||||
|
||||
instructions.setDelayRequested(false);
|
||||
instructions.setDelaySeconds(0);
|
||||
instructions.setEncrypted(false);
|
||||
// defaults
|
||||
//instructions.setDelayRequested(false);
|
||||
//instructions.setDelaySeconds(0);
|
||||
//instructions.setEncrypted(false);
|
||||
|
||||
clove.setCertificate(Certificate.NULL_CERT);
|
||||
clove.setDeliveryInstructions(instructions);
|
||||
|
@ -44,7 +44,7 @@ import net.i2p.util.Log;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class BatchedPreprocessor extends TrivialPreprocessor {
|
||||
class BatchedPreprocessor extends TrivialPreprocessor {
|
||||
private long _pendingSince;
|
||||
private final String _name;
|
||||
|
||||
|
@ -10,8 +10,7 @@ import net.i2p.router.RouterContext;
|
||||
* router config setting, and track fragmentation.
|
||||
*
|
||||
*/
|
||||
public class BatchedRouterPreprocessor extends BatchedPreprocessor {
|
||||
protected RouterContext _routerContext;
|
||||
class BatchedRouterPreprocessor extends BatchedPreprocessor {
|
||||
private TunnelCreatorConfig _config;
|
||||
protected HopConfig _hopConfig;
|
||||
private final long _sendDelay;
|
||||
@ -34,7 +33,6 @@ public class BatchedRouterPreprocessor extends BatchedPreprocessor {
|
||||
/** for OBGWs */
|
||||
public BatchedRouterPreprocessor(RouterContext ctx, TunnelCreatorConfig cfg) {
|
||||
super(ctx, getName(cfg));
|
||||
_routerContext = ctx;
|
||||
_config = cfg;
|
||||
_sendDelay = initialSendDelay();
|
||||
}
|
||||
@ -42,7 +40,6 @@ public class BatchedRouterPreprocessor extends BatchedPreprocessor {
|
||||
/** for IBGWs */
|
||||
public BatchedRouterPreprocessor(RouterContext ctx, HopConfig cfg) {
|
||||
super(ctx, getName(cfg));
|
||||
_routerContext = ctx;
|
||||
_hopConfig = cfg;
|
||||
_sendDelay = initialSendDelay();
|
||||
}
|
||||
@ -103,14 +100,14 @@ public class BatchedRouterPreprocessor extends BatchedPreprocessor {
|
||||
} else {
|
||||
def = DEFAULT_BATCH_FREQUENCY;
|
||||
}
|
||||
return _routerContext.getProperty(PROP_ROUTER_BATCH_FREQUENCY, def);
|
||||
return _context.getProperty(PROP_ROUTER_BATCH_FREQUENCY, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notePreprocessing(long messageId, int numFragments, int totalLength, List<Long> messageIds, String msg) {
|
||||
if (_config != null)
|
||||
_routerContext.messageHistory().fragmentMessage(messageId, numFragments, totalLength, messageIds, _config, msg);
|
||||
_context.messageHistory().fragmentMessage(messageId, numFragments, totalLength, messageIds, _config, msg);
|
||||
else
|
||||
_routerContext.messageHistory().fragmentMessage(messageId, numFragments, totalLength, messageIds, _hopConfig, msg);
|
||||
_context.messageHistory().fragmentMessage(messageId, numFragments, totalLength, messageIds, _hopConfig, msg);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import net.i2p.util.DecayingHashSet;
|
||||
* decaying bloom filter.
|
||||
*
|
||||
*/
|
||||
public class BloomFilterIVValidator implements IVValidator {
|
||||
class BloomFilterIVValidator implements IVValidator {
|
||||
private final RouterContext _context;
|
||||
private final DecayingBloomFilter _filter;
|
||||
private final ByteCache _ivXorCache = ByteCache.getInstance(32, HopProcessor.IV_LENGTH);
|
||||
@ -30,6 +30,8 @@ public class BloomFilterIVValidator implements IVValidator {
|
||||
private static final long MIN_MEM_TO_USE_BLOOM = 64*1024*1024l;
|
||||
private static final long MIN_MEM_FOR_BIG_BLOOM = 128*1024*1024l;
|
||||
private static final long MIN_MEM_FOR_HUGE_BLOOM = 256*1024*1024l;
|
||||
/** for testing */
|
||||
private static final String PROP_FORCE = "router.forceDecayingBloomFilter";
|
||||
|
||||
public BloomFilterIVValidator(RouterContext ctx, int KBps) {
|
||||
_context = ctx;
|
||||
@ -40,7 +42,9 @@ public class BloomFilterIVValidator implements IVValidator {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
if (KBps < MIN_SHARE_KBPS_TO_USE_BLOOM || maxMemory < MIN_MEM_TO_USE_BLOOM)
|
||||
if (_context.getBooleanProperty(PROP_FORCE))
|
||||
_filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV"); // 2MB fixed
|
||||
else if (KBps < MIN_SHARE_KBPS_TO_USE_BLOOM || maxMemory < MIN_MEM_TO_USE_BLOOM)
|
||||
_filter = new DecayingHashSet(ctx, HALFLIFE_MS, 16, "TunnelIVV"); // appx. 4MB max
|
||||
else if (KBps >= MIN_SHARE_KBPS_FOR_HUGE_BLOOM && maxMemory >= MIN_MEM_FOR_HUGE_BLOOM)
|
||||
_filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV", 25); // 8MB fixed
|
||||
@ -49,7 +53,7 @@ public class BloomFilterIVValidator implements IVValidator {
|
||||
else
|
||||
_filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV"); // 2MB fixed
|
||||
ctx.statManager().createRateStat("tunnel.duplicateIV", "Note that a duplicate IV was received", "Tunnels",
|
||||
new long[] { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l });
|
||||
new long[] { 60*60*1000l });
|
||||
}
|
||||
|
||||
public boolean receiveIV(byte ivData[], int ivOffset, byte payload[], int payloadOffset) {
|
||||
@ -57,8 +61,9 @@ public class BloomFilterIVValidator implements IVValidator {
|
||||
DataHelper.xor(ivData, ivOffset, payload, payloadOffset, buf.getData(), 0, HopProcessor.IV_LENGTH);
|
||||
boolean dup = _filter.add(buf.getData());
|
||||
_ivXorCache.release(buf);
|
||||
if (dup) _context.statManager().addRateData("tunnel.duplicateIV", 1, 1);
|
||||
if (dup) _context.statManager().addRateData("tunnel.duplicateIV", 1);
|
||||
return !dup; // return true if it is OK, false if it isn't
|
||||
}
|
||||
|
||||
public void destroy() { _filter.stopDecaying(); }
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* Fill in the encrypted BuildRequestRecords in a TunnelBuildMessage
|
||||
*/
|
||||
public class BuildMessageGenerator {
|
||||
public abstract class BuildMessageGenerator {
|
||||
|
||||
/** return null if it is unable to find a router's public key (etc) */
|
||||
/****
|
||||
@ -58,10 +58,12 @@ public class BuildMessageGenerator {
|
||||
/**
|
||||
* Place the asymmetrically encrypted record in the specified record slot,
|
||||
* containing the hop's configuration (as well as the reply info, if it is an outbound endpoint)
|
||||
*
|
||||
* @param msg out parameter
|
||||
*/
|
||||
public static void createRecord(int recordNum, int hop, TunnelBuildMessage msg, TunnelCreatorConfig cfg, Hash replyRouter, long replyTunnel, I2PAppContext ctx, PublicKey peerKey) {
|
||||
byte encrypted[] = new byte[TunnelBuildMessage.RECORD_SIZE];
|
||||
Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
//Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
if (peerKey != null) {
|
||||
BuildRequestRecord req = null;
|
||||
if ( (!cfg.isInbound()) && (hop + 1 == cfg.getLength()) ) //outbound endpoint
|
||||
@ -69,22 +71,22 @@ public class BuildMessageGenerator {
|
||||
else
|
||||
req = createUnencryptedRecord(ctx, cfg, hop, null, -1);
|
||||
Hash peer = cfg.getPeer(hop);
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Record " + recordNum + "/" + hop + "/" + peer.toBase64()
|
||||
+ ": unencrypted = " + Base64.encode(req.getData().getData()));
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Record " + recordNum + "/" + hop + "/" + peer.toBase64()
|
||||
// + ": unencrypted = " + Base64.encode(req.getData().getData()));
|
||||
req.encryptRecord(ctx, peerKey, peer, encrypted, 0);
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Record " + recordNum + "/" + hop + ": encrypted = " + Base64.encode(encrypted));
|
||||
} else {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Record " + recordNum + "/" + hop + "/ is blank/random");
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Record " + recordNum + "/" + hop + "/ is blank/random");
|
||||
ctx.random().nextBytes(encrypted);
|
||||
}
|
||||
msg.setRecord(recordNum, new ByteArray(encrypted));
|
||||
}
|
||||
|
||||
private static BuildRequestRecord createUnencryptedRecord(I2PAppContext ctx, TunnelCreatorConfig cfg, int hop, Hash replyRouter, long replyTunnel) {
|
||||
Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
//Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
if (hop < cfg.getLength()) {
|
||||
// ok, now lets fill in some data
|
||||
HopConfig hopConfig = cfg.getConfig(hop);
|
||||
@ -129,9 +131,9 @@ public class BuildMessageGenerator {
|
||||
nextMsgId = ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE);
|
||||
}
|
||||
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug("Hop " + hop + " has the next message ID of " + nextMsgId + " for " + cfg
|
||||
+ " with replyKey " + replyKey.toBase64() + " and replyIV " + Base64.encode(iv));
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug("Hop " + hop + " has the next message ID of " + nextMsgId + " for " + cfg
|
||||
// + " with replyKey " + replyKey.toBase64() + " and replyIV " + Base64.encode(iv));
|
||||
|
||||
BuildRequestRecord rec= new BuildRequestRecord();
|
||||
rec.createRecord(ctx, recvTunnelId, peer, nextTunnelId, nextPeer, nextMsgId, layerKey, ivKey, replyKey,
|
||||
@ -148,19 +150,19 @@ public class BuildMessageGenerator {
|
||||
* @param order list of hop #s as Integers. For instance, if (order.get(1) is 4), it is peer cfg.getPeer(4)
|
||||
*/
|
||||
public static void layeredEncrypt(I2PAppContext ctx, TunnelBuildMessage msg, TunnelCreatorConfig cfg, List order) {
|
||||
Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
//Log log = ctx.logManager().getLog(BuildMessageGenerator.class);
|
||||
// encrypt the records so that the right elements will be visible at the right time
|
||||
for (int i = 0; i < msg.getRecordCount(); i++) {
|
||||
ByteArray rec = msg.getRecord(i);
|
||||
Integer hopNum = (Integer)order.get(i);
|
||||
int hop = hopNum.intValue();
|
||||
if ( (isBlank(cfg, hop)) || (!cfg.isInbound() && hop == 1) ) {
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(msg.getUniqueId() + ": not pre-decrypting record " + i + "/" + hop + " for " + cfg);
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug(msg.getUniqueId() + ": not pre-decrypting record " + i + "/" + hop + " for " + cfg);
|
||||
continue;
|
||||
}
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(msg.getUniqueId() + ": pre-decrypting record " + i + "/" + hop + " for " + cfg);
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug(msg.getUniqueId() + ": pre-decrypting record " + i + "/" + hop + " for " + cfg);
|
||||
// ok, now decrypt the record with all of the reply keys from cfg.getConfig(0) through hop-1
|
||||
int stop = (cfg.isInbound() ? 0 : 1);
|
||||
for (int j = hop-1; j >= stop; j--) {
|
||||
@ -168,14 +170,14 @@ public class BuildMessageGenerator {
|
||||
SessionKey key = hopConfig.getReplyKey();
|
||||
byte iv[] = hopConfig.getReplyIV().getData();
|
||||
int off = rec.getOffset();
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(msg.getUniqueId() + ": pre-decrypting record " + i + "/" + hop + " for " + cfg
|
||||
+ " with " + key.toBase64() + "/" + Base64.encode(iv));
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug(msg.getUniqueId() + ": pre-decrypting record " + i + "/" + hop + " for " + cfg
|
||||
// + " with " + key.toBase64() + "/" + Base64.encode(iv));
|
||||
ctx.aes().decrypt(rec.getData(), off, rec.getData(), off, key, iv, TunnelBuildMessage.RECORD_SIZE);
|
||||
}
|
||||
}
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(msg.getUniqueId() + ": done pre-decrypting all records for " + cfg);
|
||||
//if (log.shouldLog(Log.DEBUG))
|
||||
// log.debug(msg.getUniqueId() + ": done pre-decrypting all records for " + cfg);
|
||||
}
|
||||
|
||||
public static boolean isBlank(TunnelCreatorConfig cfg, int hop) {
|
||||
|
@ -20,11 +20,11 @@ import net.i2p.util.Log;
|
||||
* the next hop
|
||||
*/
|
||||
public class BuildMessageProcessor {
|
||||
private DecayingBloomFilter _filter;
|
||||
private final DecayingBloomFilter _filter;
|
||||
|
||||
public BuildMessageProcessor(I2PAppContext ctx) {
|
||||
_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*60*1000 });
|
||||
// all createRateStat in TunnelDispatcher
|
||||
}
|
||||
/**
|
||||
* Decrypt the record targetting us, encrypting all of the other records with the included
|
||||
|
@ -16,7 +16,7 @@ import net.i2p.util.Log;
|
||||
* hops agreed to participate in the tunnel, or if not, why not.
|
||||
*
|
||||
*/
|
||||
public class BuildReplyHandler {
|
||||
public abstract class BuildReplyHandler {
|
||||
|
||||
/**
|
||||
* Decrypt the tunnel build reply records. This overwrites the contents of the reply
|
||||
|
@ -90,14 +90,13 @@ The total size, including the tunnel ID and IV, is 1028 bytes.
|
||||
|
||||
*
|
||||
*/
|
||||
public class FragmentHandler {
|
||||
protected RouterContext _context;
|
||||
protected Log _log;
|
||||
class FragmentHandler {
|
||||
protected final RouterContext _context;
|
||||
protected final Log _log;
|
||||
private final Map<Long, FragmentedMessage> _fragmentedMessages;
|
||||
private DefragmentedReceiver _receiver;
|
||||
private final DefragmentedReceiver _receiver;
|
||||
private int _completed;
|
||||
private int _failed;
|
||||
private static final long[] RATES = { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000 };
|
||||
|
||||
/** don't wait more than 60s to defragment the partial message */
|
||||
static long MAX_DEFRAGMENT_TIME = 60*1000;
|
||||
@ -108,16 +107,7 @@ public class FragmentHandler {
|
||||
_log = context.logManager().getLog(FragmentHandler.class);
|
||||
_fragmentedMessages = new HashMap(8);
|
||||
_receiver = receiver;
|
||||
_context.statManager().createRateStat("tunnel.smallFragments", "How many pad bytes are in small fragments?",
|
||||
"Tunnels", RATES);
|
||||
_context.statManager().createRateStat("tunnel.fullFragments", "How many tunnel messages use the full data area?",
|
||||
"Tunnels", RATES);
|
||||
_context.statManager().createRateStat("tunnel.fragmentedComplete", "How many fragments were in a completely received message?",
|
||||
"Tunnels", RATES);
|
||||
_context.statManager().createRequiredRateStat("tunnel.fragmentedDropped", "Number of dropped fragments",
|
||||
"Tunnels", RATES);
|
||||
_context.statManager().createRequiredRateStat("tunnel.corruptMessage", "Corrupt messages received",
|
||||
"Tunnels", RATES);
|
||||
// all createRateStat in TunnelDispatcher
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,16 +24,16 @@ import net.i2p.util.SimpleTimer;
|
||||
* Warning - this is all unsynchronized here - receivers must implement synchronization
|
||||
*
|
||||
*/
|
||||
public class FragmentedMessage {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
class FragmentedMessage {
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private long _messageId;
|
||||
private Hash _toRouter;
|
||||
private TunnelId _toTunnel;
|
||||
private ByteArray _fragments[];
|
||||
private boolean _lastReceived;
|
||||
private int _highFragmentNum;
|
||||
private long _createdOn;
|
||||
private final long _createdOn;
|
||||
private boolean _completed;
|
||||
private long _releasedAfter;
|
||||
private SimpleTimer.TimedEvent _expireEvent;
|
||||
@ -46,15 +46,10 @@ public class FragmentedMessage {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(FragmentedMessage.class);
|
||||
_messageId = -1;
|
||||
_toRouter = null;
|
||||
_toTunnel = null;
|
||||
_fragments = new ByteArray[MAX_FRAGMENTS];
|
||||
_lastReceived = false;
|
||||
_highFragmentNum = -1;
|
||||
_releasedAfter = -1;
|
||||
_createdOn = ctx.clock().now();
|
||||
_expireEvent = null;
|
||||
_completed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,11 +15,11 @@ import net.i2p.util.Log;
|
||||
* InbuondGatewayProcessor).
|
||||
*
|
||||
*/
|
||||
public class HopProcessor {
|
||||
protected I2PAppContext _context;
|
||||
private Log _log;
|
||||
protected HopConfig _config;
|
||||
private IVValidator _validator;
|
||||
class HopProcessor {
|
||||
protected final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
protected final HopConfig _config;
|
||||
private final IVValidator _validator;
|
||||
|
||||
/** helpful flag for debugging */
|
||||
static final boolean USE_ENCRYPTION = true;
|
||||
|
@ -14,7 +14,7 @@ import net.i2p.util.Log;
|
||||
* same thing in both instances.
|
||||
*
|
||||
*/
|
||||
public class InboundEndpointProcessor {
|
||||
class InboundEndpointProcessor {
|
||||
private final RouterContext _context;
|
||||
private final Log _log;
|
||||
private final TunnelCreatorConfig _config;
|
||||
@ -90,15 +90,15 @@ public class InboundEndpointProcessor {
|
||||
* 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) {
|
||||
Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
||||
//Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class);
|
||||
ByteArray ba = _cache.acquire();
|
||||
byte cur[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH]; // so we dont malloc
|
||||
for (int i = cfg.getLength()-2; i >= 0; i--) { // dont include the endpoint, since that is the creator
|
||||
OutboundGatewayProcessor.decrypt(ctx, iv, orig, offset, length, cur, cfg.getConfig(i));
|
||||
if (log.shouldLog(Log.DEBUG)) {
|
||||
//if (log.shouldLog(Log.DEBUG)) {
|
||||
//log.debug("IV at hop " + i + ": " + Base64.encode(orig, offset, HopProcessor.IV_LENGTH));
|
||||
//log.debug("hop " + i + ": " + Base64.encode(orig, offset + HopProcessor.IV_LENGTH, length - HopProcessor.IV_LENGTH));
|
||||
}
|
||||
//}
|
||||
}
|
||||
_cache.release(ba);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import net.i2p.I2PAppContext;
|
||||
* Override the hop processor to seed the message with a random
|
||||
* IV.
|
||||
*/
|
||||
public class InboundGatewayProcessor extends HopProcessor {
|
||||
class InboundGatewayProcessor extends HopProcessor {
|
||||
public InboundGatewayProcessor(I2PAppContext ctx, HopConfig config) {
|
||||
super(ctx, config, DummyValidator.getInstance());
|
||||
}
|
||||
|
@ -26,11 +26,11 @@ import net.i2p.util.Log;
|
||||
* When a message arrives at the inbound tunnel endpoint, this distributor
|
||||
* honors the instructions (safely)
|
||||
*/
|
||||
public class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
||||
private RouterContext _context;
|
||||
private Log _log;
|
||||
private Hash _client;
|
||||
private GarlicMessageReceiver _receiver;
|
||||
class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
||||
private final RouterContext _context;
|
||||
private final Log _log;
|
||||
private final Hash _client;
|
||||
private final GarlicMessageReceiver _receiver;
|
||||
|
||||
private static final int MAX_DISTRIBUTE_TIME = 10*1000;
|
||||
|
||||
@ -39,8 +39,7 @@ public class InboundMessageDistributor implements GarlicMessageReceiver.CloveRec
|
||||
_client = client;
|
||||
_log = ctx.logManager().getLog(InboundMessageDistributor.class);
|
||||
_receiver = new GarlicMessageReceiver(ctx, this, client);
|
||||
_context.statManager().createRateStat("tunnel.dropDangerousClientTunnelMessage", "How many tunnel messages come down a client tunnel that we shouldn't expect (lifetime is the 'I2NP type')", "Tunnels", new long[] { 60*60*1000 });
|
||||
_context.statManager().createRateStat("tunnel.handleLoadClove", "When do we receive load test cloves", "Tunnels", new long[] { 60*60*1000 });
|
||||
// all createRateStat in TunnelDispatcher
|
||||
}
|
||||
|
||||
public void distribute(I2NPMessage msg, Hash target) {
|
||||
|
@ -7,8 +7,8 @@ import net.i2p.I2PAppContext;
|
||||
* it on to the first hop.
|
||||
*
|
||||
*/
|
||||
public class InboundSender implements TunnelGateway.Sender {
|
||||
private InboundGatewayProcessor _processor;
|
||||
class InboundSender implements TunnelGateway.Sender {
|
||||
private final InboundGatewayProcessor _processor;
|
||||
|
||||
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
||||
|
||||
|
@ -13,7 +13,7 @@ import net.i2p.util.Log;
|
||||
* InboundEndpointProcessor, as its the same 'undo' function of the tunnel crypto.
|
||||
*
|
||||
*/
|
||||
public class OutboundGatewayProcessor {
|
||||
class OutboundGatewayProcessor {
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private final TunnelCreatorConfig _config;
|
||||
|
@ -14,7 +14,7 @@ import net.i2p.util.Log;
|
||||
* When a message arrives at the outbound tunnel endpoint, this distributor
|
||||
* honors the instructions.
|
||||
*/
|
||||
public class OutboundMessageDistributor {
|
||||
class OutboundMessageDistributor {
|
||||
private final RouterContext _context;
|
||||
private final int _priority;
|
||||
private final Log _log;
|
||||
|
@ -9,11 +9,11 @@ import net.i2p.util.Log;
|
||||
* layers, and forward it on to the first hop.
|
||||
*
|
||||
*/
|
||||
public class OutboundSender implements TunnelGateway.Sender {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private TunnelCreatorConfig _config;
|
||||
private OutboundGatewayProcessor _processor;
|
||||
class OutboundSender implements TunnelGateway.Sender {
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private final TunnelCreatorConfig _config;
|
||||
private final OutboundGatewayProcessor _processor;
|
||||
|
||||
static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION;
|
||||
|
||||
|
@ -12,13 +12,13 @@ import net.i2p.util.Log;
|
||||
* and honor the instructions as received.
|
||||
*
|
||||
*/
|
||||
public class OutboundTunnelEndpoint {
|
||||
private RouterContext _context;
|
||||
private Log _log;
|
||||
private HopConfig _config;
|
||||
private HopProcessor _processor;
|
||||
private FragmentHandler _handler;
|
||||
private OutboundMessageDistributor _outDistributor;
|
||||
class OutboundTunnelEndpoint {
|
||||
private final RouterContext _context;
|
||||
private final Log _log;
|
||||
private final HopConfig _config;
|
||||
private final HopProcessor _processor;
|
||||
private final FragmentHandler _handler;
|
||||
private final OutboundMessageDistributor _outDistributor;
|
||||
|
||||
public OutboundTunnelEndpoint(RouterContext ctx, HopConfig config, HopProcessor processor) {
|
||||
_context = ctx;
|
||||
|
@ -2,6 +2,8 @@ package net.i2p.router.tunnel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.TunnelId;
|
||||
@ -33,9 +35,9 @@ import net.i2p.util.Log;
|
||||
* </ol>
|
||||
*
|
||||
*/
|
||||
public class PumpedTunnelGateway extends TunnelGateway {
|
||||
private final List<Pending> _prequeue;
|
||||
private TunnelGatewayPumper _pumper;
|
||||
class PumpedTunnelGateway extends TunnelGateway {
|
||||
private final BlockingQueue<Pending> _prequeue;
|
||||
private final TunnelGatewayPumper _pumper;
|
||||
|
||||
/**
|
||||
* @param preprocessor this pulls Pending messages off a list, builds some
|
||||
@ -47,7 +49,7 @@ public class PumpedTunnelGateway extends TunnelGateway {
|
||||
*/
|
||||
public PumpedTunnelGateway(RouterContext context, QueuePreprocessor preprocessor, Sender sender, Receiver receiver, TunnelGatewayPumper pumper) {
|
||||
super(context, preprocessor, sender, receiver);
|
||||
_prequeue = new ArrayList(4);
|
||||
_prequeue = new LinkedBlockingQueue();
|
||||
_pumper = pumper;
|
||||
}
|
||||
|
||||
@ -64,13 +66,8 @@ public class PumpedTunnelGateway extends TunnelGateway {
|
||||
public void add(I2NPMessage msg, Hash toRouter, TunnelId toTunnel) {
|
||||
_messagesSent++;
|
||||
Pending cur = new PendingImpl(msg, toRouter, toTunnel);
|
||||
long beforeLock = System.currentTimeMillis();
|
||||
synchronized (_prequeue) {
|
||||
_prequeue.add(cur);
|
||||
}
|
||||
_prequeue.offer(cur);
|
||||
_pumper.wantsPumping(this);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("GW prequeue time: " + (System.currentTimeMillis()-beforeLock) + " for " + msg.getUniqueId() + " on " + toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,14 +81,10 @@ public class PumpedTunnelGateway extends TunnelGateway {
|
||||
* Must be empty when called; will always be emptied before return.
|
||||
*/
|
||||
void pump(List<Pending> queueBuf) {
|
||||
synchronized (_prequeue) {
|
||||
if (!_prequeue.isEmpty()) {
|
||||
queueBuf.addAll(_prequeue);
|
||||
_prequeue.clear();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_prequeue.drainTo(queueBuf);
|
||||
if (queueBuf.isEmpty())
|
||||
return;
|
||||
|
||||
long startAdd = System.currentTimeMillis();
|
||||
long beforeLock = startAdd;
|
||||
long afterAdded = -1;
|
||||
|
@ -6,7 +6,7 @@ import net.i2p.util.Log;
|
||||
/**
|
||||
* Minor extension to allow message history integration
|
||||
*/
|
||||
public class RouterFragmentHandler extends FragmentHandler {
|
||||
class RouterFragmentHandler extends FragmentHandler {
|
||||
|
||||
public RouterFragmentHandler(RouterContext context, DefragmentedReceiver receiver) {
|
||||
super(context, receiver);
|
||||
|
@ -14,9 +14,9 @@ import net.i2p.router.RouterContext;
|
||||
*
|
||||
* @since 0.7.9
|
||||
*/
|
||||
public class ThrottledPumpedTunnelGateway extends PumpedTunnelGateway {
|
||||
class ThrottledPumpedTunnelGateway extends PumpedTunnelGateway {
|
||||
/** saved so we can note messages that get dropped */
|
||||
private HopConfig _config;
|
||||
private final HopConfig _config;
|
||||
|
||||
public ThrottledPumpedTunnelGateway(RouterContext context, QueuePreprocessor preprocessor, Sender sender,
|
||||
Receiver receiver, TunnelGatewayPumper pumper, HopConfig config) {
|
||||
|
@ -19,7 +19,7 @@ import net.i2p.util.Log;
|
||||
*
|
||||
* See FragmentHandler Javadoc for tunnel message fragment format
|
||||
*/
|
||||
public class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
|
||||
class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
|
||||
protected final RouterContext _context;
|
||||
protected final Log _log;
|
||||
|
||||
|
@ -9,7 +9,7 @@ import net.i2p.router.RouterContext;
|
||||
*
|
||||
* @deprecated unused
|
||||
*/
|
||||
public class TrivialRouterPreprocessor extends TrivialPreprocessor {
|
||||
class TrivialRouterPreprocessor extends TrivialPreprocessor {
|
||||
|
||||
public TrivialRouterPreprocessor(RouterContext ctx) {
|
||||
super(ctx);
|
||||
|
@ -43,6 +43,8 @@ public class TunnelDispatcher implements Service {
|
||||
/** what is the date/time we last deliberately dropped a tunnel? **/
|
||||
private long _lastDropTime;
|
||||
private final TunnelGatewayPumper _pumper;
|
||||
|
||||
private static final long[] RATES = { 10*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000 };
|
||||
|
||||
/** Creates a new instance of TunnelDispatcher */
|
||||
public TunnelDispatcher(RouterContext ctx) {
|
||||
@ -148,6 +150,22 @@ public class TunnelDispatcher implements Service {
|
||||
ctx.statManager().createRateStat("tunnel.inboundLookupSuccess", "Was a deferred lookup successful?", "Tunnels", new long[] { 60*60*1000 });
|
||||
// following is for TunnelParticipant
|
||||
ctx.statManager().createRateStat("tunnel.participantLookupSuccess", "Was a deferred lookup successful?", "Tunnels", new long[] { 60*60*1000 });
|
||||
// following is for BuildMessageProcessor
|
||||
ctx.statManager().createRateStat("tunnel.buildRequestDup", "How frequently we get dup build request messages", "Tunnels", new long[] { 60*60*1000 });
|
||||
// following are for FragmentHandler
|
||||
ctx.statManager().createRateStat("tunnel.smallFragments", "How many pad bytes are in small fragments?",
|
||||
"Tunnels", RATES);
|
||||
ctx.statManager().createRateStat("tunnel.fullFragments", "How many tunnel messages use the full data area?",
|
||||
"Tunnels", RATES);
|
||||
ctx.statManager().createRateStat("tunnel.fragmentedComplete", "How many fragments were in a completely received message?",
|
||||
"Tunnels", RATES);
|
||||
ctx.statManager().createRequiredRateStat("tunnel.fragmentedDropped", "Number of dropped fragments",
|
||||
"Tunnels", RATES);
|
||||
ctx.statManager().createRequiredRateStat("tunnel.corruptMessage", "Corrupt messages received",
|
||||
"Tunnels", RATES);
|
||||
// following are for InboundMessageDistributor
|
||||
ctx.statManager().createRateStat("tunnel.dropDangerousClientTunnelMessage", "How many tunnel messages come down a client tunnel that we shouldn't expect (lifetime is the 'I2NP type')", "Tunnels", new long[] { 60*60*1000 });
|
||||
ctx.statManager().createRateStat("tunnel.handleLoadClove", "When do we receive load test cloves", "Tunnels", new long[] { 60*60*1000 });
|
||||
}
|
||||
|
||||
/** for IBGW */
|
||||
|
@ -33,16 +33,16 @@ import net.i2p.util.SimpleTimer;
|
||||
* </ol>
|
||||
*
|
||||
*/
|
||||
public class TunnelGateway {
|
||||
protected RouterContext _context;
|
||||
protected Log _log;
|
||||
class TunnelGateway {
|
||||
protected final RouterContext _context;
|
||||
protected final Log _log;
|
||||
protected final List<Pending> _queue;
|
||||
protected QueuePreprocessor _preprocessor;
|
||||
protected Sender _sender;
|
||||
protected Receiver _receiver;
|
||||
protected final QueuePreprocessor _preprocessor;
|
||||
protected final Sender _sender;
|
||||
protected final Receiver _receiver;
|
||||
protected long _lastFlush;
|
||||
protected int _flushFrequency;
|
||||
protected DelayedFlush _delayedFlush;// FIXME Exporting non-public type through public API FIXME
|
||||
//protected int _flushFrequency;
|
||||
protected final DelayedFlush _delayedFlush;// FIXME Exporting non-public type through public API FIXME
|
||||
protected int _messagesSent;
|
||||
|
||||
/**
|
||||
@ -60,7 +60,7 @@ public class TunnelGateway {
|
||||
_preprocessor = preprocessor;
|
||||
_sender = sender;
|
||||
_receiver = receiver;
|
||||
_flushFrequency = 500;
|
||||
//_flushFrequency = 500;
|
||||
_delayedFlush = new DelayedFlush();
|
||||
_lastFlush = _context.clock().now();
|
||||
_context.statManager().createRateStat("tunnel.lockedGatewayAdd", "How long do we block when adding a message to a tunnel gateway's queue", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
@ -183,14 +183,14 @@ public class TunnelGateway {
|
||||
* Stores all the state for an unsent or partially-sent message
|
||||
*/
|
||||
public static class Pending {
|
||||
protected Hash _toRouter;
|
||||
protected TunnelId _toTunnel;
|
||||
protected long _messageId;
|
||||
protected long _expiration;
|
||||
protected byte _remaining[];
|
||||
protected final Hash _toRouter;
|
||||
protected final TunnelId _toTunnel;
|
||||
protected final long _messageId;
|
||||
protected final long _expiration;
|
||||
protected final byte _remaining[];
|
||||
protected int _offset;
|
||||
protected int _fragmentNumber;
|
||||
protected long _created;
|
||||
protected final long _created;
|
||||
private List<Long> _messageIds;
|
||||
|
||||
public Pending(I2NPMessage message, Hash toRouter, TunnelId toTunnel) {
|
||||
|
@ -12,8 +12,8 @@ import net.i2p.util.I2PThread;
|
||||
* run through the tunnel gateways that have had messages added to them and push
|
||||
* those messages through the preprocessing and sending process
|
||||
*/
|
||||
public class TunnelGatewayPumper implements Runnable {
|
||||
private RouterContext _context;
|
||||
class TunnelGatewayPumper implements Runnable {
|
||||
private final RouterContext _context;
|
||||
private final BlockingQueue<PumpedTunnelGateway> _wantsPumping;
|
||||
private boolean _stop;
|
||||
private static final int MIN_PUMPERS = 1;
|
||||
@ -24,7 +24,6 @@ public class TunnelGatewayPumper implements Runnable {
|
||||
public TunnelGatewayPumper(RouterContext ctx) {
|
||||
_context = ctx;
|
||||
_wantsPumping = new LinkedBlockingQueue();
|
||||
_stop = false;
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
|
@ -8,11 +8,11 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Serve as the gatekeeper for a tunnel with no hops.
|
||||
* Serve as the gatekeeper for a tunnel with no hops, either inbound or outbound.
|
||||
*
|
||||
*/
|
||||
public class TunnelGatewayZeroHop extends TunnelGateway {
|
||||
private TunnelCreatorConfig _config;
|
||||
class TunnelGatewayZeroHop extends TunnelGateway {
|
||||
private final TunnelCreatorConfig _config;
|
||||
private OutboundMessageDistributor _outDistributor;
|
||||
private InboundMessageDistributor _inDistributor;
|
||||
|
||||
|
@ -17,7 +17,7 @@ import net.i2p.util.Log;
|
||||
* InboundMessageDistributor to receive defragmented and decrypted messages,
|
||||
* which it will then selectively forward.
|
||||
*/
|
||||
public class TunnelParticipant {
|
||||
class TunnelParticipant {
|
||||
private final RouterContext _context;
|
||||
private final Log _log;
|
||||
private final HopConfig _config;
|
||||
|
@ -75,7 +75,8 @@ class BuildHandler {
|
||||
|
||||
_context.statManager().createRequiredRateStat("tunnel.rejectOverloaded", "Delay to process rejected request (ms)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRequiredRateStat("tunnel.acceptLoad", "Delay to process accepted request (ms)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("tunnel.dropConnLimits", "Drop instead of reject due to conn limits", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRateStat("tunnel.dropConnLimits", "Drop instead of reject due to conn limits", "Tunnels", new long[] { 10*60*1000 });
|
||||
_context.statManager().createRateStat("tunnel.rejectConnLimits", "Reject due to conn limits", "Tunnels", new long[] { 10*60*1000 });
|
||||
_context.statManager().createRequiredRateStat("tunnel.dropLoad", "Delay before dropping request (ms)?", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRequiredRateStat("tunnel.dropLoadDelay", "Delay before abandoning request (ms)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
_context.statManager().createRequiredRateStat("tunnel.dropLoadBacklog", "Pending request count when dropped", "Tunnels", new long[] { 60*1000, 10*60*1000 });
|
||||
@ -507,6 +508,7 @@ class BuildHandler {
|
||||
if (bw != 'O' && bw != 'N' &&
|
||||
((isInGW && ! _context.commSystem().haveInboundCapacity(87)) ||
|
||||
(isOutEnd && ! _context.commSystem().haveOutboundCapacity(87)))) {
|
||||
_context.statManager().addRateData("tunnel.rejectConnLimits", 1);
|
||||
_context.throttle().setTunnelStatus(_x("Rejecting tunnels: Connection limit"));
|
||||
response = TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
|
||||
}
|
||||
|
@ -79,9 +79,11 @@ class TestJob extends JobImpl {
|
||||
_outTunnel = null;
|
||||
if (_cfg.isInbound()) {
|
||||
_replyTunnel = _cfg;
|
||||
// TODO if testing is re-enabled, pick closest to far end
|
||||
_outTunnel = getContext().tunnelManager().selectOutboundTunnel();
|
||||
_otherTunnel = (PooledTunnelCreatorConfig) _outTunnel;
|
||||
} else {
|
||||
// TODO if testing is re-enabled, pick closest to far end
|
||||
_replyTunnel = getContext().tunnelManager().selectInboundTunnel();
|
||||
_outTunnel = _cfg;
|
||||
_otherTunnel = (PooledTunnelCreatorConfig) _replyTunnel;
|
||||
@ -117,7 +119,7 @@ class TestJob extends JobImpl {
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
|
||||
|
||||
PayloadGarlicConfig payload = new PayloadGarlicConfig();
|
||||
payload.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
|
||||
payload.setCertificate(Certificate.NULL_CERT);
|
||||
payload.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
||||
payload.setPayload(m);
|
||||
payload.setRecipient(getContext().router().getRouterInfo());
|
||||
|
@ -47,10 +47,11 @@ public abstract class TunnelPeerSelector {
|
||||
*/
|
||||
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
|
||||
int length = settings.getLength();
|
||||
int override = settings.getLengthOverride();
|
||||
if (override != 0)
|
||||
length = override;
|
||||
else if (settings.getLengthVariance() != 0) {
|
||||
//int override = settings.getLengthOverride();
|
||||
//if (override != 0)
|
||||
// length = override;
|
||||
//else if (settings.getLengthVariance() != 0) {
|
||||
if (settings.getLengthVariance() != 0) {
|
||||
int skew = settings.getLengthVariance();
|
||||
if (skew > 0)
|
||||
length += ctx.random().nextInt(skew+1);
|
||||
|
@ -50,7 +50,7 @@ public class TunnelPool {
|
||||
_log = ctx.logManager().getLog(TunnelPool.class);
|
||||
_manager = mgr;
|
||||
_settings = settings;
|
||||
_tunnels = new ArrayList(settings.getLength() + settings.getBackupQuantity());
|
||||
_tunnels = new ArrayList(settings.getTotalQuantity());
|
||||
_peerSelector = sel;
|
||||
_expireSkew = _context.random().nextInt(90*1000);
|
||||
_started = System.currentTimeMillis();
|
||||
@ -292,7 +292,7 @@ public class TunnelPool {
|
||||
* Used to prevent a zillion of them
|
||||
*/
|
||||
boolean needFallback() {
|
||||
int needed = _settings.getBackupQuantity() + _settings.getQuantity();
|
||||
int needed = _settings.getTotalQuantity();
|
||||
int fallbacks = 0;
|
||||
synchronized (_tunnels) {
|
||||
for (int i = 0; i < _tunnels.size(); i++) {
|
||||
@ -495,7 +495,7 @@ public class TunnelPool {
|
||||
*
|
||||
*/
|
||||
boolean buildFallback() {
|
||||
int quantity = _settings.getBackupQuantity() + _settings.getQuantity();
|
||||
int quantity = _settings.getTotalQuantity();
|
||||
int usable = 0;
|
||||
synchronized (_tunnels) {
|
||||
usable = _tunnels.size();
|
||||
@ -678,7 +678,7 @@ public class TunnelPool {
|
||||
if (!isAlive()) {
|
||||
return 0;
|
||||
}
|
||||
int wanted = getSettings().getBackupQuantity() + getSettings().getQuantity();
|
||||
int wanted = getSettings().getTotalQuantity();
|
||||
|
||||
boolean allowZeroHop = ((getSettings().getLength() + getSettings().getLengthVariance()) <= 0);
|
||||
|
||||
|
Reference in New Issue
Block a user