package net.i2p.router.networkdb.kademlia; import net.i2p.data.i2np.DatabaseSearchReplyMessage; import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.MessageSelector; import net.i2p.router.RouterContext; import net.i2p.util.Log; /** * Mostly replaced by IterativeLookupSelector */ class FloodOnlyLookupSelector implements MessageSelector { private final RouterContext _context; private final FloodOnlySearchJob _search; private boolean _matchFound; private final Log _log; public FloodOnlyLookupSelector(RouterContext ctx, FloodOnlySearchJob search) { _context = ctx; _search = search; _log = ctx.logManager().getLog(getClass()); } public boolean continueMatching() { return _search.getLookupsRemaining() > 0 && !_matchFound && _context.clock().now() < getExpiration(); } public long getExpiration() { return (_matchFound ? -1 : _search.getExpiration()); } public boolean isMatch(I2NPMessage message) { if (message == null) return false; if (message instanceof DatabaseStoreMessage) { DatabaseStoreMessage dsm = (DatabaseStoreMessage)message; // is it worth making sure the reply came in on the right tunnel? if (_search.getKey().equals(dsm.getKey())) { _search.decrementRemaining(); _matchFound = true; return true; } } else if (message instanceof DatabaseSearchReplyMessage) { DatabaseSearchReplyMessage dsrm = (DatabaseSearchReplyMessage)message; if (_search.getKey().equals(dsrm.getSearchKey())) { // TODO - dsrm.getFromHash() can't be trusted - check against the list of // those we sent the search to in _search ? // assume 0 new, all old, 0 invalid, 0 dup _context.profileManager().dbLookupReply(dsrm.getFromHash(), 0, dsrm.getNumReplies(), 0, 0, System.currentTimeMillis()-_search.getCreated()); // Moved from FloodOnlyLookupMatchJob so it is called for all replies // rather than just the last one // Got a netDb reply pointing us at other floodfills... // Only process if we don't know enough floodfills or are starting up if (_search.shouldProcessDSRM()) { if (_log.shouldLog(Log.INFO)) _log.info(_search.getJobId() + ": Processing DSRM via SingleLookupJob, apparently from " + dsrm.getFromHash()); // Chase the hashes from the reply _context.jobQueue().addJob(new SingleLookupJob(_context, dsrm)); } else if (_log.shouldLog(Log.INFO)) { int remaining = _search.getLookupsRemaining(); _log.info(_search.getJobId() + ": got a DSRM apparently from " + dsrm.getFromHash() + " when we were looking for " + _search.getKey() + ", with " + remaining + " outstanding searches"); } // if no more left, time to fail int remaining = _search.decrementRemaining(dsrm.getFromHash()); return remaining <= 0; } } return false; } /** @since 0.9.12 */ public String toString() { return "FOL Selector for " + _search.getKey(); } }