]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Prevent dangling references in structured logging calls
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 5 Jan 2026 16:01:30 +0000 (17:01 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 19 Jan 2026 10:01:31 +0000 (11:01 +0100)
I had not realized before that the `Logging::Loggable` ctor takes
a `const` reference to the object we pass to it, meaning that we
cannot pass temporaries to it without creating dangling references.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-discovery.cc
pdns/dnsdistdist/dnsdist-healthchecks.cc
pdns/dnsdistdist/dnsdist-idstate.cc
pdns/dnsdistdist/dnsdist-lua-ffi.cc
pdns/dnsdistdist/dnsdist-nghttp2-in.cc
pdns/dnsdistdist/dnsdist-secpoll.cc
pdns/dnsdistdist/dnsdist.cc
pdns/dnsdistdist/docs/advanced/structured-logging-dictionary.rst

index 9c48af7aa5f84e86949a58414a1e6b0cd4b0806c..a0aa1bd75cfa4b14b318ebed7ad474a415be9240 100644 (file)
@@ -460,7 +460,7 @@ void DownstreamState::handleUDPTimeout(IDState& ids)
   SLOG(infolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s",
                d_config.remote.toStringWithPort(), getName(),
                ids.internal.qname.toLogString(), QType(ids.internal.qtype).toString(), ids.internal.origRemote.toStringWithPort()),
-       getLogger()->info(Logr::Info, "Had a downstream timeout", "dns.question.name", Logging::Loggable(ids.internal.qname), "dns.question.type", Logging::Loggable(QType(ids.internal.qtype)), "dns.question.id", Logging::Loggable(ntohs(ids.internal.origID)), "client.address", Logging::Loggable(ids.internal.origRemote)));
+       getLogger()->info(Logr::Info, "Had a downstream timeout", "dns.question.name", Logging::Loggable(ids.internal.qname), "dns.question.type", Logging::Loggable(ids.internal.qtype), "dns.question.class", Logging::Loggable(ids.internal.qclass), "dns.question.id", Logging::Loggable(ntohs(ids.internal.origID)), "client.address", Logging::Loggable(ids.internal.origRemote)));
 
   const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
   const auto& timeoutRespRules = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::TimeoutResponseRules);
@@ -780,7 +780,7 @@ void DownstreamState::updateNextLazyHealthCheck(LazyHealthCheckStats& stats, boo
       stats.d_nextCheck = now + d_config.d_lazyHealthCheckFailedInterval;
       if (!checkScheduled) {
         VERBOSESLOG(infolog("Backend %s is in failed state but had %d consecutive successful checks, next check in %d seconds", getNameWithAddr(), std::to_string(consecutiveSuccessfulChecks), d_config.d_lazyHealthCheckFailedInterval),
-                    getLogger()->info(Logr::Info, "Backend is in failed state but had a successful check", "backend.health_check.consecutive_successful_checks", Logging::Loggable(std::to_string(consecutiveSuccessfulChecks)), "backend.health_check.next_check", Logging::Loggable(d_config.d_lazyHealthCheckFailedInterval)));
+                    getLogger()->info(Logr::Info, "Backend is in failed state but had a successful check", "backend.health_check.consecutive_successful_checks", Logging::Loggable(consecutiveSuccessfulChecks), "backend.health_check.next_check", Logging::Loggable(d_config.d_lazyHealthCheckFailedInterval)));
       }
     }
     else {
@@ -868,7 +868,7 @@ void DownstreamState::submitHealthCheckResult(bool initial, bool newResult)
       if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
         auto stats = d_lazyHealthCheckStats.lock();
         VERBOSESLOG(infolog("Backend %s had %d successful checks, moving to Healthy", getNameWithAddr(), std::to_string(consecutiveSuccessfulChecks)),
-                    getLogger()->info(Logr::Info, "Backend had a successful check, moving to Healthy", "backend.health_check.consecutive_successful_checks", Logging::Loggable(std::to_string(consecutiveSuccessfulChecks))));
+                    getLogger()->info(Logr::Info, "Backend had a successful check, moving to Healthy", "backend.health_check.consecutive_successful_checks", Logging::Loggable(consecutiveSuccessfulChecks)));
         stats->d_status = LazyHealthCheckStats::LazyStatus::Healthy;
         stats->d_lastResults.clear();
       }
