Author: toad
Date: 2006-08-24 01:09:58 +0000 (Thu, 24 Aug 2006)
New Revision: 10249
Modified:
trunk/freenet/src/freenet/node/IPDetectorPluginManager.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/NodeIPDetector.java
trunk/freenet/src/freenet/transport/IPAddressDetector.java
Log:
Lots of work on IP address detection.
Modified: trunk/freenet/src/freenet/node/IPDetectorPluginManager.java
===================================================================
--- trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2006-08-23
22:37:23 UTC (rev 10248)
+++ trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2006-08-24
01:09:58 UTC (rev 10249)
@@ -6,6 +6,8 @@
import java.util.Vector;
import freenet.io.comm.Peer;
+import freenet.node.useralerts.SimpleUserAlert;
+import freenet.node.useralerts.UserAlert;
import freenet.pluginmanager.DetectedIP;
import freenet.pluginmanager.FredPluginIPDetector;
import freenet.support.Logger;
@@ -21,12 +23,34 @@
private final Ticker ticker;
private final Node node;
FredPluginIPDetector[] plugins;
+ private SimpleUserAlert noConnectionAlert;
+ private SimpleUserAlert symmetricAlert;
+ private SimpleUserAlert portRestrictedAlert;
+ private SimpleUserAlert restrictedAlert;
+ private SimpleUserAlert connectedAlert;
IPDetectorPluginManager(Node node, NodeIPDetector detector) {
plugins = new FredPluginIPDetector[0];
this.node = node;
this.ticker = node.ps;
this.detector = detector;
+ noConnectionAlert = new SimpleUserAlert(false, "No UDP
connectivity",
+ "Your internet connection does not appear to
support UDP. " +
+ "Unless this detection is wrong, it is unlikely
that Freenet will work on your computer at present.",
+ UserAlert.CRITICAL_ERROR);
+ symmetricAlert = new SimpleUserAlert(false, "Symmetric firewall
detected",
+ "Your internet connection appears to be behind
a symmetric NAT or firewall. " +
+ "You will probably only be able to connect to
users directly connected to the internet or behind " +
+ "restricted cone NATs.", UserAlert.ERROR);
+ portRestrictedAlert = new SimpleUserAlert(true, "Port
restricted cone NAT detected",
+ "Your internet connection appears to be behind
a port-restricted NAT (router). "+
+ "You will be able to connect to most other
users, but not those behind symmetric NATs.", UserAlert.MINOR);
+ restrictedAlert = new SimpleUserAlert(true, "Restricted cone
NAT detected",
+ "Your internet connection appears to be behind
a \"restricted cone\" NAT (router). "+
+ "You should be able to connect to most other
users.", UserAlert.WARNING);
+ connectedAlert = new SimpleUserAlert(true, "Direct internet
connection detected",
+ "You appear to be directly connected to the
internet. Congratulations, you should be able to connect "+
+ "to any other freenet node.",
UserAlert.WARNING);
}
void start() {
@@ -121,7 +145,7 @@
public void maybeRun() {
Logger.minor(this, "Maybe running IP detection plugins", new
Exception("debug"));
PeerNode[] peers = node.getPeerNodes();
- PeerNode[] conns = node.getDarknetConnections();
+ PeerNode[] conns = node.getConnectedPeers();
Peer[] nodeAddrs = detector.getPrimaryIPAddress();
long now = System.currentTimeMillis();
synchronized(this) {
@@ -226,6 +250,9 @@
}
}
+ if(detector.maybeSymmetric &&
lastDetectAttemptEndedTime <= 0) // If it appears to be an SNAT, do a detection
at least once
+ maybeUrgent = true;
+
if(maybeUrgent) {
if(firstTimeUrgent <= 0)
firstTimeUrgent = now;
@@ -260,6 +287,7 @@
}
}
if(count > 2) {
+ Logger.minor(this,
"Recently connected peers count: "+count);
maybeFake = true;
}
}
@@ -375,10 +403,49 @@
}
}
DetectedIP[] list = (DetectedIP[])
map.values().toArray(new DetectedIP[map.size()]);
+ int countOpen = 0;
+ int countRestricted = 0;
+ int countPortRestricted = 0;
+ int countSymmetric = 0;
+ int countClosed = 0;
for(int i=0;i<list.length;i++) {
Logger.minor(this, "Detected IP:
"+list[i].publicAddress+ " : type "+list[i].natType);
System.out.println("Detected IP:
"+list[i].publicAddress+ " : type "+list[i].natType);
+ switch(list[i].natType) {
+ case DetectedIP.FULL_CONE_NAT:
+ case DetectedIP.FULL_INTERNET:
+ countOpen++;
+ break;
+ case DetectedIP.NO_UDP:
+ countClosed++;
+ break;
+ case DetectedIP.NOT_SUPPORTED:
+ // Ignore
+ break;
+ case DetectedIP.RESTRICTED_CONE_NAT:
+ countRestricted++;
+ break;
+ case DetectedIP.PORT_RESTRICTED_NAT:
+ countPortRestricted++;
+ break;
+ case DetectedIP.SYMMETRIC_NAT:
+ case DetectedIP.SYMMETRIC_UDP_FIREWALL:
+ countSymmetric++;
+ break;
+ }
}
+
+ if(countClosed > 0 && (countOpen + countRestricted +
countPortRestricted + countSymmetric) == 0) {
+
node.clientCore.alerts.register(noConnectionAlert);
+ } else if(countSymmetric > 0 && (countOpen +
countRestricted + countPortRestricted == 0)) {
+ node.clientCore.alerts.register(symmetricAlert);
+ } else if(countPortRestricted > 0 && (countOpen +
countRestricted == 0)) {
+
node.clientCore.alerts.register(portRestrictedAlert);
+ } else if(countRestricted > 0 && (countOpen == 0)) {
+
node.clientCore.alerts.register(restrictedAlert);
+ } else if(countOpen > 0) {
+ node.clientCore.alerts.register(connectedAlert);
+ }
detector.processDetectedIPs(list);
} finally {
runner = null;
@@ -387,4 +454,8 @@
}
+ public boolean isEmpty() {
+ return plugins.length == 0;
+ }
+
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-08-23 22:37:23 UTC (rev
10248)
+++ trunk/freenet/src/freenet/node/Node.java 2006-08-24 01:09:58 UTC (rev
10249)
@@ -2775,10 +2775,13 @@
}
public PeerNode[] getPeerNodes() {
- PeerManager pm = peers;
- return pm.myPeers;
+ return peers.myPeers;
}
+ public PeerNode[] getConnectedPeers() {
+ return peers.connectedPeers;
+ }
+
public PeerNodeStatus[] getPeerNodeStatuses() {
PeerNodeStatus[] peerNodeStatuses = new
PeerNodeStatus[peers.myPeers.length];
for (int peerIndex = 0, peerCount = peers.myPeers.length;
peerIndex < peerCount; peerIndex++) {
Modified: trunk/freenet/src/freenet/node/NodeIPDetector.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeIPDetector.java 2006-08-23 22:37:23 UTC
(rev 10248)
+++ trunk/freenet/src/freenet/node/NodeIPDetector.java 2006-08-24 01:09:58 UTC
(rev 10249)
@@ -14,6 +14,9 @@
import freenet.io.comm.FreenetInetAddress;
import freenet.io.comm.Peer;
import freenet.node.useralerts.IPUndetectedUserAlert;
+import freenet.node.useralerts.SimpleUserAlert;
+import freenet.node.useralerts.UserAlert;
+import freenet.node.useralerts.UserAlertManager;
import freenet.pluginmanager.DetectedIP;
import freenet.pluginmanager.FredPluginIPDetector;
import freenet.support.Logger;
@@ -46,7 +49,11 @@
public boolean includeLocalAddressesInNoderefs;
/** ARK inserter. */
private final NodeARKInserter arkPutter;
+ /** Set when we have grounds to believe that we may be behind a
symmetric NAT. */
+ boolean maybeSymmetric;
+ SimpleUserAlert maybeSymmetricAlert;
+
public NodeIPDetector(Node node) {
this.node = node;
this.ticker = node.ps;
@@ -63,6 +70,7 @@
* third parties if available and UP&P if available.
*/
Peer[] detectPrimaryIPAddress() {
+ boolean setMaybeSymmetric = false;
Vector addresses = new Vector();
if(overrideIPAddress != null) {
// If the IP is overridden, the override has to be the
first element.
@@ -102,6 +110,7 @@
// DNSRequester doesn't deal with our own node
InetAddress ip = p.getAddress(true);
if(!IPUtil.checkAddress(ip)) continue;
+ Logger.normal(this, "Peer
"+peerList[i].getPeer()+" thinks we are "+p);
if(countsByPeer.containsKey(ip)) {
Integer count = (Integer)
countsByPeer.get(p);
Integer newCount = new
Integer(count.intValue()+1);
@@ -143,6 +152,27 @@
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!");
+
setMaybeSymmetric = true;
+
+
if(ipDetectorManager != null && ipDetectorManager.isEmpty()) {
+
if(maybeSymmetricAlert == null) {
+
maybeSymmetricAlert = new SimpleUserAlert(true, "Connection problems",
+
"It looks like your node may be behind a symmetric NAT. You may
have connection " +
+
"problems; if you are behind a symmetric NAT you will probably
only be able to " +
+
"connect to peers which are open to the internet.",
UserAlert.ERROR);
+ }
+
if(node.clientCore != null && node.clientCore.alerts != null)
+
node.clientCore.alerts.register(maybeSymmetricAlert);
+ } else {
+
if(maybeSymmetricAlert != null)
+
node.clientCore.alerts.unregister(maybeSymmetricAlert);
+ }
+
+
addresses.add(new Peer(best.getFreenetAddress(), node.portNumber));
+ }
}
}
}
@@ -156,6 +186,7 @@
}
}
lastIPAddress = (Peer[]) addresses.toArray(new
Peer[addresses.size()]);
+ this.maybeSymmetric = setMaybeSymmetric;
return lastIPAddress;
}
@@ -166,7 +197,14 @@
public boolean hasDirectlyDetectedIP() {
InetAddress[] addrs = ipDetector.getAddress();
- return (addrs != null && addrs.length > 0);
+ if(addrs == null || addrs.length == 0) return false;
+ for(int i=0;i<addrs.length;i++) {
+ if(IPAddressDetector.isValidAddress(addrs[i], false)) {
+ Logger.minor(this, "Has a directly detected IP:
"+addrs[i]);
+ return true;
+ }
+ }
+ return false;
}
/**
Modified: trunk/freenet/src/freenet/transport/IPAddressDetector.java
===================================================================
--- trunk/freenet/src/freenet/transport/IPAddressDetector.java 2006-08-23
22:37:23 UTC (rev 10248)
+++ trunk/freenet/src/freenet/transport/IPAddressDetector.java 2006-08-24
01:09:58 UTC (rev 10249)
@@ -189,6 +189,9 @@
Logger.debug(
this,
"Address " + x + ": " +
i);
+ if(isValidAddress(i,
detector.includeLocalAddressesInNoderefs)) {
+ output.add(i);
+ }
if(i.isAnyLocalAddress()) {
// Wildcard address, 0.0.0.0,
ignore.
} else if(i.isLinkLocalAddress() ||
i.isLoopbackAddress() ||
@@ -207,6 +210,23 @@
lastAddressList = (InetAddress[]) output.toArray(new
InetAddress[output.size()]);
}
+ public static boolean isValidAddress(InetAddress i, boolean
includeLocalAddressesInNoderefs) {
+ if(i.isAnyLocalAddress()) {
+ // Wildcard address, 0.0.0.0, ignore.
+ return false;
+ } else if(i.isLinkLocalAddress() || i.isLoopbackAddress() ||
+ i.isSiteLocalAddress()) {
+ if(includeLocalAddressesInNoderefs) {
+ return true;
+ } else return false;
+ } else if(i.isMulticastAddress()) {
+ // Ignore
+ return false;
+ } else {
+ return true;
+ }
+ }
+
protected boolean isInternetAddress(InetAddress addr) {
return detector.includeLocalAddressesInNoderefs() ||
IPUtil.checkAddress(addr);
}