forked from I2P_Developers/i2p.i2p
i2psnark:
- Add new flood-resistant KBucket trim policy - Limit received MsgID size
This commit is contained in:
@ -46,13 +46,15 @@ class DHTNodes {
|
|||||||
private static final int MAX_PEERS = 799;
|
private static final int MAX_PEERS = 799;
|
||||||
/** Buckets older than this are refreshed - BEP 5 says 15 minutes */
|
/** Buckets older than this are refreshed - BEP 5 says 15 minutes */
|
||||||
private static final long MAX_BUCKET_AGE = 15*60*1000;
|
private static final long MAX_BUCKET_AGE = 15*60*1000;
|
||||||
|
private static final int KAD_K = 8;
|
||||||
|
private static final int KAD_B = 1;
|
||||||
|
|
||||||
public DHTNodes(I2PAppContext ctx, NID me) {
|
public DHTNodes(I2PAppContext ctx, NID me) {
|
||||||
_context = ctx;
|
_context = ctx;
|
||||||
_expireTime = MAX_EXPIRE_TIME;
|
_expireTime = MAX_EXPIRE_TIME;
|
||||||
_log = _context.logManager().getLog(DHTNodes.class);
|
_log = _context.logManager().getLog(DHTNodes.class);
|
||||||
_nodeMap = new ConcurrentHashMap();
|
_nodeMap = new ConcurrentHashMap();
|
||||||
_kad = new KBucketSet(ctx, me, 8, 1);
|
_kad = new KBucketSet(ctx, me, KAD_K, KAD_B, new KBTrimmer(ctx, KAD_K));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
37
apps/i2psnark/java/src/org/klomp/snark/dht/KBTrimmer.java
Normal file
37
apps/i2psnark/java/src/org/klomp/snark/dht/KBTrimmer.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package org.klomp.snark.dht;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.kademlia.KBucket;
|
||||||
|
import net.i2p.kademlia.KBucketSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an element older than 15 minutes, but only if the bucket hasn't changed in 5 minutes.
|
||||||
|
*/
|
||||||
|
class KBTrimmer implements KBucketSet.KBucketTrimmer<NID> {
|
||||||
|
private final I2PAppContext _ctx;
|
||||||
|
private final int _max;
|
||||||
|
|
||||||
|
private static final long MIN_BUCKET_AGE = 5*60*1000;
|
||||||
|
private static final long MAX_NODE_AGE = 15*60*1000;
|
||||||
|
|
||||||
|
public KBTrimmer(I2PAppContext ctx, int max) {
|
||||||
|
_ctx = ctx;
|
||||||
|
_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean trim(KBucket<NID> kbucket, NID toAdd) {
|
||||||
|
long now = _ctx.clock().now();
|
||||||
|
if (kbucket.getLastChanged() > now - MIN_BUCKET_AGE)
|
||||||
|
return false;
|
||||||
|
Set<NID> entries = kbucket.getEntries();
|
||||||
|
for (NID nid : entries) {
|
||||||
|
if (nid.lastSeen() < now - MAX_NODE_AGE) {
|
||||||
|
if (kbucket.remove(nid))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entries.size() < _max;
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,9 @@ import net.i2p.data.ByteArray;
|
|||||||
*/
|
*/
|
||||||
class MsgID extends ByteArray {
|
class MsgID extends ByteArray {
|
||||||
|
|
||||||
|
/** BEP 5: 2 bytes, incremented */
|
||||||
private static final int MY_TOK_LEN = 8;
|
private static final int MY_TOK_LEN = 8;
|
||||||
|
private static final int MAX_TOK_LEN = 16;
|
||||||
|
|
||||||
/** outgoing - generate a random ID */
|
/** outgoing - generate a random ID */
|
||||||
public MsgID(I2PAppContext ctx) {
|
public MsgID(I2PAppContext ctx) {
|
||||||
@ -28,5 +30,8 @@ class MsgID extends ByteArray {
|
|||||||
/** incoming - save the ID (arbitrary length) */
|
/** incoming - save the ID (arbitrary length) */
|
||||||
public MsgID(byte[] data) {
|
public MsgID(byte[] data) {
|
||||||
super(data);
|
super(data);
|
||||||
|
// lets not get carried away
|
||||||
|
if (data.length > MAX_TOK_LEN)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user