Search in sources :

Example 1 with DatabaseLookupMessage

use of net.i2p.data.i2np.DatabaseLookupMessage in project i2p.i2p by i2p.

the class FloodfillVerifyStoreJob method buildLookup.

/**
 * @return non-null
 */
private DatabaseLookupMessage buildLookup(TunnelInfo replyTunnelInfo) {
    // If we are verifying a leaseset, use the destination's own tunnels,
    // to avoid association by the exploratory tunnel OBEP.
    // Unless it is an encrypted leaseset.
    DatabaseLookupMessage m = new DatabaseLookupMessage(getContext(), true);
    m.setMessageExpiration(getContext().clock().now() + VERIFY_TIMEOUT);
    m.setReplyTunnel(replyTunnelInfo.getReceiveTunnelId(0));
    m.setFrom(replyTunnelInfo.getPeer(0));
    m.setSearchKey(_key);
    m.setSearchType(_isRouterInfo ? DatabaseLookupMessage.Type.RI : DatabaseLookupMessage.Type.LS);
    return m;
}
Also used : DatabaseLookupMessage(net.i2p.data.i2np.DatabaseLookupMessage)

Example 2 with DatabaseLookupMessage

use of net.i2p.data.i2np.DatabaseLookupMessage in project i2p.i2p by i2p.

the class FloodfillVerifyStoreJob method runJob.

/**
 *  Query a random floodfill for the leaseset or routerinfo
 *  that we just stored to a (hopefully different) floodfill peer.
 *
 *  If it fails (after a timeout period), resend the data.
 *  If the queried data is older than what we stored, that counts as a fail.
 */
public void runJob() {
    _target = pickTarget();
    if (_target == null) {
        _facade.verifyFinished(_key);
        return;
    }
    boolean isInboundExploratory;
    TunnelInfo replyTunnelInfo;
    if (_isRouterInfo || getContext().keyRing().get(_key) != null) {
        replyTunnelInfo = getContext().tunnelManager().selectInboundExploratoryTunnel(_target);
        isInboundExploratory = true;
    } else {
        replyTunnelInfo = getContext().tunnelManager().selectInboundTunnel(_key, _target);
        isInboundExploratory = false;
    }
    if (replyTunnelInfo == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("No inbound tunnels to get a reply from!");
        return;
    }
    DatabaseLookupMessage lookup = buildLookup(replyTunnelInfo);
    // If we are verifying a leaseset, use the destination's own tunnels,
    // to avoid association by the exploratory tunnel OBEP.
    // Unless it is an encrypted leaseset.
    TunnelInfo outTunnel;
    if (_isRouterInfo || getContext().keyRing().get(_key) != null)
        outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(_target);
    else
        outTunnel = getContext().tunnelManager().selectOutboundTunnel(_key, _target);
    if (outTunnel == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("No outbound tunnels to verify a store");
        _facade.verifyFinished(_key);
        return;
    }
    // garlic encrypt to hide contents from the OBEP
    RouterInfo peer = _facade.lookupRouterInfoLocally(_target);
    if (peer == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Fail finding target RI");
        _facade.verifyFinished(_key);
        return;
    }
    if (DatabaseLookupMessage.supportsEncryptedReplies(peer)) {
        // register the session with the right SKM
        MessageWrapper.OneTimeSession sess;
        if (isInboundExploratory) {
            sess = MessageWrapper.generateSession(getContext());
        } else {
            sess = MessageWrapper.generateSession(getContext(), _key);
            if (sess == null) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("No SKM to reply to");
                _facade.verifyFinished(_key);
                return;
            }
        }
        if (_log.shouldLog(Log.INFO))
            _log.info("Requesting encrypted reply from " + _target + ' ' + sess.key + ' ' + sess.tag);
        lookup.setReplySession(sess.key, sess.tag);
    }
    Hash fromKey;
    if (_isRouterInfo)
        fromKey = null;
    else
        fromKey = _key;
    _wrappedMessage = MessageWrapper.wrap(getContext(), lookup, fromKey, peer);
    if (_wrappedMessage == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Fail Garlic encrypting");
        _facade.verifyFinished(_key);
        return;
    }
    I2NPMessage sent = _wrappedMessage.getMessage();
    if (_log.shouldLog(Log.INFO))
        _log.info("Starting verify (stored " + _key + " to " + _sentTo + "), asking " + _target);
    _sendTime = getContext().clock().now();
    _expiration = _sendTime + VERIFY_TIMEOUT;
    getContext().messageRegistry().registerPending(new VerifyReplySelector(), new VerifyReplyJob(getContext()), new VerifyTimeoutJob(getContext()));
    getContext().tunnelDispatcher().dispatchOutbound(sent, outTunnel.getSendTunnelId(0), _target);
}
Also used : DatabaseLookupMessage(net.i2p.data.i2np.DatabaseLookupMessage) RouterInfo(net.i2p.data.router.RouterInfo) I2NPMessage(net.i2p.data.i2np.I2NPMessage) TunnelInfo(net.i2p.router.TunnelInfo) Hash(net.i2p.data.Hash)

