Search in sources :

Example 1 with DatabaseSearchReplyMessage

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

the class FloodOnlyLookupMatchJob method setMessage.

public void setMessage(I2NPMessage message) {
    if (message instanceof DatabaseSearchReplyMessage) {
        // DSRM processing now in FloodOnlyLookupSelector instead of here,
        // a dsrm is only passed in when there are no more lookups remaining
        // so that all DSRM's are processed, not just the last one.
        _search.failed();
        return;
    }
    try {
        DatabaseStoreMessage dsm = (DatabaseStoreMessage) message;
        if (_log.shouldLog(Log.INFO))
            _log.info(_search.getJobId() + ": got a DSM for " + dsm.getKey().toBase64());
        // Should we just pass the DataStructure directly back to somebody?
        if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
            // Since HFDSMJ wants to setReceivedAsPublished(), we have to
            // set a flag saying this was really the result of a query,
            // so don't do that.
            LeaseSet ls = (LeaseSet) dsm.getEntry();
            ls.setReceivedAsReply();
            getContext().netDb().store(dsm.getKey(), ls);
        } else {
            getContext().netDb().store(dsm.getKey(), (RouterInfo) dsm.getEntry());
        }
    } catch (UnsupportedCryptoException uce) {
        _search.failed();
        return;
    } catch (IllegalArgumentException iae) {
        if (_log.shouldLog(Log.WARN))
            _log.warn(_search.getJobId() + ": Received an invalid store reply", iae);
    }
}
Also used : LeaseSet(net.i2p.data.LeaseSet) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage)

Example 2 with DatabaseSearchReplyMessage

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

the class SearchUpdateReplyFoundJob method runJob.

public void runJob() {
    if (_isFloodfillPeer)
        _job.decrementOutstandingFloodfillSearches();
    I2NPMessage message = _message;
    if (_log.shouldLog(Log.INFO))
        _log.info(getJobId() + ": Reply from " + _peer.toBase64() + " with message " + message.getClass().getSimpleName());
    long howLong = System.currentTimeMillis() - _sentOn;
    // assume requests are 1KB (they're almost always much smaller, but tunnels have a fixed size)
    int msgSize = 1024;
    if (_replyTunnel != null) {
        for (int i = 0; i < _replyTunnel.getLength(); i++) getContext().profileManager().tunnelDataPushed(_replyTunnel.getPeer(i), howLong, msgSize);
        _replyTunnel.incrementVerifiedBytesTransferred(msgSize);
    }
    if (_outTunnel != null) {
        for (int i = 0; i < _outTunnel.getLength(); i++) getContext().profileManager().tunnelDataPushed(_outTunnel.getPeer(i), howLong, msgSize);
        _outTunnel.incrementVerifiedBytesTransferred(msgSize);
    }
    if (message instanceof DatabaseStoreMessage) {
        long timeToReply = _state.dataFound(_peer);
        DatabaseStoreMessage msg = (DatabaseStoreMessage) message;
        DatabaseEntry entry = msg.getEntry();
        try {
            _facade.store(msg.getKey(), entry);
            getContext().profileManager().dbLookupSuccessful(_peer, timeToReply);
        } catch (UnsupportedCryptoException iae) {
            // don't blame the peer
            getContext().profileManager().dbLookupSuccessful(_peer, timeToReply);
            _state.abort();
        // searchNext() will call fail()
        } catch (IllegalArgumentException iae) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("Peer " + _peer + " sent us invalid data: ", iae);
            // blame the peer
            getContext().profileManager().dbLookupReply(_peer, 0, 0, 1, 0, timeToReply);
        }
    } else if (message instanceof DatabaseSearchReplyMessage) {
        _job.replyFound((DatabaseSearchReplyMessage) message, _peer);
    } else {
        if (_log.shouldLog(Log.ERROR))
            _log.error(getJobId() + ": What?! Reply job matched a strange message: " + message);
        return;
    }
    _job.searchNext();
}
Also used : I2NPMessage(net.i2p.data.i2np.I2NPMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) DatabaseEntry(net.i2p.data.DatabaseEntry)

Example 3 with DatabaseSearchReplyMessage

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

