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

[vidalia-svn] r2557: Re-write UPNP code so that all UPNP operations occur from on (in vidalia/branches/upnp/src/vidalia: . config)



Author: sjmurdoch
Date: 2008-05-07 11:28:32 -0400 (Wed, 07 May 2008)
New Revision: 2557

Modified:
   vidalia/branches/upnp/src/vidalia/config/serversettings.cpp
   vidalia/branches/upnp/src/vidalia/config/serversettings.h
   vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp
   vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h
   vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp
   vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h
   vidalia/branches/upnp/src/vidalia/mainwindow.cpp
Log:
Re-write UPNP code so that all UPNP operations occur from one thread. This makes the logic much cleaner, but there is some fairly subtle locking going on.

Modified: vidalia/branches/upnp/src/vidalia/config/serversettings.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/serversettings.cpp	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/serversettings.cpp	2008-05-07 15:28:32 UTC (rev 2557)
@@ -134,10 +134,8 @@
 {
   bool rc;
 
+  configurePortForwarding();
   if (isServerEnabled()) {
-    /* Configure UPnP device to forward DirPort and OrPort */
-    /* TODO: does isServerEnabled() return true when a server is just set up? */
-    configurePortForwarding(true, true);
     rc = torControl()->setConf(confValues(), errmsg);
   } else { 
     QStringList resetKeys;
@@ -156,7 +154,6 @@
                 << SETTING_BANDWIDTH_BURST;
     }
     rc = torControl()->resetConf(resetKeys, errmsg);
-    configurePortForwarding(false, true);
   }
   return rc;
 }
@@ -169,7 +166,7 @@
 true, will forward ORPort and DirPort; otherwise will remove exising
 port mappings */
 void
-ServerSettings::configurePortForwarding(bool enable, bool async)
+ServerSettings::configurePortForwarding()
 {
 #ifdef USE_MINIUPNPC
   quint16 ORPort, DirPort;
@@ -182,15 +179,15 @@
     return;
 
   ORPort = getORPort();
+  if (!isServerEnabled())
+    ORPort = 0;
+
   DirPort = getDirPort();
+  if (!isServerEnabled() || !isDirectoryMirror())
+    DirPort = 0;
 
-  enableORPort = isServerEnabled();
-  enableDirPort = enableORPort && isDirectoryMirror();
-
-  if (async)
-    UPNPControl::configurePortForwardingAsync(enable, enableORPort, enableDirPort, ORPort, DirPort);
-  else
-    UPNPControl::configurePortForwardingSync(enable, enableORPort, enableDirPort, ORPort, DirPort);
+  UPNPControl *control = UPNPControl::Instance();
+  control->setDesiredState(DirPort, ORPort);
 #endif
 }
 

Modified: vidalia/branches/upnp/src/vidalia/config/serversettings.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/serversettings.h	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/serversettings.h	2008-05-07 15:28:32 UTC (rev 2557)
@@ -82,8 +82,8 @@
   /** Gets the maximum burst rate (in B/s) of this server. */
   quint32 getBandwidthBurstRate();
 
-  /** If enable is true, configure UPnP device to forward ORPort, otherwise remove mapping */
-  void configurePortForwarding(bool enable, bool async);
+  /** Configure port forwarding */
+  void configurePortForwarding();
 
   void cleanupPortForwarding();
 protected:

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp	2008-05-07 15:28:32 UTC (rev 2557)
@@ -16,14 +16,14 @@
 
 #include "upnpcontrol.h"
 
+#include <QMutex>
+
 #ifdef WIN32
 #include <winsock2.h>
 #endif
 
 #include "upnpcontrolthread.h"
 
