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");
}
}