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); } }