forked from I2P_Developers/i2p.i2p
Tunnels: Ban peer on excessive build requests
Drop requests if previous or next peer is banned Console: Drop peer when manually banned Update: Drop peer when banlisted
This commit is contained in:
@@ -651,8 +651,10 @@ class NewsFetcher extends UpdateRunner {
|
||||
continue;
|
||||
}
|
||||
Hash h = Hash.create(b);
|
||||
if (!ban.isBanlistedForever(h))
|
||||
if (!ban.isBanlistedForever(h)) {
|
||||
ban.banlistRouterForever(h, reason);
|
||||
_context.commSystem().forceDisconnect(h);
|
||||
}
|
||||
} else {
|
||||
byte[] ip = Addresses.getIP(s);
|
||||
if (ip == null) {
|
||||
|
||||
@@ -22,6 +22,7 @@ public class ConfigPeerHandler extends FormHandler {
|
||||
Hash h = getHash();
|
||||
if (h != null) {
|
||||
_context.banlist().banlistRouterForever(h, _t("Manually banned via {0}"), "<a href=\"configpeer\">configpeer</a>");
|
||||
_context.commSystem().forceDisconnect(h);
|
||||
addFormNotice(_t("Peer") + " " + _peer + " " + _t("banned until restart") );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
2021-11-21 zzz
|
||||
* Console: Drop peer when manually banned
|
||||
* Tunnels:
|
||||
- Ban peer on excessive build requests
|
||||
- Drop requests if previous or next peer is banned
|
||||
* Update: Drop peer when banlisted
|
||||
|
||||
2021-11-12 zzz
|
||||
* Tunnels: Improve build success when at conn limits
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ Sybil:47.90.120.30
|
||||
Sybil:47.208.97.112
|
||||
Sybil:51.211.161.115
|
||||
Sybil:66.42.58.61
|
||||
Tunnels:93.157.12.248
|
||||
Sybil:95.47.57.0/24
|
||||
Sybil:95.85.100.0/22
|
||||
Sybil:95.85.104.0/22
|
||||
@@ -135,3 +136,4 @@ Sybil:2400;8500;1302;819;a150;95;134;1590
|
||||
Sybil:2400;8500;1302;824;a150;95;144;951
|
||||
Sybil:2400;8500;1302;825;150;95;147;89
|
||||
Sybil:2400;8500;1302;828;a150;95;153;2202
|
||||
Tunnels:JbifzqZZqeTXtxK6KDqNUPWaW-phKqeS~tfJT82SIYI=
|
||||
|
||||
@@ -18,10 +18,10 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Git";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 5;
|
||||
public final static long BUILD = 6;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
public final static String EXTRA = "-rc";
|
||||
public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + FULL_VERSION);
|
||||
|
||||
@@ -33,6 +33,7 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||
import static net.i2p.router.transport.ntcp.OutboundNTCP2State.*;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ByteArrayStream;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
@@ -181,8 +182,8 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
|
||||
InetAddress addr = this._con.getChannel().socket().getInetAddress();
|
||||
byte[] ip = (addr == null) ? null : addr.getAddress();
|
||||
if (_context.banlist().isBanlistedForever(aliceHash)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Dropping inbound connection from permanently banlisted peer: " + aliceHash);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Dropping inbound connection from permanently banlisted peer at " + Addresses.toString(ip) + " : " + aliceHash);
|
||||
// So next time we will not accept the con from this IP,
|
||||
// rather than doing the whole handshake
|
||||
if(ip != null)
|
||||
|
||||
@@ -467,6 +467,13 @@ class BuildHandler implements Runnable {
|
||||
Hash from = state.fromHash;
|
||||
if (from == null && state.from != null)
|
||||
from = state.from.calculateHash();
|
||||
if (from != null && _context.banlist().isBanlisted(from)) {
|
||||
// Usually won't have connected, but may have been banlisted after connect
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Drop request, previous peer is banned: " + from);
|
||||
_context.commSystem().mayDisconnect(from);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (timeSinceReceived > (BuildRequestor.REQUEST_TIMEOUT*3)) {
|
||||
// don't even bother, since we are so overloaded locally
|
||||
@@ -499,13 +506,15 @@ class BuildHandler implements Runnable {
|
||||
return -1;
|
||||
}
|
||||
|
||||
long beforeLookup = System.currentTimeMillis();
|
||||
Hash nextPeer = req.readNextIdentity();
|
||||
long readPeerTime = System.currentTimeMillis()-beforeLookup;
|
||||
if (_context.banlist().isBanlisted(nextPeer)) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Drop request, next peer is banned: " + nextPeer);
|
||||
if (from != null)
|
||||
_context.commSystem().mayDisconnect(from);
|
||||
return -1;
|
||||
}
|
||||
RouterInfo nextPeerInfo = _context.netDb().lookupRouterInfoLocally(nextPeer);
|
||||
long lookupTime = System.currentTimeMillis()-beforeLookup;
|
||||
if (lookupTime > 500 && _log.shouldLog(Log.WARN))
|
||||
_log.warn("Took too long to lookup the request: " + lookupTime + "/" + readPeerTime + " for " + req);
|
||||
if (nextPeerInfo == null) {
|
||||
// limit concurrent next-hop lookups to prevent job queue overload attacks
|
||||
int numTunnels = _context.tunnelManager().getParticipatingCount();
|
||||
@@ -549,7 +558,7 @@ class BuildHandler implements Runnable {
|
||||
+ " ID: " + state.msg.getUniqueId()
|
||||
+ " handled and we know the next peer "
|
||||
+ nextPeer + " after " + handleTime
|
||||
+ "/" + decryptTime + "/" + lookupTime + "/" + timeSinceReceived);
|
||||
+ "/" + decryptTime + "/" + timeSinceReceived);
|
||||
return handleTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.router.tunnel.pool;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
|
||||
@@ -30,6 +31,7 @@ import net.i2p.util.SimpleTimer;
|
||||
class ParticipatingThrottler {
|
||||
private final RouterContext context;
|
||||
private final ObjectCounter<Hash> counter;
|
||||
private final Log _log;
|
||||
|
||||
/** portion of the tunnel lifetime */
|
||||
private static final int LIFETIME_PORTION = 3;
|
||||
@@ -41,6 +43,7 @@ class ParticipatingThrottler {
|
||||
ParticipatingThrottler(RouterContext ctx) {
|
||||
this.context = ctx;
|
||||
this.counter = new ObjectCounter<Hash>();
|
||||
_log = ctx.logManager().getLog(ParticipatingThrottler.class);
|
||||
ctx.simpleTimer2().addPeriodicEvent(new Cleaner(), CLEAN_TIME);
|
||||
}
|
||||
|
||||
@@ -48,7 +51,16 @@ class ParticipatingThrottler {
|
||||
boolean shouldThrottle(Hash h) {
|
||||
int numTunnels = this.context.tunnelManager().getParticipatingCount();
|
||||
int limit = Math.max(MIN_LIMIT, Math.min(MAX_LIMIT, numTunnels * PERCENT_LIMIT / 100));
|
||||
return this.counter.increment(h) > limit;
|
||||
int count = counter.increment(h);
|
||||
boolean rv = count > limit;
|
||||
if (rv && count == 2 * limit) {
|
||||
context.banlist().banlistRouter(h, "Excess participating tunnels", null, null, context.clock().now() + 30*60*1000);
|
||||
// drop after any accepted tunnels have expired
|
||||
context.simpleTimer2().addEvent(new Disconnector(h), 11*60*1000);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Banning router for excess part. tunnels, limit: " + limit + " count: " + count + ' ' + h.toBase64());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private class Cleaner implements SimpleTimer.TimedEvent {
|
||||
@@ -56,4 +68,15 @@ class ParticipatingThrottler {
|
||||
ParticipatingThrottler.this.counter.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.52
|
||||
*/
|
||||
private class Disconnector implements SimpleTimer.TimedEvent {
|
||||
private final Hash h;
|
||||
public Disconnector(Hash h) { this.h = h; }
|
||||
public void timeReached() {
|
||||
context.commSystem().forceDisconnect(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.router.tunnel.pool;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
|
||||
@@ -15,6 +16,7 @@ import net.i2p.util.SimpleTimer;
|
||||
class RequestThrottler {
|
||||
private final RouterContext context;
|
||||
private final ObjectCounter<Hash> counter;
|
||||
private final Log _log;
|
||||
|
||||
/** portion of the tunnel lifetime */
|
||||
private static final int LIFETIME_PORTION = 6;
|
||||
@@ -26,6 +28,7 @@ class RequestThrottler {
|
||||
RequestThrottler(RouterContext ctx) {
|
||||
this.context = ctx;
|
||||
this.counter = new ObjectCounter<Hash>();
|
||||
_log = ctx.logManager().getLog(RequestThrottler.class);
|
||||
ctx.simpleTimer2().addPeriodicEvent(new Cleaner(), CLEAN_TIME);
|
||||
}
|
||||
|
||||
@@ -33,7 +36,16 @@ class RequestThrottler {
|
||||
boolean shouldThrottle(Hash h) {
|
||||
int numTunnels = this.context.tunnelManager().getParticipatingCount();
|
||||
int limit = Math.max(MIN_LIMIT, Math.min(MAX_LIMIT, numTunnels * PERCENT_LIMIT / 100));
|
||||
return this.counter.increment(h) > limit;
|
||||
int count = counter.increment(h);
|
||||
boolean rv = count > limit;
|
||||
if (rv && count == 2 * limit) {
|
||||
context.banlist().banlistRouter(h, "Excess tunnel requests", null, null, context.clock().now() + 30*60*1000);
|
||||
// drop after any accepted tunnels have expired
|
||||
context.simpleTimer2().addEvent(new Disconnector(h), 11*60*1000);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Banning router for excess tunnel requests, limit: " + limit + " count: " + count + ' ' + h.toBase64());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private class Cleaner implements SimpleTimer.TimedEvent {
|
||||
@@ -41,4 +53,15 @@ class RequestThrottler {
|
||||
RequestThrottler.this.counter.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.52
|
||||
*/
|
||||
private class Disconnector implements SimpleTimer.TimedEvent {
|
||||
private final Hash h;
|
||||
public Disconnector(Hash h) { this.h = h; }
|
||||
public void timeReached() {
|
||||
context.commSystem().forceDisconnect(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user