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 java.util.HashSet; import java.util.Set; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.data.i2np.GarlicMessage; import net.i2p.router.Job; import net.i2p.router.JobImpl; import net.i2p.router.MessageSelector; import net.i2p.router.OutNetMessage; import net.i2p.router.ReplyJob; import net.i2p.router.RouterContext; import net.i2p.util.Log; /** * Build a garlic message from config, encrypt it, and enqueue it for delivery. * */ public class SendGarlicJob extends JobImpl { private Log _log; //private RouterInfo _target; private GarlicConfig _config; private Job _onSend; private Job _onSendFailed; private ReplyJob _onReply; private Job _onReplyFailed; private long _timeoutMs; private int _priority; private MessageSelector _replySelector; private GarlicMessage _message; private SessionKey _wrappedKey; private Set<SessionTag> _wrappedTags; /** * * @param config ??? * @param onSend after the ping is successful * @param onSendFailed after the ping fails or times out * @param onReply ??? * @param onReplyFailed ??? * @param timeoutMs how long to wait before timing out * @param priority how high priority to send this test * @param replySelector ??? */ public SendGarlicJob(RouterContext ctx, GarlicConfig config, Job onSend, Job onSendFailed, ReplyJob onReply, Job onReplyFailed, long timeoutMs, int priority, MessageSelector replySelector) { this(ctx, config, onSend, onSendFailed, onReply, onReplyFailed, timeoutMs, priority, replySelector, new SessionKey(), new HashSet<SessionTag>()); } public SendGarlicJob(RouterContext ctx, GarlicConfig config, Job onSend, Job onSendFailed, ReplyJob onReply, Job onReplyFailed, long timeoutMs, int priority, MessageSelector replySelector, SessionKey wrappedKey, Set<SessionTag> wrappedTags) { super(ctx); _log = ctx.logManager().getLog(SendGarlicJob.class); if (config == null) throw new IllegalArgumentException("No config specified"); if (config.getRecipient() == null) throw new IllegalArgumentException("No recipient in the config"); //_target = target; _config = config; _onSend = onSend; _onSendFailed = onSendFailed; _onReply = onReply; _onReplyFailed = onReplyFailed; _timeoutMs = timeoutMs; _priority = priority; _replySelector = replySelector; _message = null; _wrappedKey = wrappedKey; _wrappedTags = wrappedTags; } public String getName() { return "Build Garlic Message"; } public void runJob() { long before = getContext().clock().now(); _message = GarlicMessageBuilder.buildMessage(getContext(), _config, _wrappedKey, _wrappedTags, getContext().sessionKeyManager()); long after = getContext().clock().now(); if ( (after - before) > 1000) { if (_log.shouldLog(Log.WARN)) _log.warn("Building the garlic took too long [" + (after-before)+" ms]"); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Building the garlic was fast! " + (after - before) + " ms"); } getContext().jobQueue().addJob(new SendJob(getContext())); } private class SendJob extends JobImpl { public SendJob(RouterContext enclosingContext) { super(enclosingContext); } public String getName() { return "Send Built Garlic Message"; } public void runJob() { if (_config.getRecipient() != null) _log.info("sending garlic to recipient " + _config.getRecipient().getIdentity().getHash().toBase64()); else _log.info("sending garlic to public key " + _config.getRecipientPublicKey()); sendGarlic(); } } private void sendGarlic() { long when = _message.getMessageExpiration(); // + Router.CLOCK_FUDGE_FACTOR; OutNetMessage msg = new OutNetMessage(getContext(), _message, when, _priority, _config.getRecipient()); msg.setOnFailedReplyJob(_onReplyFailed); msg.setOnFailedSendJob(_onSendFailed); msg.setOnReplyJob(_onReply); msg.setOnSendJob(_onSend); msg.setReplySelector(_replySelector); //_log.info("Sending garlic message to [" + _config.getRecipient() + "] encrypted with " + _config.getRecipientPublicKey() + " or " + _config.getRecipient().getIdentity().getPublicKey()); //_log.debug("Garlic config data:\n" + _config); //msg.setTarget(_target); getContext().outNetMessagePool().add(msg); _log.debug("Garlic message added to outbound network message pool"); } }