SyncRes::s_event_trace_enabled = ::arg().asNum("event-trace-enabled");
SyncRes::s_save_parent_ns_set = ::arg().mustDo("save-parent-ns-set");
SyncRes::s_max_busy_dot_probes = ::arg().asNum("max-busy-dot-probes");
+ SyncRes::s_max_CNAMES_followed = ::arg().asNum("max-cnames-followed");
{
uint64_t sse = ::arg().asNum("serve-stale-extensions");
if (sse > std::numeric_limits<uint16_t>::max()) {
''',
'versionchanged': ('5.1.0', 'The default used to be 60, with an extra allowance if qname minimization was enabled. Having better algorithms allows for a lower default limit.'),
},
+ {
+ 'name' : 'max_cnames_followed',
+ 'section' : 'recursor',
+ 'type' : LType.Uint64,
+ 'default' : '10',
+ 'help' : 'Maximum number CNAME records followed',
+ 'doc' : '''
+Maximum length of a CNAME chain. If a CNAME chain exceeds this length, a ``ServFail`` answer will be returned.
+Previously, this limit was fixed at 10.
+ ''',
+ 'versionadded': '5.1.0'
+ },
{
'name' : 'max_ns_address_qperq',
'section' : 'outgoing',
int SyncRes::s_event_trace_enabled;
bool SyncRes::s_save_parent_ns_set;
unsigned int SyncRes::s_max_busy_dot_probes;
-unsigned int SyncRes::s_max_CNAMES_followed = 10;
+unsigned int SyncRes::s_max_CNAMES_followed;
bool SyncRes::s_addExtendedResolutionDNSErrors;
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
SyncRes::s_locked_ttlperc = 0;
SyncRes::s_minimize_one_label = 4;
SyncRes::s_max_minimize_count = 10;
+ SyncRes::s_max_CNAMES_followed = 10;
SyncRes::clearNSSpeeds();
BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U);
BOOST_CHECK_EQUAL(res, RCode::ServFail);
BOOST_CHECK_EQUAL(ret.size(), length);
BOOST_CHECK_EQUAL(length, SyncRes::s_max_CNAMES_followed + 1);
+
+ // Currently a CNAME bounds check originating from the record cache causes an ImmediateServFail
+ // exception. This is different from the non-cached case, tested above. There a ServFail is
+ // returned with a partial CNAME chain. This should be fixed one way or another. For details, see
+ // how the result of syncres.cc:scanForCNAMELoop() is handled in the two cases.
+ ret.clear();
+ length = 0;
+ BOOST_CHECK_EXCEPTION(sr->beginResolve(target, QType(QType::A), QClass::IN, ret),
+ ImmediateServFailException,
+ [&](const ImmediateServFailException& isfe) {
+ return isfe.reason == "max number of CNAMEs exceeded";
+ });
}
BOOST_AUTO_TEST_CASE(test_cname_target_servfail)