diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/DHTNodes.java b/apps/i2psnark/java/src/org/klomp/snark/dht/DHTNodes.java index 1b2ae428e7c3aea0ac8542c84bb5a3e3803256bc..64a650bae8b2fb08a3c2643d7f78a9152858bc44 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/dht/DHTNodes.java +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/DHTNodes.java @@ -46,13 +46,15 @@ class DHTNodes { private static final int MAX_PEERS = 799; /** Buckets older than this are refreshed - BEP 5 says 15 minutes */ 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) { _context = ctx; _expireTime = MAX_EXPIRE_TIME; _log = _context.logManager().getLog(DHTNodes.class); _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() { diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/KBTrimmer.java b/apps/i2psnark/java/src/org/klomp/snark/dht/KBTrimmer.java new file mode 100644 index 0000000000000000000000000000000000000000..96809cbc214b27e9720d4b846c7962f13aab90b2 --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/KBTrimmer.java @@ -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; + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/MsgID.java b/apps/i2psnark/java/src/org/klomp/snark/dht/MsgID.java index 6d53f7c8fb1a17bee2815aa54b6908f56766020e..c28fba5c70ac5eb0cd5c096e44764f6a08ed4d91 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/dht/MsgID.java +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/MsgID.java @@ -14,7 +14,9 @@ import net.i2p.data.ByteArray; */ class MsgID extends ByteArray { + /** BEP 5: 2 bytes, incremented */ private static final int MY_TOK_LEN = 8; + private static final int MAX_TOK_LEN = 16; /** outgoing - generate a random ID */ public MsgID(I2PAppContext ctx) { @@ -28,5 +30,8 @@ class MsgID extends ByteArray { /** incoming - save the ID (arbitrary length) */ public MsgID(byte[] data) { super(data); + // lets not get carried away + if (data.length > MAX_TOK_LEN) + throw new IllegalArgumentException(); } }