@@ -948,7 +948,7 @@ void DownstreamState::registerXsk(std::vector<std::shared_ptr<XskSocket>>& xsks)
 
     if (addresses.size() > 1) {
       SLOG(warnlog("More than one address configured on interface %s, picking the first one (%s) for XSK. Set the 'source' parameter on 'newServer' if you want to use a different address.", ifName, addresses.at(0).toString()),
-           getLogger()->info(Logr::Warning, "More than one address configured on this interface, picking the first one for XSK. Set the 'source' parameter on 'newServer' if you want to use a different address.", "source.interface", Logging::Loggable(ifName), "backend.address", Logging::Loggable(addresses.at(0).toString())));
+           getLogger()->info(Logr::Warning, "More than one address configured on this interface, picking the first one for XSK. Set the 'source' parameter on 'newServer' if you want to use a different address.", "source.interface", Logging::Loggable(ifName), "backend.address", Logging::Loggable(addresses.at(0))));
     }
     d_config.sourceAddr = addresses.at(0);
   }
index d07ac100396afb87063cddaef6a5be88c94e363e..da1904c100d22158c7a4b0eccaf28d78420e947f 100644 (file)
@@ -250,7 +250,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const Logr::Logger& topLogger, const
     pw.addOpt(4096, 0, 0);
     pw.commit();
 
-    auto logger = topLogger.withValues("dns.query.id", Logging::Loggable(id), "dns.query.name", Logging::Loggable(s_discoveryDomain), "dns.query.type", Logging::Loggable(QType(s_discoveryType)));
+    auto logger = topLogger.withValues("dns.query.id", Logging::Loggable(id), "dns.query.name", Logging::Loggable(s_discoveryDomain), "dns.query.type", Logging::Loggable(s_discoveryType));
 
     uint16_t querySize = static_cast<uint16_t>(packet.size());
     const uint8_t sizeBytes[] = {static_cast<uint8_t>(querySize / 256), static_cast<uint8_t>(querySize % 256)};
@@ -342,7 +342,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const Logr::Logger& topLogger, const
     if (receivedName != s_discoveryDomain || receivedType != s_discoveryType || receivedClass != QClass::IN) {
       if (verbose) {
         SLOG(warnlog("Invalid answer, either the qname (%s / %s), qtype (%s / %s) or qclass (%s / %s) does not match, received from the backend %s", receivedName, s_discoveryDomain, QType(receivedType).toString(), s_discoveryType.toString(), QClass(receivedClass).toString(), QClass::IN.toString(), addr.toStringWithPort()),
-             logger->info(Logr::Warning, "Response received from the backend doesn't match query", "dns.response.name", Logging::Loggable(receivedName), "dns.response.type", Logging::Loggable(QType(receivedType)), "dns.response.class", Logging::Loggable(receivedClass)));
+             logger->info(Logr::Warning, "Response received from the backend doesn't match query", "dns.response.name", Logging::Loggable(receivedName), "dns.response.type", Logging::Loggable(receivedType), "dns.response.class", Logging::Loggable(receivedClass)));
       }
       return false;
     }