the class InboundMessageDistributor method handleClove.

/**
 * Handle a clove removed from the garlic message
 */
public void handleClove(DeliveryInstructions instructions, I2NPMessage data) {
    int type = data.getType();
    switch(instructions.getDeliveryMode()) {
        case DeliveryInstructions.DELIVERY_MODE_LOCAL:
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("local delivery instructions for clove: " + data.getClass().getSimpleName());
            if (type == GarlicMessage.MESSAGE_TYPE) {
                _receiver.receive((GarlicMessage) data);
            } else if (type == DatabaseStoreMessage.MESSAGE_TYPE) {
                // Treat db store explicitly here (not in HandleFloodfillDatabaseStoreMessageJob),
                // since we don't want to republish (or flood)
                // unnecessarily. Reply tokens ignored.
                DatabaseStoreMessage dsm = (DatabaseStoreMessage) data;
                // Ensure the reply info is cleared, just in case
                dsm.setReplyToken(0);
                dsm.setReplyTunnel(null);
                dsm.setReplyGateway(null);
                if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
                    // Case 1:
                    // store of our own LS.
                    // This is almost certainly a response to a FloodfillVerifyStoreJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the verify marked as successful.
                    // Case 2:
                    // Store of somebody else's LS.
                    // This could be an encrypted response to an IterativeSearchJob search.
                    // We must send to the InNetMessagePool so the message can be matched
                    // and the search marked as successful.
                    // Or, it's a normal LS bundled with data and a MessageStatusMessage.
                    // ... and inject it.
                    ((LeaseSet) dsm.getEntry()).setReceivedAsReply();
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic LS down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                } else {
                    if (_client != null) {
                        // drop it, since the data we receive shouldn't include router
                        // references, as that might get us to talk to them (and therefore
                        // open an attack vector)
                        _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, DatabaseStoreMessage.MESSAGE_TYPE);
                        _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + dsm, new Exception("cause"));
                        return;
                    }
                    // ... and inject it.
                    if (_log.shouldLog(Log.INFO))
                        _log.info("Storing garlic RI down tunnel for: " + dsm.getKey() + " sent to: " + _client);
                    _context.inNetMessagePool().add(dsm, null, null);
                }
            } else if (_client != null && type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
                // DSRMs show up here now that replies are encrypted
                // TODO: Strip in IterativeLookupJob etc. instead, depending on
                // LS or RI and client or expl., so that we can safely follow references
                // in a reply to a LS lookup over client tunnels.
                // ILJ would also have to follow references via client tunnels
                DatabaseSearchReplyMessage orig = (DatabaseSearchReplyMessage) data;
                /**
                 **
                 *                    if (orig.getNumReplies() > 0) {
                 *                        if (_log.shouldLog(Log.INFO))
                 *                            _log.info("Removing replies from a garlic DSRM down a tunnel for " + _client + ": " + data);
                 *                        DatabaseSearchReplyMessage newMsg = new DatabaseSearchReplyMessage(_context);
                 *                        newMsg.setFromHash(orig.getFromHash());
                 *                        newMsg.setSearchKey(orig.getSearchKey());
                 *                        orig = newMsg;
                 *                     }
                 ***
                 */
                _context.inNetMessagePool().add(orig, null, null);
            } else if (type == DataMessage.MESSAGE_TYPE) {
                // a data message targetting the local router is how we send load tests (real
                // data messages target destinations)
                _context.statManager().addRateData("tunnel.handleLoadClove", 1);
                data = null;
            // _context.inNetMessagePool().add(data, null, null);
            } else if (_client != null && type != DeliveryStatusMessage.MESSAGE_TYPE) {
                // drop it, since the data we receive shouldn't include other stuff,
                // as that might open an attack vector
                _context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, data.getType());
                _log.error("Dropped dangerous message down a tunnel for " + _client + ": " + data, new Exception("cause"));
            } else {
                _context.inNetMessagePool().add(data, null, null);
            }
            return;
        case DeliveryInstructions.DELIVERY_MODE_DESTINATION:
            Hash to = instructions.getDestination();
            // Can we route UnknownI2NPMessages to a destination too?
            if (type != DataMessage.MESSAGE_TYPE) {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("cant send a " + data.getClass().getSimpleName() + " to a destination");
            } else if (_client != null && _client.equals(to)) {
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("data message came down a tunnel for " + _client);
                DataMessage dm = (DataMessage) data;
                Payload payload = new Payload();
                payload.setEncryptedData(dm.getData());
                ClientMessage m = new ClientMessage(_client, payload);
                _context.clientManager().messageReceived(m);
            } else if (_client != null) {
                // Shared tunnel?
                TunnelPoolSettings tgt = _context.tunnelManager().getInboundSettings(to);
                if (tgt != null && _client.equals(tgt.getAliasOf())) {
                    // same as above, just different log
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("data message came down a tunnel for " + _client + " targeting shared " + to);
                    DataMessage dm = (DataMessage) data;
                    Payload payload = new Payload();
                    payload.setEncryptedData(dm.getData());
                    ClientMessage m = new ClientMessage(to, payload);
                    _context.clientManager().messageReceived(m);
                } else {
                    if (_log.shouldLog(Log.ERROR))
                        _log.error("Data message came down a tunnel for " + _client + " but targetted " + to);
                }
            } else {
                if (_log.shouldLog(Log.ERROR))
                    _log.error("Data message came down an exploratory tunnel targeting " + to);
            }
            return;
        // fall through
        case DeliveryInstructions.DELIVERY_MODE_ROUTER:
        case DeliveryInstructions.DELIVERY_MODE_TUNNEL:
            if (_log.shouldLog(Log.INFO))
                _log.info("clove targetted " + instructions.getRouter() + ":" + instructions.getTunnelId() + ", treat recursively to prevent leakage");
            distribute(data, instructions.getRouter(), instructions.getTunnelId());
            return;
        default:
            if (_log.shouldLog(Log.ERROR))
                _log.error("Unknown instruction " + instructions.getDeliveryMode() + ": " + instructions);
            return;
    }
}
Also used : DataMessage(net.i2p.data.i2np.DataMessage) DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) TunnelPoolSettings(net.i2p.router.TunnelPoolSettings) Payload(net.i2p.data.Payload) ClientMessage(net.i2p.router.ClientMessage) Hash(net.i2p.data.Hash)

