| /**************************************************************************** |
| ** |
| ** Copyright (C) 2012 Jeremy Lainé <jeremy.laine@m4x.org> |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtNetwork module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qdnslookup.h" |
| #include "qdnslookup_p.h" |
| |
| #include <qcoreapplication.h> |
| #include <qdatetime.h> |
| #include <qrandom.h> |
| #include <qurl.h> |
| |
| #include <algorithm> |
| |
| QT_BEGIN_NAMESPACE |
| |
| #if QT_CONFIG(thread) |
| Q_GLOBAL_STATIC(QDnsLookupThreadPool, theDnsLookupThreadPool); |
| #endif |
| |
| static bool qt_qdnsmailexchangerecord_less_than(const QDnsMailExchangeRecord &r1, const QDnsMailExchangeRecord &r2) |
| { |
| // Lower numbers are more preferred than higher ones. |
| return r1.preference() < r2.preference(); |
| } |
| |
| /* |
| Sorts a list of QDnsMailExchangeRecord objects according to RFC 5321. |
| */ |
| |
| static void qt_qdnsmailexchangerecord_sort(QList<QDnsMailExchangeRecord> &records) |
| { |
| // If we have no more than one result, we are done. |
| if (records.size() <= 1) |
| return; |
| |
| // Order the records by preference. |
| std::sort(records.begin(), records.end(), qt_qdnsmailexchangerecord_less_than); |
| |
| int i = 0; |
| while (i < records.size()) { |
| |
| // Determine the slice of records with the current preference. |
| QList<QDnsMailExchangeRecord> slice; |
| const quint16 slicePreference = records.at(i).preference(); |
| for (int j = i; j < records.size(); ++j) { |
| if (records.at(j).preference() != slicePreference) |
| break; |
| slice << records.at(j); |
| } |
| |
| // Randomize the slice of records. |
| while (!slice.isEmpty()) { |
| const unsigned int pos = QRandomGenerator::global()->bounded(slice.size()); |
| records[i++] = slice.takeAt(pos); |
| } |
| } |
| } |
| |
| static bool qt_qdnsservicerecord_less_than(const QDnsServiceRecord &r1, const QDnsServiceRecord &r2) |
| { |
| // Order by priority, or if the priorities are equal, |
| // put zero weight records first. |
| return r1.priority() < r2.priority() |
| || (r1.priority() == r2.priority() |
| && r1.weight() == 0 && r2.weight() > 0); |
| } |
| |
| /* |
| Sorts a list of QDnsServiceRecord objects according to RFC 2782. |
| */ |
| |
| static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records) |
| { |
| // If we have no more than one result, we are done. |
| if (records.size() <= 1) |
| return; |
| |
| // Order the records by priority, and for records with an equal |
| // priority, put records with a zero weight first. |
| std::sort(records.begin(), records.end(), qt_qdnsservicerecord_less_than); |
| |
| int i = 0; |
| while (i < records.size()) { |
| |
| // Determine the slice of records with the current priority. |
| QList<QDnsServiceRecord> slice; |
| const quint16 slicePriority = records.at(i).priority(); |
| unsigned int sliceWeight = 0; |
| for (int j = i; j < records.size(); ++j) { |
| if (records.at(j).priority() != slicePriority) |
| break; |
| sliceWeight += records.at(j).weight(); |
| slice << records.at(j); |
| } |
| #ifdef QDNSLOOKUP_DEBUG |
| qDebug("qt_qdnsservicerecord_sort() : priority %i (size: %i, total weight: %i)", |
| slicePriority, slice.size(), sliceWeight); |
| #endif |
| |
| // Order the slice of records. |
| while (!slice.isEmpty()) { |
| const unsigned int weightThreshold = QRandomGenerator::global()->bounded(sliceWeight + 1); |
| unsigned int summedWeight = 0; |
| for (int j = 0; j < slice.size(); ++j) { |
| summedWeight += slice.at(j).weight(); |
| if (summedWeight >= weightThreshold) { |
| #ifdef QDNSLOOKUP_DEBUG |
| qDebug("qt_qdnsservicerecord_sort() : adding %s %i (weight: %i)", |
| qPrintable(slice.at(j).target()), slice.at(j).port(), |
| slice.at(j).weight()); |
| #endif |
| // Adjust the slice weight and take the current record. |
| sliceWeight -= slice.at(j).weight(); |
| records[i++] = slice.takeAt(j); |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| const char *QDnsLookupPrivate::msgNoIpV6NameServerAdresses = |
| QT_TRANSLATE_NOOP("QDnsLookupRunnable", "IPv6 addresses for nameservers are currently not supported"); |
| |
| /*! |
| \class QDnsLookup |
| \brief The QDnsLookup class represents a DNS lookup. |
| \since 5.0 |
| |
| \inmodule QtNetwork |
| \ingroup network |
| |
| QDnsLookup uses the mechanisms provided by the operating system to perform |
| DNS lookups. To perform a lookup you need to specify a \l name and \l type |
| then invoke the \l{QDnsLookup::lookup()}{lookup()} slot. The |
| \l{QDnsLookup::finished()}{finished()} signal will be emitted upon |
| completion. |
| |
| For example, you can determine which servers an XMPP chat client should |
| connect to for a given domain with: |
| |
| \snippet code/src_network_kernel_qdnslookup.cpp 0 |
| |
| Once the request finishes you can handle the results with: |
| |
| \snippet code/src_network_kernel_qdnslookup.cpp 1 |
| |
| \note If you simply want to find the IP address(es) associated with a host |
| name, or the host name associated with an IP address you should use |
| QHostInfo instead. |
| */ |
| |
| /*! |
| \enum QDnsLookup::Error |
| |
| Indicates all possible error conditions found during the |
| processing of the DNS lookup. |
| |
| \value NoError no error condition. |
| |
| \value ResolverError there was an error initializing the system's |
| DNS resolver. |
| |
| \value OperationCancelledError the lookup was aborted using the abort() |
| method. |
| |
| \value InvalidRequestError the requested DNS lookup was invalid. |
| |
| \value InvalidReplyError the reply returned by the server was invalid. |
| |
| \value ServerFailureError the server encountered an internal failure |
| while processing the request (SERVFAIL). |
| |
| \value ServerRefusedError the server refused to process the request for |
| security or policy reasons (REFUSED). |
| |
| \value NotFoundError the requested domain name does not exist |
| (NXDOMAIN). |
| */ |
| |
| /*! |
| \enum QDnsLookup::Type |
| |
| Indicates the type of DNS lookup that was performed. |
| |
| \value A IPv4 address records. |
| |
| \value AAAA IPv6 address records. |
| |
| \value ANY any records. |
| |
| \value CNAME canonical name records. |
| |
| \value MX mail exchange records. |
| |
| \value NS name server records. |
| |
| \value PTR pointer records. |
| |
| \value SRV service records. |
| |
| \value TXT text records. |
| */ |
| |
| /*! |
| \fn void QDnsLookup::finished() |
| |
| This signal is emitted when the reply has finished processing. |
| */ |
| |
| /*! |
| \fn void QDnsLookup::nameChanged(const QString &name) |
| |
| This signal is emitted when the lookup \l name changes. |
| \a name is the new lookup name. |
| */ |
| |
| /*! |
| \fn void QDnsLookup::typeChanged(Type type) |
| |
| This signal is emitted when the lookup \l type changes. |
| \a type is the new lookup type. |
| */ |
| |
| /*! |
| Constructs a QDnsLookup object and sets \a parent as the parent object. |
| |
| The \l type property will default to QDnsLookup::A. |
| */ |
| |
| QDnsLookup::QDnsLookup(QObject *parent) |
| : QObject(*new QDnsLookupPrivate, parent) |
| { |
| qRegisterMetaType<QDnsLookupReply>(); |
| } |
| /*! |
| Constructs a QDnsLookup object for the given \a type and \a name and sets |
| \a parent as the parent object. |
| */ |
| |
| QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent) |
| : QObject(*new QDnsLookupPrivate, parent) |
| { |
| Q_D(QDnsLookup); |
| qRegisterMetaType<QDnsLookupReply>(); |
| d->name = name; |
| d->type = type; |
| } |
| |
| /*! |
| \fn QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) |
| \since 5.4 |
| Constructs a QDnsLookup object for the given \a type, \a name and |
| \a nameserver and sets \a parent as the parent object. |
| */ |
| |
| QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) |
| : QObject(*new QDnsLookupPrivate, parent) |
| { |
| Q_D(QDnsLookup); |
| qRegisterMetaType<QDnsLookupReply>(); |
| d->name = name; |
| d->type = type; |
| d->nameserver = nameserver; |
| } |
| |
| /*! |
| Destroys the QDnsLookup object. |
| |
| It is safe to delete a QDnsLookup object even if it is not finished, you |
| will simply never receive its results. |
| */ |
| |
| QDnsLookup::~QDnsLookup() |
| { |
| } |
| |
| /*! |
| \property QDnsLookup::error |
| \brief the type of error that occurred if the DNS lookup failed, or NoError. |
| */ |
| |
| QDnsLookup::Error QDnsLookup::error() const |
| { |
| return d_func()->reply.error; |
| } |
| |
| /*! |
| \property QDnsLookup::errorString |
| \brief a human-readable description of the error if the DNS lookup failed. |
| */ |
| |
| QString QDnsLookup::errorString() const |
| { |
| return d_func()->reply.errorString; |
| } |
| |
| /*! |
| Returns whether the reply has finished or was aborted. |
| */ |
| |
| bool QDnsLookup::isFinished() const |
| { |
| return d_func()->isFinished; |
| } |
| |
| /*! |
| \property QDnsLookup::name |
| \brief the name to lookup. |
| |
| \note The name will be encoded using IDNA, which means it's unsuitable for |
| querying SRV records compatible with the DNS-SD specification. |
| */ |
| |
| QString QDnsLookup::name() const |
| { |
| return d_func()->name; |
| } |
| |
| void QDnsLookup::setName(const QString &name) |
| { |
| Q_D(QDnsLookup); |
| if (name != d->name) { |
| d->name = name; |
| emit nameChanged(name); |
| } |
| } |
| |
| /*! |
| \property QDnsLookup::type |
| \brief the type of DNS lookup. |
| */ |
| |
| QDnsLookup::Type QDnsLookup::type() const |
| { |
| return d_func()->type; |
| } |
| |
| void QDnsLookup::setType(Type type) |
| { |
| Q_D(QDnsLookup); |
| if (type != d->type) { |
| d->type = type; |
| emit typeChanged(type); |
| } |
| } |
| |
| /*! |
| \property QDnsLookup::nameserver |
| \brief the nameserver to use for DNS lookup. |
| */ |
| |
| QHostAddress QDnsLookup::nameserver() const |
| { |
| return d_func()->nameserver; |
| } |
| |
| void QDnsLookup::setNameserver(const QHostAddress &nameserver) |
| { |
| Q_D(QDnsLookup); |
| if (nameserver != d->nameserver) { |
| d->nameserver = nameserver; |
| emit nameserverChanged(nameserver); |
| } |
| } |
| |
| /*! |
| Returns the list of canonical name records associated with this lookup. |
| */ |
| |
| QList<QDnsDomainNameRecord> QDnsLookup::canonicalNameRecords() const |
| { |
| return d_func()->reply.canonicalNameRecords; |
| } |
| |
| /*! |
| Returns the list of host address records associated with this lookup. |
| */ |
| |
| QList<QDnsHostAddressRecord> QDnsLookup::hostAddressRecords() const |
| { |
| return d_func()->reply.hostAddressRecords; |
| } |
| |
| /*! |
| Returns the list of mail exchange records associated with this lookup. |
| |
| The records are sorted according to |
| \l{http://www.rfc-editor.org/rfc/rfc5321.txt}{RFC 5321}, so if you use them |
| to connect to servers, you should try them in the order they are listed. |
| */ |
| |
| QList<QDnsMailExchangeRecord> QDnsLookup::mailExchangeRecords() const |
| { |
| return d_func()->reply.mailExchangeRecords; |
| } |
| |
| /*! |
| Returns the list of name server records associated with this lookup. |
| */ |
| |
| QList<QDnsDomainNameRecord> QDnsLookup::nameServerRecords() const |
| { |
| return d_func()->reply.nameServerRecords; |
| } |
| |
| /*! |
| Returns the list of pointer records associated with this lookup. |
| */ |
| |
| QList<QDnsDomainNameRecord> QDnsLookup::pointerRecords() const |
| { |
| return d_func()->reply.pointerRecords; |
| } |
| |
| /*! |
| Returns the list of service records associated with this lookup. |
| |
| The records are sorted according to |
| \l{http://www.rfc-editor.org/rfc/rfc2782.txt}{RFC 2782}, so if you use them |
| to connect to servers, you should try them in the order they are listed. |
| */ |
| |
| QList<QDnsServiceRecord> QDnsLookup::serviceRecords() const |
| { |
| return d_func()->reply.serviceRecords; |
| } |
| |
| /*! |
| Returns the list of text records associated with this lookup. |
| */ |
| |
| QList<QDnsTextRecord> QDnsLookup::textRecords() const |
| { |
| return d_func()->reply.textRecords; |
| } |
| |
| /*! |
| Aborts the DNS lookup operation. |
| |
| If the lookup is already finished, does nothing. |
| */ |
| |
| void QDnsLookup::abort() |
| { |
| Q_D(QDnsLookup); |
| if (d->runnable) { |
| d->runnable = 0; |
| d->reply = QDnsLookupReply(); |
| d->reply.error = QDnsLookup::OperationCancelledError; |
| d->reply.errorString = tr("Operation cancelled"); |
| d->isFinished = true; |
| emit finished(); |
| } |
| } |
| |
| /*! |
| Performs the DNS lookup. |
| |
| The \l{QDnsLookup::finished()}{finished()} signal is emitted upon completion. |
| */ |
| |
| void QDnsLookup::lookup() |
| { |
| Q_D(QDnsLookup); |
| d->isFinished = false; |
| d->reply = QDnsLookupReply(); |
| d->runnable = new QDnsLookupRunnable(d->type, QUrl::toAce(d->name), d->nameserver); |
| connect(d->runnable, SIGNAL(finished(QDnsLookupReply)), |
| this, SLOT(_q_lookupFinished(QDnsLookupReply)), |
| Qt::BlockingQueuedConnection); |
| #if QT_CONFIG(thread) |
| theDnsLookupThreadPool()->start(d->runnable); |
| #endif |
| } |
| |
| /*! |
| \class QDnsDomainNameRecord |
| \brief The QDnsDomainNameRecord class stores information about a domain |
| name record. |
| |
| \inmodule QtNetwork |
| \ingroup network |
| \ingroup shared |
| |
| When performing a name server lookup, zero or more records will be returned. |
| Each record is represented by a QDnsDomainNameRecord instance. |
| |
| \sa QDnsLookup |
| */ |
| |
| /*! |
| Constructs an empty domain name record object. |
| */ |
| |
| QDnsDomainNameRecord::QDnsDomainNameRecord() |
| : d(new QDnsDomainNameRecordPrivate) |
| { |
| } |
| |
| /*! |
| Constructs a copy of \a other. |
| */ |
| |
| QDnsDomainNameRecord::QDnsDomainNameRecord(const QDnsDomainNameRecord &other) |
| : d(other.d) |
| { |
| } |
| |
| /*! |
| Destroys a domain name record. |
| */ |
| |
| QDnsDomainNameRecord::~QDnsDomainNameRecord() |
| { |
| } |
| |
| /*! |
| Returns the name for this record. |
| */ |
| |
| QString QDnsDomainNameRecord::name() const |
| { |
| return d->name; |
| } |
| |
| /*! |
| Returns the duration in seconds for which this record is valid. |
| */ |
| |
| quint32 QDnsDomainNameRecord::timeToLive() const |
| { |
| return d->timeToLive; |
| } |
| |
| /*! |
| Returns the value for this domain name record. |
| */ |
| |
| QString QDnsDomainNameRecord::value() const |
| { |
| return d->value; |
| } |
| |
| /*! |
| Assigns the data of the \a other object to this record object, |
| and returns a reference to it. |
| */ |
| |
| QDnsDomainNameRecord &QDnsDomainNameRecord::operator=(const QDnsDomainNameRecord &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| /*! |
| \fn void QDnsDomainNameRecord::swap(QDnsDomainNameRecord &other) |
| |
| Swaps this domain-name record instance with \a other. This |
| function is very fast and never fails. |
| */ |
| |
| /*! |
| \class QDnsHostAddressRecord |
| \brief The QDnsHostAddressRecord class stores information about a host |
| address record. |
| |
| \inmodule QtNetwork |
| \ingroup network |
| \ingroup shared |
| |
| When performing an address lookup, zero or more records will be |
| returned. Each record is represented by a QDnsHostAddressRecord instance. |
| |
| \sa QDnsLookup |
| */ |
| |
| /*! |
| Constructs an empty host address record object. |
| */ |
| |
| QDnsHostAddressRecord::QDnsHostAddressRecord() |
| : d(new QDnsHostAddressRecordPrivate) |
| { |
| } |
| |
| /*! |
| Constructs a copy of \a other. |
| */ |
| |
| QDnsHostAddressRecord::QDnsHostAddressRecord(const QDnsHostAddressRecord &other) |
| : d(other.d) |
| { |
| } |
| |
| /*! |
| Destroys a host address record. |
| */ |
| |
| QDnsHostAddressRecord::~QDnsHostAddressRecord() |
| { |
| } |
| |
| /*! |
| Returns the name for this record. |
| */ |
| |
| QString QDnsHostAddressRecord::name() const |
| { |
| return d->name; |
| } |
| |
| /*! |
| Returns the duration in seconds for which this record is valid. |
| */ |
| |
| quint32 QDnsHostAddressRecord::timeToLive() const |
| { |
| return d->timeToLive; |
| } |
| |
| /*! |
| Returns the value for this host address record. |
| */ |
| |
| QHostAddress QDnsHostAddressRecord::value() const |
| { |
| return d->value; |
| } |
| |
| /*! |
| Assigns the data of the \a other object to this record object, |
| and returns a reference to it. |
| */ |
| |
| QDnsHostAddressRecord &QDnsHostAddressRecord::operator=(const QDnsHostAddressRecord &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| /*! |
| \fn void QDnsHostAddressRecord::swap(QDnsHostAddressRecord &other) |
| |
| Swaps this host address record instance with \a other. This |
| function is very fast and never fails. |
| */ |
| |
| /*! |
| \class QDnsMailExchangeRecord |
| \brief The QDnsMailExchangeRecord class stores information about a DNS MX record. |
| |
| \inmodule QtNetwork |
| \ingroup network |
| \ingroup shared |
| |
| When performing a lookup on a service, zero or more records will be |
| returned. Each record is represented by a QDnsMailExchangeRecord instance. |
| |
| The meaning of the fields is defined in |
| \l{http://www.rfc-editor.org/rfc/rfc1035.txt}{RFC 1035}. |
| |
| \sa QDnsLookup |
| */ |
| |
| /*! |
| Constructs an empty mail exchange record object. |
| */ |
| |
| QDnsMailExchangeRecord::QDnsMailExchangeRecord() |
| : d(new QDnsMailExchangeRecordPrivate) |
| { |
| } |
| |
| /*! |
| Constructs a copy of \a other. |
| */ |
| |
| QDnsMailExchangeRecord::QDnsMailExchangeRecord(const QDnsMailExchangeRecord &other) |
| : d(other.d) |
| { |
| } |
| |
| /*! |
| Destroys a mail exchange record. |
| */ |
| |
| QDnsMailExchangeRecord::~QDnsMailExchangeRecord() |
| { |
| } |
| |
| /*! |
| Returns the domain name of the mail exchange for this record. |
| */ |
| |
| QString QDnsMailExchangeRecord::exchange() const |
| { |
| return d->exchange; |
| } |
| |
| /*! |
| Returns the name for this record. |
| */ |
| |
| QString QDnsMailExchangeRecord::name() const |
| { |
| return d->name; |
| } |
| |
| /*! |
| Returns the preference for this record. |
| */ |
| |
| quint16 QDnsMailExchangeRecord::preference() const |
| { |
| return d->preference; |
| } |
| |
| /*! |
| Returns the duration in seconds for which this record is valid. |
| */ |
| |
| quint32 QDnsMailExchangeRecord::timeToLive() const |
| { |
| return d->timeToLive; |
| } |
| |
| /*! |
| Assigns the data of the \a other object to this record object, |
| and returns a reference to it. |
| */ |
| |
| QDnsMailExchangeRecord &QDnsMailExchangeRecord::operator=(const QDnsMailExchangeRecord &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| /*! |
| \fn void QDnsMailExchangeRecord::swap(QDnsMailExchangeRecord &other) |
| |
| Swaps this mail exchange record with \a other. This function is |
| very fast and never fails. |
| */ |
| |
| /*! |
| \class QDnsServiceRecord |
| \brief The QDnsServiceRecord class stores information about a DNS SRV record. |
| |
| \inmodule QtNetwork |
| \ingroup network |
| \ingroup shared |
| |
| When performing a lookup on a service, zero or more records will be |
| returned. Each record is represented by a QDnsServiceRecord instance. |
| |
| The meaning of the fields is defined in |
| \l{http://www.rfc-editor.org/rfc/rfc2782.txt}{RFC 2782}. |
| |
| \sa QDnsLookup |
| */ |
| |
| /*! |
| Constructs an empty service record object. |
| */ |
| |
| QDnsServiceRecord::QDnsServiceRecord() |
| : d(new QDnsServiceRecordPrivate) |
| { |
| } |
| |
| /*! |
| Constructs a copy of \a other. |
| */ |
| |
| QDnsServiceRecord::QDnsServiceRecord(const QDnsServiceRecord &other) |
| : d(other.d) |
| { |
| } |
| |
| /*! |
| Destroys a service record. |
| */ |
| |
| QDnsServiceRecord::~QDnsServiceRecord() |
| { |
| } |
| |
| /*! |
| Returns the name for this record. |
| */ |
| |
| QString QDnsServiceRecord::name() const |
| { |
| return d->name; |
| } |
| |
| /*! |
| Returns the port on the target host for this service record. |
| */ |
| |
| quint16 QDnsServiceRecord::port() const |
| { |
| return d->port; |
| } |
| |
| /*! |
| Returns the priority for this service record. |
| |
| A client must attempt to contact the target host with the lowest-numbered |
| priority. |
| */ |
| |
| quint16 QDnsServiceRecord::priority() const |
| { |
| return d->priority; |
| } |
| |
| /*! |
| Returns the domain name of the target host for this service record. |
| */ |
| |
| QString QDnsServiceRecord::target() const |
| { |
| return d->target; |
| } |
| |
| /*! |
| Returns the duration in seconds for which this record is valid. |
| */ |
| |
| quint32 QDnsServiceRecord::timeToLive() const |
| { |
| return d->timeToLive; |
| } |
| |
| /*! |
| Returns the weight for this service record. |
| |
| The weight field specifies a relative weight for entries with the same |
| priority. Entries with higher weights should be selected with a higher |
| probability. |
| */ |
| |
| quint16 QDnsServiceRecord::weight() const |
| { |
| return d->weight; |
| } |
| |
| /*! |
| Assigns the data of the \a other object to this record object, |
| and returns a reference to it. |
| */ |
| |
| QDnsServiceRecord &QDnsServiceRecord::operator=(const QDnsServiceRecord &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| /*! |
| \fn void QDnsServiceRecord::swap(QDnsServiceRecord &other) |
| |
| Swaps this service record instance with \a other. This function is |
| very fast and never fails. |
| */ |
| |
| /*! |
| \class QDnsTextRecord |
| \brief The QDnsTextRecord class stores information about a DNS TXT record. |
| |
| \inmodule QtNetwork |
| \ingroup network |
| \ingroup shared |
| |
| When performing a text lookup, zero or more records will be |
| returned. Each record is represented by a QDnsTextRecord instance. |
| |
| The meaning of the fields is defined in |
| \l{http://www.rfc-editor.org/rfc/rfc1035.txt}{RFC 1035}. |
| |
| \sa QDnsLookup |
| */ |
| |
| /*! |
| Constructs an empty text record object. |
| */ |
| |
| QDnsTextRecord::QDnsTextRecord() |
| : d(new QDnsTextRecordPrivate) |
| { |
| } |
| |
| /*! |
| Constructs a copy of \a other. |
| */ |
| |
| QDnsTextRecord::QDnsTextRecord(const QDnsTextRecord &other) |
| : d(other.d) |
| { |
| } |
| |
| /*! |
| Destroys a text record. |
| */ |
| |
| QDnsTextRecord::~QDnsTextRecord() |
| { |
| } |
| |
| /*! |
| Returns the name for this text record. |
| */ |
| |
| QString QDnsTextRecord::name() const |
| { |
| return d->name; |
| } |
| |
| /*! |
| Returns the duration in seconds for which this record is valid. |
| */ |
| |
| quint32 QDnsTextRecord::timeToLive() const |
| { |
| return d->timeToLive; |
| } |
| |
| /*! |
| Returns the values for this text record. |
| */ |
| |
| QList<QByteArray> QDnsTextRecord::values() const |
| { |
| return d->values; |
| } |
| |
| /*! |
| Assigns the data of the \a other object to this record object, |
| and returns a reference to it. |
| */ |
| |
| QDnsTextRecord &QDnsTextRecord::operator=(const QDnsTextRecord &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| /*! |
| \fn void QDnsTextRecord::swap(QDnsTextRecord &other) |
| |
| Swaps this text record instance with \a other. This function is |
| very fast and never fails. |
| */ |
| |
| void QDnsLookupPrivate::_q_lookupFinished(const QDnsLookupReply &_reply) |
| { |
| Q_Q(QDnsLookup); |
| if (runnable == q->sender()) { |
| #ifdef QDNSLOOKUP_DEBUG |
| qDebug("DNS reply for %s: %i (%s)", qPrintable(name), _reply.error, qPrintable(_reply.errorString)); |
| #endif |
| reply = _reply; |
| runnable = 0; |
| isFinished = true; |
| emit q->finished(); |
| } |
| } |
| |
| void QDnsLookupRunnable::run() |
| { |
| QDnsLookupReply reply; |
| |
| // Validate input. |
| if (requestName.isEmpty()) { |
| reply.error = QDnsLookup::InvalidRequestError; |
| reply.errorString = tr("Invalid domain name"); |
| emit finished(reply); |
| return; |
| } |
| |
| // Perform request. |
| query(requestType, requestName, nameserver, &reply); |
| |
| // Sort results. |
| qt_qdnsmailexchangerecord_sort(reply.mailExchangeRecords); |
| qt_qdnsservicerecord_sort(reply.serviceRecords); |
| |
| emit finished(reply); |
| } |
| |
| #if QT_CONFIG(thread) |
| QDnsLookupThreadPool::QDnsLookupThreadPool() |
| : signalsConnected(false) |
| { |
| // Run up to 5 lookups in parallel. |
| setMaxThreadCount(5); |
| } |
| |
| void QDnsLookupThreadPool::start(QRunnable *runnable) |
| { |
| // Ensure threads complete at application destruction. |
| if (!signalsConnected) { |
| QMutexLocker signalsLocker(&signalsMutex); |
| if (!signalsConnected) { |
| QCoreApplication *app = QCoreApplication::instance(); |
| if (!app) { |
| qWarning("QDnsLookup requires a QCoreApplication"); |
| delete runnable; |
| return; |
| } |
| |
| moveToThread(app->thread()); |
| connect(app, SIGNAL(destroyed()), |
| SLOT(_q_applicationDestroyed()), Qt::DirectConnection); |
| signalsConnected = true; |
| } |
| } |
| |
| QThreadPool::start(runnable); |
| } |
| |
| void QDnsLookupThreadPool::_q_applicationDestroyed() |
| { |
| waitForDone(); |
| signalsConnected = false; |
| } |
| #endif // QT_CONFIG(thread) |
| QT_END_NAMESPACE |
| |
| #include "moc_qdnslookup.cpp" |