index 82f6c6a62b02110ae810d06560f5b27de9ff0718..c42012b1b28d44b385733a94e6047c4fefd02231 100644 (file)
@@ -75,7 +75,7 @@ static void updateLatencyMetrics(DownstreamState& downstream, int elapsed /* mic
 static std::shared_ptr<Logr::Logger> getLoggerFromData(const std::shared_ptr<const HealthCheckData>& data)
 {
   const auto& downstream = data->d_ds;
-  return dnsdist::logging::getTopLogger()->withName("backend-health-check")->withValues("health_check.proto", Logging::Loggable(downstream->doHealthcheckOverTCP() ? (data->d_tcpHandler->isTLS() ? "DoT" : "tcp") : "udp"), "backend.name", Logging::Loggable(downstream->getName()), "backend.address", Logging::Loggable(downstream->d_config.remote), "dns.query.id", Logging::Loggable(data->d_queryID), "dns.query.name", Logging::Loggable(data->d_checkName), "dns.query.type", Logging::Loggable(QType(data->d_checkType)), "dns.query.class", Logging::Loggable(data->d_checkClass));
+  return dnsdist::logging::getTopLogger()->withName("backend-health-check")->withValues("health_check.proto", Logging::Loggable(downstream->doHealthcheckOverTCP() ? (data->d_tcpHandler->isTLS() ? "DoT" : "tcp") : "udp"), "backend.name", Logging::Loggable(downstream->getName()), "backend.address", Logging::Loggable(downstream->d_config.remote), "dns.query.id", Logging::Loggable(data->d_queryID), "dns.query.name", Logging::Loggable(data->d_checkName), "dns.query.type", Logging::Loggable(data->d_checkType), "dns.query.class", Logging::Loggable(data->d_checkClass));
 }
 
 static bool handleResponse(std::shared_ptr<HealthCheckData>& data)
@@ -143,7 +143,7 @@ static bool handleResponse(std::shared_ptr<HealthCheckData>& data)
       ++data->d_ds->d_healthCheckMetrics.d_mismatchErrors;
       if (verboseHealthChecks) {
         SLOG(infolog("Backend %s responded to health check with an invalid qname (%s vs %s), qtype (%s vs %s) or qclass (%d vs %d)", downstream->getNameWithAddr(), receivedName.toLogString(), data->d_checkName.toLogString(), QType(receivedType).toString(), QType(data->d_checkType).toString(), receivedClass, data->d_checkClass),
-             logger->info(Logr::Info, "Backend responded to health check with an invalid qname, qtype or qclass", "dns.response.name", Logging::Loggable(receivedName), "dns.response.qtype", Logging::Loggable(QType(receivedType)), "dns.response.class", Logging::Loggable(QClass(receivedClass))));
+             logger->info(Logr::Info, "Backend responded to health check with an invalid qname, qtype or qclass", "dns.response.name", Logging::Loggable(receivedName), "dns.response.qtype", Logging::Loggable(receivedType), "dns.response.class", Logging::Loggable(receivedClass)));
       }
       return false;
     }
index 4a0b011fc4d2af07fe0bbe75f2844056d9c0f0e5..9855dfe898f1b919506e2b811ea4954e0ffc166f 100644 (file)
@@ -169,6 +169,6 @@ std::shared_ptr<const Logr::Logger> InternalQueryState::getLogger(std::shared_pt
   if (!parent) {
     parent = dnsdist::logging::getTopLogger();
   }
-  auto logger = parent->withValues("dns.question.name", Logging::Loggable(this->qname), "dns.question.type", Logging::Loggable(QType(this->qtype)), "dns.question.class", Logging::Loggable(QClass(this->qclass)), "source.address", Logging::Loggable(this->origRemote), "destination.address", Logging::Loggable(this->origDest), "proto", Logging::Loggable(this->protocol), "dns.question.id", Logging::Loggable(ntohs(this->origID)), "dns.question.flags", Logging::Loggable(this->origFlags));
+  auto logger = parent->withValues("dns.question.name", Logging::Loggable(this->qname), "dns.question.type", Logging::Loggable(this->qtype), "dns.question.class", Logging::Loggable(this->qclass), "source.address", Logging::Loggable(this->origRemote), "destination.address", Logging::Loggable(this->origDest), "proto", Logging::Loggable(this->protocol), "dns.question.id", Logging::Loggable(ntohs(this->origID)), "dns.question.flags", Logging::Loggable(this->origFlags));
   return logger;
 }
index 14fd86fe5d7b5a0c129c696b109a28597e4a8220..86f8f8f1a572c250c0ce694f3773212f1767b260 100644 (file)
@@ -1759,7 +1759,7 @@ bool dnsdist_ffi_network_endpoint_new(const char* path, size_t pathSize, dnsdist
   }
   catch (const std::exception& e) {
     VERBOSESLOG(infolog("Error creating a new network endpoint: %s", e.what()),
-                getLogger(__func__)->error(Logr::Info, e.what(), "Error creating a new network endpoint", "path", Logging::Loggable(std::string_view(path, pathSize))));
+                getLogger(__func__)->error(Logr::Info, e.what(), "Error creating a new network endpoint", "path", Logging::Loggable(path)));
     return false;
   }
 }
@@ -2391,16 +2391,16 @@ void dnsdist_ffi_svc_record_parameters_add_ipv4_hint(dnsdist_ffi_svc_record_para
   }
   catch (const std::exception& exp) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv4_hint: %s", exp.what()),
-         getLogger(__func__)->error(Logr::Error, exp.what(), "Exception adding IPv4 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->error(Logr::Error, exp.what(), "Exception adding IPv4 hint to SVC record"));
 
   }
   catch (const PDNSException& exp) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv4_hint: %s", exp.reason),
-         getLogger(__func__)->error(Logr::Error, exp.reason, "Exception adding IPv4 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->error(Logr::Error, exp.reason, "Exception adding IPv4 hint to SVC record"));
   }
   catch (...) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv4_hint"),
-         getLogger(__func__)->info(Logr::Error, "Exception adding IPv4 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->info(Logr::Error, "Exception adding IPv4 hint to SVC record"));
   }
 }
 
@@ -2414,15 +2414,15 @@ void dnsdist_ffi_svc_record_parameters_add_ipv6_hint(dnsdist_ffi_svc_record_para
   }
   catch (const std::exception& exp) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv6_hint: %s", exp.what()),
-         getLogger(__func__)->error(Logr::Error, exp.what(), "Exception adding IPv6 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->error(Logr::Error, exp.what(), "Exception adding IPv6 hint to SVC record"));
   }
   catch (const PDNSException& exp) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv6_hint: %s", exp.reason),
-         getLogger(__func__)->error(Logr::Error, exp.reason, "Exception adding IPv6 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->error(Logr::Error, exp.reason, "Exception adding IPv6 hint to SVC record"));
   }
   catch (...) {
     SLOG(errlog("Exception in dnsdist_ffi_svc_record_parameters_add_ipv6_hint"),
-         getLogger(__func__)->info(Logr::Error, "Exception adding IPv6 hint to SVC record", "value", Logging::Loggable(std::string_view(value, valueLen))));
+         getLogger(__func__)->info(Logr::Error, "Exception adding IPv6 hint to SVC record"));
   }
 }
 
index 6801eed883b7bbf4578037794a19508c4a67a66e..6802b3083b05e0157d774214ed43fc9de3eb3886 100644 (file)
@@ -1083,22 +1083,17 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const
   (void)flags;
   auto* conn = static_cast<IncomingHTTP2Connection*>(user_data);
 
-  auto toLoggable = [](const uint8_t* str, size_t strSize) {
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API
-    return Logging::Loggable(std::string_view(reinterpret_cast<const char*>(str), strSize));
-  };
-
   if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
     if (nghttp2_check_header_name(name, nameLen) == 0) {
       VERBOSESLOG(infolog("Invalid header name"),
-                  conn->getLogger()->info(Logr::Info, "Invalid header name on DoH connection", "http.request.header", toLoggable(name, nameLen)));
+                  conn->getLogger()->info(Logr::Info, "Invalid header name on DoH connection"));
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     }
 
 #if defined(HAVE_NGHTTP2_CHECK_HEADER_VALUE_RFC9113)
     if (nghttp2_check_header_value_rfc9113(value, valuelen) == 0) {
       VERBOSESLOG(infolog("Invalid header value"),
-                  conn->getLogger()->info(Logr::Info, "Invalid header value on DoH connection", "http.request.header", toLoggable(name, nameLen)));
+                  conn->getLogger()->info(Logr::Info, "Invalid header value on DoH connection"));
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     }
 #endif /* HAVE_NGHTTP2_CHECK_HEADER_VALUE_RFC9113 */
@@ -1120,7 +1115,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const
 #if defined(HAVE_NGHTTP2_CHECK_PATH)
       if (nghttp2_check_path(value, valuelen) == 0) {
         VERBOSESLOG(infolog("Invalid path value"),
-                    conn->getLogger()->info(Logr::Info, "Invalid path value on DoH connection", "http.path", toLoggable(value, valuelen)));
+                    conn->getLogger()->info(Logr::Info, "Invalid path value on DoH connection", "http.path", Logging::Loggable(valueView)));
         return NGHTTP2_ERR_CALLBACK_FAILURE;
       }
 #endif /* HAVE_NGHTTP2_CHECK_PATH */
