propagate from branch 'i2p.i2p.zzz.test3' (head 459a56e53d8d694591071574e87474b5e95d6494)
to branch 'i2p.i2p' (head ffa1aab7aa8e75d75c183fd6f76140f7d840a6ae)
This commit is contained in:
214
router/java/test/net/i2p/router/message/BuildTestMessageJob.java
Normal file
214
router/java/test/net/i2p/router/message/BuildTestMessageJob.java
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
125
router/java/test/net/i2p/router/message/SendGarlicJob.java
Normal file
125
router/java/test/net/i2p/router/message/SendGarlicJob.java
Normal 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");
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user