forked from I2P_Developers/i2p.i2p
Prop 157 updates
- Fix registration of reply key/tag with SKM - Allow OTBRM down client tunnel - Disable tunnel hop throttles for allowLocal - Various cleanups
This commit is contained in:
@ -318,7 +318,8 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
||||
_context.statManager().addRateData("tunnel.handleLoadClove", 1);
|
||||
data = null;
|
||||
//_context.inNetMessagePool().add(data, null, null);
|
||||
} else if (_client != null && type != DeliveryStatusMessage.MESSAGE_TYPE) {
|
||||
} else if (_client != null && type != DeliveryStatusMessage.MESSAGE_TYPE &&
|
||||
type != OutboundTunnelBuildReplyMessage.MESSAGE_TYPE) {
|
||||
// drop it, since the data we receive shouldn't include other stuff,
|
||||
// as that might open an attack vector
|
||||
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1,
|
||||
|
@ -421,6 +421,9 @@ public abstract class TunnelCreatorConfig implements TunnelInfo {
|
||||
buf.append("\nHop ").append(i);
|
||||
buf.append(": ").append(_config[i]);
|
||||
}
|
||||
if (_garlicReplyKeys != null) {
|
||||
buf.append("\nGarlic reply key: ").append(_garlicReplyKeys.key).append(" tag: ").append(_garlicReplyKeys.rtag);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import net.i2p.data.EmptyProperties;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.router.RouterIdentity;
|
||||
import net.i2p.data.router.RouterInfo;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.TunnelId;
|
||||
import net.i2p.data.i2np.BuildRequestRecord;
|
||||
import net.i2p.data.i2np.BuildResponseRecord;
|
||||
@ -32,9 +31,7 @@ import net.i2p.router.Job;
|
||||
import net.i2p.router.JobImpl;
|
||||
import net.i2p.router.OutNetMessage;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.crypto.ratchet.RatchetSessionTag;
|
||||
import net.i2p.router.networkdb.kademlia.MessageWrapper;
|
||||
import net.i2p.router.networkdb.kademlia.MessageWrapper.OneTimeSession;
|
||||
import net.i2p.router.peermanager.TunnelHistory;
|
||||
import net.i2p.router.tunnel.HopConfig;
|
||||
import net.i2p.router.tunnel.TunnelDispatcher;
|
||||
@ -161,9 +158,10 @@ class BuildHandler implements Runnable {
|
||||
|
||||
_processor = new BuildMessageProcessor(ctx);
|
||||
// used for previous hop, for all requests
|
||||
_requestThrottler = new RequestThrottler(ctx);
|
||||
boolean testMode = ctx.getBooleanProperty("i2np.allowLocal");
|
||||
_requestThrottler = testMode ? null : new RequestThrottler(ctx);
|
||||
// used for previous and next hops, for successful builds only
|
||||
_throttler = new ParticipatingThrottler(ctx);
|
||||
_throttler = testMode ? null : new ParticipatingThrottler(ctx);
|
||||
_buildReplyHandler = new BuildReplyHandler(ctx);
|
||||
_buildMessageHandlerJob = new TunnelBuildMessageHandlerJob(ctx);
|
||||
_buildReplyMessageHandlerJob = new TunnelBuildReplyMessageHandlerJob(ctx);
|
||||
@ -854,7 +852,7 @@ class BuildHandler implements Runnable {
|
||||
// Check participating throttle counters for previous and next hops
|
||||
// This is at the end as it compares to a percentage of created tunnels.
|
||||
// We may need another counter above for requests.
|
||||
if (response == 0 && !isInGW) {
|
||||
if (response == 0 && !isInGW && _throttler != null) {
|
||||
if (from != null && _throttler.shouldThrottle(from)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting tunnel (hop throttle), previous hop: " + from + ": " + req);
|
||||
@ -864,7 +862,7 @@ class BuildHandler implements Runnable {
|
||||
}
|
||||
}
|
||||
if (response == 0 && (!isOutEnd) &&
|
||||
_throttler.shouldThrottle(nextPeer)) {
|
||||
_throttler != null && _throttler.shouldThrottle(nextPeer)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Rejecting tunnel (hop throttle), next hop: " + req);
|
||||
_context.statManager().addRateData("tunnel.rejectHopThrottle", 1);
|
||||
@ -1020,10 +1018,7 @@ class BuildHandler implements Runnable {
|
||||
I2NPMessage outMessage;
|
||||
if (state.msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE) {
|
||||
// garlic encrypt
|
||||
OneTimeSession ots = req.readGarlicKeys();
|
||||
SessionKey sk = ots.key;
|
||||
RatchetSessionTag st = ots.rtag;
|
||||
outMessage = MessageWrapper.wrap(_context, replyMsg, sk, st);
|
||||
outMessage = MessageWrapper.wrap(_context, replyMsg, req.readGarlicKeys());
|
||||
if (outMessage == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("OTBRM encrypt fail");
|
||||
@ -1102,7 +1097,7 @@ class BuildHandler implements Runnable {
|
||||
accept = false;
|
||||
}
|
||||
}
|
||||
if (accept) {
|
||||
if (accept && _requestThrottler != null) {
|
||||
// early request throttle check, before queueing and decryption
|
||||
Hash fh = fromHash;
|
||||
if (fh == null && from != null)
|
||||
|
@ -146,19 +146,15 @@ abstract class BuildRequestor {
|
||||
Hash farEnd = cfg.getFarEnd();
|
||||
TunnelManagerFacade mgr = ctx.tunnelManager();
|
||||
boolean isInbound = settings.isInbound();
|
||||
// OB only, short record only
|
||||
SessionKeyManager replySKM = null;
|
||||
if (settings.isExploratory() || !usePairedTunnels(ctx)) {
|
||||
if (isInbound) {
|
||||
pairedTunnel = mgr.selectOutboundExploratoryTunnel(farEnd);
|
||||
} else {
|
||||
pairedTunnel = mgr.selectInboundExploratoryTunnel(farEnd);
|
||||
if (pairedTunnel != null) {
|
||||
OneTimeSession ots = cfg.getGarlicReplyKeys();
|
||||
if (ots != null) {
|
||||
SessionKeyManager skm = ctx.sessionKeyManager();
|
||||
RatchetSKM rskm = (RatchetSKM) skm;
|
||||
rskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
cfg.setGarlicReplyKeys(null);
|
||||
}
|
||||
replySKM = ctx.sessionKeyManager();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -169,26 +165,10 @@ abstract class BuildRequestor {
|
||||
} else {
|
||||
pairedTunnel = mgr.selectInboundTunnel(from, farEnd);
|
||||
if (pairedTunnel != null) {
|
||||
OneTimeSession ots = cfg.getGarlicReplyKeys();
|
||||
if (ots != null) {
|
||||
SessionKeyManager skm = ctx.clientManager().getClientSessionKeyManager(from);
|
||||
if (skm != null) {
|
||||
if (skm instanceof RatchetSKM) {
|
||||
RatchetSKM rskm = (RatchetSKM) skm;
|
||||
rskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
cfg.setGarlicReplyKeys(null);
|
||||
} else if (skm instanceof MuxedSKM) {
|
||||
MuxedSKM mskm = (MuxedSKM) skm;
|
||||
mskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
cfg.setGarlicReplyKeys(null);
|
||||
} else {
|
||||
// ElG-only won't work, fall back to expl.
|
||||
pairedTunnel = null;
|
||||
}
|
||||
} else {
|
||||
// no client SKM, fall back to expl.
|
||||
pairedTunnel = null;
|
||||
}
|
||||
replySKM = ctx.clientManager().getClientSessionKeyManager(from);
|
||||
if (replySKM == null && cfg.getGarlicReplyKeys() != null) {
|
||||
// no client SKM, fall back to expl.
|
||||
pairedTunnel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,13 +198,7 @@ abstract class BuildRequestor {
|
||||
pairedTunnel = null;
|
||||
}
|
||||
if (pairedTunnel != null) {
|
||||
OneTimeSession ots = cfg.getGarlicReplyKeys();
|
||||
if (ots != null) {
|
||||
SessionKeyManager skm = ctx.sessionKeyManager();
|
||||
RatchetSKM rskm = (RatchetSKM) skm;
|
||||
rskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
cfg.setGarlicReplyKeys(null);
|
||||
}
|
||||
replySKM = ctx.sessionKeyManager();
|
||||
}
|
||||
}
|
||||
if (pairedTunnel != null && log.shouldLog(Log.INFO))
|
||||
@ -305,6 +279,21 @@ abstract class BuildRequestor {
|
||||
}
|
||||
OutNetMessage outMsg = new OutNetMessage(ctx, msg, ctx.clock().now() + FIRST_HOP_TIMEOUT, PRIORITY, peer);
|
||||
outMsg.setOnFailedSendJob(new TunnelBuildFirstHopFailJob(ctx, cfg, exec));
|
||||
OneTimeSession ots = cfg.getGarlicReplyKeys();
|
||||
if (ots != null && replySKM != null) {
|
||||
if (replySKM instanceof RatchetSKM) {
|
||||
RatchetSKM rskm = (RatchetSKM) replySKM;
|
||||
rskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
} else if (replySKM instanceof MuxedSKM) {
|
||||
MuxedSKM mskm = (MuxedSKM) replySKM;
|
||||
mskm.tagsReceived(ots.key, ots.rtag, 2 * BUILD_MSG_TIMEOUT);
|
||||
} else {
|
||||
// non-EC client, shouldn't happen, checked at top of createTunnelBuildMessage() below
|
||||
if (log.shouldWarn())
|
||||
log.warn("Unsupported SKM for garlic reply to: " + cfg);
|
||||
}
|
||||
cfg.setGarlicReplyKeys(null);
|
||||
}
|
||||
try {
|
||||
ctx.outNetMessagePool().add(outMsg);
|
||||
} catch (RuntimeException re) {
|
||||
@ -345,8 +334,8 @@ abstract class BuildRequestor {
|
||||
Hash replyRouter;
|
||||
boolean useVariable = SEND_VARIABLE && cfg.getLength() <= MEDIUM_RECORDS;
|
||||
boolean useShortTBM = SEND_SHORT && ctx.keyManager().getPublicKey().getType() == EncType.ECIES_X25519;
|
||||
if (useShortTBM && !pool.getSettings().isExploratory()) {
|
||||
// pool must be EC also
|
||||
if (useShortTBM && !cfg.isInbound() && !pool.getSettings().isExploratory()) {
|
||||
// client must be EC also to get garlic OTBRM reply
|
||||
LeaseSetKeys lsk = ctx.keyManager().getKeys(pool.getSettings().getDestination());
|
||||
if (lsk != null) {
|
||||
if (!lsk.isSupported(EncType.ECIES_X25519))
|
||||
|
Reference in New Issue
Block a user