-#define UPNPCONTROL_DEBUG 1
-
 UPNPControl* UPNPControl::pInstance = 0;
 UPNPControl* UPNPControl::Instance()
 {
@@ -34,264 +34,37 @@
 
 UPNPControl::UPNPControl()
 {
-  init_upnp();
-  forwardedORPort = 0;
-  forwardedDirPort = 0;
-  controlThread = NULL;
+  _forwardedORPort = 0;
+  _forwardedDirPort = 0;
+  mutex = new QMutex();
+  controlThread = new UPNPControlThread(this);
+  controlThread->start();
 }
 
-int
-UPNPControl::forwardDirPort(quint16 port)
+UPNPControl::~UPNPControl()
 {
-  if (forwardedPorts.contains(port))
-    return 0;
-
-  int retval = forwardPort(port);
-  if (retval)
-    return retval;
-  else
-    forwardedDirPort = port;
-
-  return 0;
+  delete mutex;
+  delete controlThread;
 }
 
-int
-UPNPControl::forwardORPort(quint16 port)
-{ 
-  if (forwardedPorts.contains(port))
-    return 0;
+void UPNPControl::cleanup(){
+  pInstance->controlThread->stop();
+  delete pInstance;
+  pInstance = 0;
+}  
 
-  int retval = forwardPort(port);
-  if (retval)
-    return retval;
-  else
-    forwardedORPort = port;
-
-  return 0;
+void UPNPControl::getDesiredState(quint16 *desiredDirPort, quint16 *desiredOrPort) {
+  mutex->lock();
+  *desiredDirPort = _forwardedDirPort;
+  *desiredOrPort = _forwardedORPort;
+  mutex->unlock();
+  controlThread->wakeup();
 }
 
-int
-UPNPControl::disableDirPort()
-{
-  int retval = disablePort(forwardedDirPort);
-  if (retval)
-    return retval;
-  else
-    forwardedDirPort = 0;
-
-  return 0;
+void UPNPControl::setDesiredState(quint16 desiredDirPort, quint16 desiredOrPort) {
+  mutex->lock();
+  _forwardedDirPort = desiredDirPort;
+  _forwardedORPort = desiredOrPort;
+  mutex->unlock();
+  controlThread->wakeup();
 }
-
-int
-UPNPControl::disableORPort()
-{ 
-  int retval = disablePort(forwardedORPort);
-  if (retval)
-    return retval;
-  else
-    forwardedORPort = 0;
-
-  return 0;
-}
-
-int
-UPNPControl::forwardPort(quint16 port)
-{
-  int retval;
-  
-  char sPort[6];
-  
-  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);
-
-  // Add the port mapping of external:port -> internal:port
-  retval = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
-			       sPort, sPort, lanaddr, "Tor server", "TCP");
-  if(UPNPCOMMAND_SUCCESS != retval) {
-    #ifdef UPNPCONTROL_DEBUG
-    printf("AddPortMapping(%s, %s, %s) failed with code %d\n",
-	   sPort, sPort, lanaddr, retval);
-    fflush(stdout);
-    #endif
-    return 1;
-  }
-  
-  // Check if the port mapping was accepted
-  retval = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
-					    data.servicetype,
-					    sPort, "TCP",
-					    intClient, intPort);
-  if(UPNPCOMMAND_SUCCESS != retval) {
-    #ifdef UPNPCONTROL_DEBUG
-    printf("GetSpecificPortMappingEntry() failed with code %d\n", retval);
-    fflush(stdout);
-    #endif
-    return 2;
-  }
-  
-  if(! intClient[0]) {
-    #ifdef UPNPCONTROL_DEBUG
-    printf("GetSpecificPortMappingEntry failed.\n");
-    fflush(stdout);
-    #endif
-    return 3;
-  }
-  
-  // Output the mapping
-  #ifdef UPNPCONTROL_DEBUG
-  printf("(external):%s -> %s:%s\n", sPort, intClient, intPort);
-  fflush(stdout);
-  #endif
-
-  // Save the mapping
-  forwardedPorts.append(port);
-
-  return 0;
-}
-
-int
-UPNPControl::disablePort(quint16 port)
-{
-  char sPort[6];
-  
-  // Port 0 should never be forwarded
-  if (0 == port)
-    return 4;
-
-  // Convert the port number to a string
-  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
-    printf("DeletePortMapping() failed with code %d\n", retval);
-    fflush(stdout);
-#endif
-    return 1;
-  }
-  
-  // Output the cancelled mapping
-#ifdef UPNPCONTROL_DEBUG
-  printf("(external):%s -> <>\n", sPort);
-  fflush(stdout);
-#endif
-  
-
-  // 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()
-{
-  struct UPNPDev * devlist;
-  int retval;
-
-  memset(&urls, 0, sizeof(struct UPNPUrls));
-  memset(&data, 0, sizeof(struct IGDdatas));
-
-  devlist = upnpDiscover(2000, NULL, NULL);
-  retval = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
-
-  #ifdef UPNPCONTROL_DEBUG
-  printf("GetValidIGD returned: %d\n", retval);
-  fflush(stdout);
-  #endif
-
-  freeUPNPDevlist(devlist);
-}
-
-void
-UPNPControl::configurePortForwardingAsync(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort)
-{
-  UPNPControlThread *thread = new UPNPControlThread(enable, enableORPort, enableDirPort, ORPort, DirPort);
-  thread->start();
-  //TODO: How to de-allocate memory? What about locking?
-}
-
-void
-UPNPControl::cleanup()
-{
-  if (pInstance!=0 && pInstance->controlThread != NULL) {
-    delete pInstance->controlThread;
-    pInstance->controlThread = 0;
-  }
-}
-
-void
-UPNPControl::setThread(UPNPControlThread *thread)
-{
-  UPNPControl::cleanup();
-  controlThread = thread;
-}
-
-void
-UPNPControl::configurePortForwardingSync(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort)
-{
-#ifdef WIN32  
-  // Workaround from http://trolltech.com/developer/knowledgebase/579
-  WSAData wsadata;
-  if (WSAStartup(MAKEWORD(2,0), &wsadata)!=0) {
-    qFatal("WSAStartup failure while disabling UPnP port forwarding");
-  }
-#endif
-
-  UPNPControl *pUNPControl = UPNPControl::Instance();
-
-  // Remove all port forwards
-  if (!enable) {
-    pUNPControl->disableForwarding();
-    return;
-  }
-
-  // Configure port forwards, if Tor is using them
-  if (enableORPort)
-    pUNPControl->forwardORPort(ORPort);
-  else
-    pUNPControl->disableORPort();
-
-  if (enableDirPort)
-    pUNPControl->forwardDirPort(DirPort);
-  else
-    pUNPControl->disableDirPort();
-
-#ifdef WIN32
-  WSACleanup();
-#endif
-}

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h	2008-05-07 15:28:32 UTC (rev 2557)
@@ -18,57 +18,31 @@
 #define _UPNPCONTROL_H
 
 #include <QObject>
