try {
Object o = node.makeRequestSender(key.getNodeKey(true), node.maxHTL(), uid, tag, null, localOnly, ignoreStore, false, true, canWriteClientCache, realTimeFlag);
if(o instanceof SSKBlock)
try {
tag.setServedFromDatastore();
SSKBlock block = (SSKBlock) o;
key.setPublicKey(block.getPubKey());
return ClientSSKBlock.construct(block, key);
} catch(SSKVerifyException e) {
Logger.error(this, "Does not verify: " + e, e);
throw new LowLevelGetException(LowLevelGetException.DECODE_FAILED);
}
if(o == null)
throw new LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
rs = (RequestSender) o;
boolean rejectedOverload = false;
short waitStatus = 0;
while(true) {
waitStatus = rs.waitUntilStatusChange(waitStatus);
if((!rejectedOverload) && (waitStatus & RequestSender.WAIT_REJECTED_OVERLOAD) != 0) {
requestStarters.rejectedOverload(true, false, realTimeFlag);
rejectedOverload = true;
}
int status = rs.getStatus();
if(status == RequestSender.NOT_FINISHED)
continue;
if(status != RequestSender.TIMED_OUT && status != RequestSender.GENERATED_REJECTED_OVERLOAD && status != RequestSender.INTERNAL_ERROR) {
if(logMINOR)
Logger.minor(this, "SSK fetch cost " + rs.getTotalSentBytes() + '/' + rs.getTotalReceivedBytes() + " bytes (" + status + ')');
nodeStats.localSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
nodeStats.localSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
if(status == RequestSender.SUCCESS)
// See comments above successfulSskFetchBytesSentAverage : we don't relay the data, so
// reporting the sent bytes would be inaccurate.
//nodeStats.successfulSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
nodeStats.successfulSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
}
long rtt = System.currentTimeMillis() - startTime;
if((status == RequestSender.TIMED_OUT) ||
(status == RequestSender.GENERATED_REJECTED_OVERLOAD)) {
if(!rejectedOverload) {
requestStarters.rejectedOverload(true, false, realTimeFlag);
rejectedOverload = true;
}
node.nodeStats.reportSSKOutcome(rtt, false, realTimeFlag);
} else
if(rs.hasForwarded() &&
((status == RequestSender.DATA_NOT_FOUND) ||
(status == RequestSender.RECENTLY_FAILED) ||
(status == RequestSender.SUCCESS) ||
(status == RequestSender.ROUTE_NOT_FOUND) ||
(status == RequestSender.VERIFY_FAILURE) ||
(status == RequestSender.GET_OFFER_VERIFY_FAILURE))) {
if(!rejectedOverload)
requestStarters.requestCompleted(true, false, key.getNodeKey(true), realTimeFlag);
// Count towards RTT even if got a RejectedOverload - but not if timed out.
requestStarters.getThrottle(true, false, realTimeFlag).successfulCompletion(rtt);
node.nodeStats.reportSSKOutcome(rtt, status == RequestSender.SUCCESS, realTimeFlag);
}
if(rs.getStatus() == RequestSender.SUCCESS)
try {
SSKBlock block = rs.getSSKBlock();
key.setPublicKey(block.getPubKey());
return ClientSSKBlock.construct(block, key);
} catch(SSKVerifyException e) {
Logger.error(this, "Does not verify: " + e, e);
throw new LowLevelGetException(LowLevelGetException.DECODE_FAILED);
}