QDnsLookup/Windows: add a simple decoded domain cache

Avoid decoding multiple times the domain name when it comes in
sequence. This happens when a given domain label either has multiple
entries in its record set or when it's a CNAME (or both), such as in:

;; ANSWER SECTION:
cname-cname.test.qt-project.org. 3600 IN CNAME  cname.test.qt-project.org.
cname.test.qt-project.org. 1614 IN      CNAME   multi.test.qt-project.org.
multi.test.qt-project.org. 1614 IN      A       198.51.100.2
multi.test.qt-project.org. 1614 IN      A       198.51.100.3
multi.test.qt-project.org. 1614 IN      A       198.51.100.1

Label targets from other records such as MX and SRV usually do show up
again, in the Additional section, but the chance that they are
sequential isn't very good, so we don't cache those.

;; ANSWER SECTION:
mx-multi.test.qt-project.org. 3354 IN   MX      10 multi.test.qt-project.org.
mx-multi.test.qt-project.org. 3354 IN   MX      20 a-single.test.qt-project.org.

;; ADDITIONAL SECTION:
multi.test.qt-project.org. 1145 IN      A       198.51.100.3
multi.test.qt-project.org. 1145 IN      A       198.51.100.1
multi.test.qt-project.org. 1145 IN      A       198.51.100.2
a-single.test.qt-project.org. 3364 IN   A       192.0.2.1

Change-Id: I5f7f427ded124479baa6fffd175f5cf88939ee73
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Thiago Macieira 2023-05-15 09:09:18 -07:00
parent 8b6bd8ed99
commit 59a2a32276

View File

@ -95,9 +95,21 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
else if (status != ERROR_SUCCESS)
return reply->makeResolverSystemError(status);
QStringView lastEncodedName;
QString cachedDecodedName;
auto extractAndCacheHost = [&](QStringView name) -> const QString & {
lastEncodedName = name;
cachedDecodedName = decodeLabel(name);
return cachedDecodedName;
};
auto extractMaybeCachedHost = [&](QStringView name) -> const QString & {
return lastEncodedName == name ? cachedDecodedName : extractAndCacheHost(name);
};
// Extract results.
for (PDNS_RECORD ptr = results.pQueryRecords; ptr != NULL; ptr = ptr->pNext) {
const QString name = decodeLabel(ptr->pName);
// warning: always assign name to the record before calling extractXxxHost() again
const QString &name = extractMaybeCachedHost(ptr->pName);
if (ptr->wType == QDnsLookup::A) {
QDnsHostAddressRecord record;
record.d->name = name;
@ -117,7 +129,7 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
QDnsDomainNameRecord record;
record.d->name = name;
record.d->timeToLive = ptr->dwTtl;
record.d->value = decodeLabel(ptr->Data.Cname.pNameHost);
record.d->value = extractAndCacheHost(ptr->Data.Cname.pNameHost);
reply->canonicalNameRecords.append(record);
} else if (ptr->wType == QDnsLookup::MX) {
QDnsMailExchangeRecord record;