[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[vidalia-svn] r2613: Give UPNPControlThread methods more well-defined return valu (in vidalia: . branches/upnp/src/vidalia branches/upnp/src/vidalia/config)
Author: edmanm
Date: 2008-05-26 19:56:33 -0400 (Mon, 26 May 2008)
New Revision: 2613
Modified:
vidalia/
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
vidalia/branches/upnp/src/vidalia/mainwindow.h
Log:
r369@thebe: edmanm | 2008-05-26 19:57:11 -0400
Give UPNPControlThread methods more well-defined return values. Add a
UPNPControl::error() signal emitted when port forwarding or IGD discovery
fails. Add a slot to display a message box when the error() signal is emitted.
Property changes on: vidalia
___________________________________________________________________
svk:merge ticket from /local/vidalia [r369] on 45a62a8a-8088-484c-baad-c7b3e776dd32
Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.cpp 2008-05-26 23:56:33 UTC (rev 2613)
@@ -41,6 +41,7 @@
{
_forwardedORPort = 0;
_forwardedDirPort = 0;
+ _error = UnknownError;
mutex = new QMutex();
controlThread = new UPNPControlThread(this);
controlThread->start();
@@ -89,3 +90,48 @@
controlThread->wakeup();
}
+void
+UPNPControl::setError(UPNPError upnpError)
+{
+ mutex->lock();
+ _error = upnpError;
+ mutex->unlock();
+
+ emit error(upnpError);
+}
+
+/** Returns the type of error that occurred last. */
+UPNPControl::UPNPError
+UPNPControl::error() const
+{
+ QMutexLocker locker(mutex);
+ return _error;
+}
+
+/** Returns a QString describing the type of error that occurred last. */
+QString
+UPNPControl::errorString() const
+{
+ UPNPError error = this->error();
+
+ switch (error) {
+ case Success:
+ return tr("Success");
+ case NoUPNPDevicesFound:
+ return tr("No UPnP-enabled devices found");
+ case NoValidIGDsFound:
+ return tr("No valid UPnP-enabled Internet gateway devices found");
+ case WSAStartupFailed:
+ return tr("WSAStartup failed");
+ case AddPortMappingFailed:
+ return tr("Failed to add a port mapping");
+ case GetPortMappingFailed:
+ return tr("Failed to retrieve a port mapping");
+ case DeletePortMappingFailed:
+ return tr("Failed to remove a port mapping");
+ default:
+ return tr("Unknown error");
+ }
+}
+
+
Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrol.h 2008-05-26 23:56:33 UTC (rev 2613)
@@ -29,6 +29,18 @@
Q_OBJECT
public:
+ /** UPnP-related error values. */
+ enum UPNPError {
+ Success,
+ NoUPNPDevicesFound,
+ NoValidIGDsFound,
+ WSAStartupFailed,
+ AddPortMappingFailed,
+ GetPortMappingFailed,
+ DeletePortMappingFailed,
+ UnknownError
+ };
+
/** Returns a pointer to this object's singleton instance. */
static UPNPControl* Instance();
/** Terminates the UPnP control thread and frees memory allocated to this
@@ -41,19 +53,34 @@
* <b>desiredDirPort</b> and <b>desiredOrPort</b>, respectively. */
void setDesiredState(quint16 desiredDirPort, quint16 desiredOrPort);
+ /** Returns the type of error that occurred last. */
+ UPNPError error() const;
+ /** Returns a QString describing the type of error that occurred last. */
+ QString errorString() const;
+
+signals:
+ /** Emitted when a UPnP error occurs. */
+ void error(UPNPError error);
+
protected:
/** Constructor. Initializes and starts a thread in which all blocking UPnP
* operations will be performed. */
UPNPControl();
/** Destructor. cleanup() should be called before the object is destroyed. */
~UPNPControl();
-
+
+ /** Sets the most recent UPnP-related error to <b>error</b>. */
+ void setError(UPNPError error);
+
private:
static UPNPControl* pInstance; /**< UPNPControl singleton instance. */
quint16 _forwardedORPort; /**< Currently forwarded ORPort. */
quint16 _forwardedDirPort; /**< Currently forwarded DirPort. */
QMutex *mutex; /**< Mutex around variables shared with UPNPControlThread. */
+ UPNPError _error; /**< Most recent UPNP error. */
+
+ friend class UPNPControlThread;
UPNPControlThread *controlThread; /**< Thread used for UPnP operations. */
};
Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.cpp 2008-05-26 23:56:33 UTC (rev 2613)
@@ -104,7 +104,7 @@
UPNPControlThread::configurePorts() {
quint16 desiredDirPort, desiredOrPort;
bool force_init = false;
- int retval = 0;
+ UPNPControl::UPNPError retval = UPNPControl::Success;
vDebug("configurePorts()");
@@ -126,36 +126,31 @@
/* Configure DirPort */
if (desiredDirPort != _dirPort) {
retval = updatePort(_dirPort, desiredDirPort);
- if (!retval)
+ if (retval == UPNPControl::Success)
_dirPort = desiredDirPort;
}
/* Configure ORPort */
if (desiredOrPort != _orPort) {
retval = updatePort(_orPort, desiredOrPort);
- if (!retval)
+ if (retval == UPNPControl::Success)
_orPort = desiredOrPort;
}
} else {
/* Add the mapping even if they exist already */
retval = updatePort(0, desiredDirPort);
- if (!retval)
+ if (retval == UPNPControl::Success)
_dirPort = desiredDirPort;
retval = updatePort(0, desiredOrPort);
- if (!retval)
+ if (retval == UPNPControl::Success)
_orPort = desiredOrPort;
}
vInfo("configurePorts() result: %1").arg(retval);
-
- if (retval) {
- QString message;
- QTextStream(&message)
- << "Failed to configure automatic port forwarding (status: "
- << retval << ")";
- QMessageBox::warning(0, QString("Automatic port forwarding"), message);
- }
+
+ if (retval != UPNPControl::Success)
+ UPNPControl::Instance()->setError(retval);
}
/** Terminates the UPnP control thread's run() loop.
@@ -193,33 +188,34 @@
/** Updates the port mapping for <b>oldPort</b>, changing it to
* <b>newPort</b>. */
-int
+UPNPControl::UPNPError
UPNPControlThread::updatePort(quint16 oldPort, quint16 newPort)
{
- int retval;
+ UPNPControl::UPNPError retval;
#ifdef Q_OS_WIN32
// Workaround from http://trolltech.com/developer/knowledgebase/579
WSAData wsadata;
if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) {
- vWarn("WSAStartup failure while disabling UPnP port forwarding");
+ vWarn("WSAStartup failure while updating UPnP port forwarding");
+ return UPNPControl::WSAStartupFailed;
}
#endif
if (_upnpInitialized.isNull() && (oldPort != 0 || newPort != 0)) {
retval = initializeUPNP();
- if (0 == retval)
+ if (retval == UPNPControl::Success)
_upnpInitialized = QTime::currentTime();
else
_upnpInitialized = QTime();
} else {
- retval = 0;
+ retval = UPNPControl::Success;
}
- if (!retval && oldPort != 0)
+ if (retval == UPNPControl::Success && oldPort != 0)
retval = disablePort(oldPort);
- if (!retval && newPort != 0)
+ if (retval == UPNPControl::Success && newPort != 0)
retval = forwardPort(newPort);
#ifdef Q_OS_WIN32
@@ -232,7 +228,7 @@
/** Discovers UPnP-enabled IGDs on the network. Based on
* http://miniupnp.free.fr/files/download.php?file=xchat-upnp20061022.patch
* This method will block for UPNPCONTROL_DISCOVER_TIMEOUT milliseconds. */
-int
+UPNPControl::UPNPError
UPNPControlThread::initializeUPNP()
{
struct UPNPDev *devlist;
@@ -244,7 +240,7 @@
devlist = upnpDiscover(UPNPCONTROL_DISCOVER_TIMEOUT, NULL, NULL);
if (NULL == devlist) {
vWarn("upnpDiscover returned: NULL");
- return 5;
+ return UPNPControl::NoUPNPDevicesFound;
}
retval = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
@@ -254,14 +250,14 @@
freeUPNPDevlist(devlist);
if (retval != 1 && retval != 2)
- return 6;
+ return UPNPControl::NoValidIGDsFound;
- return 0;
+ return UPNPControl::Success;
}
/** Adds a port forwarding mapping from external:<b>port</b> to
* internal:<b>port</b>. Returns 0 on success, or non-zero on failure. */
-int
+UPNPControl::UPNPError
UPNPControlThread::forwardPort(quint16 port)
{
int retval;
@@ -276,11 +272,11 @@
// Add the port mapping of external:port -> internal:port
retval = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
- sPort, sPort, lanaddr, "Tor server", "TCP");
+ sPort, sPort, lanaddr, "Tor relay", "TCP");
if(UPNPCOMMAND_SUCCESS != retval) {
vWarn("AddPortMapping(%1, %2, %3) failed with code %4")
.arg(sPort).arg(sPort).arg(lanaddr).arg(retval);
- return 1;
+ return UPNPControl::AddPortMappingFailed;
}
// Check if the port mapping was accepted
@@ -288,23 +284,23 @@
sPort, "TCP", intClient, intPort);
if(UPNPCOMMAND_SUCCESS != retval) {
vWarn("GetSpecificPortMappingEntry() failed with code %1").arg(retval);
- return 2;
+ return UPNPControl::GetPortMappingFailed;
}
if(! intClient[0]) {
vWarn("GetSpecificPortMappingEntry failed.");
- return 3;
+ return UPNPControl::GetPortMappingFailed;
}
// Output the mapping
vInfo("(external):%1 -> %2:%3").arg(sPort).arg(intClient).arg(intPort);
- return 0;
+ return UPNPControl::Success;
}
/** Removes the port mapping for <b>port</b>. Returns 0 on success or non-zero
* on failure. */
-int
+UPNPControl::UPNPError
UPNPControlThread::disablePort(quint16 port)
{
char sPort[6];
@@ -317,12 +313,12 @@
sPort, "TCP");
if(UPNPCOMMAND_SUCCESS != retval) {
vWarn("DeletePortMapping() failed with code %1").arg(retval);
- return 4;
+ return UPNPControl::DeletePortMappingFailed;
}
// Output the cancelled mapping
vInfo("(external):%1 -> <>").arg(sPort);
- return 0;
+ return UPNPControl::Success;
}
Modified: vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/config/upnpcontrolthread.h 2008-05-26 23:56:33 UTC (rev 2613)
@@ -21,16 +21,14 @@
#include <QMutex>
#include <QWaitCondition>
#include <QTime>
+#include "upnpcontrol.h"
#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
@@ -60,16 +58,16 @@
void configurePorts();
/** Discovers UPnP-enabled IGDs on the network. This method will block for
* UPNPCONTROL_DISCOVER_TIMEOUT milliseconds. */
- int initializeUPNP();
+ UPNPControl::UPNPError initializeUPNP();
/** Updates the port mapping for <b>oldPort</b>, changing it to
* <b>newPort</b>. */
- int updatePort(quint16 oldPort, quint16 newPort);
+ UPNPControl::UPNPError updatePort(quint16 oldPort, quint16 newPort);
/** Adds a port forwarding mapping from external:<b>port</b> to
* internal:<b>port</b>. Returns 0 on success, or non-zero on failure. */
- int forwardPort(quint16 port);
+ UPNPControl::UPNPError forwardPort(quint16 port);
/** Removes the port mapping for <b>port</b>. Returns 0 on success or
* non-zero on failure. */
- int disablePort(quint16 port);
+ UPNPControl::UPNPError disablePort(quint16 port);
QTime _upnpInitialized; /**< Time at which the UPnP state was last set. */
bool _keepRunning; /**< True if the control thread should keep running. */
Modified: vidalia/branches/upnp/src/vidalia/mainwindow.cpp
===================================================================
--- vidalia/branches/upnp/src/vidalia/mainwindow.cpp 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/mainwindow.cpp 2008-05-26 23:56:33 UTC (rev 2613)
@@ -141,7 +141,11 @@
/* Catch signals when the application is running or shutting down */
connect(vApp, SIGNAL(running()), this, SLOT(running()));
connect(vApp, SIGNAL(shutdown()), this, SLOT(shutdown()));
-
+
+ /* Catch UPnP-related signals */
+ connect(UPNPControl::Instance(), SIGNAL(error(UPNPControl::UPNPError)),
+ this, SLOT(upnpError(UPNPControl::UPNPError)));
+
if (TrayIcon::isTrayIconSupported()) {
/* Make the tray icon visible */
_trayIcon.show();
@@ -1173,4 +1177,16 @@
return "Unknown";
}
+/** Called when a UPnP error occurs. */
+void
+MainWindow::upnpError(UPNPControl::UPNPError error)
+{
+ Q_UNUSED(error);
+ VMessageBox::warning(this,
+ tr("Port Forwarding Failed"),
+ p(tr("Vidalia was unable to configure automatic port forwarding."))
+ + p(UPNPControl::Instance()->errorString()),
+ VMessageBox::Ok);
+}
+
Modified: vidalia/branches/upnp/src/vidalia/mainwindow.h
===================================================================
--- vidalia/branches/upnp/src/vidalia/mainwindow.h 2008-05-26 23:20:52 UTC (rev 2612)
+++ vidalia/branches/upnp/src/vidalia/mainwindow.h 2008-05-26 23:56:33 UTC (rev 2613)
@@ -26,6 +26,7 @@
#include "log/messagelog.h"
#include "bwgraph/bwgraph.h"
#include "config/configdialog.h"
+#include "config/upnpcontrol.h"
#include "help/browser/helpbrowser.h"
#include "network/netviewer.h"
#include "ui_mainwindow.h"
@@ -103,7 +104,9 @@
void onBrowserFailed(QString errmsg);
/** Called when the proxy server fails to start */
void onProxyFailed(QString errmsg);
-
+ /** Called when a UPnP error occurs. */
+ void upnpError(UPNPControl::UPNPError error);
+
private:
enum TorStatus {
Unset, /**< Tor's status has not yet been set. */