-#include <QList>
+#include <QMutex>
 
-#define STATICLIB
-#include <miniupnpc/miniwget.h>
-#include <miniupnpc/miniupnpc.h>
-#include <miniupnpc/upnpcommands.h>
+/* Forward declaration to make it build */
+class UPNPControlThread;
 
-#include "upnpcontrolthread.h"
-
 class UPNPControl : public QObject
 {
   Q_OBJECT
 
 public:
   static UPNPControl* Instance();
-
-  int disableForwarding();
-
-  int forwardDirPort(quint16 port);
-  int forwardORPort(quint16 port);
-  int disableDirPort();
-  int disableORPort();
-
-  static void configurePortForwardingAsync(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort);
-  static void configurePortForwardingSync(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort);
-
   static void cleanup();
-
-  void setThread(UPNPControlThread *thread);
-
+  void getDesiredState(quint16 *desiredDirPort, quint16 *desiredOrPort);
+  void setDesiredState(quint16 desiredDirPort, quint16 desiredOrPort);
 protected:
   UPNPControl();
+  ~UPNPControl();
+  
 private:
   static UPNPControl* pInstance;
 
-  int forwardPort(quint16 port);
-  int disablePort(quint16 port);
-
-  /** Used by miniupnpc library */
-  struct UPNPUrls urls;
-  struct IGDdatas data;
-  char lanaddr[16];
-  void init_upnp();
-  void upnp_add_redir (const char * addr, int port);
-  void upnp_rem_redir(int port);
-
   /* Currently forwarded ports */
-  QList<quint16> forwardedPorts;
-  quint16 forwardedORPort;
-  quint16 forwardedDirPort;
-
+  quint16 _forwardedORPort;
+  quint16 _forwardedDirPort;
+  QMutex *mutex;
   UPNPControlThread *controlThread;
 };
 

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp	2008-05-07 15:28:32 UTC (rev 2557)
@@ -15,21 +15,245 @@
 */
 
 #include "upnpcontrolthread.h"
+
+#include <QWaitCondition>
+#include <QMutex>
+
+#ifdef WIN32
+#include <winsock2.h>
+#endif
+
 #include "upnpcontrol.h"
 
