Nameserver01

Status: Final

Purpose

  • Detect whether authoritative nameservers also behave as recursors.

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Nameserver addresses from ZoneNameservers .
    • Three hardcoded probe names:
      • xn--nameservertest.iis.se
      • xn--nameservertest.icann.org
      • xn--nameservertest.ripe.net
    • A query responses from each nameserver.
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: parallel nameserver query fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Read nameserver list from ZoneNameservers .
  3. For each nameserver (parallelized, input-order merged logs):
    • If transport is disabled, emit IPV4_DISABLED or IPV6_DISABLED for rrtype A, then skip this nameserver.
    • Initialize counters: responseCount, nxdomainCount, hasRAWithAnswer, allNxdomainAA=true, and isNoRecursor=true.
    • For each probe name:
      • Query A.
      • If no DNS message is returned, emit NO_RESPONSE (ns, domain), set isNoRecursor=false, and continue.
      • Increment responseCount.
      • If the response has RA=1 and at least one record in the ANSWER section, set hasRAWithAnswer=true. The RA bit alone is advisory: many authoritative-only nameservers leak RA=1 while returning a referral (no ANSWER records), which is not recursion.
      • If response RCODE is NXDOMAIN, increment nxdomainCount. If the response does not have AA=1, set allNxdomainAA=false.
    • If hasRAWithAnswer=true, record server as recursor and set isNoRecursor=false.
    • Else if responseCount>0 and nxdomainCount==responseCount and allNxdomainAA==false, record server as recursor and set isNoRecursor=false.
    • If isNoRecursor is still true, record server as non-recursor.
  4. After all parallel tasks, emit a single consolidated IS_A_RECURSOR with servers list (if any), and a single consolidated NO_RECURSOR with servers list (if any).
  5. Emit TEST_CASE_END.

Per-NS Recursor Probe and Classification (steps 2-5)

ns list = ZoneNameservers  (no testcase-local dedupe)

probes = [
   xn--nameservertest.iis.se,
   xn--nameservertest.icann.org,
   xn--nameservertest.ripe.net,
]

For each nameserver (parallel; fan-out = resolver.defaults.parallel):

   transport disabled for A  -> IPV4_DISABLED / IPV6_DISABLED, skip
   init responseCount=0, nxdomainCount=0, hasRAWithAnswer=false,
        allNxdomainAA=true, isNoRecursor=true

   for each probe in probes:
      query A at probe
      +- resp.Msg == nil          -> NO_RESPONSE (ns, domain=probe)
      |                              isNoRecursor=false; continue
      +- otherwise:
            responseCount += 1
            resp.RA AND len(ANSWER) > 0 -> hasRAWithAnswer=true
            RCODE == NXDOMAIN -> nxdomainCount += 1
                                 !AA -> allNxdomainAA=false

   hasRAWithAnswer == true
      -> recursorSet[ns]; isNoRecursor=false
   else if responseCount > 0
              AND nxdomainCount == responseCount
              AND allNxdomainAA == false
      -> recursorSet[ns]; isNoRecursor=false
   isNoRecursor still true
      -> nonRecursorSet[ns]

After all tasks:
  recursorSet    non-empty -> IS_A_RECURSOR (servers; sorted)
  nonRecursorSet non-empty -> NO_RECURSOR   (servers; sorted)

emit TEST_CASE_END

Emitted Tags (Possible Set)

TagEmitted when
IPV4_DISABLEDIPv4 nameserver evaluation is skipped because IPv4 is disabled.
IPV6_DISABLEDIPv6 nameserver evaluation is skipped because IPv6 is disabled.
IS_A_RECURSORNameserver returned RA=1 together with at least one record in the ANSWER section on any probe response, or all received probe responses were NXDOMAIN without all having AA=1.
NO_RECURSORNameserver produced responses but did not match recursor criteria and had no NO_RESPONSE for probes.
NO_RESPONSEA probe query returned no DNS message.
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDrrtypestringrrtype skipped (A).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDrrtypestringrrtype skipped (A).
IS_A_RECURSORserversarray<object>Structured sorted list of nameservers classified as recursors ({ns}, {address} items).
NO_RECURSORserversarray<object>Structured sorted list of nameservers classified as non-recursors ({ns}, {address} items).
NO_RESPONSEnsstringNameserver identity (ns name only; use address for IP) with missing response.
NO_RESPONSEaddressstringNameserver IP address for the same endpoint.
NO_RESPONSEdomainstringProbe name queried.
TEST_CASE_ENDtestcasestringTestcase display name (Nameserver01).
TEST_CASE_STARTtestcasestringTestcase display name (Nameserver01).

Severity Levels Per Tag

TagLevelNotes
IPV4_DISABLEDDEBUGDefault from share/profile.json (test_levels.NAMESERVER).
IPV6_DISABLEDDEBUGDefault from share/profile.json (test_levels.NAMESERVER).
IS_A_RECURSORERRORDefault from share/profile.json (test_levels.NAMESERVER).
NO_RECURSORINFODefault from share/profile.json (test_levels.NAMESERVER).
NO_RESPONSEDEBUGDefault from share/profile.json (test_levels.NAMESERVER).
TEST_CASE_ENDDEBUGDefault from share/profile.json (test_levels.NAMESERVER).
TEST_CASE_STARTDEBUGDefault from share/profile.json (test_levels.NAMESERVER).

Differences From Upstream

  • Differences (Upstream vs Gonemaster):
    • Upstream: describes evaluation over the retrieved nameserver IP set. Gonemaster: iterates the raw ZoneNameservers list without testcase-local deduplication, so duplicate name/ip entries can be evaluated more than once.
    • Upstream: does not explicitly describe testcase boundary and transport-disabled debug emissions. Gonemaster: emits TEST_CASE_START, TEST_CASE_END, IPV4_DISABLED, and IPV6_DISABLED.
    • Upstream: classifies a server as a recursor when all probe responses are NXDOMAIN, regardless of the AA flag. Gonemaster: excludes servers from recursor classification when all NXDOMAIN responses also have AA=1, since this indicates the server claims authoritative knowledge (e.g. a fake root zone) rather than performing recursion. Reported upstream.
  • Potential upstream report:
    • no

Edge Cases And Limitations

  • A nameserver can emit both NO_RESPONSE (for one or more probes) and IS_A_RECURSOR (from other probe responses) in the same testcase run.
  • Up to three NO_RESPONSE entries can be emitted per nameserver (one per probe name).
  • If transport is disabled for a nameserver, no recursor classification tags are emitted for that nameserver.
  • A nameserver that claims to be authoritative for the root zone (responds with AA=1 and NXDOMAIN to all probes) is not classified as a recursor, since the NXDOMAIN responses come from fake authoritative data rather than recursive resolution.
  • A nameserver that returns a referral (no records in the ANSWER section, e.g. NOERROR with root NS records in the AUTHORITY section) and sets RA=1 on the response is not classified as a recursor. Some authoritative-only daemons leak the RA bit; without ANSWER records there is no recursion evidence.