diff options
Diffstat (limited to 'src')
| -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 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnectionTargetResolver.cpp | 31 | ||||
| -rw-r--r-- | src/kvirc/kvs/KviKvsAsyncDnsOperation.cpp | 16 | ||||
| -rw-r--r-- | src/kvirc/kvs/KviKvsDnsManager.cpp | 16 |
7 files changed, 362 insertions, 47 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_ diff --git a/src/kvirc/kernel/KviIrcConnectionTargetResolver.cpp b/src/kvirc/kernel/KviIrcConnectionTargetResolver.cpp index abf384ae7..3bedfcff6 100644 --- a/src/kvirc/kernel/KviIrcConnectionTargetResolver.cpp +++ b/src/kvirc/kernel/KviIrcConnectionTargetResolver.cpp @@ -259,7 +259,7 @@ void KviIrcConnectionTargetResolver::proxyLookupTerminated(KviDnsResolver *) { if(m_pProxyDns->state() != KviDnsResolver::Success) { - QString szErr = KviError::getDescription(m_pProxyDns->error()); + QString szErr = m_pProxyDns->errorString(); m_pConsole->output(KVI_OUT_SYSTEMERROR, __tr2qs("Can't find the proxy IP address: %Q"), &szErr); @@ -275,18 +275,6 @@ void KviIrcConnectionTargetResolver::proxyLookupTerminated(KviDnsResolver *) m_pTarget->proxy()->m_szIp = m_pProxyDns->firstIpAddress(); g_pProxyDataBase->updateProxyIp(m_pTarget->proxy()->m_szIp.toUtf8().data(),szFirstIpAddress.toUtf8().data()); - - if(m_pProxyDns->hostnameCount() > 1) - { - QString szFirstHostname = m_pProxyDns->firstHostname(); - - for(QString * addr = m_pProxyDns->hostnameList()->next();addr;addr = m_pProxyDns->hostnameList()->next()) - { - if(!_OUTPUT_QUIET) - m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, - __tr2qs("Proxy %Q has a nickname: %Q"),&szFirstHostname,addr); - } - } } delete m_pProxyDns; @@ -371,7 +359,7 @@ void KviIrcConnectionTargetResolver::serverLookupTerminated(KviDnsResolver *) { if(m_pServerDns->state() != KviDnsResolver::Success) { - QString szErr = KviError::getDescription(m_pServerDns->error()); + QString szErr = m_pServerDns->errorString(); m_pConsole->output(KVI_OUT_SYSTEMERROR, __tr2qs("Can't find the server IP address: %Q"), &szErr); @@ -420,9 +408,9 @@ void KviIrcConnectionTargetResolver::serverLookupTerminated(KviDnsResolver *) &szIpAddress); m_pTarget->server()->setIp(szIpAddress); - QString szFirstHostname = m_pServerDns->firstHostname(); + QString szFirstHostname = m_pServerDns->hostName(); - if(!KviQString::equalCI(m_pTarget->server()->m_szHostname,m_pServerDns->firstHostname())) + if(!KviQString::equalCI(m_pTarget->server()->m_szHostname,m_pServerDns->hostName())) { if(!_OUTPUT_QUIET) m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, @@ -434,17 +422,6 @@ void KviIrcConnectionTargetResolver::serverLookupTerminated(KviDnsResolver *) m_pTarget->server()->m_szIp = szIpAddress; - if(m_pServerDns->hostnameCount() > 1) - { - for(QString * addr = m_pServerDns->hostnameList()->next();addr;addr = m_pServerDns->hostnameList()->next()) - { - if(!_OUTPUT_QUIET) - m_pConsole->output(KVI_OUT_SYSTEMMESSAGE, - __tr2qs("Server %Q has a nickname: %Q"), - &szFirstHostname,addr); - } - } - delete m_pServerDns; m_pServerDns = 0; haveServerIp(); diff --git a/src/kvirc/kvs/KviKvsAsyncDnsOperation.cpp b/src/kvirc/kvs/KviKvsAsyncDnsOperation.cpp index 3d72b2892..8b3374ffb 100644 --- a/src/kvirc/kvs/KviKvsAsyncDnsOperation.cpp +++ b/src/kvirc/kvs/KviKvsAsyncDnsOperation.cpp @@ -75,17 +75,17 @@ void KviKvsAsyncDnsOperation::lookupTerminated(KviDnsResolver *) { params.append(new KviKvsVariant(m_szQuery)); params.append(new KviKvsVariant((kvs_int_t)0)); - params.append(new KviKvsVariant(KviError::getDescription(m_pDns->error()))); + params.append(new KviKvsVariant(m_pDns->errorString())); params.append(new KviKvsVariant()); params.append(new KviKvsVariant(*m_pMagic)); } else { - QString * fh = m_pDns->hostnameList()->first(); + QString szHostName = m_pDns->hostName(); QString * fi = m_pDns->ipAddressList()->first(); params.append(new KviKvsVariant(m_szQuery)); params.append(new KviKvsVariant((kvs_int_t)1)); params.append(new KviKvsVariant(fi ? *fi : QString("?.?.?.?"))); - params.append(new KviKvsVariant(fh ? *fh : QString("?.?"))); + params.append(new KviKvsVariant(szHostName.isEmpty() ? QString("?.?") : szHostName)); params.append(new KviKvsVariant(*m_pMagic)); } @@ -101,16 +101,12 @@ void KviKvsAsyncDnsOperation::lookupTerminated(KviDnsResolver *) if(m_pDns->state() == KviDnsResolver::Failure) { - QString strDescription(KviError::getDescription(m_pDns->error())); + QString strDescription(m_pDns->errorString()); pWnd->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Error: %Q","kvs"),&strDescription); } else { + QString szHostName = m_pDns->hostName(); + pWnd->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Hostname: %Q","kvs"),&szHostName); int idx = 1; - for(QString * h = m_pDns->hostnameList()->first();h;h = m_pDns->hostnameList()->next()) - { - pWnd->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Hostname %d: %Q","kvs"),idx,h); - idx++; - } - idx = 1; for(QString * a = m_pDns->ipAddressList()->first();a;a = m_pDns->ipAddressList()->next()) { pWnd->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("IP address %d: %Q","kvs"),idx,a); diff --git a/src/kvirc/kvs/KviKvsDnsManager.cpp b/src/kvirc/kvs/KviKvsDnsManager.cpp index 3f93619b0..91ccdb974 100644 --- a/src/kvirc/kvs/KviKvsDnsManager.cpp +++ b/src/kvirc/kvs/KviKvsDnsManager.cpp @@ -136,14 +136,14 @@ void KviKvsDnsManager::dnsLookupTerminated(KviDnsResolver * pDns) { // $4... is the magic data o->parameterList()->prepend(new KviKvsVariant()); // $3 - o->parameterList()->prepend(new KviKvsVariant(KviError::getDescription(o->dns()->error()))); // $2 + o->parameterList()->prepend(new KviKvsVariant(o->dns()->errorString())); // $2 o->parameterList()->prepend(new KviKvsVariant((kvs_int_t)0)); // $1 } else { - QString * fh = o->dns()->hostnameList()->first(); + QString szHostName = o->dns()->hostName(); QString * fi = o->dns()->ipAddressList()->first(); // $4... is the magic data - o->parameterList()->prepend(new KviKvsVariant(fh ? *fh : QString("?.?"))); // $3 + o->parameterList()->prepend(new KviKvsVariant(szHostName.isEmpty() ? QString("?.?") : szHostName)); // $3 o->parameterList()->prepend(new KviKvsVariant(fi ? *fi : QString("?.?.?.?"))); // $2 o->parameterList()->prepend(new KviKvsVariant((kvs_int_t)1)); // $1 } @@ -157,16 +157,12 @@ void KviKvsDnsManager::dnsLookupTerminated(KviDnsResolver * pDns) if(o->dns()->state() == KviDnsResolver::Failure) { - QString szErr = KviError::getDescription(o->dns()->error()); + QString szErr = o->dns()->errorString(); o->window()->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Error: %Q","kvs"),&szErr); } else { + QString szHostName = o->dns()->hostName(); + o->window()->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Hostname: %Q","kvs"),&szHostName); int idx = 1; - for(QString * h = o->dns()->hostnameList()->first();h;h = o->dns()->hostnameList()->next()) - { - o->window()->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("Hostname %d: %Q","kvs"),idx,h); - idx++; - } - idx = 1; for(QString * a = o->dns()->ipAddressList()->first();a;a = o->dns()->ipAddressList()->next()) { o->window()->output(KVI_OUT_HOSTLOOKUP,__tr2qs_ctx("IP address %d: %Q","kvs"),idx,a); |
