Search in sources :

Example 1 with ClientMessage

use of net.i2p.router.ClientMessage in project i2p.i2p by i2p.

the class ClientManager method distributeMessage.

/**
 * Distribute message to a local or remote destination.
 * @param msgId the router's ID for this message
 * @param messageNonce the client's ID for this message
 * @param flags ignored for local
 */
void distributeMessage(Destination fromDest, Destination toDest, Payload payload, MessageId msgId, long messageNonce, long expiration, int flags) {
    // check if there is a runner for it
    ClientConnectionRunner runner = getRunner(toDest);
    if (runner != null) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Message " + msgId + " is targeting a local destination.  distribute it as such");
        ClientConnectionRunner sender = getRunner(fromDest);
        if (sender == null) {
            // sender went away
            return;
        }
        // run this inline so we don't clog up the job queue
        Job j = new DistributeLocal(toDest, runner, sender, fromDest, payload, msgId, messageNonce);
        // _ctx.jobQueue().addJob(j);
        j.runJob();
    } else {
        // remote.  w00t
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Message " + msgId + " is targeting a REMOTE destination!  Added to the client message pool");
        runner = getRunner(fromDest);
        if (runner == null) {
            // sender went away
            return;
        }
        SessionConfig config = runner.getConfig(fromDest.calculateHash());
        if (config == null)
            return;
        ClientMessage msg = new ClientMessage(toDest, payload, config, fromDest, msgId, messageNonce, expiration, flags);
        _ctx.clientMessagePool().add(msg, true);
    }
}
Also used : SessionConfig(net.i2p.data.i2cp.SessionConfig) ClientMessage(net.i2p.router.ClientMessage) Job(net.i2p.router.Job)

Example 2 with ClientMessage

use of net.i2p.router.ClientMessage 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)

Aggregations

ClientMessage (net.i2p.router.ClientMessage)2 Hash (net.i2p.data.Hash)1 Payload (net.i2p.data.Payload)1 SessionConfig (net.i2p.data.i2cp.SessionConfig)1 DataMessage (net.i2p.data.i2np.DataMessage)1 DatabaseSearchReplyMessage (net.i2p.data.i2np.DatabaseSearchReplyMessage)1 DatabaseStoreMessage (net.i2p.data.i2np.DatabaseStoreMessage)1 Job (net.i2p.router.Job)1 TunnelPoolSettings (net.i2p.router.TunnelPoolSettings)1