diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index c551cc13579ce6690ce01369dce3d4a322dc99df..361966c5d38feac591657e17247da3df4b33236d 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -629,6 +629,12 @@ class BuildHandler implements Runnable { boolean isInGW = req.readIsInboundGateway(); boolean isOutEnd = req.readIsOutboundEndpoint(); + Hash from = state.fromHash; + if (from == null && state.from != null) + from = state.from.calculateHash(); + // warning, from could be null, but it should only + // happen if we will be a IBGW and it came from us as a OBEP + if (isInGW && isOutEnd) { _context.statManager().addRateData("tunnel.rejectHostile", 1); _log.error("Dropping build request, IBGW+OBEP"); @@ -645,21 +651,17 @@ class BuildHandler implements Runnable { _log.warn("Dropping build request, we are the next hop"); return; } - // previous test should be sufficient to keep it from getting here but maybe not? if (!isInGW) { - Hash from = state.fromHash; - if (from == null && state.from != null) - from = state.from.calculateHash(); - if (_context.routerHash().equals(from)) { + // if from is null, it came via OutboundMessageDistributor.distribute(), + // i.e. we were the OBEP, which is fine if we're going to be an IBGW + // but if not, something is seriously wrong here. + if (from == null || _context.routerHash().equals(from)) { _context.statManager().addRateData("tunnel.rejectHostile", 1); _log.error("Dropping build request, we are the previous hop"); return; } } if ((!isOutEnd) && (!isInGW)) { - Hash from = state.fromHash; - if (from == null && state.from != null) - from = state.from.calculateHash(); // Previous and next hop the same? Don't help somebody be evil. Drop it without a reply. // A-B-C-A is not preventable if (nextPeer.equals(from)) { @@ -761,9 +763,6 @@ class BuildHandler implements Runnable { // 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) { - Hash from = state.fromHash; - if (from == null && state.from != null) - from = state.from.calculateHash(); if (from != null && _throttler.shouldThrottle(from)) { if (_log.shouldLog(Log.WARN)) _log.warn("Rejecting tunnel (hop throttle), previous hop: " + from); @@ -784,8 +783,7 @@ class BuildHandler implements Runnable { if (_log.shouldLog(Log.DEBUG)) _log.debug("Responding to " + state.msg.getUniqueId() + "/" + ourId + " after " + recvDelay + " with " + response - + " from " + (state.fromHash != null ? state.fromHash : - state.from != null ? state.from.calculateHash() : "tunnel")); + + " from " + (from != null ? from : "tunnel")); HopConfig cfg = null; if (response == 0) { @@ -798,10 +796,8 @@ class BuildHandler implements Runnable { // default //cfg.setReceiveFrom(null); } else { - if (state.fromHash != null) { - cfg.setReceiveFrom(state.fromHash); - } else if (state.from != null) { - cfg.setReceiveFrom(state.from.calculateHash()); + if (from != null) { + cfg.setReceiveFrom(from); } else { // b0rk return; @@ -838,27 +834,28 @@ class BuildHandler implements Runnable { _log.warn("DUP ID failure " + state.msg.getUniqueId() + "/" + cfg.getReceiveTunnel() + " as " + (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant")); } } + + // determination of response is now complete + if (response != 0) { _context.statManager().addRateData("tunnel.reject." + response, 1); - _context.messageHistory().tunnelRejected(state.fromHash, new TunnelId(ourId), nextPeer, + _context.messageHistory().tunnelRejected(from, new TunnelId(ourId), nextPeer, "rejecting for " + response + ": " + state.msg.getUniqueId() + "/" + ourId + "/" + req.readNextTunnelId() + " delay " + recvDelay + " as " + (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant")); - } - - // Connection congestion control: - // If we rejected the request, are near our conn limits, and aren't connected to the next hop, - // just drop it. - // 81% = between 75% control measures in Transports and 87% rejection above - if (response != 0 && - (! _context.routerHash().equals(nextPeer)) && - (! _context.commSystem().haveOutboundCapacity(81)) && - (! _context.commSystem().isEstablished(nextPeer))) { - _context.statManager().addRateData("tunnel.dropConnLimits", 1); - if (_log.shouldLog(Log.WARN)) - _log.warn("Not sending rejection due to conn limits"); - return; + // Connection congestion control: + // If we rejected the request, are near our conn limits, and aren't connected to the next hop, + // just drop it. + // 81% = between 75% control measures in Transports and 87% rejection above + if ((! _context.routerHash().equals(nextPeer)) && + (! _context.commSystem().haveOutboundCapacity(81)) && + (! _context.commSystem().isEstablished(nextPeer))) { + _context.statManager().addRateData("tunnel.dropConnLimits", 1); + if (_log.shouldLog(Log.WARN)) + _log.warn("Not sending rejection due to conn limits"); + return; + } } EncryptedBuildRecord reply = BuildResponseRecord.create(_context, response, req.readReplyKey(), req.readReplyIV(), state.msg.getUniqueId()); @@ -934,6 +931,11 @@ class BuildHandler implements Runnable { * but could also be the reply where we are the IBEP. */ private class TunnelBuildMessageHandlerJobBuilder implements HandlerJobBuilder { + + /** + * Either from or fromHash may be null, but both should be null only if + * we're to be a IBGW and it came from us as a OBEP. + */ public Job createJob(I2NPMessage receivedMessage, RouterIdentity from, Hash fromHash) { // need to figure out if this is a reply to an inbound tunnel request (where we are the // endpoint, receiving the request at the last hop) @@ -1060,6 +1062,10 @@ class BuildHandler implements Runnable { final Hash fromHash; final long recvTime; + /** + * Either f or h may be null, but both should be null only if + * we're to be a IBGW and it came from us as a OBEP. + */ public BuildMessageState(RouterContext ctx, I2NPMessage m, RouterIdentity f, Hash h) { _ctx = ctx; msg = (TunnelBuildMessage)m;