enforce diversification of tunnel participants.

when picking peers to participate in a tunnel, we still select from the 'fast' tier,
except now we pick the ones that have least recently agreed to participate in a tunnel.
(they're already in the fast tier, so they're reliable [ish]).
the diversification has been pretty good so far, but i'm going to leave 'er running and monitor it overnight
This commit is contained in:
jrandom
2004-08-17 05:20:17 +00:00
committed by zzz
parent 8e9c541eba
commit 2f8993995b
3 changed files with 38 additions and 6 deletions

View File

@@ -10,8 +10,11 @@ package net.i2p.router.peermanager;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
import java.util.Set;
import net.i2p.data.Hash;
@@ -72,9 +75,9 @@ class PeerManager {
* Find some peers that meet the criteria and we have the netDb info for locally
*
*/
Set selectPeers(PeerSelectionCriteria criteria) {
List selectPeers(PeerSelectionCriteria criteria) {
int numPasses = 0;
Set rv = new HashSet(criteria.getMinimumRequired());
List rv = new ArrayList(criteria.getMinimumRequired());
Set exclude = new HashSet(1);
exclude.add(_context.routerHash());
while (rv.size() < criteria.getMinimumRequired()) {
@@ -86,7 +89,12 @@ class PeerManager {
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
break;
case PeerSelectionCriteria.PURPOSE_TUNNEL:
_organizer.selectFastPeers(criteria.getMinimumRequired(), exclude, curVals);
// pull all of the fast ones, regardless of how many we
// want - we'll whittle them down later (40 lines from now)
int num = _organizer.countFastPeers();
if (num <= 0)
num = criteria.getMaximumRequired();
_organizer.selectFastPeers(num, exclude, curVals);
break;
case PeerSelectionCriteria.PURPOSE_SOURCE_ROUTE:
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
@@ -111,7 +119,8 @@ class PeerManager {
if (null != _context.netDb().lookupRouterInfoLocally(peer)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer " + peer.toBase64() + " is locally known, so we'll allow its selection");
rv.add(peer);
if (!rv.contains(peer))
rv.add(peer);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer " + peer.toBase64() + " is NOT locally known, disallowing its selection");
@@ -123,6 +132,29 @@ class PeerManager {
}
if (_log.shouldLog(Log.INFO))
_log.info("Peers selected after " + numPasses + ": " + rv);
if (criteria.getPurpose() == PeerSelectionCriteria.PURPOSE_TUNNEL) {
// we selected extra peers above. now lets strip that down to the
// minimum requested, ordering it by the least recently agreed to
// first
TreeMap ordered = new TreeMap();
for (Iterator iter = rv.iterator(); iter.hasNext(); ) {
Hash peer = (Hash)iter.next();
PeerProfile prof = _organizer.getProfile(peer);
long when = prof.getTunnelHistory().getLastAgreedTo();
while (ordered.containsKey(new Long(when)))
when++;
ordered.put(new Long(when), peer);
}
rv.clear();
for (Iterator iter = ordered.values().iterator(); iter.hasNext(); ) {
if (rv.size() >= criteria.getMaximumRequired()) break;
Hash peer = (Hash)iter.next();
rv.add(peer);
}
if (_log.shouldLog(Log.INFO))
_log.info("Peers selected after " + numPasses + ", sorted for a tunnel: " + rv);
}
return rv;
}

View File

@@ -56,7 +56,7 @@ public class PeerManagerFacadeImpl implements PeerManagerFacade {
}
public List selectPeers(PeerSelectionCriteria criteria) {
return new ArrayList(_manager.selectPeers(criteria));
return _manager.selectPeers(criteria);
}
public void renderStatusHTML(OutputStream out) throws IOException {

View File

@@ -89,7 +89,7 @@ public class PeerTestJob extends JobImpl {
criteria.setMinimumRequired(getTestConcurrency());
criteria.setMaximumRequired(getTestConcurrency());
criteria.setPurpose(PeerSelectionCriteria.PURPOSE_TEST);
Set peerHashes = _manager.selectPeers(criteria);
List peerHashes = _manager.selectPeers(criteria);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer selection found " + peerHashes.size() + " peers");