forked from I2P_Developers/i2p.i2p
minor refactoring, javadoc
dont add an arbitrary extra Router.CLOCK_FUDGE_FACTOR to the expiration
This commit is contained in:
@@ -97,31 +97,10 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
_log.error("Someone br0ke us. where is this message supposed to go again?",
|
_log.error("Someone br0ke us. where is this message supposed to go again?",
|
||||||
getAddedBy());
|
getAddedBy());
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
forwardToGateway();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
TunnelMessage msg = new TunnelMessage(_context);
|
|
||||||
try {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
|
||||||
_message.writeBytes(baos);
|
|
||||||
msg.setData(baos.toByteArray());
|
|
||||||
msg.setTunnelId(_tunnelId);
|
|
||||||
msg.setMessageExpiration(new Date(_expiration));
|
|
||||||
_context.jobQueue().addJob(new SendMessageDirectJob(_context, msg,
|
|
||||||
_destRouter, _onSend,
|
|
||||||
_onReply, _onFailure,
|
|
||||||
_selector, _expiration,
|
|
||||||
_priority));
|
|
||||||
|
|
||||||
String bodyType = _message.getClass().getName();
|
|
||||||
_context.messageHistory().wrap(bodyType, _message.getUniqueId(),
|
|
||||||
TunnelMessage.class.getName(), msg.getUniqueId());
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
if (_log.shouldLog(Log.ERROR))
|
|
||||||
_log.error("Error writing out the tunnel message to send to the tunnel", ioe);
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
if (_log.shouldLog(Log.ERROR))
|
|
||||||
_log.error("Error writing out the tunnel message to send to the tunnel", dfe);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info.messageProcessed();
|
info.messageProcessed();
|
||||||
@@ -139,7 +118,43 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward this job's message to the gateway of the tunnel requested
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void forwardToGateway() {
|
||||||
|
TunnelMessage msg = new TunnelMessage(_context);
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||||
|
_message.writeBytes(baos);
|
||||||
|
msg.setData(baos.toByteArray());
|
||||||
|
msg.setTunnelId(_tunnelId);
|
||||||
|
msg.setMessageExpiration(new Date(_expiration));
|
||||||
|
_context.jobQueue().addJob(new SendMessageDirectJob(_context, msg,
|
||||||
|
_destRouter, _onSend,
|
||||||
|
_onReply, _onFailure,
|
||||||
|
_selector, _expiration,
|
||||||
|
_priority));
|
||||||
|
|
||||||
|
String bodyType = _message.getClass().getName();
|
||||||
|
_context.messageHistory().wrap(bodyType, _message.getUniqueId(),
|
||||||
|
TunnelMessage.class.getName(), msg.getUniqueId());
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("Error writing out the tunnel message to send to the tunnel", ioe);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("Error writing out the tunnel message to send to the tunnel", dfe);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are the gateway for the tunnel this message is bound to,
|
||||||
|
* so wrap it accordingly and send it on its way.
|
||||||
|
*
|
||||||
|
*/
|
||||||
private void handleAsGateway(TunnelInfo info) {
|
private void handleAsGateway(TunnelInfo info) {
|
||||||
// since we are the gateway, we don't need to verify the data structures
|
// since we are the gateway, we don't need to verify the data structures
|
||||||
TunnelInfo us = getUs(info);
|
TunnelInfo us = getUs(info);
|
||||||
@@ -176,6 +191,11 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are the participant in the tunnel, so verify the signature / data and
|
||||||
|
* forward it to the next hop.
|
||||||
|
*
|
||||||
|
*/
|
||||||
private void handleAsParticipant(TunnelInfo info) {
|
private void handleAsParticipant(TunnelInfo info) {
|
||||||
// SendTunnelMessageJob shouldn't be used for participants!
|
// SendTunnelMessageJob shouldn't be used for participants!
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@@ -251,6 +271,11 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
return (us.getSigningKey() != null); // only the gateway can sign
|
return (us.getSigningKey() != null); // only the gateway can sign
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the tunnel message with appropriate instructions for the
|
||||||
|
* tunnel endpoint, then encrypt and sign it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
private TunnelMessage prepareMessage(TunnelInfo info) {
|
private TunnelMessage prepareMessage(TunnelInfo info) {
|
||||||
TunnelMessage msg = new TunnelMessage(_context);
|
TunnelMessage msg = new TunnelMessage(_context);
|
||||||
|
|
||||||
@@ -316,6 +341,10 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and sign the verification structure, using the tunnel's signing key
|
||||||
|
*
|
||||||
|
*/
|
||||||
private TunnelVerificationStructure createVerificationStructure(byte encryptedMessage[], TunnelInfo info) {
|
private TunnelVerificationStructure createVerificationStructure(byte encryptedMessage[], TunnelInfo info) {
|
||||||
TunnelVerificationStructure struct = new TunnelVerificationStructure();
|
TunnelVerificationStructure struct = new TunnelVerificationStructure();
|
||||||
struct.setMessageHash(_context.sha().calculateHash(encryptedMessage));
|
struct.setMessageHash(_context.sha().calculateHash(encryptedMessage));
|
||||||
@@ -323,6 +352,11 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encrypt the structure (the message or instructions)
|
||||||
|
*
|
||||||
|
* @param paddedSize minimum size to pad to
|
||||||
|
*/
|
||||||
private byte[] encrypt(DataStructure struct, SessionKey key, int paddedSize) {
|
private byte[] encrypt(DataStructure struct, SessionKey key, int paddedSize) {
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(paddedSize);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(paddedSize);
|
||||||
@@ -342,6 +376,12 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are both the endpoint and gateway for the tunnel, so honor
|
||||||
|
* what was requested of us (processing the message locally,
|
||||||
|
* forwarding to a router, forwarding to a tunnel, etc)
|
||||||
|
*
|
||||||
|
*/
|
||||||
private void honorInstructions(TunnelInfo info) {
|
private void honorInstructions(TunnelInfo info) {
|
||||||
if (_selector != null)
|
if (_selector != null)
|
||||||
createFakeOutNetMessage();
|
createFakeOutNetMessage();
|
||||||
@@ -357,93 +397,112 @@ public class SendTunnelMessageJob extends JobImpl {
|
|||||||
RouterIdentity ident = _context.router().getRouterInfo().getIdentity();
|
RouterIdentity ident = _context.router().getRouterInfo().getIdentity();
|
||||||
|
|
||||||
if (_destRouter != null) {
|
if (_destRouter != null) {
|
||||||
I2NPMessage msg = null;
|
honorSendRemote(info, ident);
|
||||||
if (_targetTunnelId != null) {
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Forward " + _message.getClass().getName()
|
|
||||||
+ " message off to remote tunnel "
|
|
||||||
+ _targetTunnelId.getTunnelId() + " on router "
|
|
||||||
+ _destRouter.toBase64());
|
|
||||||
TunnelMessage tmsg = new TunnelMessage(_context);
|
|
||||||
tmsg.setEncryptedDeliveryInstructions(null);
|
|
||||||
tmsg.setTunnelId(_targetTunnelId);
|
|
||||||
tmsg.setVerificationStructure(null);
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
|
||||||
try {
|
|
||||||
_message.writeBytes(baos);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
if (_log.shouldLog(Log.ERROR))
|
|
||||||
_log.error("Error writing out the message to be forwarded...??", ioe);
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
if (_log.shouldLog(Log.ERROR))
|
|
||||||
_log.error("Error writing message to be forwarded...???", dfe);
|
|
||||||
}
|
|
||||||
tmsg.setData(baos.toByteArray());
|
|
||||||
msg = tmsg;
|
|
||||||
} else {
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Forward " + _message.getClass().getName()
|
|
||||||
+ " message off to remote router " + _destRouter.toBase64());
|
|
||||||
msg = _message;
|
|
||||||
}
|
|
||||||
long now = _context.clock().now();
|
|
||||||
//if (_expiration < now) {
|
|
||||||
_expiration = now + Router.CLOCK_FUDGE_FACTOR;
|
|
||||||
//_log.info("Fudging the message send so it expires in the fudge factor...");
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (_expiration - 30*1000 < now) {
|
|
||||||
if (_log.shouldLog(Log.ERROR))
|
|
||||||
_log.error("Why are we trying to send a " + _message.getClass().getName()
|
|
||||||
+ " message with " + (_expiration-now) + "ms left?", getAddedBy());
|
|
||||||
}
|
|
||||||
|
|
||||||
String bodyType = _message.getClass().getName();
|
|
||||||
_context.messageHistory().wrap(bodyType, _message.getUniqueId(),
|
|
||||||
TunnelMessage.class.getName(), msg.getUniqueId());
|
|
||||||
|
|
||||||
// don't specify a selector, since createFakeOutNetMessage already does that
|
|
||||||
_context.jobQueue().addJob(new SendMessageDirectJob(_context, msg, _destRouter,
|
|
||||||
_onSend, _onReply, _onFailure,
|
|
||||||
null, _expiration, _priority));
|
|
||||||
} else {
|
} else {
|
||||||
if ( (info.getDestination() == null) || !(_message instanceof DataMessage) ) {
|
honorSendLocal(info, ident);
|
||||||
// its a network message targeting us...
|
}
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
}
|
||||||
_log.debug("Destination is null or its not a DataMessage - pass it off to the InNetMessagePool");
|
|
||||||
InNetMessage msg = new InNetMessage(_context);
|
/**
|
||||||
msg.setFromRouter(ident);
|
* We are the gateway and endpoint and we have been asked to forward the
|
||||||
msg.setFromRouterHash(ident.getHash());
|
* message to a remote location (either a tunnel or a router).
|
||||||
msg.setMessage(_message);
|
*
|
||||||
msg.setReplyBlock(null);
|
*/
|
||||||
_context.inNetMessagePool().add(msg);
|
private void honorSendRemote(TunnelInfo info, RouterIdentity ident) {
|
||||||
} else {
|
I2NPMessage msg = null;
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_targetTunnelId != null) {
|
||||||
_log.debug("Destination is not null and it is a DataMessage - pop it into the ClientMessagePool");
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
DataMessage msg = (DataMessage)_message;
|
_log.debug("Forward " + _message.getClass().getName()
|
||||||
boolean valid = _context.messageValidator().validateMessage(msg.getUniqueId(), msg.getMessageExpiration().getTime());
|
+ " message off to remote tunnel "
|
||||||
if (!valid) {
|
+ _targetTunnelId.getTunnelId() + " on router "
|
||||||
if (_log.shouldLog(Log.WARN))
|
+ _destRouter.toBase64());
|
||||||
_log.warn("Duplicate data message received [" + msg.getUniqueId() + " expiring on " + msg.getMessageExpiration() + "]");
|
TunnelMessage tmsg = new TunnelMessage(_context);
|
||||||
_context.messageHistory().droppedOtherMessage(msg);
|
tmsg.setEncryptedDeliveryInstructions(null);
|
||||||
_context.messageHistory().messageProcessingError(msg.getUniqueId(), msg.getClass().getName(), "Duplicate");
|
tmsg.setTunnelId(_targetTunnelId);
|
||||||
return;
|
tmsg.setVerificationStructure(null);
|
||||||
}
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||||
|
try {
|
||||||
Payload payload = new Payload();
|
_message.writeBytes(baos);
|
||||||
payload.setEncryptedData(msg.getData());
|
} catch (IOException ioe) {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
MessageReceptionInfo receptionInfo = new MessageReceptionInfo();
|
_log.error("Error writing out the message to be forwarded...??", ioe);
|
||||||
receptionInfo.setFromPeer(ident.getHash());
|
} catch (DataFormatException dfe) {
|
||||||
receptionInfo.setFromTunnel(_tunnelId);
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("Error writing message to be forwarded...???", dfe);
|
||||||
ClientMessage clientMessage = new ClientMessage();
|
|
||||||
clientMessage.setDestination(info.getDestination());
|
|
||||||
clientMessage.setPayload(payload);
|
|
||||||
clientMessage.setReceptionInfo(receptionInfo);
|
|
||||||
_context.clientMessagePool().add(clientMessage);
|
|
||||||
_context.messageHistory().receivePayloadMessage(msg.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
tmsg.setData(baos.toByteArray());
|
||||||
|
msg = tmsg;
|
||||||
|
} else {
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Forward " + _message.getClass().getName()
|
||||||
|
+ " message off to remote router " + _destRouter.toBase64());
|
||||||
|
msg = _message;
|
||||||
|
}
|
||||||
|
long now = _context.clock().now();
|
||||||
|
//if (_expiration < now) {
|
||||||
|
//_expiration = now + Router.CLOCK_FUDGE_FACTOR;
|
||||||
|
//_log.info("Fudging the message send so it expires in the fudge factor...");
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (_expiration - 10*1000 < now) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Why are we trying to send a " + _message.getClass().getName()
|
||||||
|
+ " message with " + (_expiration-now) + "ms left?", getAddedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
String bodyType = _message.getClass().getName();
|
||||||
|
_context.messageHistory().wrap(bodyType, _message.getUniqueId(),
|
||||||
|
TunnelMessage.class.getName(), msg.getUniqueId());
|
||||||
|
|
||||||
|
// don't specify a selector, since createFakeOutNetMessage already does that
|
||||||
|
_context.jobQueue().addJob(new SendMessageDirectJob(_context, msg, _destRouter,
|
||||||
|
_onSend, _onReply, _onFailure,
|
||||||
|
null, _expiration, _priority));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are the gateway and endpoint, and the instructions say to forward the
|
||||||
|
* message to, uh, us. The message may be a normal network message or they
|
||||||
|
* may be a client DataMessage.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void honorSendLocal(TunnelInfo info, RouterIdentity ident) {
|
||||||
|
if ( (info.getDestination() == null) || !(_message instanceof DataMessage) ) {
|
||||||
|
// its a network message targeting us...
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Destination is null or its not a DataMessage - pass it off to the InNetMessagePool");
|
||||||
|
InNetMessage msg = new InNetMessage(_context);
|
||||||
|
msg.setFromRouter(ident);
|
||||||
|
msg.setFromRouterHash(ident.getHash());
|
||||||
|
msg.setMessage(_message);
|
||||||
|
msg.setReplyBlock(null);
|
||||||
|
_context.inNetMessagePool().add(msg);
|
||||||
|
} else {
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Destination is not null and it is a DataMessage - pop it into the ClientMessagePool");
|
||||||
|
DataMessage msg = (DataMessage)_message;
|
||||||
|
boolean valid = _context.messageValidator().validateMessage(msg.getUniqueId(), msg.getMessageExpiration().getTime());
|
||||||
|
if (!valid) {
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Duplicate data message received [" + msg.getUniqueId() + " expiring on " + msg.getMessageExpiration() + "]");
|
||||||
|
_context.messageHistory().droppedOtherMessage(msg);
|
||||||
|
_context.messageHistory().messageProcessingError(msg.getUniqueId(), msg.getClass().getName(), "Duplicate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Payload payload = new Payload();
|
||||||
|
payload.setEncryptedData(msg.getData());
|
||||||
|
|
||||||
|
MessageReceptionInfo receptionInfo = new MessageReceptionInfo();
|
||||||
|
receptionInfo.setFromPeer(ident.getHash());
|
||||||
|
receptionInfo.setFromTunnel(_tunnelId);
|
||||||
|
|
||||||
|
ClientMessage clientMessage = new ClientMessage();
|
||||||
|
clientMessage.setDestination(info.getDestination());
|
||||||
|
clientMessage.setPayload(payload);
|
||||||
|
clientMessage.setReceptionInfo(receptionInfo);
|
||||||
|
_context.clientMessagePool().add(clientMessage);
|
||||||
|
_context.messageHistory().receivePayloadMessage(msg.getUniqueId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user