@@ -1141,7 +1136,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const
 #if defined(HAVE_NGHTTP2_CHECK_METHOD)
       if (nghttp2_check_method(value, valuelen) == 0) {
         VERBOSESLOG(infolog("Invalid method value"),
-                    conn->getLogger()->info(Logr::Info, "Invalid method value on DoH connection", "http.method", toLoggable(value, valuelen)));
+                    conn->getLogger()->info(Logr::Info, "Invalid method value on DoH connection"));
         return NGHTTP2_ERR_CALLBACK_FAILURE;
       }
 #endif /* HAVE_NGHTTP2_CHECK_METHOD */
@@ -1155,7 +1150,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const
       else {
         query.d_method = PendingQuery::Method::Unsupported;
         VERBOSESLOG(infolog("Unsupported method value"),
-                    conn->getLogger()->info(Logr::Info, "Unsupported method on DoH connection", "http.method", toLoggable(value, valuelen)));
+                    conn->getLogger()->info(Logr::Info, "Unsupported method on DoH connection"));
         return 0;
       }
     }
index 92c5bec3aac79ca9e42831ba4591f37875807242..c618cd308a7727368b2a68d1825f205f916d1c42 100644 (file)
@@ -167,7 +167,7 @@ static std::string getSecPollStatus(const Logr::Logger& logger, const std::strin
 
     if (receivedName != sentName || receivedType != QType::TXT || receivedClass != QClass::IN) {
       VERBOSESLOG(warnlog("Invalid answer, either the qname (%s / %s), qtype (%s / %s) or qclass (%s / %s) does not match, received from the secpoll stub resolver %s", receivedName, sentName, QType(receivedType).toString(), QType(QType::TXT).toString(), QClass(receivedClass).toString(), QClass::IN.toString(), dest.toString()),
-                  resolverLogger->info(Logr::Warning, "Invalid status polling response received from the stub resolver, either the name, type or qclass does not match", "dns.response.size", Logging::Loggable(reply.size()), "dns.response.id", Logging::Loggable(dnsHeader.id), "dns.response.name", Logging::Loggable(receivedName), "dns.response.type", Logging::Loggable(QType(receivedType)), "dns.response.class", Logging::Loggable(QClass(receivedClass))));
+                  resolverLogger->info(Logr::Warning, "Invalid status polling response received from the stub resolver, either the name, type or qclass does not match", "dns.response.size", Logging::Loggable(reply.size()), "dns.response.id", Logging::Loggable(dnsHeader.id), "dns.response.name", Logging::Loggable(receivedName), "dns.response.type", Logging::Loggable(receivedType), "dns.response.class", Logging::Loggable(receivedClass)));
       continue;
     }
 
