forked from I2P_Developers/i2p.i2p
Compare commits
2 Commits
i2p.i2p.2.
...
i2p.i2p.2.
Author | SHA1 | Date | |
---|---|---|---|
4066e5df02 | |||
c49023af18 |
@ -119,6 +119,10 @@ public class InNetMessagePool implements Service {
|
|||||||
_handlerJobBuilders[i2npMessageType] = builder;
|
_handlerJobBuilders[i2npMessageType] = builder;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int add(I2NPMessage messageBody, RouterIdentity fromRouter, Hash fromRouterHash) {
|
||||||
|
return add(messageBody, fromRouter, fromRouterHash, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new message to the pool.
|
* Add a new message to the pool.
|
||||||
@ -134,7 +138,10 @@ public class InNetMessagePool implements Service {
|
|||||||
* @return -1 for some types of errors but not all; 0 otherwise
|
* @return -1 for some types of errors but not all; 0 otherwise
|
||||||
* (was queue length, long ago)
|
* (was queue length, long ago)
|
||||||
*/
|
*/
|
||||||
public int add(I2NPMessage messageBody, RouterIdentity fromRouter, Hash fromRouterHash) {
|
public int add(I2NPMessage messageBody,
|
||||||
|
RouterIdentity fromRouter,
|
||||||
|
Hash fromRouterHash,
|
||||||
|
long msgIDBloomXor) {
|
||||||
final MessageHistory history = _context.messageHistory();
|
final MessageHistory history = _context.messageHistory();
|
||||||
final boolean doHistory = history.getDoLog();
|
final boolean doHistory = history.getDoLog();
|
||||||
|
|
||||||
@ -158,7 +165,11 @@ public class InNetMessagePool implements Service {
|
|||||||
// just validate the expiration
|
// just validate the expiration
|
||||||
invalidReason = _context.messageValidator().validateMessage(exp);
|
invalidReason = _context.messageValidator().validateMessage(exp);
|
||||||
} else {
|
} else {
|
||||||
invalidReason = _context.messageValidator().validateMessage(messageBody.getUniqueId(), exp);
|
if (msgIDBloomXor == 0)
|
||||||
|
invalidReason = _context.messageValidator().validateMessage(messageBody.getUniqueId(), exp);
|
||||||
|
else
|
||||||
|
invalidReason = _context.messageValidator().validateMessage(messageBody.getUniqueId()
|
||||||
|
^ msgIDBloomXor, exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidReason != null) {
|
if (invalidReason != null) {
|
||||||
|
@ -85,7 +85,9 @@ public class TunnelPoolSettings {
|
|||||||
private static final int MIN_PRIORITY = -25;
|
private static final int MIN_PRIORITY = -25;
|
||||||
private static final int MAX_PRIORITY = 25;
|
private static final int MAX_PRIORITY = 25;
|
||||||
private static final int EXPLORATORY_PRIORITY = 30;
|
private static final int EXPLORATORY_PRIORITY = 30;
|
||||||
|
|
||||||
|
private final long _msgIdBloomXor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exploratory tunnel
|
* Exploratory tunnel
|
||||||
*/
|
*/
|
||||||
@ -116,6 +118,8 @@ public class TunnelPoolSettings {
|
|||||||
_IPRestriction = DEFAULT_IP_RESTRICTION;
|
_IPRestriction = DEFAULT_IP_RESTRICTION;
|
||||||
_unknownOptions = new Properties();
|
_unknownOptions = new Properties();
|
||||||
_randomKey = generateRandomKey();
|
_randomKey = generateRandomKey();
|
||||||
|
_msgIdBloomXor = RandomSource.getInstance().nextLong();
|
||||||
|
|
||||||
if (_isExploratory && !_isInbound)
|
if (_isExploratory && !_isInbound)
|
||||||
_priority = EXPLORATORY_PRIORITY;
|
_priority = EXPLORATORY_PRIORITY;
|
||||||
if (!_isExploratory)
|
if (!_isExploratory)
|
||||||
@ -286,6 +290,8 @@ public class TunnelPoolSettings {
|
|||||||
*/
|
*/
|
||||||
public Properties getUnknownOptions() { return _unknownOptions; }
|
public Properties getUnknownOptions() { return _unknownOptions; }
|
||||||
|
|
||||||
|
public long getMsgIdBloomXor() { return _msgIdBloomXor; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defaults in props are NOT honored.
|
* Defaults in props are NOT honored.
|
||||||
* In-JVM client side must promote defaults to the primary map.
|
* In-JVM client side must promote defaults to the primary map.
|
||||||
|
@ -111,6 +111,8 @@ public class TransportManager implements TransportEventListener {
|
|||||||
|
|
||||||
private static final long UPNP_REFRESH_TIME = UPnP.LEASE_TIME_SECONDS * 1000L / 3;
|
private static final long UPNP_REFRESH_TIME = UPnP.LEASE_TIME_SECONDS * 1000L / 3;
|
||||||
|
|
||||||
|
private final long _msgIdBloomXor;
|
||||||
|
|
||||||
public TransportManager(RouterContext context) {
|
public TransportManager(RouterContext context) {
|
||||||
_context = context;
|
_context = context;
|
||||||
_log = _context.logManager().getLog(TransportManager.class);
|
_log = _context.logManager().getLog(TransportManager.class);
|
||||||
@ -134,6 +136,7 @@ public class TransportManager implements TransportEventListener {
|
|||||||
_dhThread = (_enableUDP || enableNTCP2) ? new DHSessionKeyBuilder.PrecalcRunner(context) : null;
|
_dhThread = (_enableUDP || enableNTCP2) ? new DHSessionKeyBuilder.PrecalcRunner(context) : null;
|
||||||
// always created, even if NTCP2 is not enabled, because ratchet needs it
|
// always created, even if NTCP2 is not enabled, because ratchet needs it
|
||||||
_xdhThread = new X25519KeyFactory(context);
|
_xdhThread = new X25519KeyFactory(context);
|
||||||
|
_msgIdBloomXor = _context.random().nextLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -965,7 +968,7 @@ public class TransportManager implements TransportEventListener {
|
|||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("I2NPMessage received: " + message.getClass().getSimpleName() /*, new Exception("Where did I come from again?") */ );
|
_log.debug("I2NPMessage received: " + message.getClass().getSimpleName() /*, new Exception("Where did I come from again?") */ );
|
||||||
try {
|
try {
|
||||||
_context.inNetMessagePool().add(message, fromRouter, fromRouterHash);
|
_context.inNetMessagePool().add(message, fromRouter, fromRouterHash, _msgIdBloomXor);
|
||||||
//if (_log.shouldLog(Log.DEBUG))
|
//if (_log.shouldLog(Log.DEBUG))
|
||||||
// _log.debug("Added to in pool");
|
// _log.debug("Added to in pool");
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
|
@ -33,7 +33,8 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
private final Log _log;
|
private final Log _log;
|
||||||
private final Hash _client;
|
private final Hash _client;
|
||||||
private final GarlicMessageReceiver _receiver;
|
private final GarlicMessageReceiver _receiver;
|
||||||
|
private String _clientNickname;
|
||||||
|
private final long _msgIdBloomXor;
|
||||||
/**
|
/**
|
||||||
* @param client null for router tunnel
|
* @param client null for router tunnel
|
||||||
*/
|
*/
|
||||||
@ -43,6 +44,23 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
_log = ctx.logManager().getLog(InboundMessageDistributor.class);
|
_log = ctx.logManager().getLog(InboundMessageDistributor.class);
|
||||||
_receiver = new GarlicMessageReceiver(ctx, this, client);
|
_receiver = new GarlicMessageReceiver(ctx, this, client);
|
||||||
// all createRateStat in TunnelDispatcher
|
// all createRateStat in TunnelDispatcher
|
||||||
|
|
||||||
|
if (_client != null) {
|
||||||
|
TunnelPoolSettings clienttps = _context.tunnelManager().getInboundSettings(_client);
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Initializing client (nickname: "
|
||||||
|
+ clienttps.getDestinationNickname()
|
||||||
|
+ " b32: " + _client.toBase32()
|
||||||
|
+ ") InboundMessageDistributor with tunnel pool settings: " + clienttps);
|
||||||
|
_clientNickname = clienttps.getDestinationNickname();
|
||||||
|
_msgIdBloomXor = clienttps.getMsgIdBloomXor();
|
||||||
|
} else {
|
||||||
|
_clientNickname = "NULL/Expl";
|
||||||
|
_msgIdBloomXor = 0;
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Initializing null or exploratory InboundMessageDistributor");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void distribute(I2NPMessage msg, Hash target) {
|
public void distribute(I2NPMessage msg, Hash target) {
|
||||||
@ -51,7 +69,9 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
|
|
||||||
public void distribute(I2NPMessage msg, Hash target, TunnelId tunnel) {
|
public void distribute(I2NPMessage msg, Hash target, TunnelId tunnel) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("IBMD for " + _client + " to " + target + " / " + tunnel + " : " + msg);
|
_log.debug("IBMD for " + _clientNickname + " ("
|
||||||
|
+ ((_client != null) ? _client.toBase32() : "null")
|
||||||
|
+ ") to " + target + " / " + tunnel + " : " + msg);
|
||||||
|
|
||||||
// allow messages on client tunnels even after client disconnection, as it may
|
// allow messages on client tunnels even after client disconnection, as it may
|
||||||
// include e.g. test messages, etc. DataMessages will be dropped anyway
|
// include e.g. test messages, etc. DataMessages will be dropped anyway
|
||||||
@ -98,7 +118,8 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
// We handle this safely, so we don't ask him again.
|
// We handle this safely, so we don't ask him again.
|
||||||
// Todo: if peer was ff and RI is not ff, queue for exploration in netdb (but that isn't part of the facade now)
|
// Todo: if peer was ff and RI is not ff, queue for exploration in netdb (but that isn't part of the facade now)
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("Dropping DSM down a tunnel for " + _client.toBase32() + ": " + msg);
|
_log.warn("Inbound DSM received down a tunnel for " + _clientNickname
|
||||||
|
+ " (" + _client.toBase32() + "): " + msg);
|
||||||
// Handle safely by just updating the caps table, after doing basic validation
|
// Handle safely by just updating the caps table, after doing basic validation
|
||||||
Hash key = dsm.getKey();
|
Hash key = dsm.getKey();
|
||||||
if (_context.routerHash().equals(key))
|
if (_context.routerHash().equals(key))
|
||||||
@ -176,9 +197,12 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
} // switch
|
} // switch
|
||||||
} // client != null
|
} // client != null
|
||||||
|
|
||||||
if ( (target == null) || ( (tunnel == null) && (_context.routerHash().equals(target) ) ) ) {
|
if ( (target == null) && (tunnel == null) ) {
|
||||||
// targetting us either implicitly (no target) or explicitly (no tunnel)
|
// Since the InboundMessageDistributor handles messages for the endpoint,
|
||||||
// make sure we don't honor any remote requests directly (garlic instructions, etc)
|
// most messages that arrive here have both target==null and tunnel==null.
|
||||||
|
// Messages with targeting instructions need careful handling, and will
|
||||||
|
// typically be dropped because we're the endpoint. Especially when they
|
||||||
|
// specifically target this router (_context.routerHash().equals(target)).
|
||||||
if (type == GarlicMessage.MESSAGE_TYPE) {
|
if (type == GarlicMessage.MESSAGE_TYPE) {
|
||||||
// in case we're looking for replies to a garlic message (cough load tests cough)
|
// in case we're looking for replies to a garlic message (cough load tests cough)
|
||||||
_context.inNetMessagePool().handleReplies(msg);
|
_context.inNetMessagePool().handleReplies(msg);
|
||||||
@ -187,47 +211,43 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
_receiver.receive((GarlicMessage)msg);
|
_receiver.receive((GarlicMessage)msg);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("distributing inbound tunnel message into our inNetMessagePool: " + msg);
|
_log.info("distributing inbound tunnel message into our inNetMessagePool"
|
||||||
_context.inNetMessagePool().add(msg, null, null);
|
+ " (for client " + _clientNickname + " ("
|
||||||
|
+ ((_client != null) ? _client.toBase32() : "null")
|
||||||
|
+ ") to target=NULL/tunnel=NULL " + msg);
|
||||||
|
if (_msgIdBloomXor == 0)
|
||||||
|
_context.inNetMessagePool().add(msg, null, null);
|
||||||
|
else
|
||||||
|
_context.inNetMessagePool().add(msg, null, null, _msgIdBloomXor);
|
||||||
}
|
}
|
||||||
/****** latency measuring attack?
|
|
||||||
} else if (_context.routerHash().equals(target)) {
|
} else if (_context.routerHash().equals(target)) {
|
||||||
// the want to send it to a tunnel, except we are also that tunnel's gateway
|
if (type == GarlicMessage.MESSAGE_TYPE)
|
||||||
// dispatch it directly
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
|
||||||
_log.info("distributing inbound tunnel message back out, except we are the gateway");
|
|
||||||
TunnelGatewayMessage gw = new TunnelGatewayMessage(_context);
|
|
||||||
gw.setMessage(msg);
|
|
||||||
gw.setTunnelId(tunnel);
|
|
||||||
gw.setMessageExpiration(_context.clock().now()+10*1000);
|
|
||||||
gw.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
|
||||||
_context.tunnelDispatcher().dispatch(gw);
|
|
||||||
******/
|
|
||||||
} else {
|
|
||||||
// ok, they want us to send it remotely, but that'd bust our anonymity,
|
|
||||||
// so we send it out a tunnel first
|
|
||||||
// TODO use the OCMOSJ cache to pick OB tunnel we are already using?
|
|
||||||
TunnelInfo out = _context.tunnelManager().selectOutboundTunnel(_client, target);
|
|
||||||
if (out == null) {
|
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("no outbound tunnel to send the client message for " + _client + ": " + msg);
|
_log.warn("Dropping inbound garlic message TARGETED TO OUR ROUTER for client "
|
||||||
return;
|
+ _clientNickname + " ("
|
||||||
}
|
+ ((_client != null) ? _client.toBase32() : "null")
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
+ ") to " + target + " / " + tunnel);
|
||||||
_log.debug("distributing IB tunnel msg type " + type + " back out " + out
|
else
|
||||||
+ " targetting " + target);
|
if (_log.shouldLog(Log.WARN))
|
||||||
TunnelId outId = out.getSendTunnelId(0);
|
_log.warn("Dropping inbound message TARGETED TO OUR ROUTER for client "
|
||||||
if (outId == null) {
|
+ _clientNickname + " (" + ((_client != null) ? _client.toBase32() : "null")
|
||||||
if (_log.shouldLog(Log.ERROR))
|
+ ") to " + target + " / " + tunnel + " : " + msg);
|
||||||
_log.error("strange? outbound tunnel has no outboundId? " + out
|
return;
|
||||||
+ " failing to distribute " + msg);
|
} else {
|
||||||
return;
|
if (type == GarlicMessage.MESSAGE_TYPE)
|
||||||
}
|
if (_log.shouldLog(Log.WARN))
|
||||||
long exp = _context.clock().now() + 20*1000;
|
_log.warn("Dropping targeted inbound garlic message for client "
|
||||||
if (msg.getMessageExpiration() < exp)
|
+ _clientNickname + " ("
|
||||||
msg.setMessageExpiration(exp);
|
+ ((_client != null) ? _client.toBase32() : "null")
|
||||||
_context.tunnelDispatcher().dispatchOutbound(msg, outId, tunnel, target);
|
+ ") to " + target + " / " + tunnel);
|
||||||
|
else
|
||||||
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Dropping targeted inbound message for client " + _clientNickname
|
||||||
|
+ " (" + ((_client != null) ? _client.toBase32() : "null")
|
||||||
|
+ " to " + target + " / " + tunnel + " : " + msg);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -269,9 +289,13 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
// ... and inject it.
|
// ... and inject it.
|
||||||
((LeaseSet)dsm.getEntry()).setReceivedBy(_client);
|
((LeaseSet)dsm.getEntry()).setReceivedBy(_client);
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Storing garlic LS down tunnel for: " + dsm.getKey() + " sent to: " +
|
_log.info("Storing garlic LS down tunnel for: " + dsm.getKey() + " sent to: "
|
||||||
(_client != null ? _client.toBase32() : "router"));
|
+ _clientNickname + " ("
|
||||||
_context.inNetMessagePool().add(dsm, null, null);
|
+ (_client != null ? _client.toBase32() : ") router"));
|
||||||
|
if (_msgIdBloomXor == 0)
|
||||||
|
_context.inNetMessagePool().add(dsm, null, null);
|
||||||
|
else
|
||||||
|
_context.inNetMessagePool().add(dsm, null, null, _msgIdBloomXor);
|
||||||
} else {
|
} else {
|
||||||
if (_client != null) {
|
if (_client != null) {
|
||||||
// drop it, since the data we receive shouldn't include router
|
// drop it, since the data we receive shouldn't include router
|
||||||
@ -279,7 +303,8 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
// open an attack vector)
|
// open an attack vector)
|
||||||
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1,
|
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1,
|
||||||
DatabaseStoreMessage.MESSAGE_TYPE);
|
DatabaseStoreMessage.MESSAGE_TYPE);
|
||||||
_log.error("Dropped dangerous message down a tunnel for " + _client.toBase32() + ": " + dsm, new Exception("cause"));
|
_log.error("Dropped dangerous message down a tunnel for " + _clientNickname
|
||||||
|
+ " ("+ _client.toBase32() + ") : " + dsm, new Exception("cause"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Case 3:
|
// Case 3:
|
||||||
@ -288,11 +313,14 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
// We must send to the InNetMessagePool so the message can be matched
|
// We must send to the InNetMessagePool so the message can be matched
|
||||||
// and the search marked as successful.
|
// and the search marked as successful.
|
||||||
// note that encrypted replies to RI lookups is currently disables in ISJ, we won't get here.
|
// note that encrypted replies to RI lookups is currently disables in ISJ, we won't get here.
|
||||||
|
|
||||||
// ... and inject it.
|
// ... and inject it.
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Storing garlic RI down tunnel for: " + dsm.getKey());
|
_log.info("Storing garlic RI down tunnel (" + _clientNickname
|
||||||
_context.inNetMessagePool().add(dsm, null, null);
|
+ ") for: " + dsm.getKey());
|
||||||
|
if (_msgIdBloomXor == 0)
|
||||||
|
_context.inNetMessagePool().add(dsm, null, null);
|
||||||
|
else
|
||||||
|
_context.inNetMessagePool().add(dsm, null, null, _msgIdBloomXor);
|
||||||
}
|
}
|
||||||
} else if (_client != null && type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
|
} else if (_client != null && type == DatabaseSearchReplyMessage.MESSAGE_TYPE) {
|
||||||
// DSRMs show up here now that replies are encrypted
|
// DSRMs show up here now that replies are encrypted
|
||||||
@ -311,7 +339,10 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
orig = newMsg;
|
orig = newMsg;
|
||||||
}
|
}
|
||||||
****/
|
****/
|
||||||
_context.inNetMessagePool().add(orig, null, null);
|
if (_msgIdBloomXor == 0)
|
||||||
|
_context.inNetMessagePool().add(orig, null, null);
|
||||||
|
else
|
||||||
|
_context.inNetMessagePool().add(orig, null, null, _msgIdBloomXor);
|
||||||
} else if (type == DataMessage.MESSAGE_TYPE) {
|
} else if (type == DataMessage.MESSAGE_TYPE) {
|
||||||
// a data message targetting the local router is how we send load tests (real
|
// a data message targetting the local router is how we send load tests (real
|
||||||
// data messages target destinations)
|
// data messages target destinations)
|
||||||
@ -324,9 +355,14 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
// as that might open an attack vector
|
// as that might open an attack vector
|
||||||
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1,
|
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1,
|
||||||
data.getType());
|
data.getType());
|
||||||
_log.error("Dropped dangerous message down a tunnel for " + _client.toBase32() + ": " + data, new Exception("cause"));
|
_log.error("Dropped dangerous message received down a tunnel for "
|
||||||
|
+ _clientNickname + " (" + _client.toBase32() + ") : "
|
||||||
|
+ data, new Exception("cause"));
|
||||||
} else {
|
} else {
|
||||||
_context.inNetMessagePool().add(data, null, null);
|
if (_msgIdBloomXor == 0)
|
||||||
|
_context.inNetMessagePool().add(data, null, null);
|
||||||
|
else
|
||||||
|
_context.inNetMessagePool().add(data, null, null, _msgIdBloomXor);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -370,9 +406,14 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
|
|
||||||
case DeliveryInstructions.DELIVERY_MODE_ROUTER: // fall through
|
case DeliveryInstructions.DELIVERY_MODE_ROUTER: // fall through
|
||||||
case DeliveryInstructions.DELIVERY_MODE_TUNNEL:
|
case DeliveryInstructions.DELIVERY_MODE_TUNNEL:
|
||||||
|
// Targeted messages are usually dropped, but it is safe to
|
||||||
|
// allow distribute() to evaluate the message.
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("clove targetted " + instructions.getRouter() + ":" + instructions.getTunnelId()
|
_log.info("Recursively handling message from targeted clove (for client:"
|
||||||
+ ", treat recursively to prevent leakage");
|
+ _clientNickname + " " + ((_client != null) ? _client.toBase32() : "null")
|
||||||
|
+ ", msg type: " + data.getClass().getSimpleName() + "): " + instructions.getRouter()
|
||||||
|
+ ":" + instructions.getTunnelId() + " msg: " + data);
|
||||||
|
|
||||||
distribute(data, instructions.getRouter(), instructions.getTunnelId());
|
distribute(data, instructions.getRouter(), instructions.getTunnelId());
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user