static struct taskstats s_almost_expired_tasks;
static struct taskstats s_resolve_tasks;
-static void resolve(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept
+// forceNoQM is true means resolve using no qm, false means use default value
+static void resolveInternal(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task, bool forceNoQM) noexcept
{
auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "netmask", Logging::Loggable(task.d_netmask.empty() ? "" : task.d_netmask.toString()));
const string msg = "Exception while running a background ResolveTask";
vector<DNSRecord> ret;
resolver.setRefreshAlmostExpired(task.d_refreshMode);
resolver.setQuerySource(task.d_netmask);
+ if (forceNoQM) {
+ resolver.setQNameMinimization(false);
+ }
bool exceptionOccurred = true;
try {
log->info(Logr::Debug, "resolving", "refresh", Logging::Loggable(task.d_refreshMode));
}
}
+static void resolveForceNoQM(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept
+{
+ resolveInternal(now, logErrors, task, true);
+}
+
+static void resolve(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept
+{
+ resolveInternal(now, logErrors, task, false);
+}
+
static void tryDoT(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept
{
auto log = g_slog->withName("taskq")->withValues("method", Logging::Loggable("tryDoT"), "name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "ip", Logging::Loggable(task.d_ip));
}
}
-void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline)
+void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline, bool forceQMOff)
{
if (SyncRes::isUnsupported(qtype)) {
auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype).toString()));
log->error(Logr::Error, "Cannot push task", "qtype unsupported");
return;
}
- pdns::ResolveTask task{qname, qtype, deadline, false, resolve, {}, {}, {}};
+ auto func = forceQMOff ? resolveForceNoQM : resolve;
+ pdns::ResolveTask task{qname, qtype, deadline, false, func, {}, {}, {}};
auto lock = s_taskQueue.lock();
bool inserted = lock->rateLimitSet.insert(now, task);
if (inserted) {
void runTasks(size_t max, bool logErrors);
bool runTaskOnce(bool logErrors);
void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline, const Netmask& netmask);
-void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline);
+void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline, bool forceQMOff);
bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ipAddress, time_t deadline, const DNSName& nsname);
void taskQueueClear();
pdns::ResolveTask taskQueuePop();
// There are a few cases where an answer is neither stored in the record cache nor in the neg cache.
// An example is a SOA-less NODATA response. Rate limiting will kick in if those tasks are pushed too often.
// We might want to fix these cases (and always either store positive or negative) some day.
- pushResolveTask(qname, qtype, d_now.tv_sec, d_now.tv_sec + 60);
+ pushResolveTask(qname, qtype, d_now.tv_sec, d_now.tv_sec + 60, false);
additionalsNotInCache = true;
}
break;
NegCache::NegCacheEntry ne;
bool inNegCache = g_negCache->get(qname, QType::AAAA, d_now, ne, false);
if (!inNegCache) {
- pushResolveTask(qname, QType::AAAA, d_now.tv_sec, d_now.tv_sec + 60);
+ pushResolveTask(qname, QType::AAAA, d_now.tv_sec, d_now.tv_sec + 60, true);
}
}
}
BOOST_AUTO_TEST_CASE(test_resolve_queue_rate_limit)
{
taskQueueClear();
- pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1);
+ pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1, false);
BOOST_CHECK_EQUAL(getTaskSize(), 1U);
taskQueuePop();
BOOST_CHECK_EQUAL(getTaskSize(), 0U);
// Should hit rate limiting
- pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1);
+ pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1, false);
BOOST_CHECK_EQUAL(getTaskSize(), 0U);
// Should not hit rate limiting as time has passed
- pushResolveTask(DNSName("foo"), QType::AAAA, 61, 62);
+ pushResolveTask(DNSName("foo"), QType::AAAA, 61, 62, false);
BOOST_CHECK_EQUAL(getTaskSize(), 1U);
}