forked from I2P_Developers/i2p.i2p
* RequestLeaseSetJob: Only disconnect client after multiple dropped
lease set requests; reduce timeout, other cleanups
This commit is contained in:
18
history.txt
18
history.txt
@@ -1,6 +1,20 @@
|
||||
2012-11-05 zzz
|
||||
* Console:
|
||||
- Fix NPE after restart (ticket #763)
|
||||
- Move more nonces out of system properties
|
||||
* i2psnark:
|
||||
- More DHT limits
|
||||
- Announce to backup trackers if DHT is empty
|
||||
- Use PEX and DHT info in torrent peer count
|
||||
- Don't use temp files for announces
|
||||
* PeerManager: Don't reorganize as often if it takes too long (ticket #765)
|
||||
* RequestLeaseSetJob: Only disconnect client after multiple dropped
|
||||
lease set requests; reduce timeout, other cleanups
|
||||
* Unsigned Update: Fix notification on failure
|
||||
|
||||
2012-11-02 kytv
|
||||
* German, Portuguese, and Swedish translation updates from Transifex
|
||||
* Refreshed English po files to push to TX.
|
||||
* German, Portuguese, and Swedish translation updates from Transifex
|
||||
* Refreshed English po files to push to TX.
|
||||
|
||||
2012-11-02 zzz
|
||||
* configstats: Fix group sorting, translate groups
|
||||
|
||||
@@ -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 = 4;
|
||||
public final static long BUILD = 5;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -71,6 +71,7 @@ class ClientConnectionRunner {
|
||||
private final Map<MessageId, Payload> _messages;
|
||||
/** lease set request state, or null if there is no request pending on at the moment */
|
||||
private LeaseRequestState _leaseRequest;
|
||||
private int _consecutiveLeaseRequestFails;
|
||||
/** currently allocated leaseSet, or null if none is allocated */
|
||||
private LeaseSet _currentLeaseSet;
|
||||
/** set of messageIds created but not yet ACCEPTED */
|
||||
@@ -100,6 +101,7 @@ class ClientConnectionRunner {
|
||||
// e.g. on local access
|
||||
private static final int MAX_MESSAGE_ID = 0x4000000;
|
||||
|
||||
private static final int MAX_LEASE_FAILS = 5;
|
||||
private static final int BUF_SIZE = 32*1024;
|
||||
|
||||
/** @since 0.9.2 */
|
||||
@@ -191,12 +193,17 @@ class ClientConnectionRunner {
|
||||
/** data for the current leaseRequest, or null if there is no active leaseSet request */
|
||||
LeaseRequestState getLeaseRequest() { return _leaseRequest; }
|
||||
|
||||
void setLeaseRequest(LeaseRequestState req) {
|
||||
/** @param req non-null */
|
||||
public void failLeaseRequest(LeaseRequestState req) {
|
||||
boolean disconnect = false;
|
||||
synchronized (this) {
|
||||
if ( (_leaseRequest != null) && (req != _leaseRequest) )
|
||||
_log.error("Changing leaseRequest from " + _leaseRequest + " to " + req);
|
||||
_leaseRequest = req;
|
||||
if (_leaseRequest == req) {
|
||||
_leaseRequest = null;
|
||||
disconnect = ++_consecutiveLeaseRequestFails > MAX_LEASE_FAILS;
|
||||
}
|
||||
}
|
||||
if (disconnect)
|
||||
disconnectClient("Too many leaseset request fails");
|
||||
}
|
||||
|
||||
/** already closed? */
|
||||
@@ -287,6 +294,7 @@ class ClientConnectionRunner {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("LeaseSet created fully: " + state + " / " + ls);
|
||||
_leaseRequest = null;
|
||||
_consecutiveLeaseRequestFails = 0;
|
||||
}
|
||||
}
|
||||
if ( (state != null) && (state.getOnGranted() != null) )
|
||||
@@ -351,9 +359,8 @@ class ClientConnectionRunner {
|
||||
_acceptedPending.add(id);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("** Receiving message [" + id.getMessageId() + "] with payload of size ["
|
||||
+ payload.getSize() + "]" + " for session [" + _sessionId.getSessionId()
|
||||
+ "]");
|
||||
_log.debug("** Receiving message " + id.getMessageId() + " with payload of size "
|
||||
+ payload.getSize() + " for session " + _sessionId.getSessionId());
|
||||
//long beforeDistribute = _context.clock().now();
|
||||
// the following blocks as described above
|
||||
SessionConfig cfg = _config;
|
||||
@@ -380,7 +387,7 @@ class ClientConnectionRunner {
|
||||
if (sid == null) return;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Acking message send [accepted]" + id + " / " + nonce + " for sessionId "
|
||||
+ sid, new Exception("sendAccepted"));
|
||||
+ sid);
|
||||
MessageStatusMessage status = new MessageStatusMessage();
|
||||
status.setMessageId(id.getMessageId());
|
||||
status.setSessionId(sid.getSessionId());
|
||||
@@ -486,10 +493,11 @@ class ClientConnectionRunner {
|
||||
return; // already requesting
|
||||
} else {
|
||||
_leaseRequest = state = new LeaseRequestState(onCreateJob, onFailedJob, _context.clock().now() + expirationTime, set);
|
||||
_log.debug("Not already requesting, continue to request " + set);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("New request: " + state);
|
||||
}
|
||||
}
|
||||
_context.jobQueue().addJob(new RequestLeaseSetJob(_context, this, set, _context.clock().now() + expirationTime, onCreateJob, onFailedJob, state));
|
||||
_context.jobQueue().addJob(new RequestLeaseSetJob(_context, this, state));
|
||||
}
|
||||
|
||||
private class Rerequest implements SimpleTimer.TimedEvent {
|
||||
@@ -646,8 +654,8 @@ class ClientConnectionRunner {
|
||||
if (!alreadyAccepted(_messageId)) {
|
||||
_log.warn("Almost send an update for message " + _messageId + " to "
|
||||
+ MessageStatusMessage.getStatusString(msg.getStatus())
|
||||
+ " for session [" + _sessionId.getSessionId()
|
||||
+ "] before they knew the messageId! delaying .5s");
|
||||
+ " for session " + _sessionId.getSessionId()
|
||||
+ " before they knew the messageId! delaying .5s");
|
||||
_lastTried = _context.clock().now();
|
||||
requeue(REQUEUE_DELAY);
|
||||
return;
|
||||
@@ -680,15 +688,14 @@ class ClientConnectionRunner {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.info("Updating message status for message " + _messageId + " to "
|
||||
+ MessageStatusMessage.getStatusString(msg.getStatus())
|
||||
+ " for session [" + _sessionId.getSessionId()
|
||||
+ "] (with nonce=2), retrying after ["
|
||||
+ (_context.clock().now() - _lastTried)
|
||||
+ "]");
|
||||
+ " for session " + _sessionId.getSessionId()
|
||||
+ " (with nonce=2), retrying after "
|
||||
+ (_context.clock().now() - _lastTried));
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Updating message status for message " + _messageId + " to "
|
||||
+ MessageStatusMessage.getStatusString(msg.getStatus())
|
||||
+ " for session [" + _sessionId.getSessionId() + "] (with nonce=2)");
|
||||
+ " for session " + _sessionId.getSessionId() + " (with nonce=2)");
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -62,6 +62,8 @@ class ClientManager {
|
||||
|
||||
private static final int INTERNAL_QUEUE_SIZE = 256;
|
||||
|
||||
private static final long REQUEST_LEASESET_TIMEOUT = 60*1000;
|
||||
|
||||
public ClientManager(RouterContext context, int port) {
|
||||
_ctx = context;
|
||||
_log = context.logManager().getLog(ClientManager.class);
|
||||
@@ -275,6 +277,8 @@ class ClientManager {
|
||||
* within the timeout specified, queue up the onFailedJob. This call does not
|
||||
* block.
|
||||
*
|
||||
* UNUSED, the call below without jobs is always used.
|
||||
*
|
||||
* @param dest Destination from which the LeaseSet's authorization should be requested
|
||||
* @param set LeaseSet with requested leases - this object must be updated to contain the
|
||||
* signed version (as well as any changed/added/removed Leases)
|
||||
@@ -290,12 +294,10 @@ class ClientManager {
|
||||
+ dest.calculateHash().toBase64() + ". disconnected?");
|
||||
_ctx.jobQueue().addJob(onFailedJob);
|
||||
} else {
|
||||
runner.requestLeaseSet(set, _ctx.clock().now() + timeout, onCreateJob, onFailedJob);
|
||||
runner.requestLeaseSet(set, timeout, onCreateJob, onFailedJob);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int REQUEST_LEASESET_TIMEOUT = 120*1000;
|
||||
|
||||
public void requestLeaseSet(Hash dest, LeaseSet ls) {
|
||||
ClientConnectionRunner runner = getRunner(dest);
|
||||
if (runner != null) {
|
||||
|
||||
@@ -110,6 +110,8 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte
|
||||
* within the timeout specified, queue up the onFailedJob. This call does not
|
||||
* block.
|
||||
*
|
||||
* UNUSED, the call below without jobs is always used.
|
||||
*
|
||||
* @param dest Destination from which the LeaseSet's authorization should be requested
|
||||
* @param set LeaseSet with requested leases - this object must be updated to contain the
|
||||
* signed version (as well as any changed/added/removed Leases)
|
||||
|
||||
@@ -28,6 +28,9 @@ class LeaseRequestState {
|
||||
private final long _expiration;
|
||||
private boolean _successful;
|
||||
|
||||
/**
|
||||
* @param expiration absolute time
|
||||
*/
|
||||
public LeaseRequestState(Job onGranted, Job onFailed, long expiration, LeaseSet requested) {
|
||||
_onGranted = onGranted;
|
||||
_onFailed = onFailed;
|
||||
|
||||
@@ -31,7 +31,7 @@ class RequestLeaseSetJob extends JobImpl {
|
||||
private final ClientConnectionRunner _runner;
|
||||
private final LeaseRequestState _requestState;
|
||||
|
||||
public RequestLeaseSetJob(RouterContext ctx, ClientConnectionRunner runner, LeaseSet set, long expiration, Job onCreate, Job onFail, LeaseRequestState state) {
|
||||
public RequestLeaseSetJob(RouterContext ctx, ClientConnectionRunner runner, LeaseRequestState state) {
|
||||
super(ctx);
|
||||
_log = ctx.logManager().getLog(RequestLeaseSetJob.class);
|
||||
_runner = runner;
|
||||
@@ -42,6 +42,7 @@ class RequestLeaseSetJob extends JobImpl {
|
||||
}
|
||||
|
||||
public String getName() { return "Request Lease Set"; }
|
||||
|
||||
public void runJob() {
|
||||
if (_runner.isDead()) return;
|
||||
|
||||
@@ -59,21 +60,23 @@ class RequestLeaseSetJob extends JobImpl {
|
||||
msg.setSessionId(_runner.getSessionId());
|
||||
|
||||
for (int i = 0; i < _requestState.getRequested().getLeaseCount(); i++) {
|
||||
msg.addEndpoint(_requestState.getRequested().getLease(i).getGateway(), _requestState.getRequested().getLease(i).getTunnelId());
|
||||
msg.addEndpoint(_requestState.getRequested().getLease(i).getGateway(),
|
||||
_requestState.getRequested().getLease(i).getTunnelId());
|
||||
}
|
||||
|
||||
try {
|
||||
//_runner.setLeaseRequest(state);
|
||||
_runner.doSend(msg);
|
||||
getContext().jobQueue().addJob(new CheckLeaseRequestStatus(getContext(), _requestState));
|
||||
return;
|
||||
getContext().jobQueue().addJob(new CheckLeaseRequestStatus());
|
||||
} catch (I2CPMessageException ime) {
|
||||
getContext().statManager().addRateData("client.requestLeaseSetDropped", 1, 0);
|
||||
_log.error("Error sending I2CP message requesting the lease set", ime);
|
||||
_requestState.setIsSuccessful(false);
|
||||
_runner.setLeaseRequest(null);
|
||||
_runner.disconnectClient("I2CP error requesting leaseSet");
|
||||
return;
|
||||
if (_requestState.getOnFailed() != null)
|
||||
RequestLeaseSetJob.this.getContext().jobQueue().addJob(_requestState.getOnFailed());
|
||||
_runner.failLeaseRequest(_requestState);
|
||||
// Don't disconnect, the tunnel will retry
|
||||
//_runner.disconnectClient("I2CP error requesting leaseSet");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,14 +87,12 @@ class RequestLeaseSetJob extends JobImpl {
|
||||
*
|
||||
*/
|
||||
private class CheckLeaseRequestStatus extends JobImpl {
|
||||
private final LeaseRequestState _req;
|
||||
private final long _start;
|
||||
|
||||
public CheckLeaseRequestStatus(RouterContext enclosingContext, LeaseRequestState state) {
|
||||
super(enclosingContext);
|
||||
_req = state;
|
||||
public CheckLeaseRequestStatus() {
|
||||
super(RequestLeaseSetJob.this.getContext());
|
||||
_start = System.currentTimeMillis();
|
||||
getTiming().setStartAfter(state.getExpiration());
|
||||
getTiming().setStartAfter(_requestState.getExpiration());
|
||||
}
|
||||
|
||||
public void runJob() {
|
||||
@@ -100,20 +101,22 @@ class RequestLeaseSetJob extends JobImpl {
|
||||
_log.debug("Already dead, dont try to expire the leaseSet lookup");
|
||||
return;
|
||||
}
|
||||
if (_req.getIsSuccessful()) {
|
||||
if (_requestState.getIsSuccessful()) {
|
||||
// we didn't fail
|
||||
RequestLeaseSetJob.CheckLeaseRequestStatus.this.getContext().statManager().addRateData("client.requestLeaseSetSuccess", 1, 0);
|
||||
CheckLeaseRequestStatus.this.getContext().statManager().addRateData("client.requestLeaseSetSuccess", 1);
|
||||
return;
|
||||
} else {
|
||||
RequestLeaseSetJob.CheckLeaseRequestStatus.this.getContext().statManager().addRateData("client.requestLeaseSetTimeout", 1, 0);
|
||||
CheckLeaseRequestStatus.this.getContext().statManager().addRateData("client.requestLeaseSetTimeout", 1);
|
||||
if (_log.shouldLog(Log.ERROR)) {
|
||||
long waited = System.currentTimeMillis() - _start;
|
||||
_log.error("Failed to receive a leaseSet in the time allotted (" + waited + "): " + _req + " for "
|
||||
_log.error("Failed to receive a leaseSet in the time allotted (" + waited + "): " + _requestState + " for "
|
||||
+ _runner.getConfig().getDestination().calculateHash().toBase64());
|
||||
}
|
||||
_runner.disconnectClient("Took too long to request leaseSet");
|
||||
if (_req.getOnFailed() != null)
|
||||
RequestLeaseSetJob.this.getContext().jobQueue().addJob(_req.getOnFailed());
|
||||
if (_requestState.getOnFailed() != null)
|
||||
RequestLeaseSetJob.this.getContext().jobQueue().addJob(_requestState.getOnFailed());
|
||||
_runner.failLeaseRequest(_requestState);
|
||||
// Don't disconnect, the tunnel will retry
|
||||
//_runner.disconnectClient("Took too long to request leaseSet");
|
||||
}
|
||||
}
|
||||
public String getName() { return "Check LeaseRequest Status"; }
|
||||
|
||||
Reference in New Issue
Block a user