* Message: Move 2 unused classes out of the router lib (~15KB)

(more SKM prep)
This commit is contained in:
zzz
2009-08-23 12:29:34 +00:00
parent 3f3d43df41
commit 7e547743c7
2 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,214 @@
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.Certificate;
import net.i2p.data.Hash;
import net.i2p.data.PublicKey;
import net.i2p.data.RouterInfo;
import net.i2p.data.SessionKey;
import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.data.i2np.DeliveryStatusMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.router.Job;
import net.i2p.router.JobImpl;
import net.i2p.router.MessageSelector;
import net.i2p.router.ReplyJob;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.peermanager.PeerProfile;
import net.i2p.util.Log;
/**
* Build a test message that will be sent to the target to make sure they're alive.
* Once that is verified, onSendJob is enqueued. If their reachability isn't
* known (or they're unreachable) within timeoutMs, onSendFailedJob is enqueued.
* The test message is sent at the specified priority.
*
*/
public class BuildTestMessageJob extends JobImpl {
private Log _log;
private RouterInfo _target;
private Hash _replyTo;
private Job _onSend;
private Job _onSendFailed;
private long _timeoutMs;
private int _priority;
private long _testMessageKey;
/**
*
* @param target router being tested
* @param onSendJob after the ping is successful
* @param onSendFailedJob after the ping fails or times out
* @param timeoutMs how long to wait before timing out
* @param priority how high priority to send this test
*/
public BuildTestMessageJob(RouterContext ctx, RouterInfo target, Hash replyTo,
Job onSendJob, Job onSendFailedJob, long timeoutMs, int priority) {
super(ctx);
_log = ctx.logManager().getLog(BuildTestMessageJob.class);
_target = target;
_replyTo = replyTo;
_onSend = onSendJob;
_onSendFailed = onSendFailedJob;
_timeoutMs = timeoutMs;
_priority = priority;
_testMessageKey = -1;
}
public String getName() { return "Build Test Message"; }
public void runJob() {
if (alreadyKnownReachable()) {
getContext().jobQueue().addJob(_onSend);
return;
}
// This is a test message - build a garlic with a DeliveryStatusMessage that
// first goes to the peer then back to us.
if (_log.shouldLog(Log.DEBUG))
_log.debug("Building garlic message to test " + _target.getIdentity().getHash().toBase64());
GarlicConfig config = buildGarlicCloveConfig();
// TODO: make the last params on this specify the correct sessionKey and tags used
ReplyJob replyJob = new JobReplyJob(getContext(), _onSend, config.getRecipient().getIdentity().getPublicKey(), config.getId(), null, new HashSet());
MessageSelector sel = buildMessageSelector();
SendGarlicJob job = new SendGarlicJob(getContext(), config, null, _onSendFailed, replyJob, _onSendFailed, _timeoutMs, _priority, sel);
getContext().jobQueue().addJob(job);
}
private boolean alreadyKnownReachable() {
PeerProfile profile = getContext().profileOrganizer().getProfile(_target.getIdentity().getHash());
if ( (profile == null) || (!profile.getIsActive()) )
return false;
else
return true;
}
private MessageSelector buildMessageSelector() {
return new TestMessageSelector(_testMessageKey, _timeoutMs + getContext().clock().now());
}
private GarlicConfig buildGarlicCloveConfig() {
_testMessageKey = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
if (_log.shouldLog(Log.INFO))
_log.info("Test message key: " + _testMessageKey);
GarlicConfig config = new GarlicConfig();
PayloadGarlicConfig ackClove = buildAckClove();
config.addClove(ackClove);
DeliveryInstructions instructions = new DeliveryInstructions();
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_ROUTER);
instructions.setDelayRequested(false);
instructions.setDelaySeconds(0);
instructions.setEncrypted(false);
instructions.setEncryptionKey(null);
instructions.setRouter(_target.getIdentity().getHash());
instructions.setTunnelId(null);
config.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
config.setDeliveryInstructions(instructions);
config.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
config.setExpiration(_timeoutMs+getContext().clock().now()+2*Router.CLOCK_FUDGE_FACTOR);
config.setRecipient(_target);
config.setRequestAck(false);
return config;
}
/**
* Build a clove that sends a DeliveryStatusMessage to us
*/
private PayloadGarlicConfig buildAckClove() {
PayloadGarlicConfig ackClove = new PayloadGarlicConfig();
DeliveryInstructions ackInstructions = new DeliveryInstructions();
ackInstructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_ROUTER);
ackInstructions.setRouter(_replyTo); // yikes!
ackInstructions.setDelayRequested(false);
ackInstructions.setDelaySeconds(0);
ackInstructions.setEncrypted(false);
DeliveryStatusMessage msg = new DeliveryStatusMessage(getContext());
msg.setArrival(getContext().clock().now());
msg.setMessageId(_testMessageKey);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Delivery status message key: " + _testMessageKey + " arrival: " + msg.getArrival());
ackClove.setCertificate(new Certificate(Certificate.CERTIFICATE_TYPE_NULL, null));
ackClove.setDeliveryInstructions(ackInstructions);
ackClove.setExpiration(_timeoutMs+getContext().clock().now());
ackClove.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
ackClove.setPayload(msg);
ackClove.setRecipient(_target);
ackClove.setRequestAck(false);
return ackClove;
}
/**
* Search inbound messages for delivery status messages with our key
*/
private final static class TestMessageSelector implements MessageSelector {
private long _testMessageKey;
private long _timeout;
public TestMessageSelector(long key, long timeout) {
_testMessageKey = key;
_timeout = timeout;
}
public boolean continueMatching() { return false; }
public long getExpiration() { return _timeout; }
public boolean isMatch(I2NPMessage inMsg) {
if (inMsg.getType() == DeliveryStatusMessage.MESSAGE_TYPE) {
return ((DeliveryStatusMessage)inMsg).getMessageId() == _testMessageKey;
} else {
return false;
}
}
}
/**
* On reply, fire off the specified job
*
*/
private static final class JobReplyJob extends JobImpl implements ReplyJob {
private Job _job;
private PublicKey _target;
private long _msgId;
private Set _sessionTagsDelivered;
private SessionKey _keyDelivered;
public JobReplyJob(RouterContext ctx, Job job, PublicKey target, long msgId, SessionKey keyUsed, Set tagsDelivered) {
super(ctx);
_job = job;
_target = target;
_msgId = msgId;
_keyDelivered = keyUsed;
_sessionTagsDelivered = tagsDelivered;
}
public String getName() { return "Reply To Test Message Received"; }
public void runJob() {
if ( (_keyDelivered != null) &&
(_sessionTagsDelivered != null) &&
(_sessionTagsDelivered.size() > 0) )
getContext().sessionKeyManager().tagsDelivered(_target, _keyDelivered, _sessionTagsDelivered);
getContext().jobQueue().addJob(_job);
}
public void setMessage(I2NPMessage message) {
// ignored, this is just a ping
}
}
}

View File

@ -0,0 +1,125 @@
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.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 _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());
}
public SendGarlicJob(RouterContext ctx, GarlicConfig config, Job onSend, Job onSendFailed, ReplyJob onReply, Job onReplyFailed, long timeoutMs, int priority, MessageSelector replySelector, SessionKey wrappedKey, Set 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);
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]", getAddedBy());
} 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() {
OutNetMessage msg = new OutNetMessage(getContext());
long when = _message.getMessageExpiration(); // + Router.CLOCK_FUDGE_FACTOR;
msg.setExpiration(when);
msg.setMessage(_message);
msg.setOnFailedReplyJob(_onReplyFailed);
msg.setOnFailedSendJob(_onSendFailed);
msg.setOnReplyJob(_onReply);
msg.setOnSendJob(_onSend);
msg.setPriority(_priority);
msg.setReplySelector(_replySelector);
msg.setTarget(_config.getRecipient());
//_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");
}
}