forked from I2P_Developers/i2p.i2p
Tunnels: Updates for proposal 157
- Fix compatibility check for OB tunnels - Add test code to send STBM to explicit peers - Skip too-many-tunnels check when in test mode - Cleanups and Log tweaks
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
2021-07-28 zzz
|
||||
* Tunnels: Fixes for proposal 157
|
||||
|
||||
2021-07-23 zzz
|
||||
* Transport: Fix UPnP IPv6 NPE
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Git";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 6;
|
||||
public final static long BUILD = 7;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -316,7 +316,6 @@ class BuildHandler implements Runnable {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(msg.getUniqueId() + ": Handling the reply after " + rtt + ", delayed " + delay + " waiting for " + cfg);
|
||||
|
||||
// TODO OTBRM
|
||||
List<Integer> order = cfg.getReplyOrder();
|
||||
int statuses[] = _buildReplyHandler.decrypt(msg, cfg, order);
|
||||
if (statuses != null) {
|
||||
@@ -628,11 +627,11 @@ class BuildHandler implements Runnable {
|
||||
_currentLookups.decrementAndGet();
|
||||
getContext().statManager().addRateData("tunnel.rejectTimeout", 1);
|
||||
getContext().statManager().addRateData("tunnel.buildLookupSuccess", 0);
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
if (_log.shouldInfo()) {
|
||||
Hash from = _state.fromHash;
|
||||
if (from == null && _state.from != null)
|
||||
from = _state.from.calculateHash();
|
||||
_log.warn("Next hop lookup failure: " + _req
|
||||
_log.info("Next hop lookup failure: " + _req
|
||||
+ " From: " + from
|
||||
+ " ID: " + _state.msg.getUniqueId());
|
||||
}
|
||||
@@ -1025,8 +1024,9 @@ class BuildHandler implements Runnable {
|
||||
}
|
||||
replyMsg.setUniqueId(req.readReplyMessageId());
|
||||
replyMsg.setMessageExpiration(expires);
|
||||
boolean replyGwIsUs = _context.routerHash().equals(nextPeer);
|
||||
I2NPMessage outMessage;
|
||||
if (state.msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE) {
|
||||
if (!replyGwIsUs && state.msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE && !_context.getBooleanProperty("router.disableEncryptOTBRM")) {
|
||||
// garlic encrypt
|
||||
outMessage = MessageWrapper.wrap(_context, replyMsg, req.readGarlicKeys());
|
||||
if (outMessage == null) {
|
||||
@@ -1041,7 +1041,7 @@ class BuildHandler implements Runnable {
|
||||
m.setMessage(outMessage);
|
||||
m.setMessageExpiration(expires);
|
||||
m.setTunnelId(new TunnelId(nextId));
|
||||
if (_context.routerHash().equals(nextPeer)) {
|
||||
if (replyGwIsUs) {
|
||||
// ok, we are the gateway, so inject it
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("We are the reply gateway for " + nextId
|
||||
@@ -1282,8 +1282,8 @@ class BuildHandler implements Runnable {
|
||||
//getContext().tunnelDispatcher().remove(_cfg);
|
||||
getContext().statManager().addRateData("tunnel.rejectTimeout2", 1);
|
||||
Log log = getContext().logManager().getLog(BuildHandler.class);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Timeout contacting next hop for " + _cfg);
|
||||
if (log.shouldInfo())
|
||||
log.info("Timeout contacting next hop for " + _cfg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ abstract class BuildMessageGenerator {
|
||||
private static BuildRequestRecord createUnencryptedRecord(I2PAppContext ctx, TunnelCreatorConfig cfg, int hop,
|
||||
Hash replyRouter, long replyTunnel, boolean isEC,
|
||||
boolean isShort) {
|
||||
if (isShort && !isEC)
|
||||
throw new IllegalArgumentException();
|
||||
if (hop < cfg.getLength()) {
|
||||
// ok, now lets fill in some data
|
||||
HopConfig hopConfig = cfg.getConfig(hop);
|
||||
@@ -118,8 +120,6 @@ abstract class BuildMessageGenerator {
|
||||
nextPeer = peer; // self
|
||||
}
|
||||
}
|
||||
SessionKey layerKey = hopConfig.getLayerKey();
|
||||
SessionKey ivKey = hopConfig.getIVKey();
|
||||
boolean isInGW = (cfg.isInbound() && (hop == 0));
|
||||
boolean isOutEnd = (!cfg.isInbound() && (hop + 1 >= cfg.getLength()));
|
||||
|
||||
@@ -138,6 +138,8 @@ abstract class BuildMessageGenerator {
|
||||
nextMsgId,
|
||||
isInGW, isOutEnd, EmptyProperties.INSTANCE);
|
||||
} else {
|
||||
SessionKey layerKey = hopConfig.getLayerKey();
|
||||
SessionKey ivKey = hopConfig.getIVKey();
|
||||
SessionKey replyKey = cfg.getAESReplyKey(hop);
|
||||
byte iv[] = cfg.getAESReplyIV(hop);
|
||||
if (iv == null)
|
||||
@@ -147,6 +149,8 @@ abstract class BuildMessageGenerator {
|
||||
iv, isInGW, isOutEnd, EmptyProperties.INSTANCE);
|
||||
}
|
||||
} else {
|
||||
SessionKey layerKey = hopConfig.getLayerKey();
|
||||
SessionKey ivKey = hopConfig.getIVKey();
|
||||
SessionKey replyKey = cfg.getAESReplyKey(hop);
|
||||
byte iv[] = cfg.getAESReplyIV(hop);
|
||||
if (iv == null)
|
||||
|
||||
@@ -3,9 +3,11 @@ package net.i2p.router.tunnel.pool;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.crypto.EncType;
|
||||
import net.i2p.crypto.SessionKeyManager;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.PublicKey;
|
||||
@@ -233,7 +235,9 @@ abstract class BuildRequestor {
|
||||
//long beforeDispatch = System.currentTimeMillis();
|
||||
if (cfg.isInbound()) {
|
||||
Hash ibgw = cfg.getPeer(0);
|
||||
if (msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE) {
|
||||
// don't wrap if IBGW == OBEP
|
||||
if (msg.getType() == ShortTunnelBuildMessage.MESSAGE_TYPE &&
|
||||
!ibgw.equals(pairedTunnel.getEndpoint())) {
|
||||
// STBM is garlic encrypted to the IBGW, to hide it from the OBEP
|
||||
RouterInfo peer = ctx.netDb().lookupRouterInfoLocally(ibgw);
|
||||
if (peer != null) {
|
||||
@@ -263,6 +267,7 @@ abstract class BuildRequestor {
|
||||
if (log.shouldLog(Log.INFO))
|
||||
log.info("Sending the tunnel build request directly to " + cfg.getPeer(1)
|
||||
+ " for " + cfg + " waiting for the reply of " + cfg.getReplyMessageId()
|
||||
+ " via IB tunnel " + pairedTunnel
|
||||
+ " with msgId=" + msg.getUniqueId());
|
||||
// send it directly to the first hop
|
||||
// Add some fuzz to the TBM expiration to make it harder to guess how many hops
|
||||
@@ -345,13 +350,36 @@ abstract class BuildRequestor {
|
||||
}
|
||||
}
|
||||
|
||||
// Testing, send to explicitPeers only
|
||||
List<Hash> explicitPeers = null;
|
||||
if (useShortTBM) {
|
||||
String peers = ctx.getProperty("explicitPeers");
|
||||
if (peers != null && !peers.isEmpty()) {
|
||||
explicitPeers = new ArrayList<Hash>(4);
|
||||
StringTokenizer tok = new StringTokenizer(peers, ",");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String peerStr = tok.nextToken();
|
||||
Hash peer = new Hash();
|
||||
try {
|
||||
peer.fromBase64(peerStr);
|
||||
explicitPeers.add(peer);
|
||||
} catch (DataFormatException dfe) {}
|
||||
}
|
||||
if (explicitPeers.isEmpty())
|
||||
useShortTBM = false;
|
||||
} else {
|
||||
useShortTBM = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.isInbound()) {
|
||||
//replyTunnel = 0; // as above
|
||||
replyRouter = ctx.routerHash();
|
||||
if (useShortTBM) {
|
||||
// check all the tunnel peers except ourselves
|
||||
for (int i = 0; i < cfg.getLength() - 1; i++) {
|
||||
if (!supportsShortTBM(ctx, cfg.getPeer(i))) {
|
||||
// TODO remove explicit check
|
||||
if (!explicitPeers.contains(cfg.getPeer(i)) || !supportsShortTBM(ctx, cfg.getPeer(i))) {
|
||||
useShortTBM = false;
|
||||
break;
|
||||
}
|
||||
@@ -362,8 +390,9 @@ abstract class BuildRequestor {
|
||||
replyRouter = pairedTunnel.getPeer(0);
|
||||
if (useShortTBM) {
|
||||
// check all the tunnel peers except ourselves
|
||||
for (int i = 1; i < cfg.getLength() - 1; i++) {
|
||||
if (!supportsShortTBM(ctx, cfg.getPeer(i))) {
|
||||
for (int i = 1; i < cfg.getLength(); i++) {
|
||||
// TODO remove explicit check
|
||||
if (!explicitPeers.contains(cfg.getPeer(i)) || !supportsShortTBM(ctx, cfg.getPeer(i))) {
|
||||
useShortTBM = false;
|
||||
break;
|
||||
}
|
||||
@@ -451,6 +480,8 @@ abstract class BuildRequestor {
|
||||
BuildMessageGenerator.createRecord(i, hop, msg, cfg, replyRouter, replyTunnel, ctx, key);
|
||||
}
|
||||
BuildMessageGenerator.layeredEncrypt(ctx, msg, cfg, order);
|
||||
//if (useShortTBM && log.shouldWarn())
|
||||
// log.warn("Sending STBM: " + cfg.toStringFull());
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,9 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
||||
*/
|
||||
protected boolean shouldSelectExplicit(TunnelPoolSettings settings) {
|
||||
if (settings.isExploratory()) return false;
|
||||
// To test IB or OB only
|
||||
//if (settings.isInbound()) return false;
|
||||
//if (!settings.isInbound()) return false;
|
||||
Properties opts = settings.getUnknownOptions();
|
||||
String peers = opts.getProperty("explicitPeers");
|
||||
if (peers == null)
|
||||
@@ -216,7 +219,8 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
||||
|
||||
Set<Hash> peers = new HashSet<Hash>(8);
|
||||
peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting());
|
||||
peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
|
||||
if (!ctx.getBooleanProperty("i2np.allowLocal"))
|
||||
peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
|
||||
if (filterUnreachable(isInbound, isExploratory)) {
|
||||
// This is the only use for getPeersByCapability? And the whole set of datastructures in PeerManager?
|
||||
Collection<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
|
||||
|
||||
Reference in New Issue
Block a user