[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r2542: Handle multiple forwarded ports (for ORPort and DirPort) (vidalia/branches/upnp/src/vidalia/config)



Author: sjmurdoch
Date: 2008-04-28 08:08:43 -0400 (Mon, 28 Apr 2008)
New Revision: 2542

Modified:
   vidalia/branches/upnp/src/vidalia/config/serversettings.cpp
   vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp
   vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h
Log:
Handle multiple forwarded ports (for ORPort and DirPort)

Modified: vidalia/branches/upnp/src/vidalia/config/serversettings.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/serversettings.cpp	2008-04-28 10:13:41 UTC (rev 2541)
+++ vidalia/branches/upnp/src/vidalia/config/serversettings.cpp	2008-04-28 12:08:43 UTC (rev 2542)
@@ -164,18 +164,32 @@
 /* TODO: We should call this periodically, in case the router gets rebooted or forgets its UPnP settings */
 /* TODO: Remove port forwarding when Tor is shutdown or the ORPort changes */
 /* TODO: init_upnp() will block for up to 2 seconds. We should fire off a thread */
-/** Configure UPnP device to forward DirPort and ORPort */
+
+/** Configure UPnP device to forward DirPort and ORPort. If enable is
+true, will forward ORPort and DirPort; otherwise will remove exising
+port mappings */
 void
 ServerSettings::configurePortForwarding(bool enable)
 {
 #ifdef USE_MINIUPNPC
   UPNPControl *pUNPControl = UPNPControl::Instance();
 
-  if (enable) {
-    pUNPControl->forwardPort(getORPort());
-  } else {
+  // Remove all port forwards
+  if (!enable) {
     pUNPControl->disableForwarding();
+    return;
   }
+
+  // Configure port forwards, if Tor is using them
+  if (isServerEnabled())
+    pUNPControl->forwardORPort(getORPort());
+  else
+    pUNPControl->disableORPort();
+
+  if (isServerEnabled() && isDirectoryMirror())
+    pUNPControl->forwardDirPort(getDirPort());
+  else
+    pUNPControl->disableDirPort();
 #endif
 }
 

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp	2008-04-28 10:13:41 UTC (rev 2541)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp	2008-04-28 12:08:43 UTC (rev 2542)
@@ -29,10 +29,65 @@
 UPNPControl::UPNPControl()
 {
   init_upnp();
-  forwardedPort = 0;
+  forwardedORPort = 0;
+  forwardedDirPort = 0;
 }
 
 int
+UPNPControl::forwardDirPort(quint16 port)
+{
+  if (forwardedPorts.contains(port))
+    return 0;
+
+  int retval = forwardPort(port);
+  if (retval)
+    return retval;
+  else
+    forwardedDirPort = port;
+
+  return 0;
+}
+
+int
+UPNPControl::forwardORPort(quint16 port)
+{ 
+  if (forwardedPorts.contains(port))
+    return 0;
+
+  int retval = forwardPort(port);
+  if (retval)
+    return retval;
+  else
+    forwardedORPort = port;
+
+  return 0;
+}
+
+int
+UPNPControl::disableDirPort()
+{
+  int retval = disablePort(forwardedDirPort);
+  if (retval)
+    return retval;
+  else
+    forwardedDirPort = 0;
+
+  return 0;
+}
+
+int
+UPNPControl::disableORPort()
+{ 
+  int retval = disablePort(forwardedORPort);
+  if (retval)
+    return retval;
+  else
+    forwardedORPort = 0;
+
+  return 0;
+}
+
+int
 UPNPControl::forwardPort(quint16 port)
 {
   int retval;
@@ -42,6 +97,10 @@
   char intClient[16];
   char intPort[6];
 
+  // Don't forward port 0
+  if (0 == port)
+    return 4;
+
   // Convert the port number to a string
   snprintf(sPort, sizeof(sPort), "%d", port);
 
@@ -85,44 +144,71 @@
   #endif
 
   // Save the mapping
-  forwardedPort = port;
+  forwardedPorts.append(port);
 
   return 0;
 }
 
 int
-UPNPControl::disableForwarding()
+UPNPControl::disablePort(quint16 port)
 {
   char sPort[6];
+  
+  // Port 0 should never be forwarded
+  if (0 == port)
+    return 4;
 
-  if (0 == forwardedPort)
-    return 0;
-
   // Convert the port number to a string
-  snprintf(sPort, sizeof(sPort), "%d", forwardedPort);
-
+  snprintf(sPort, sizeof(sPort), "%d", port);
+  
+  // Remove the mapping
   int retval = UPNP_DeletePortMapping(urls.controlURL, data.servicetype, sPort, "TCP");
   if(UPNPCOMMAND_SUCCESS != retval) {
-    #ifdef UPNPCONTROL_DEBUG   
+#ifdef UPNPCONTROL_DEBUG   
     printf("DeletePortMapping() failed with code %d\n", retval);
     fflush(stdout);
-    #endif
+#endif
     return 1;
   }
-
+  
   // Output the cancelled mapping
-  #ifdef UPNPCONTROL_DEBUG
+#ifdef UPNPCONTROL_DEBUG
   printf("(external):%s -> <>\n", sPort);
   fflush(stdout);
-  #endif
+#endif
+  
 
-  // Save the mapping
-  forwardedPort = 0;
+  // Save the removal
+  forwardedPorts.removeAll(port);
 
   return 0;
 }
 
+int
+UPNPControl::disableForwarding()
+{
+  char sPort[6];
+  quint16 port;
+  int retval;
 
+  while (!forwardedPorts.isEmpty()) {
+    // Get the port number
+    port = forwardedPorts.last();
+
+    // Disable the port forward
+    retval = disablePort(port);
+
+    // Check if there was an error
+    if (retval)
+      return retval;
+  }
+
+  forwardedDirPort = forwardedORPort = 0;
+
+  return 0;
+}
+
+
 /** Based on http://miniupnp.free.fr/files/download.php?file=xchat-upnp20061022.patch */
 void
 UPNPControl::init_upnp()

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h	2008-04-28 10:13:41 UTC (rev 2541)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h	2008-04-28 12:08:43 UTC (rev 2542)
@@ -18,6 +18,7 @@
 #define _UPNPCONTROL_H
 
 #include <QObject>
+#include <QList>
 
 #define STATICLIB
 #include <miniupnpc/miniwget.h>
@@ -30,13 +31,21 @@
 
 public:
   static UPNPControl* Instance();
-  int forwardPort(quint16 port);
+
   int disableForwarding();
+
+  int forwardDirPort(quint16 port);
+  int forwardORPort(quint16 port);
+  int disableDirPort();
+  int disableORPort();
 protected:
   UPNPControl();
 private:
   static UPNPControl* pInstance;
 
+  int forwardPort(quint16 port);
+  int disablePort(quint16 port);
+
   /** Used by miniupnpc library */
   struct UPNPUrls urls;
   struct IGDdatas data;
@@ -45,8 +54,10 @@
   void upnp_add_redir (const char * addr, int port);
   void upnp_rem_redir(int port);
 
-  /* Currently forwarded port */
-  quint16 forwardedPort;
+  /* Currently forwarded ports */
+  QList<quint16> forwardedPorts;
+  quint16 forwardedORPort;
+  quint16 forwardedDirPort;
 };
 
 #endif