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);


Reply via email to