index 8cdbf55063e1fdde4dde2d38d07bb97b32159553..dbf2b6b5729c7b6295c2c078c7b43e62384a415f 100644 (file)
@@ -2712,7 +2712,7 @@ static void checkFileDescriptorsLimits(size_t udpBindsCount, size_t tcpBindsCoun
   getrlimit(RLIMIT_NOFILE, &resourceLimits);
   if (resourceLimits.rlim_cur <= requiredFDsCount) {
     SLOG(warnlog("Warning, this configuration can use more than %d file descriptors, web server and console connections not included, and the current limit is %d.", std::to_string(requiredFDsCount), std::to_string(resourceLimits.rlim_cur)),
-         dnsdist::logging::getTopLogger()->info(Logr::Warning, "Warning, this configuration can use more file descriptors, web server and console connections not included, than the currently configured limit", "system.required_file_descriptors", Logging::Loggable(requiredFDsCount), "system.file_descriptors_limit", Logging::Loggable(std::to_string(resourceLimits.rlim_cur))));
+         dnsdist::logging::getTopLogger()->info(Logr::Warning, "Warning, this configuration can use more file descriptors, web server and console connections not included, than the currently configured limit", "system.required_file_descriptors", Logging::Loggable(requiredFDsCount), "system.file_descriptors_limit", Logging::Loggable(resourceLimits.rlim_cur)));
 #ifdef HAVE_SYSTEMD
     SLOG(warnlog("You can increase this value by using LimitNOFILE= in the systemd unit file or ulimit."),
          dnsdist::logging::getTopLogger()->info(Logr::Warning, "You can increase this value by using LimitNOFILE= in the systemd unit file over ulimit"));
index 7283682d395fddb802f98d4a3697ebda4cdf148f..ab533faed2510a58d51145b7b5687b579feba3e9 100644 (file)
@@ -75,7 +75,7 @@ Common keys are:
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``destination.address``         |``ip address:port``  |``"192.0.2.42:53"``                   |Destination address of a packet (may be more specific than ``frontend.address``, or be the next hop and differ from ``client.address`` when the proxy protocol is being used, for example).|
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|``dns.question.class``          |``DNS class``        |``"IN"``                              |The DNS query class.                                                                                                                                                                       |
+|``dns.question.class``          |``unsigned integer`` |``1``                                 |The DNS query class.                                                                                                                                                                       |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``dns.question.id``             |``unsigned integer`` |``42``                                |The DNS query ID.                                                                                                                                                                          |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -87,9 +87,9 @@ Common keys are:
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``dns.question.size``           |``unsigned integer`` |``42``                                |Size of the DNS query packet, in bytes.                                                                                                                                                    |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|``dns.question.type``           |``DNS type``         |``"AAAA"``                            |The DNS query type.                                                                                                                                                                        |
+|``dns.question.type``           |``unsigned integer`` |``28``                                |The DNS query type.                                                                                                                                                                        |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|``dns.response.class``          |``DNS class``        |``"IN"``                              |The DNS response class.                                                                                                                                                                    |
+|``dns.response.class``          |``unsigned integer`` |``1``                                 |The DNS response class.                                                                                                                                                                    |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``dns.response.id``             |``unsigned integer`` |``42``                                |The DNS response ID.                                                                                                                                                                       |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -101,7 +101,7 @@ Common keys are:
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``dns.response.size``           |``unsigned integer`` |``42``                                |Size of the DNS response packet, in bytes.                                                                                                                                                 |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-|``dns.response.type``           |``DNS type``         |``"AAAA"``                            |The DNS response type.                                                                                                                                                                     |
+|``dns.response.type``           |``unsigned integer`` |``28``                                |The DNS response type.                                                                                                                                                                     |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |``frontend.address``            |``ip address:port``  |``"[::]:53"``                         |Address this frontend is listening on.                                                                                                                                                     |
 +--------------------------------+---------------------+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+