Example 4 with DatabaseSearchReplyMessage

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

the class HandleDatabaseLookupMessageJob method sendClosest.

protected void sendClosest(Hash key, Set<Hash> routerHashes, Hash toPeer, TunnelId replyTunnel) {
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Sending closest routers to key " + key + ": # peers = " + routerHashes.size() + " tunnel " + replyTunnel);
    DatabaseSearchReplyMessage msg = new DatabaseSearchReplyMessage(getContext());
    msg.setFromHash(getContext().routerHash());
    msg.setSearchKey(key);
    int i = 0;
    for (Hash h : routerHashes) {
        msg.addReply(h);
        if (++i >= MAX_ROUTERS_RETURNED)
            break;
    }
    getContext().statManager().addRateData("netDb.lookupsHandled", 1);
    // should this go via garlic messages instead?
    sendMessage(msg, toPeer, replyTunnel);
}
Also used : DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage) Hash(net.i2p.data.Hash)

Example 5 with DatabaseSearchReplyMessage

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

the class FloodOnlyLookupSelector method isMatch.

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());
            // 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;
}
Also used : DatabaseStoreMessage(net.i2p.data.i2np.DatabaseStoreMessage) DatabaseSearchReplyMessage(net.i2p.data.i2np.DatabaseSearchReplyMessage)

Aggregations

DatabaseSearchReplyMessage (net.i2p.data.i2np.DatabaseSearchReplyMessage)5 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)4 Hash (net.i2p.data.Hash)2 DatabaseEntry (net.i2p.data.DatabaseEntry)1 LeaseSet (net.i2p.data.LeaseSet)1 Payload (net.i2p.data.Payload)1 DataMessage (net.i2p.data.i2np.DataMessage)1 I2NPMessage (net.i2p.data.i2np.I2NPMessage)1 ClientMessage (net.i2p.router.ClientMessage)1 TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)1