Example 3 with DatabaseLookupMessage

use of net.i2p.data.i2np.DatabaseLookupMessage in project i2p.i2p by i2p.

the class SingleSearchJob method runJob.

@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);
}
Also used : DatabaseLookupMessage(net.i2p.data.i2np.DatabaseLookupMessage) TunnelInfo(net.i2p.router.TunnelInfo)

Example 4 with DatabaseLookupMessage

use of net.i2p.data.i2np.DatabaseLookupMessage in project i2p.i2p by i2p.

the class ExploreJob method buildMessage.

/**
 * Build the database search message, but unlike the normal searches, we're more explicit in
 * what we /dont/ want.  We don't just ask them to ignore the peers we've already searched
 * on, but to ignore a number of the peers we already know about (in the target key's bucket) as well.
 *
 * Perhaps we may want to ignore other keys too, such as the ones in nearby
 * buckets, but we probably don't want the dontIncludePeers set to get too
 * massive (aka sending the entire routing table as 'dont tell me about these
 * guys').  but maybe we do.  dunno.  lots of implications.
 *
 * FloodfillPeerSelector would add only the floodfill peers,
 * and PeerSelector doesn't include the floodfill peers,
 * so we add the ff peers ourselves and then use the regular PeerSelector.
 *
 * @param replyTunnelId tunnel to receive replies through, or our router hash if replyGateway is null
 * @param replyGateway gateway for the reply tunnel, if null, we are sending direct, do not encrypt
 * @param expiration when the search should stop
 * @param peer the peer to send it to
 *
 * @return a DatabaseLookupMessage or GarlicMessage or null on error
 */
@Override
protected I2NPMessage buildMessage(TunnelId replyTunnelId, Hash replyGateway, long expiration, RouterInfo peer) {
    DatabaseLookupMessage msg = new DatabaseLookupMessage(getContext(), true);
    msg.setSearchKey(getState().getTarget());
    msg.setFrom(replyGateway);
    // Moved below now that DLM makes a copy
    // msg.setDontIncludePeers(getState().getClosestAttempted(MAX_CLOSEST));
    Set<Hash> dontIncludePeers = getState().getClosestAttempted(MAX_CLOSEST);
    msg.setMessageExpiration(expiration);
    if (replyTunnelId != null)
        msg.setReplyTunnel(replyTunnelId);
    int available = MAX_CLOSEST - dontIncludePeers.size();
    if (available > 0) {
        // Supported as of 0.7.9
        if (dontIncludePeers.add(Hash.FAKE_HASH))
            available--;
    }
    // supported as of 0.9.16. TODO remove fake hash above
    msg.setSearchType(DatabaseLookupMessage.Type.EXPL);
    KBucketSet<Hash> ks = _facade.getKBuckets();
    Hash rkey = getContext().routingKeyGenerator().getRoutingKey(getState().getTarget());
    // in a few releases, we can (and should) remove this,
    // as routers will honor the above flag, and we want the table to include
    // only non-floodfills.
    // Removed in 0.8.8, good thing, as we had well over MAX_CLOSEST floodfills.
    // if (available > 0 && ks != null) {
    // List peers = _peerSelector.selectFloodfillParticipants(rkey, available, ks);
    // int len = peers.size();
    // if (len > 0)
    // msg.getDontIncludePeers().addAll(peers);
    // }
    available = MAX_CLOSEST - dontIncludePeers.size();
    if (available > 0) {
        // selectNearestExplicit adds our hash to the dontInclude set (3rd param) ...
        // And we end up with MAX_CLOSEST+1 entries.
        // We don't want our hash in the message's don't-include list though.
        // We're just exploring, but this could give things away, and tie our exploratory tunnels to our router,
        // so let's not put our hash in there.
        Set<Hash> dontInclude = new HashSet<Hash>(dontIncludePeers);
        List<Hash> peers = _peerSelector.selectNearestExplicit(rkey, available, dontInclude, ks);
        dontIncludePeers.addAll(peers);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Peers we don't want to hear about: " + dontIncludePeers);
    msg.setDontIncludePeers(dontIncludePeers);
    // Now encrypt if we can
    I2NPMessage outMsg;
    if (replyTunnelId != null && getContext().getProperty(IterativeSearchJob.PROP_ENCRYPT_RI, IterativeSearchJob.DEFAULT_ENCRYPT_RI)) {
        // request encrypted reply?
        if (DatabaseLookupMessage.supportsEncryptedReplies(peer)) {
            MessageWrapper.OneTimeSession sess;
            sess = MessageWrapper.generateSession(getContext());
            if (_log.shouldLog(Log.INFO))
                _log.info(getJobId() + ": Requesting encrypted reply from " + peer.getIdentity().calculateHash() + ' ' + sess.key + ' ' + sess.tag);
            msg.setReplySession(sess.key, sess.tag);
        }
        // may be null
        outMsg = MessageWrapper.wrap(getContext(), msg, peer);
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getJobId() + ": Encrypted exploratory DLM for " + getState().getTarget() + " to " + peer.getIdentity().calculateHash());
    } else {
        outMsg = msg;
    }
    return outMsg;
}
Also used : DatabaseLookupMessage(net.i2p.data.i2np.DatabaseLookupMessage) I2NPMessage(net.i2p.data.i2np.I2NPMessage) Hash(net.i2p.data.Hash) HashSet(java.util.HashSet)

