use of net.i2p.data.Payload 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;
}
}
use of net.i2p.data.Payload in project i2p.i2p by i2p.
the class SendMessageMessage method readMessage.
/**
* Read the body into the data structures
*
* @throws IOException
*/
@Override
public void readMessage(InputStream in, int length, int type) throws I2CPMessageException, IOException {
if (type != getType())
throw new I2CPMessageException("Invalid message type (found: " + type + " supported: " + getType() + " class: " + getClass().getName() + ")");
if (length < 0)
throw new IOException("Negative payload size");
try {
_sessionId = new SessionId();
_sessionId.readBytes(in);
_destination = Destination.create(in);
_payload = new Payload();
_payload.readBytes(in);
_nonce = DataHelper.readLong(in, 4);
} catch (DataFormatException dfe) {
throw new I2CPMessageException("Unable to load the message data", dfe);
}
}
use of net.i2p.data.Payload in project i2p.i2p by i2p.
the class I2CPMessageProducer method sendMessage.
/**
* Package up and send the payload to the router for delivery
*
* @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
* @since 0.8.4
*/
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, long expires, int flags) throws I2PSessionException {
if (!updateBps(payload.length, expires))
// drop the message... send fail notification?
return;
SendMessageMessage msg;
if (expires > 0 || flags > 0) {
SendMessageExpiresMessage smsg = new SendMessageExpiresMessage();
smsg.setExpiration(expires);
smsg.setFlags(flags);
msg = smsg;
} else
msg = new SendMessageMessage();
msg.setDestination(dest);
SessionId sid = session.getSessionId();
if (sid == null) {
_log.error(session.toString() + " send message w/o session", new Exception());
return;
}
msg.setSessionId(sid);
msg.setNonce(nonce);
Payload data = createPayload(dest, payload, null, null, null, null);
msg.setPayload(data);
session.sendMessage(msg);
}
use of net.i2p.data.Payload in project i2p.i2p by i2p.
the class MessagePayloadMessageHandler method decryptPayload.
/**
* Decrypt the payload
*
* We don't really decrypt (no more end-to-end crypto)
* If we do, we need to use the correct key manager in the decrypt() call below
*/
private Payload decryptPayload(MessagePayloadMessage msg, I2PSessionImpl session) throws DataFormatException {
Payload payload = msg.getPayload();
// if (!I2CPMessageProducer.END_TO_END_CRYPTO) {
payload.setUnencryptedData(payload.getEncryptedData());
return payload;
// }
// byte[] data = _context.elGamalAESEngine().decrypt(payload.getEncryptedData(), session.getDecryptionKey());
// if (data == null) {
// if (_log.shouldLog(Log.WARN))
// _log.warn("Error decrypting the payload");
// throw new DataFormatException("Unable to decrypt the payload");
// }
// payload.setUnencryptedData(data);
// return payload;
}
use of net.i2p.data.Payload in project i2p.i2p by i2p.
the class OutboundClientMessageOneShotJob method buildClove.
/**
* Build the payload clove that will be used for all of the messages,
* placing the clove in the status structure.
*
* @return null on failure
*/
private PayloadGarlicConfig buildClove() {
PayloadGarlicConfig clove = new PayloadGarlicConfig();
DeliveryInstructions instructions = new DeliveryInstructions();
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_DESTINATION);
instructions.setDestination(_to.calculateHash());
// defaults
// instructions.setDelayRequested(false);
// instructions.setDelaySeconds(0);
// instructions.setEncrypted(false);
clove.setCertificate(Certificate.NULL_CERT);
clove.setDeliveryInstructions(instructions);
clove.setExpiration(OVERALL_TIMEOUT_MS_DEFAULT + getContext().clock().now());
clove.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
DataMessage msg = new DataMessage(getContext());
Payload p = _clientMessage.getPayload();
if (p == null)
return null;
byte[] d = p.getEncryptedData();
if (d == null)
return null;
msg.setData(d);
msg.setMessageExpiration(clove.getExpiration());
clove.setPayload(msg);
// _log.debug(getJobId() + ": Built payload clove with id " + clove.getId());
return clove;
}
Aggregations