Author: toad
Date: 2007-09-07 16:03:24 +0000 (Fri, 07 Sep 2007)
New Revision: 15000
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/pluginmanager/ForwardPort.java
trunk/freenet/src/freenet/pluginmanager/ForwardPortCallback.java
trunk/freenet/src/freenet/pluginmanager/ForwardPortStatus.java
trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
trunk/freenet/src/freenet/pluginmanager/PluginManager.java
Log:
Basic support for port forwarding plugins
Modified: trunk/freenet/src/freenet/node/IPDetectorPluginManager.java
===================================================================
--- trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2007-09-07
15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2007-09-07
16:03:24 UTC (rev 15000)
@@ -2,6 +2,9 @@
import java.net.InetAddress;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
import java.util.Vector;
import freenet.io.comm.FreenetInetAddress;
@@ -10,7 +13,11 @@
import freenet.node.useralerts.ProxyUserAlert;
import freenet.node.useralerts.UserAlert;
import freenet.pluginmanager.DetectedIP;
+import freenet.pluginmanager.ForwardPort;
+import freenet.pluginmanager.ForwardPortCallback;
+import freenet.pluginmanager.ForwardPortStatus;
import freenet.pluginmanager.FredPluginIPDetector;
+import freenet.pluginmanager.FredPluginPortForward;
import freenet.support.HTMLNode;
import freenet.support.Logger;
import freenet.support.OOMHandler;
@@ -20,7 +27,7 @@
* Tracks all known IP address detection plugins, and runs them when
appropriate.
* Normally there would only be one, but sometimes there may be more than one.
*/
-public class IPDetectorPluginManager {
+public class IPDetectorPluginManager implements ForwardPortCallback {
public class MyUserAlert implements UserAlert {
@@ -93,6 +100,7 @@
private final NodeIPDetector detector;
private final Node node;
FredPluginIPDetector[] plugins;
+ FredPluginPortForward[] portForwardPlugins;
private final MyUserAlert noConnectionAlert;
private final MyUserAlert symmetricAlert;
private final MyUserAlert portRestrictedAlert;
@@ -104,6 +112,7 @@
IPDetectorPluginManager(Node node, NodeIPDetector detector) {
logMINOR = Logger.shouldLog(Logger.MINOR, getClass());
plugins = new FredPluginIPDetector[0];
+ portForwardPlugins = new FredPluginPortForward[0];
this.node = node;
this.detector = detector;
noConnectionAlert = new MyUserAlert(
l10n("noConnectivityTitle"), l10n("noConnectivity"),
@@ -613,4 +622,67 @@
return plugins.length == 0;
}
+ public void registerPortForwardPlugin(FredPluginPortForward forward) {
+ if(forward == null) throw new NullPointerException();
+ synchronized(this) {
+ FredPluginPortForward[] newForwardPlugins = new
FredPluginPortForward[plugins.length+1];
+ System.arraycopy(plugins, 0, newForwardPlugins, 0,
plugins.length);
+ newForwardPlugins[plugins.length] = forward;
+ portForwardPlugins = newForwardPlugins;
+ }
+ if(logMINOR) Logger.minor(this, "Registering a new port forward
plugin : " + forward);
+ forward.onChangePublicPorts(node.getPublicInterfacePorts(),
this);
+ }
+
+ /**
+ * Remove a plugin.
+ */
+ public void remove(FredPluginPortForward forward) {
+ synchronized(this) {
+ int count = 0;
+ for(int i=0;i<portForwardPlugins.length;i++) {
+ if(portForwardPlugins[i] == forward) count++;
+ }
+ if(count == 0) return;
+ FredPluginPortForward[] newPlugins = new
FredPluginPortForward[portForwardPlugins.length - count];
+ int x = 0;
+ for(int i=0;i<portForwardPlugins.length;i++) {
+ if(newPlugins[i] != forward) newPlugins[x++] =
portForwardPlugins[i];
+ }
+ portForwardPlugins = newPlugins;
+ }
+ }
+
+ void notifyPortChange(Set newPorts) {
+ FredPluginPortForward[] plugins;
+ synchronized(this) {
+ plugins = portForwardPlugins;
+ }
+ for(int i=0;i<plugins.length;i++)
+ plugins[i].onChangePublicPorts(newPorts, this);
+ }
+
+ public void portForwardStatus(Map statuses) {
+ Set currentPorts = node.getPublicInterfacePorts();
+ Iterator i = currentPorts.iterator();
+ while(i.hasNext()) {
+ ForwardPort p = (ForwardPort) i.next();
+ ForwardPortStatus status = (ForwardPortStatus)
statuses.get(p);
+ if(status == null) continue;
+ if(status.status == status.DEFINITE_SUCCESS) {
+ Logger.normal(this, "Succeeded forwarding
"+p.name+" port "+p.portNumber+" for "+p.protocol+" - port forward definitely
succeeded "+status.reasonString);
+ } else if(status.status == status.PROBABLE_SUCCESS) {
+ Logger.normal(this, "Probably succeeded
forwarding "+p.name+" port "+p.portNumber+" for "+p.protocol+" - port forward
probably succeeded "+status.reasonString);
+ } else if(status.status == status.MAYBE_SUCCESS) {
+ Logger.normal(this, "Maybe succeeded forwarding
"+p.name+" port "+p.portNumber+" for "+p.protocol+" - port forward may have
succeeded but strongly recommend out of band verification
"+status.reasonString);
+ } else if(status.status == status.DEFINITE_FAILURE) {
+ Logger.error(this, "Failed forwarding
"+p.name+" port "+p.portNumber+" for "+p.protocol+" - port forward definitely
failed "+status.reasonString);
+ } else if(status.status == status.PROBABLE_FAILURE) {
+ Logger.error(this, "Probably failed forwarding
"+p.name+" port "+p.portNumber+" for "+p.protocol+" - port forward probably
failed "+status.reasonString);
+ }
+ // Not much more we can do / want to do for now
+ // FIXME use status.externalPort.
+ }
+ }
+
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2007-09-07 15:34:12 UTC (rev
14999)
+++ trunk/freenet/src/freenet/node/Node.java 2007-09-07 16:03:24 UTC (rev
15000)
@@ -25,6 +25,7 @@
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Random;
+import java.util.Set;
import org.spaceroots.mantissa.random.MersenneTwister;
import org.tanukisoftware.wrapper.WrapperManager;
@@ -80,6 +81,7 @@
import freenet.node.useralerts.OpennetUserAlert;
import freenet.node.useralerts.TimeSkewDetectedUserAlert;
import freenet.node.useralerts.UserAlert;
+import freenet.pluginmanager.ForwardPort;
import freenet.pluginmanager.PluginManager;
import freenet.store.BerkeleyDBFreenetStore;
import freenet.store.FreenetStore;
@@ -785,6 +787,7 @@
}
if(val) o.start();
else o.stop();
+
ipDetector.ipDetectorManager.notifyPortChange(getPublicInterfacePorts());
}
});
@@ -2682,4 +2685,23 @@
return passOpennetRefsThroughDarknet;
}
+ /**
+ * Get the set of public ports that need to be forwarded. These are
internal
+ * ports, not necessarily external - they may be rewritten by the NAT.
+ * @return A Set of ForwardPort's to be fed to port forward plugins.
+ */
+ public Set getPublicInterfacePorts() {
+ HashSet set = new HashSet();
+ // FIXME IPv6 support
+ set.add(new ForwardPort("darknet", false,
ForwardPort.PROTOCOL_UDP_IPV4, darknetCrypto.portNumber));
+ OpennetManager opennet = this.opennet;
+ if(opennet != null) {
+ NodeCrypto crypto = opennet.crypto;
+ if(crypto != null) {
+ set.add(new ForwardPort("opennet", false,
ForwardPort.PROTOCOL_UDP_IPV4, crypto.portNumber));
+ }
+ }
+ return set;
+ }
+
}
Modified: trunk/freenet/src/freenet/node/NodeIPDetector.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeIPDetector.java 2007-09-07 15:34:12 UTC
(rev 14999)
+++ trunk/freenet/src/freenet/node/NodeIPDetector.java 2007-09-07 16:03:24 UTC
(rev 15000)
@@ -17,6 +17,7 @@
import freenet.node.useralerts.UserAlert;
import freenet.pluginmanager.DetectedIP;
import freenet.pluginmanager.FredPluginIPDetector;
+import freenet.pluginmanager.FredPluginPortForward;
import freenet.support.Logger;
import freenet.support.api.BooleanCallback;
import freenet.support.api.StringCallback;
@@ -440,5 +441,9 @@
node.clientCore.alerts.unregister(maybeSymmetricAlert);
}
}
+
+ public void registerPortForwardPlugin(FredPluginPortForward forward) {
+ ipDetectorManager.registerPortForwardPlugin(forward);
+ }
}
Modified: trunk/freenet/src/freenet/pluginmanager/ForwardPort.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/ForwardPort.java 2007-09-07
15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/pluginmanager/ForwardPort.java 2007-09-07
16:03:24 UTC (rev 15000)
@@ -20,11 +20,23 @@
// We don't currently support binding to a specific internal interface.
// It would be complicated: Different interfaces may be on different
LANs,
// and an IGD is normally on only one LAN.
+ private final int hashCode;
public ForwardPort(String name, boolean isIP6, int protocol, int
portNumber) {
this.name = name;
this.isIP6 = isIP6;
this.protocol = protocol;
this.portNumber = portNumber;
+ hashCode = name.hashCode() | (isIP6 ? 1 : 0) | protocol |
portNumber;
}
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public boolean equals(Object o) {
+ if(!(o instanceof ForwardPort)) return false;
+ ForwardPort f = (ForwardPort) o;
+ return (f.name.equals(name)) && f.isIP6 == isIP6 && f.protocol
== protocol && f.portNumber == portNumber;
+ }
}
Modified: trunk/freenet/src/freenet/pluginmanager/ForwardPortCallback.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/ForwardPortCallback.java
2007-09-07 15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/pluginmanager/ForwardPortCallback.java
2007-09-07 16:03:24 UTC (rev 15000)
@@ -9,6 +9,6 @@
public interface ForwardPortCallback {
/** Called to indicate status on one or more forwarded ports. */
- public void status(Map /*<ForwardPort,ForwardPortStatus>*/ statuses);
+ public void portForwardStatus(Map /*<ForwardPort,ForwardPortStatus>*/
statuses);
}
Modified: trunk/freenet/src/freenet/pluginmanager/ForwardPortStatus.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/ForwardPortStatus.java
2007-09-07 15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/pluginmanager/ForwardPortStatus.java
2007-09-07 16:03:24 UTC (rev 15000)
@@ -21,8 +21,13 @@
public final String reasonString;
- public ForwardPortStatus(int status, String reason) {
+ /** Some plugins may need to change the external port. They can return
it
+ * to the node here. */
+ public final int externalPort;
+
+ public ForwardPortStatus(int status, String reason, int externalPort) {
this.status = status;
this.reasonString = reason;
+ this.externalPort = externalPort;
}
}
Modified: trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
2007-09-07 15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/pluginmanager/PluginInfoWrapper.java
2007-09-07 16:03:24 UTC (rev 15000)
@@ -17,6 +17,7 @@
private boolean isPproxyPlugin;
private boolean isThreadlessPlugin;
private boolean isIPDetectorPlugin;
+ private boolean isPortForwardPlugin;
private String filename;
private HashSet toadletLinks=new HashSet();
//public String
@@ -34,6 +35,7 @@
isPproxyPlugin = (plug instanceof FredPluginHTTP);
isThreadlessPlugin = (plug instanceof FredPluginThreadless);
isIPDetectorPlugin = (plug instanceof FredPluginIPDetector);
+ isPortForwardPlugin = (plug instanceof FredPluginPortForward);
}
public String toString() {
@@ -99,6 +101,10 @@
return isIPDetectorPlugin;
}
+ public boolean isPortForwardPlugin() {
+ return isPortForwardPlugin;
+ }
+
public Thread getThread() {
return thread;
}
Modified: trunk/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginManager.java 2007-09-07
15:34:12 UTC (rev 14999)
+++ trunk/freenet/src/freenet/pluginmanager/PluginManager.java 2007-09-07
16:03:24 UTC (rev 15000)
@@ -128,6 +128,9 @@
if(pi.isIPDetectorPlugin()) {
node.ipDetector.registerIPDetectorPlugin((FredPluginIPDetector) plug);
}
+ if(pi.isPortForwardPlugin()) {
+
node.ipDetector.registerPortForwardPlugin((FredPluginPortForward) plug);
+ }
synchronized (pluginInfo) {
pluginInfo.put(pi.getThreadName(), pi);