package net.i2p.router.message; /* * free (adj.): unencumbered; not under the control of others * Written by jrandom in 2003 and released into the public domain * with no warranty of any kind, either expressed or implied. * It probably won't make your computer catch on fire, or eat * your children, but it might. Use at your own risk. * */ import net.i2p.data.Hash; import net.i2p.data.router.RouterIdentity; import net.i2p.data.i2np.DeliveryInstructions; import net.i2p.data.i2np.GarlicMessage; import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.TunnelGatewayMessage; import net.i2p.router.JobImpl; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.util.Log; /** * Unencrypt a garlic message and handle each of the cloves - locally destined * messages are tossed into the inbound network message pool so they're handled * as if they arrived locally. Other instructions are not yet implemented (but * need to be. soon) * * This is the handler for garlic message not received down a tunnel, which is the * case for floodfills receiving netdb messages. * It is not the handler for garlic messages received down a tunnel, * as InNetMessagePool short circuits tunnel messages, * and those garlic messages are handled in InboundMessageDistributor. * * Public for JobQueue as these jobs may be dropped. */ public class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.CloveReceiver { private final Log _log; private final GarlicMessage _message; //private RouterIdentity _from; //private Hash _fromHash; //private Map _cloves; // map of clove Id --> Expiration of cloves we've already seen //private MessageHandler _handler; //private GarlicMessageParser _parser; private final static int ROUTER_PRIORITY = OutNetMessage.PRIORITY_LOWEST; private final static int TUNNEL_PRIORITY = OutNetMessage.PRIORITY_LOWEST; /** * @param from ignored * @param fromHash ignored */ public HandleGarlicMessageJob(RouterContext context, GarlicMessage msg, RouterIdentity from, Hash fromHash) { super(context); _log = context.logManager().getLog(HandleGarlicMessageJob.class); if (_log.shouldLog(Log.DEBUG)) _log.debug("Garlic Message not down a tunnel from [" + from + "]"); _message = msg; //_from = from; //_fromHash = fromHash; //_cloves = new HashMap(); //_handler = new MessageHandler(context); //_parser = new GarlicMessageParser(context); // all createRateStat in OCMOSJ.init() } public String getName() { return "Handle Inbound Garlic Message"; } public void runJob() { GarlicMessageReceiver recv = new GarlicMessageReceiver(getContext(), this); recv.receive(_message); } public void handleClove(DeliveryInstructions instructions, I2NPMessage data) { switch (instructions.getDeliveryMode()) { case DeliveryInstructions.DELIVERY_MODE_LOCAL: if (_log.shouldLog(Log.DEBUG)) _log.debug("local delivery instructions for clove: " + data); getContext().inNetMessagePool().add(data, null, null); return; case DeliveryInstructions.DELIVERY_MODE_DESTINATION: if (_log.shouldLog(Log.ERROR)) _log.error("this message didn't come down a tunnel, not forwarding to a destination: " + instructions + " - " + data); return; case DeliveryInstructions.DELIVERY_MODE_ROUTER: if (getContext().routerHash().equals(instructions.getRouter())) { if (_log.shouldLog(Log.DEBUG)) _log.debug("router delivery instructions targetting us"); getContext().inNetMessagePool().add(data, null, null); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("router delivery instructions targetting " + instructions.getRouter().toBase64().substring(0,4) + " for " + data); SendMessageDirectJob j = new SendMessageDirectJob(getContext(), data, instructions.getRouter(), 10*1000, ROUTER_PRIORITY); // run it inline (adds to the outNetPool if it has the router info, otherwise queue a lookup) j.runJob(); //getContext().jobQueue().addJob(j); } return; case DeliveryInstructions.DELIVERY_MODE_TUNNEL: TunnelGatewayMessage gw = new TunnelGatewayMessage(getContext()); gw.setMessage(data); gw.setTunnelId(instructions.getTunnelId()); gw.setMessageExpiration(data.getMessageExpiration()); if (_log.shouldLog(Log.DEBUG)) _log.debug("tunnel delivery instructions targetting " + instructions.getRouter().toBase64().substring(0,4) + " for " + data); SendMessageDirectJob job = new SendMessageDirectJob(getContext(), gw, instructions.getRouter(), 10*1000, TUNNEL_PRIORITY); // run it inline (adds to the outNetPool if it has the router info, otherwise queue a lookup) job.runJob(); // getContext().jobQueue().addJob(job); return; default: _log.error("Unknown instruction " + instructions.getDeliveryMode() + ": " + instructions); return; } } @Override public void dropped() { getContext().messageHistory().messageProcessingError(_message.getUniqueId(), _message.getClass().getName(), "Dropped due to overload"); } }