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 c38b3cbb2d..10202eda48 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -11,6 +11,7 @@ import net.i2p.data.DataHelper; import net.i2p.data.EmptyProperties; import net.i2p.data.Hash; +import net.i2p.data.i2np.DatabaseStoreMessage; import net.i2p.data.router.RouterIdentity; import net.i2p.data.router.RouterInfo; import net.i2p.data.TunnelId; @@ -470,6 +471,48 @@ private long handleRequest(BuildMessageState state, long now) { _context.commSystem().mayDisconnect(from); return -1; } + // get my own RouterInfo + RouterInfo myRI = _context.router().getRouterInfo(); + if (myRI != null) { + String caps = myRI.getCapabilities(); + if (caps != null) { + if (caps.indexOf(Router.CAPABILITY_NO_TUNNELS) >= 0){ + _context.statManager().addRateData("tunnel.dropTunnelFromCongestionCapability", 1); + if (_log.shouldLog(Log.WARN)) + _log.warn("Drop request, we are denying tunnels due to congestion: " + from); + RouterInfo fromRI = _context.floodfillNetDb().lookupRouterInfoLocally(from); + if (fromRI != null){ + String fromVersion = fromRI.getVersion(); + // if fromVersion is greater than 0.9.58, then then ban the router due to it disrespecting our + // congestion flags + if (fromVersion != null){ + if (VersionComparator.comp(fromVersion, MIN_VERSION_HONOR_CAPS) >= 0) { + _context.statManager().addRateData("tunnel.dropTunnelFromVersion"+from, 1); + long knocks = _context.statManager().getRate("tunnel.dropTunnelFromVersion"+from).getLifetimeEventCount(); + if (knocks > 10) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Banning peer: " + fromRI.getHash() + " due to it disrespecting our congestion flags"); + _context.banlist().banlistRouter(from, "disrespected our tunnel flags", null, false); + } else if (knocks <= 1) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Replying with our RouterInfo to peer:" +fromRI.getHash() + + " to give it a chance to update their own netDb and stop asking for new tunnels"); + // send the peer our RouterInfo + int TIMEOUT = 10*1000; + DatabaseStoreMessage dsm = new DatabaseStoreMessage(_context); + dsm.setMessageExpiration(_context.clock().now() + TIMEOUT); + dsm.setEntry(myRI); + OutNetMessage outMsg = new OutNetMessage(_context, dsm, _context.clock().now() + TIMEOUT, PRIORITY, fromRI); + _context.outNetMessagePool().add(outMsg); + } + + } + } + } + return -1; + } + } + } if (timeSinceReceived > (BuildRequestor.REQUEST_TIMEOUT*3)) { // don't even bother, since we are so overloaded locally