package net.i2p.router.networkdb.kademlia;
import net.i2p.data.Hash;
import net.i2p.data.i2np.DatabaseLookupMessage;
import net.i2p.router.RouterContext;
import net.i2p.router.OutNetMessage;
import net.i2p.router.TunnelInfo;
import net.i2p.util.Log;
/**
* Ask a single peer for a single key.
* This isn't really a flood-only search job at all, but we extend
* FloodOnlySearchJob so we can use the same selectors, etc.
*
*/
class SingleSearchJob extends FloodOnlySearchJob {
private final Hash _to;
private OutNetMessage _onm;
private static final int TIMEOUT = 8*1000;
/**
* @param key for Router Info ONLY
*/
public SingleSearchJob(RouterContext ctx, Hash key, Hash to) {
// warning, null FloodfillNetworkDatabaseFacade ...
// define our own failed() and success() below so _facade isn't used.
super(ctx, null, key, null, null, TIMEOUT, false);
_to = to;
}
@Override
public String getName() { return "NetDb search key from DSRM"; }
@Override
public boolean shouldProcessDSRM() { return false; } // don't loop
@Override
public void runJob() {
_onm = getContext().messageRegistry().registerPending(_replySelector, _onReply, _onTimeout);
DatabaseLookupMessage dlm = new DatabaseLookupMessage(getContext(), true);
TunnelInfo replyTunnel = getContext().tunnelManager().selectInboundExploratoryTunnel(_to);
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(_to);
if ( (replyTunnel == null) || (outTunnel == null) ) {
failed();
return;
}
dlm.setFrom(replyTunnel.getPeer(0));
dlm.setMessageExpiration(getContext().clock().now()+5*1000);
dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
dlm.setSearchKey(_key);
dlm.setSearchType(DatabaseLookupMessage.Type.RI);
if (_log.shouldLog(Log.INFO))
_log.info(getJobId() + ": Single search for " + _key + " to " + _to);
getContext().tunnelDispatcher().dispatchOutbound(dlm, outTunnel.getSendTunnelId(0), _to);
_lookupsRemaining.set(1);
}
@Override
void failed() {
getContext().messageRegistry().unregisterPending(_onm);
getContext().profileManager().dbLookupFailed(_to);
}
@Override
void success() {
getContext().profileManager().dbLookupSuccessful(_to, System.currentTimeMillis()-_created);
}
}