forked from I2P_Developers/i2p.i2p
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:
@@ -10,8 +10,11 @@ package net.i2p.router.peermanager;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Hash;
|
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
|
* 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;
|
int numPasses = 0;
|
||||||
Set rv = new HashSet(criteria.getMinimumRequired());
|
List rv = new ArrayList(criteria.getMinimumRequired());
|
||||||
Set exclude = new HashSet(1);
|
Set exclude = new HashSet(1);
|
||||||
exclude.add(_context.routerHash());
|
exclude.add(_context.routerHash());
|
||||||
while (rv.size() < criteria.getMinimumRequired()) {
|
while (rv.size() < criteria.getMinimumRequired()) {
|
||||||
@@ -86,7 +89,12 @@ class PeerManager {
|
|||||||
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
|
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
|
||||||
break;
|
break;
|
||||||
case PeerSelectionCriteria.PURPOSE_TUNNEL:
|
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;
|
break;
|
||||||
case PeerSelectionCriteria.PURPOSE_SOURCE_ROUTE:
|
case PeerSelectionCriteria.PURPOSE_SOURCE_ROUTE:
|
||||||
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
|
_organizer.selectHighCapacityPeers(criteria.getMinimumRequired(), exclude, curVals);
|
||||||
@@ -111,7 +119,8 @@ class PeerManager {
|
|||||||
if (null != _context.netDb().lookupRouterInfoLocally(peer)) {
|
if (null != _context.netDb().lookupRouterInfoLocally(peer)) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Peer " + peer.toBase64() + " is locally known, so we'll allow its selection");
|
_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 {
|
} else {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Peer " + peer.toBase64() + " is NOT locally known, disallowing its selection");
|
_log.debug("Peer " + peer.toBase64() + " is NOT locally known, disallowing its selection");
|
||||||
@@ -123,6 +132,29 @@ class PeerManager {
|
|||||||
}
|
}
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Peers selected after " + numPasses + ": " + rv);
|
_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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ public class PeerManagerFacadeImpl implements PeerManagerFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List selectPeers(PeerSelectionCriteria criteria) {
|
public List selectPeers(PeerSelectionCriteria criteria) {
|
||||||
return new ArrayList(_manager.selectPeers(criteria));
|
return _manager.selectPeers(criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||||
|
@@ -89,7 +89,7 @@ public class PeerTestJob extends JobImpl {
|
|||||||
criteria.setMinimumRequired(getTestConcurrency());
|
criteria.setMinimumRequired(getTestConcurrency());
|
||||||
criteria.setMaximumRequired(getTestConcurrency());
|
criteria.setMaximumRequired(getTestConcurrency());
|
||||||
criteria.setPurpose(PeerSelectionCriteria.PURPOSE_TEST);
|
criteria.setPurpose(PeerSelectionCriteria.PURPOSE_TEST);
|
||||||
Set peerHashes = _manager.selectPeers(criteria);
|
List peerHashes = _manager.selectPeers(criteria);
|
||||||
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Peer selection found " + peerHashes.size() + " peers");
|
_log.debug("Peer selection found " + peerHashes.size() + " peers");
|
||||||
|
Reference in New Issue
Block a user