Peer[] detectPrimaryPeers() {
final boolean logMINOR = NodeIPPortDetector.logMINOR;
ArrayList<Peer> addresses = new ArrayList<Peer>();
FreenetInetAddress[] addrs = detectPrimaryIPAddress();
for(FreenetInetAddress addr: addrs) {
addresses.add(new Peer(addr, crypto.portNumber));
if(logMINOR)
Logger.minor(this, "Adding "+addr);
}
// Now try to get the rewritten port number from our peers.
// Only considering those within this crypto port, this time.
PeerNode[] peerList = crypto.getPeerNodes();
if(peerList != null) {
HashMap<Peer,Integer> countsByPeer = new HashMap<Peer,Integer>();
// FIXME use a standard mutable int object, we have one somewhere
for(PeerNode pn: peerList) {
Peer p = pn.getRemoteDetectedPeer();
if((p == null) || p.isNull()) continue;
// DNSRequester doesn't deal with our own node
if(!IPUtil.isValidAddress(p.getAddress(true), false)) continue;
if(logMINOR)
Logger.minor(this, "Peer "+pn.getPeer()+" thinks we are "+p);
if(countsByPeer.containsKey(p)) {
countsByPeer.put(p, countsByPeer.get(p) + 1);
} else {
countsByPeer.put(p, 1);
}
}
if(countsByPeer.size() == 1) {
Iterator<Peer> it = countsByPeer.keySet().iterator();
Peer p = (it.next());
Logger.minor(this, "Everyone agrees we are "+p);
if(!addresses.contains(p)) {
addresses.add(p);
}
} else if(countsByPeer.size() > 1) {
// Take two most popular addresses.
Peer best = null;
Peer secondBest = null;
int bestPopularity = 0;
int secondBestPopularity = 0;
for (Map.Entry<Peer,Integer> entry : countsByPeer.entrySet()) {
Peer cur = entry.getKey();
int curPop = entry.getValue();
Logger.normal(this, "Detected peer: "+cur+" popularity "+curPop);
if(curPop >= bestPopularity) {
secondBestPopularity = bestPopularity;
bestPopularity = curPop;
secondBest = best;
best = cur;
}
}
if(best != null) {
if((bestPopularity > 1) || (addrs.length == 0)) {
if(!addresses.contains(best)) {
Logger.normal(this, "Adding best peer "+best+" ("+bestPopularity+ ')');
addresses.add(best);
}
if((secondBest != null) && (secondBestPopularity > 1)) {
if(!addresses.contains(secondBest)) {
Logger.normal(this, "Adding second best peer "+secondBest+" ("+secondBest+ ')');
addresses.add(secondBest);
}
if(best.getAddress().equals(secondBest.getAddress()) && bestPopularity == 1) {
Logger.error(this, "Hrrrm, maybe this is a symmetric NAT? Expect trouble connecting!");
System.err.println("Hrrrm, maybe this is a symmetric NAT? Expect trouble connecting!");
ipDetector.setMaybeSymmetric();
Peer p = new Peer(best.getFreenetAddress(), crypto.portNumber);
if(!addresses.contains(p))
addresses.add(p);
}
}