diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketQueue.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketQueue.java index 7e9365436..214e1c2cd 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketQueue.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/PacketQueue.java @@ -281,27 +281,36 @@ class PacketQueue implements SendMessageStatusListener { case MessageStatusMessage.STATUS_SEND_FAILURE_EXPIRED_LEASESET: case MessageStatusMessage.STATUS_SEND_FAILURE_NO_LEASESET: case SendMessageStatusListener.STATUS_CANCELLED: - if (_log.shouldLog(Log.WARN)) - _log.warn("Rcvd hard failure status " + status + " for msg " + msgId + " on " + con); - _messageStatusMap.remove(id); - IOException ioe = new I2PSocketException(status); - con.getOutputStream().streamErrorOccurred(ioe); - con.getInputStream().streamErrorOccurred(ioe); - con.setConnectionError("failure code " + status); - con.disconnect(false); + if (con.getHighestAckedThrough() >= 0) { + // a retxed SYN succeeded before the first SYN failed + if (_log.shouldLog(Log.WARN)) + _log.warn("Rcvd hard failure but already connected, status " + status + " for msg " + msgId + " on " + con); + } else if (!con.getIsConnected()) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Rcvd hard failure but already closed, status " + status + " for msg " + msgId + " on " + con); + } else { + if (_log.shouldLog(Log.WARN)) + _log.warn("Rcvd hard failure status " + status + " for msg " + msgId + " on " + con); + _messageStatusMap.remove(id); + IOException ioe = new I2PSocketException(status); + con.getOutputStream().streamErrorOccurred(ioe); + con.getInputStream().streamErrorOccurred(ioe); + con.setConnectionError("failure code " + status); + con.disconnect(false); + } break; case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS: case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS: case MessageStatusMessage.STATUS_SEND_SUCCESS_LOCAL: - if (_log.shouldLog(Log.WARN)) - _log.warn("Rcvd success status " + status + " for msg " + msgId + " on " + con); + if (_log.shouldLog(Log.INFO)) + _log.info("Rcvd success status " + status + " for msg " + msgId + " on " + con); _messageStatusMap.remove(id); break; case MessageStatusMessage.STATUS_SEND_ACCEPTED: - if (_log.shouldLog(Log.WARN)) - _log.warn("Rcvd accept status " + status + " for msg " + msgId + " on " + con); + if (_log.shouldLog(Log.INFO)) + _log.info("Rcvd accept status " + status + " for msg " + msgId + " on " + con); break; default: diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/TCBShare.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/TCBShare.java index 393d3daf0..ae9e06196 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/TCBShare.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/TCBShare.java @@ -29,8 +29,8 @@ class TCBShare { private final CleanEvent _cleaner; private final double _rttDampening, _wdwDampening, _rttDevDampening; - private static final long EXPIRE_TIME = 30*60*1000; - private static final long CLEAN_TIME = 10*60*1000; + private static final long EXPIRE_TIME = 15*60*1000; + private static final long CLEAN_TIME = 5*60*1000; ///// constants defined in rfc 2140 ///// do not change unless you know what you're doing private static final double RTT_DAMPENING = 0.75; diff --git a/history.txt b/history.txt index d9a051c3f..5b6dbb5a4 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,14 @@ +2014-06-07 zzz + * Console: Fix NPE in summary bar + * Eepsite: Updated French help page (thx hummingbird) + * i2psnark: Fix errors when checking read-only files + * NetDB: Reduce negative lookup cache time + * OCMOSJ: + - Increase timeout if we must lookup leaseset + * Streaming: + - Shorter expire time in TCBCache + - Don't fail a connection once it is up + 2014-06-01 zzz * i2psnark: - Store seed/leech status in DHT tracker (ticket #1280) diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 0725033fa..f6e6df3a5 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -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 = 3; + public final static long BUILD = 4; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java index 9bb7432a6..a550a492c 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java @@ -80,6 +80,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl { public final static String OVERALL_TIMEOUT_MS_PARAM = "clientMessageTimeout"; private final static long OVERALL_TIMEOUT_MS_DEFAULT = 60*1000; private final static long OVERALL_TIMEOUT_MS_MIN = 8*1000; + private final static long OVERALL_TIMEOUT_MS_MAX = 90*1000; + private final static long LS_LOOKUP_TIMEOUT = 15*1000; + private final static long OVERALL_TIMEOUT_NOLS_MIN = OVERALL_TIMEOUT_MS_MIN + LS_LOOKUP_TIMEOUT; private final static long REPLY_TIMEOUT_MS_MIN = OVERALL_TIMEOUT_MS_DEFAULT - 5*1000; /** @@ -123,6 +126,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl { */ public OutboundClientMessageOneShotJob(RouterContext ctx, OutboundCache cache, ClientMessage msg) { super(ctx); + _start = ctx.clock().now(); _cache = cache; _log = ctx.logManager().getLog(OutboundClientMessageOneShotJob.class); @@ -132,9 +136,11 @@ public class OutboundClientMessageOneShotJob extends JobImpl { _clientMessageSize = msg.getPayload().getSize(); _from = msg.getFromDestination(); _to = msg.getDestination(); - _hashPair = new OutboundCache.HashPair(_from.calculateHash(), _to.calculateHash()); - _toString = _to.calculateHash().toBase64().substring(0,4); - _start = getContext().clock().now(); + Hash toHash = _to.calculateHash(); + _hashPair = new OutboundCache.HashPair(_from.calculateHash(), toHash); + _toString = toHash.toBase64().substring(0,4); + // we look up here rather than runJob() so we may adjust the timeout + _leaseSet = ctx.netDb().lookupLeaseSetLocally(toHash); // use expiration requested by client if available, otherwise session config, // otherwise router config, otherwise default @@ -147,8 +153,10 @@ public class OutboundClientMessageOneShotJob extends JobImpl { } // Unless it's already expired, set a min and max expiration if (overallExpiration > _start) { - overallExpiration = Math.max(overallExpiration, _start + OVERALL_TIMEOUT_MS_MIN); - overallExpiration = Math.min(overallExpiration, _start + OVERALL_TIMEOUT_MS_DEFAULT); + // extend the minimum timeout if we must lookup LS + long minTimeout = _leaseSet != null ? OVERALL_TIMEOUT_MS_MIN : OVERALL_TIMEOUT_NOLS_MIN; + overallExpiration = Math.max(overallExpiration, _start + minTimeout); + overallExpiration = Math.min(overallExpiration, _start + OVERALL_TIMEOUT_MS_MAX); if (_log.shouldLog(Log.INFO)) _log.info(getJobId() + ": Message Expiration (ms): " + (overallExpiration - _start)); } else { @@ -157,6 +165,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl { // runJob() will call dieFatal() } } else { + // undocumented until 0.9.14, unused String param = msg.getSenderConfig().getOptions().getProperty(OVERALL_TIMEOUT_MS_PARAM); if (param == null) param = ctx.router().getConfigSetting(OVERALL_TIMEOUT_MS_PARAM); @@ -185,7 +194,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl { ctx.statManager().createRateStat("client.timeoutCongestionTunnel", "How lagged our tunnels are when a send times out?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.timeoutCongestionMessage", "How fast we process messages locally when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.timeoutCongestionInbound", "How much faster we are receiving data than our average bps when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); - ctx.statManager().createRateStat("client.leaseSetFoundLocally", "How often we tried to look for a leaseSet and found it locally?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); + //ctx.statManager().createRateStat("client.leaseSetFoundLocally", "How often we tried to look for a leaseSet and found it locally?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.leaseSetFoundRemoteTime", "How long we tried to look for a remote leaseSet (when we succeeded)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.leaseSetFailedRemoteTime", "How long we tried to look for a remote leaseSet (when we failed)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.dispatchPrepareTime", "How long until we've queued up the dispatch job (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); @@ -208,12 +217,11 @@ public class OutboundClientMessageOneShotJob extends JobImpl { //if (_log.shouldLog(Log.DEBUG)) // _log.debug(getJobId() + ": Send outbound client message job beginning" + // ": preparing to search for the leaseSet for " + _toString); - long timeoutMs = _overallExpiration - now; - Hash key = _to.calculateHash(); SendJob success = new SendJob(getContext()); - _leaseSet = getContext().netDb().lookupLeaseSetLocally(key); + // set in constructor + //_leaseSet = getContext().netDb().lookupLeaseSetLocally(key); if (_leaseSet != null) { - getContext().statManager().addRateData("client.leaseSetFoundLocally", 1); + //getContext().statManager().addRateData("client.leaseSetFoundLocally", 1); if (_log.shouldLog(Log.DEBUG)) _log.debug(getJobId() + ": Send outbound client message - leaseSet found locally for " + _toString); success.runJob(); @@ -222,7 +230,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl { if (_log.shouldLog(Log.DEBUG)) _log.debug(getJobId() + ": Send outbound client message - sending off leaseSet lookup job for " + _toString); LookupLeaseSetFailedJob failed = new LookupLeaseSetFailedJob(getContext()); - getContext().netDb().lookupLeaseSet(key, success, failed, timeoutMs, _from.calculateHash()); + Hash key = _to.calculateHash(); + getContext().netDb().lookupLeaseSet(key, success, failed, LS_LOOKUP_TIMEOUT, _from.calculateHash()); } } @@ -413,7 +422,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl { public void runJob() { if (_leaseSetLookupBegin > 0) { long lookupTime = getContext().clock().now() - _leaseSetLookupBegin; - getContext().statManager().addRateData("client.leaseSetFailedRemoteTime", lookupTime, lookupTime); + getContext().statManager().addRateData("client.leaseSetFailedRemoteTime", lookupTime); } //if (_finished == Result.NONE) { @@ -514,11 +523,10 @@ public class OutboundClientMessageOneShotJob extends JobImpl { SessionKey sessKey = new SessionKey(); Set tags = new HashSet(); - long msgExpiration = _overallExpiration; // getContext().clock().now() + OVERALL_TIMEOUT_MS_DEFAULT; // Per-message flag > 0 overrides per-session option int tagsToSend = SendMessageOptions.getTagsToSend(sendFlags); GarlicMessage msg = OutboundClientMessageJobHelper.createGarlicMessage(getContext(), token, - msgExpiration, key, + _overallExpiration, key, clove, _from.calculateHash(), _to, _inTunnel, tagsToSend, tagsRequired, sessKey, tags, diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/NegativeLookupCache.java b/router/java/src/net/i2p/router/networkdb/kademlia/NegativeLookupCache.java index 6612ea9dc..abbb67ed6 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/NegativeLookupCache.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/NegativeLookupCache.java @@ -13,7 +13,7 @@ import net.i2p.util.SimpleTimer; class NegativeLookupCache { private final ObjectCounter counter; private static final int MAX_FAILS = 3; - private static final long CLEAN_TIME = 4*60*1000; + private static final long CLEAN_TIME = 2*60*1000; public NegativeLookupCache() { this.counter = new ObjectCounter();