aboutsummaryrefslogtreecommitdiffstats
path: root/src/kvilib
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2011-01-04 20:21:42 +0000
committerGravatar Szymon Tomasz Stefanek2011-01-04 20:21:42 +0000
commited4774331fa59a191d9f99a107dd2a496ab4bb58 (patch)
tree299555e059ed865187e562cd9659c01cb95b282d /src/kvilib
parentConvert the dns resolver to use QThread instead of KviThread. Next step is to... (diff)
downloadKVIrc-ed4774331fa59a191d9f99a107dd2a496ab4bb58.tar.gz
KVIrc-ed4774331fa59a191d9f99a107dd2a496ab4bb58.tar.bz2
KVIrc-ed4774331fa59a191d9f99a107dd2a496ab4bb58.zip
Add the code for a new KviDnsResolver that doesn't rely on the OS native APIs. Unfortunately QHostInfo::lookupHost() doesn't seem to correctly support IPv6 yet, so we can't enable it now. Check again later.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5294 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/kvilib')
-rw-r--r--src/kvilib/net/KviDnsResolver.cpp6
-rw-r--r--src/kvilib/net/KviDnsResolver.h5
-rw-r--r--src/kvilib/net/KviDnsResolverNew.cpp208
-rw-r--r--src/kvilib/net/KviDnsResolverNew.h127
4 files changed, 346 insertions, 0 deletions
diff --git a/src/kvilib/net/KviDnsResolver.cpp b/src/kvilib/net/KviDnsResolver.cpp
index c8058ad19..115d7e3bf 100644
--- a/src/kvilib/net/KviDnsResolver.cpp
+++ b/src/kvilib/net/KviDnsResolver.cpp
@@ -392,6 +392,12 @@ KviError::Code KviDnsResolver::error()
return m_pDnsResult->error();
}
+const QString & KviDnsResolver::errorString()
+{
+ return KviError::getDescription(error());
+}
+
+
KviDnsResolverResult * KviDnsResolver::result()
{
if(!m_pDnsResult)
diff --git a/src/kvilib/net/KviDnsResolver.h b/src/kvilib/net/KviDnsResolver.h
index becdddd5e..0308da0ec 100644
--- a/src/kvilib/net/KviDnsResolver.h
+++ b/src/kvilib/net/KviDnsResolver.h
@@ -118,7 +118,12 @@ public:
// Results (return always non null-data..but valid results only if state() == Success or Failure)
KviError::Code error();
+ const QString & errorString();
const QString & firstHostname();
+ const QString & hostName()
+ {
+ return firstHostname();
+ }
const QString & firstIpAddress();
int hostnameCount();
int ipAddressCount();
diff --git a/src/kvilib/net/KviDnsResolverNew.cpp b/src/kvilib/net/KviDnsResolverNew.cpp
new file mode 100644
index 000000000..92502f812
--- /dev/null
+++ b/src/kvilib/net/KviDnsResolverNew.cpp
@@ -0,0 +1,208 @@
+//=============================================================================
+//
+// File : KviDnsResolver.cpp
+// Creation date : Sat Jul 21 2000 17:19:31 by Szymon Stefanek
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+#include "KviDnsResolver.h"
+
+#include "KviLocale.h"
+
+#include "kvi_debug.h"
+
+#include <QHostInfo>
+
+class KviDnsResolverPrivate
+{
+public:
+ int iHostLookupId;
+ KviDnsResolver::State eState;
+ KviDnsResolver::QueryType eQueryType;
+ KviError::Code eError; // DEPRECATED
+ QString szError;
+ QString szQuery;
+ QString szHostName;
+ QString szDummy;
+ KviPointerList<QString> * pAddressList;
+};
+
+KviDnsResolver::KviDnsResolver(QObject * pParent)
+ : QObject(pParent)
+{
+ m_pPrivateData = new KviDnsResolverPrivate;
+ m_pPrivateData->eState = Idle;
+ m_pPrivateData->pAddressList = new KviPointerList<QString>(true);
+}
+
+KviDnsResolver::~KviDnsResolver()
+{
+ if(m_pPrivateData->eState == Busy)
+ QHostInfo::abortHostLookup(m_pPrivateData->iHostLookupId);
+ delete m_pPrivateData->pAddressList;
+ delete m_pPrivateData;
+}
+
+KviDnsResolver::State KviDnsResolver::state() const
+{
+ return m_pPrivateData->eState;
+}
+
+bool KviDnsResolver::lookup(const QString & szQuery,QueryType eType)
+{
+ if(m_pPrivateData->eState == Busy)
+ {
+ m_pPrivateData->eError = KviError::DNSQueryFailed;
+ m_pPrivateData->eState = Failure;
+ m_pPrivateData->szError = __tr2qs("DNS resolver busy");
+ return false;
+ }
+
+ m_pPrivateData->eQueryType = eType;
+ m_pPrivateData->eState = Busy;
+ m_pPrivateData->szQuery = szQuery;
+ m_pPrivateData->iHostLookupId = QHostInfo::lookupHost(szQuery,this,SLOT(slotHostLookupTerminated(const QHostInfo &)));
+
+ if(m_pPrivateData->iHostLookupId < 0)
+ {
+ m_pPrivateData->eError = KviError::DNSQueryFailed;
+ m_pPrivateData->eState = Failure;
+ m_pPrivateData->szError = __tr2qs("Failed to start the host lookup");
+ //emit lookupDone(this);
+ return false;
+ }
+
+ return true;
+}
+
+void KviDnsResolver::slotHostLookupTerminated(const QHostInfo &oHostInfo)
+{
+ if(oHostInfo.error() != QHostInfo::NoError)
+ {
+ m_pPrivateData->eState = Failure;
+
+ switch(oHostInfo.error())
+ {
+ case QHostInfo::HostNotFound:
+ m_pPrivateData->eError = KviError::HostNotFound;
+ break;
+ default:
+ m_pPrivateData->eError = KviError::DNSQueryFailed;
+ break;
+ }
+
+ m_pPrivateData->szError = oHostInfo.errorString();
+
+ emit lookupDone(this);
+
+ return;
+ }
+
+ m_pPrivateData->szHostName = oHostInfo.hostName();
+
+ QList<QHostAddress> lAddresses = oHostInfo.addresses();
+
+ m_pPrivateData->pAddressList->clear();
+
+ m_pPrivateData->eError = KviError::Success;
+ m_pPrivateData->szError = QString();
+ m_pPrivateData->eState = Success;
+
+ foreach(QHostAddress oAddress,lAddresses)
+ {
+ switch(m_pPrivateData->eQueryType)
+ {
+ case IPv4:
+ if(oAddress.protocol() == QAbstractSocket::IPv4Protocol)
+ m_pPrivateData->pAddressList->append(new QString(oAddress.toString()));
+ break;
+ case IPv6:
+ if(oAddress.protocol() == QAbstractSocket::IPv6Protocol)
+ m_pPrivateData->pAddressList->append(new QString(oAddress.toString()));
+ break;
+ case Any:
+ m_pPrivateData->pAddressList->append(new QString(oAddress.toString()));
+ break;
+ default:
+ KVI_ASSERT_MSG(false,"Invalid dns query type!");
+ m_pPrivateData->eState = Failure;
+ m_pPrivateData->eError = KviError::InternalError;
+ m_pPrivateData->szError = __tr2qs("Internal error: unhandled DNS query type");
+ emit lookupDone(this);
+ return;
+ break;
+ }
+ }
+
+ if(m_pPrivateData->pAddressList->isEmpty())
+ {
+ m_pPrivateData->eState = Failure;
+ m_pPrivateData->eError = KviError::ValidNameButNoIpAddress;
+ m_pPrivateData->szError = __tr2qs("DNS query returned no IP address results of the requested type");
+ }
+
+ emit lookupDone(this);
+
+}
+
+KviError::Code KviDnsResolver::error() const
+{
+ return m_pPrivateData->eError;
+}
+
+const QString & KviDnsResolver::errorString() const
+{
+ return m_pPrivateData->szError;
+}
+
+const QString & KviDnsResolver::hostName() const
+{
+ return m_pPrivateData->szHostName;
+}
+
+const QString & KviDnsResolver::firstIpAddress()
+{
+ QString * pIpAddress = m_pPrivateData->pAddressList->first();
+ if(!pIpAddress)
+ return m_pPrivateData->szDummy;
+ return *pIpAddress;
+}
+ const QString & firstIpAddress();
+
+int KviDnsResolver::ipAddressCount() const
+{
+ return m_pPrivateData->pAddressList->count();
+}
+
+KviPointerList<QString> * KviDnsResolver::ipAddressList()
+{
+ return m_pPrivateData->pAddressList;
+}
+
+const QString & KviDnsResolver::query() const
+{
+ return m_pPrivateData->szQuery;
+}
+
+bool KviDnsResolver::isRunning() const
+{
+ return m_pPrivateData->eState == Busy;
+}
+
diff --git a/src/kvilib/net/KviDnsResolverNew.h b/src/kvilib/net/KviDnsResolverNew.h
new file mode 100644
index 000000000..436575bee
--- /dev/null
+++ b/src/kvilib/net/KviDnsResolverNew.h
@@ -0,0 +1,127 @@
+#ifndef _KviDnsResolver_h_
+#define _KviDnsResolver_h_
+//=============================================================================
+//
+// File : KviDnsResolver.h
+// Creation date : Sat Jul 21 2000 13:59:11 by Szymon Stefanek
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=============================================================================
+
+
+// This is a nicely working DNS resolver that uses the QHostInfo interface
+// and thus gets rid of all the ugly OS dependancies we have.
+// It should be sufficient to rename this file and use this class
+// instead of the old KviDnsResolver.
+
+// However at present time (04.01.2010) QHostInfo doesn't seem to support
+// IPv6. Despite the documentation saying that IPv6 addresses are supported
+// the query performed by QHostInfo::lookupHost() ask only for the A record.
+//
+// Check it again with newer Qt versions and verify.
+
+#include "kvi_settings.h"
+
+#include <KviError.h> // FIXME: Get rid of this at all..
+#include <KviPointerList.h>
+
+#include <QObject>
+
+class KviDnsResolverPrivate;
+
+class QHostInfo;
+
+///
+/// \class KviDnsResolver
+/// \brief The KviDnsResolver class
+///
+/// This class...
+///
+class KVILIB_API KviDnsResolver : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ ///
+ /// Creates an instance of KviDnsResolver
+ ///
+ KviDnsResolver(QObject * pParent = NULL);
+
+ ///
+ /// Destroys the instance of KviDnsResolver
+ /// and frees all the relevant resources
+ ///
+ virtual ~KviDnsResolver();
+
+public:
+
+ enum QueryType
+ {
+ IPv4,
+ IPv6,
+ Any
+ };
+
+ enum State
+ {
+ Idle,
+ Busy,
+ Failure,
+ Success
+ };
+
+private:
+
+ KviDnsResolverPrivate * m_pPrivateData;
+
+public:
+
+ ///
+ /// Returns the resolver state
+ ///
+ State state() const;
+
+ ///
+ /// Starts a lookup for the specified DNS query of the specified type.
+ /// Returns true on success and false on failure.
+ ///
+ bool lookup(const QString & szQuery,QueryType eType);
+
+ // Results (return always non null-data..but valid results only if state() == Success or Failure)
+ KviError::Code error() const; // DEPRECATED use errorString()
+ const QString & errorString() const;
+
+ const QString & hostName() const;
+ const QString & firstIpAddress();
+ int ipAddressCount() const;
+ KviPointerList<QString> * ipAddressList();
+ const QString & query() const;
+ bool isRunning() const;
+
+private slots:
+ void slotHostLookupTerminated(const QHostInfo &oHostInfo);
+
+signals:
+ void lookupDone(KviDnsResolver *);
+
+}; // class KviDnsResolver
+
+
+#endif //!_KviDnsResolver_h_