public InetAddress getAddress(boolean doDNSRequest, boolean allowLocal) throws LocalAddressException { InetAddress a = addr.getAddress(doDNSRequest); if (a == null) return null; if (allowLocal || IPUtil.isValidAddress(a, false)) return a; throw new LocalAddressException(); }
/** * Get our Peer's. This is a list of IP:port's at which we might be contactable. Some of them will * have the same port as the listenPort, but if we are behind a NAT which rewrites our port * number, some of them may not. (If we're behind a symmetric NAT which rewrites it differently * for each connection, we're stuffed, and we tell the user). */ 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); } } } } } } lastPeers = addresses.toArray(new Peer[addresses.size()]); if (logMINOR) Logger.minor( this, "Returning for port " + crypto.portNumber + " : " + Arrays.toString(lastPeers)); return lastPeers; }