diff options
| author | 2011-01-04 20:21:42 +0000 | |
|---|---|---|
| committer | 2011-01-04 20:21:42 +0000 | |
| commit | ed4774331fa59a191d9f99a107dd2a496ab4bb58 (patch) | |
| tree | 299555e059ed865187e562cd9659c01cb95b282d /src/kvilib | |
| parent | Convert the dns resolver to use QThread instead of KviThread. Next step is to... (diff) | |
| download | KVIrc-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.cpp | 6 | ||||
| -rw-r--r-- | src/kvilib/net/KviDnsResolver.h | 5 | ||||
| -rw-r--r-- | src/kvilib/net/KviDnsResolverNew.cpp | 208 | ||||
| -rw-r--r-- | src/kvilib/net/KviDnsResolverNew.h | 127 |
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_ |