-UPNPControlThread::UPNPControlThread(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort)
+#define UPNPCONTROL_DEBUG 1
+
+UPNPControlThread::UPNPControlThread(UPNPControl *control)
 {
-  _enable = enable;
-  _enableORPort = enableORPort;
-  _enableDirPort = enableDirPort;
-  _ORPort = ORPort;
-  _DirPort = DirPort;
+  _upnpInitialized = false;
+  _keepRunning = true;
+  _control = control;
+
+  _dirPort = 0;
+  _orPort = 0;
+
+  _waitCondition = new QWaitCondition();
+  _waitMutex = new QMutex();
 }
 
+UPNPControlThread::~UPNPControlThread()
+{
+  delete _waitCondition;
+  delete _waitMutex;
+}
+
 void
 UPNPControlThread::run()
 {
-  UPNPControl *control = UPNPControl::Instance();
-  control->setThread(this);
-  UPNPControl::configurePortForwardingSync(_enable, _enableORPort, _enableDirPort, _ORPort, _DirPort);
+  bool shouldExit = false;
+
+  forever {
+    /* TODO: Check for switching OR/Dir port */
+    /* TODO: Check for router losing state */
+    
+    configurePorts();
+
+    /* Wait for something to happen */
+    _waitMutex->lock();
+    if (_keepRunning) {
+      /* We should continue */ 
+      _waitCondition->wait(_waitMutex);
+      /* Maybe we were asked to exit while waiting */
+      shouldExit = !_keepRunning;
+      _waitMutex->unlock();
+      if (shouldExit)
+	break;
+    } else {
+      /* We should exit */
+      _waitMutex->unlock();
+      break;
+    }
+  }
+
+  /* Remove the existing port forwards */
+  updatePort(_dirPort, 0);
+  updatePort(_orPort, 0);
 }
+
+void
+UPNPControlThread::configurePorts() {
+  quint16 desiredDirPort, desiredOrPort;
+
+  /* Get desired state */
+  _control->getDesiredState(&desiredDirPort, &desiredOrPort);
+  
+  /* Configure DirPort */
+  if (desiredDirPort != _dirPort) {
+    updatePort(_dirPort, desiredDirPort);
+    _dirPort = desiredDirPort;
+  }
+  
+  /* Configure ORPort */
+  if (desiredOrPort != _orPort) {
+    updatePort(_orPort, desiredOrPort);
+    _orPort = desiredOrPort;
+  }
+}
+
+void
+UPNPControlThread::stop()
+{
+  /* Lock access to _keepRunning */
+  _waitMutex->lock();
+
+  /* Ask the thread to stop */
+  _keepRunning = false;
+
+  /* Wake it up if needed */
+  _waitCondition->wakeAll();
+
+  /* Unlock shared state */
+  _waitMutex->unlock();
+
+  /* Wait for it to finish */
+  wait();
+}
+
+void
+UPNPControlThread::wakeup()
+{
+  _waitMutex->lock();
+  _waitCondition->wakeAll();
+  _waitMutex->unlock();
+}
+
+void
+UPNPControlThread::updatePort(quint16 oldPort, quint16 newPort)
+{
+
+#ifdef WIN32  
+  // Workaround from http://trolltech.com/developer/knowledgebase/579
+  WSAData wsadata;
+  if (WSAStartup(MAKEWORD(2,0), &wsadata)!=0) {
+    qFatal("WSAStartup failure while disabling UPnP port forwarding");
+  }
+#endif
+
+  if (!_upnpInitialized) {
+    init_upnp();
+    _upnpInitialized = true;
+  }
+
+  if (oldPort != 0)
+    disablePort(oldPort);
+
+  if (newPort != 0)
+    forwardPort(newPort);
+
+#ifdef WIN32
+  WSACleanup();
+#endif
+
+}
+
+/** Based on http://miniupnp.free.fr/files/download.php?file=xchat-upnp20061022.patch */
+void
+UPNPControlThread::init_upnp()
+{
+  struct UPNPDev * devlist;
+  int retval;
+
+  memset(&urls, 0, sizeof(struct UPNPUrls));
+  memset(&data, 0, sizeof(struct IGDdatas));
+
+  devlist = upnpDiscover(2000, NULL, NULL);
+  retval = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
+
+  #ifdef UPNPCONTROL_DEBUG
+  printf("GetValidIGD returned: %d\n", retval);
+  fflush(stdout);
+  #endif
+
+  freeUPNPDevlist(devlist);
+}
+
+int
+UPNPControlThread::forwardPort(quint16 port)
+{
+  int retval;
+  
+  char sPort[6];
+  
+  char intClient[16];
+  char intPort[6];
+
+  // Convert the port number to a string
+  snprintf(sPort, sizeof(sPort), "%d", port);
+
+  // Add the port mapping of external:port -> internal:port
+  retval = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
+			       sPort, sPort, lanaddr, "Tor server", "TCP");
+  if(UPNPCOMMAND_SUCCESS != retval) {
+    #ifdef UPNPCONTROL_DEBUG
+    printf("AddPortMapping(%s, %s, %s) failed with code %d\n",
+	   sPort, sPort, lanaddr, retval);
+    fflush(stdout);
+    #endif
+    return 1;
+  }
+  
+  // Check if the port mapping was accepted
+  retval = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
+					    data.servicetype,
+					    sPort, "TCP",
+					    intClient, intPort);
+  if(UPNPCOMMAND_SUCCESS != retval) {
+    #ifdef UPNPCONTROL_DEBUG
+    printf("GetSpecificPortMappingEntry() failed with code %d\n", retval);
+    fflush(stdout);
+    #endif
+    return 2;
+  }
+  
+  if(! intClient[0]) {
+    #ifdef UPNPCONTROL_DEBUG
+    printf("GetSpecificPortMappingEntry failed.\n");
+    fflush(stdout);
+    #endif
+    return 3;
+  }
+  
+  // Output the mapping
+  #ifdef UPNPCONTROL_DEBUG
+  printf("(external):%s -> %s:%s\n", sPort, intClient, intPort);
+  fflush(stdout);
+  #endif
+
+  return 0;
+}
+
+int
+UPNPControlThread::disablePort(quint16 port)
+{
+  char sPort[6];
+  
+  // Convert the port number to a string
+  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
+    printf("DeletePortMapping() failed with code %d\n", retval);
+    fflush(stdout);
+#endif
+    return 1;
+  }
+  
+  // Output the cancelled mapping
+#ifdef UPNPCONTROL_DEBUG
+  printf("(external):%s -> <>\n", sPort);
+  fflush(stdout);
+#endif
+  
+  return 0;
+}

Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h	2008-05-07 15:28:32 UTC (rev 2557)
@@ -18,19 +18,47 @@
 #define _UPNPCONTROLTHREAD_H
 
 #include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
 