Example 5 with DatabaseLookupMessage

use of net.i2p.data.i2np.DatabaseLookupMessage in project i2p.i2p by i2p.

the class IterativeSearchJob method sendQuery.

/**
 *  Send a DLM to the peer
 */
private void sendQuery(Hash peer) {
    TunnelManagerFacade tm = getContext().tunnelManager();
    RouterInfo ri = getContext().netDb().lookupRouterInfoLocally(peer);
    if (ri != null) {
        // Now that most of the netdb is Ed RIs and EC LSs, don't even bother
        // querying old floodfills that don't know about those sig types.
        // This is also more recent than the version that supports encrypted replies,
        // so we won't request unencrypted replies anymore either.
        String v = ri.getVersion();
        String since = MIN_QUERY_VERSION;
        if (VersionComparator.comp(v, since) < 0) {
            failed(peer, false);
            if (_log.shouldLog(Log.WARN))
                _log.warn(getJobId() + ": not sending query to old version " + v + ": " + peer);
            return;
        }
    }
    TunnelInfo outTunnel;
    TunnelInfo replyTunnel;
    boolean isClientReplyTunnel;
    boolean isDirect;
    if (_fromLocalDest != null) {
        outTunnel = tm.selectOutboundTunnel(_fromLocalDest, peer);
        if (outTunnel == null)
            outTunnel = tm.selectOutboundExploratoryTunnel(peer);
        replyTunnel = tm.selectInboundTunnel(_fromLocalDest, peer);
        isClientReplyTunnel = replyTunnel != null;
        if (!isClientReplyTunnel)
            replyTunnel = tm.selectInboundExploratoryTunnel(peer);
        isDirect = false;
    } else if ((!_isLease) && ri != null && getContext().commSystem().isEstablished(peer)) {
        // If it's a RI lookup, not from a client, and we're already connected, just ask directly
        // This also saves the ElG encryption for us and the decryption for the ff
        // There's no anonymity reason to use an expl. tunnel... the main reason
        // is to limit connections to the ffs. But if we're already connected,
        // do it the fast and easy way.
        outTunnel = null;
        replyTunnel = null;
        isClientReplyTunnel = false;
        isDirect = true;
        getContext().statManager().addRateData("netDb.RILookupDirect", 1);
    } else {
        outTunnel = tm.selectOutboundExploratoryTunnel(peer);
        replyTunnel = tm.selectInboundExploratoryTunnel(peer);
        isClientReplyTunnel = false;
        isDirect = false;
        getContext().statManager().addRateData("netDb.RILookupDirect", 0);
    }
    if ((!isDirect) && (replyTunnel == null || outTunnel == null)) {
        failed();
        return;
    }
    // not being able to send to the floodfill, if we don't have an older netdb entry.
    if (outTunnel != null && outTunnel.getLength() <= 1) {
        if (peer.equals(_key)) {
            failed(peer, false);
            if (_log.shouldLog(Log.WARN))
                _log.warn(getJobId() + ": not doing zero-hop self-lookup of " + peer);
            return;
        }
        if (_facade.lookupLocallyWithoutValidation(peer) == null) {
            failed(peer, false);
            if (_log.shouldLog(Log.WARN))
                _log.warn(getJobId() + ": not doing zero-hop lookup to unknown " + peer);
            return;
        }
    }
    DatabaseLookupMessage dlm = new DatabaseLookupMessage(getContext(), true);
    if (isDirect) {
        dlm.setFrom(getContext().routerHash());
    } else {
        dlm.setFrom(replyTunnel.getPeer(0));
        dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
    }
    dlm.setMessageExpiration(getContext().clock().now() + SINGLE_SEARCH_MSG_TIME);
    dlm.setSearchKey(_key);
    dlm.setSearchType(_isLease ? DatabaseLookupMessage.Type.LS : DatabaseLookupMessage.Type.RI);
    if (_log.shouldLog(Log.INFO)) {
        int tries;
        synchronized (this) {
            tries = _unheardFrom.size() + _failedPeers.size();
        }
        _log.info(getJobId() + ": ISJ try " + tries + " for " + (_isLease ? "LS " : "RI ") + _key + " to " + peer + " direct? " + isDirect + " reply via client tunnel? " + isClientReplyTunnel);
    }
    long now = getContext().clock().now();
    _sentTime.put(peer, Long.valueOf(now));
    I2NPMessage outMsg = null;
    if (isDirect) {
    // never wrap
    } else if (_isLease || (getContext().getProperty(PROP_ENCRYPT_RI, DEFAULT_ENCRYPT_RI) && getContext().jobQueue().getMaxLag() < 300)) {
        // if we have the ff RI, garlic encrypt it
        if (ri != null) {
            // if (DatabaseLookupMessage.supportsEncryptedReplies(ri)) {
            if (true) {
                MessageWrapper.OneTimeSession sess;
                if (isClientReplyTunnel)
                    sess = MessageWrapper.generateSession(getContext(), _fromLocalDest);
                else
                    sess = MessageWrapper.generateSession(getContext());
                if (sess != null) {
                    if (_log.shouldLog(Log.INFO))
                        _log.info(getJobId() + ": Requesting encrypted reply from " + peer + ' ' + sess.key + ' ' + sess.tag);
                    dlm.setReplySession(sess.key, sess.tag);
                }
            // else client went away, but send it anyway
            }
            outMsg = MessageWrapper.wrap(getContext(), dlm, ri);
            // a response may have come in.
            if (_dead) {
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug(getJobId() + ": aborting send, finished while wrapping msg to " + peer);
                return;
            }
            if (_log.shouldLog(Log.DEBUG))
                _log.debug(getJobId() + ": Encrypted DLM for " + _key + " to " + peer);
        }
    }
    if (outMsg == null)
        outMsg = dlm;
    if (isDirect) {
        OutNetMessage m = new OutNetMessage(getContext(), outMsg, outMsg.getMessageExpiration(), OutNetMessage.PRIORITY_MY_NETDB_LOOKUP, ri);
        // Should always succeed, we are connected already
        // m.setOnFailedReplyJob(onFail);
        // m.setOnFailedSendJob(onFail);
        // m.setOnReplyJob(onReply);
        // m.setReplySelector(selector);
        // getContext().messageRegistry().registerPending(m);
        getContext().commSystem().processMessage(m);
    } else {
        getContext().tunnelDispatcher().dispatchOutbound(outMsg, outTunnel.getSendTunnelId(0), peer);
    }
    // The timeout job is always run (never cancelled)
    // Note that the timeout is much shorter than the message expiration (see above)
    Job j = new IterativeTimeoutJob(getContext(), peer, this);
    long expire = Math.min(_expiration, now + _singleSearchTime);
    j.getTiming().setStartAfter(expire);
    getContext().jobQueue().addJob(j);
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) TunnelInfo(net.i2p.router.TunnelInfo) TunnelManagerFacade(net.i2p.router.TunnelManagerFacade) DatabaseLookupMessage(net.i2p.data.i2np.DatabaseLookupMessage) OutNetMessage(net.i2p.router.OutNetMessage) I2NPMessage(net.i2p.data.i2np.I2NPMessage) ReplyJob(net.i2p.router.ReplyJob) Job(net.i2p.router.Job)

Aggregations

DatabaseLookupMessage (net.i2p.data.i2np.DatabaseLookupMessage)7 TunnelInfo (net.i2p.router.TunnelInfo)4 Hash (net.i2p.data.Hash)3 I2NPMessage (net.i2p.data.i2np.I2NPMessage)3 RouterInfo (net.i2p.data.router.RouterInfo)2 Job (net.i2p.router.Job)2 HashSet (java.util.HashSet)1 OutNetMessage (net.i2p.router.OutNetMessage)1 ReplyJob (net.i2p.router.ReplyJob)1 TunnelManagerFacade (net.i2p.router.TunnelManagerFacade)1