+#define STATICLIB
+#include <miniupnpc/miniwget.h>
+#include <miniupnpc/miniupnpc.h>
+#include <miniupnpc/upnpcommands.h>
+
+/* Forward declaration to make it build */
+class UPNPControl;
+
 class UPNPControlThread : public QThread
 {
   Q_OBJECT
 
 public:
-  UPNPControlThread(bool enable, bool enableORPort, bool enableDirPort, quint16 ORPort, quint16 DirPort);
+  UPNPControlThread(UPNPControl *control);
+  ~UPNPControlThread();
+  void stop();
+  void wakeup();
 
 protected:
   void run();
 
 private:
-  bool _enable, _enableORPort, _enableDirPort;
-  quint16 _ORPort, _DirPort;
+  bool _upnpInitialized;
+  bool _keepRunning;
+  UPNPControl *_control;
+  QWaitCondition *_waitCondition;
+  QMutex *_waitMutex;
+  quint16 _dirPort, _orPort;
+
+  /** Used by miniupnpc library */
+  struct UPNPUrls urls;
+  struct IGDdatas data;
+  char lanaddr[16];
+
+  void configurePorts();
+  void init_upnp();
+  void updatePort(quint16 oldPort, quint16 newPort);
+  int forwardPort(quint16 port);
+  int disablePort(quint16 port);
 };
 #endif 

Modified: vidalia/branches/upnp/src/vidalia/mainwindow.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/mainwindow.cpp	2008-05-06 21:21:51 UTC (rev 2556)
+++ vidalia/branches/upnp/src/vidalia/mainwindow.cpp	2008-05-07 15:28:32 UTC (rev 2557)
@@ -228,7 +228,6 @@
 
   /* Disable port forwarding */
   ServerSettings settings(_torControl);
-  settings.configurePortForwarding(false, false);
   settings.cleanupPortForwarding();
 
   if (_proxyProcess->state() != QProcess::NotRunning) {
@@ -914,7 +913,7 @@
   }
 
   /* Configure UPnP port forwarding if needed */
-  serverSettings.configurePortForwarding(true, true);
+  serverSettings.configurePortForwarding();
 
   /* Check if Tor has a circuit established */
   if (_torControl->circuitEstablished())