Consistency05
Status: Final
Purpose
- Compare the delegation NS name set served by each responding parent nameserver.
- Compare delegation glue addresses against child authoritative address data for in-domain nameservers.
- Compare not-in-domain glue addresses against recursive public lookup results.
Preconditions And Inputs
- Preconditions:
- A
zone.Zoneobject is available.
- A
- Required inputs:
- Parent-side NS responses via
queryParentAll; NS records and glue A and AAAA records are read only from responses that qualify as usable referrals (step 3). - Child-side nameserver names via
AllNSNames. - Child-side nameserver servers via
AllNameservers. - Recursive lookup results via
recursefor not-in-domain checks and referral fallbacks.
- Parent-side NS responses via
- Profile/config knobs that affect behavior:
net.ipv4andnet.ipv6: filter which child nameserver addresses are queried.
Algorithm And Decision Flow
Emit
TEST_CASE_START.Query parent for child-zone NS records.
Classify each parent response. A response is a usable referral when all of the following hold:
- TC is clear,
- RCODE is NOERROR,
- the answer section is empty,
- the authority section holds NS records owned by the child zone.
A response failing any condition contributes neither NS names nor glue. AA is not consulted, since parents that set AA on referrals are still serving a referral.
Collect unique child NS names from the authority section of the usable referrals.
Read glue items
owner/ipfrom the additional section of each usable referral, keeping only owners present in the authority NS set of that same response. Glue is never taken from separate address queries to the parent, so a parent that answers out-of-domain names directly cannot contribute bogus glue.Group usable referrals by the delegation NS name set they carry:
- The per-parent key is the sorted set of lowercased NS names from that response’s authority section. Glue addresses and TTLs are not part of the key.
- A parent server that does not respond, or whose response is not a usable referral, contributes no set and is excluded from the comparison.
- With more than one distinct set, emit
MULTIPLE_DELEGATION_NS_SETwith the distinct-set count andns_names, the NS names not served by every parent (the union of all sets minus their intersection), and oneDELEGATION_NS_SETper distinct set naming the set elements and the parent servers that served it. - With zero or one distinct set, emit nothing. More than one distinct set implies a non-empty
ns_names, since sets that differ must differ by at least one name.
Split parent glue into:
- in-domain strict glue (
strictGlue), - not-in-domain extended glue (
extendedGluegrouped by NS name).
- in-domain strict glue (
Build in-domain NS name set from
AllNSNames, and in-domain child NS servers fromAllNameservers(respecting enabled IP versions).If
AllNameserversyields no usable in-domain child NS servers:- Materialize child NS server endpoints from in-domain strict glue, respecting enabled IP versions.
- Query those endpoints for the child-zone NS set and merge any in-domain names into the in-domain NS name set.
For each in-domain NS name:
- Query every in-domain child NS server for A and AAAA with RD off (
getAddrRRs). getAddrRRsemitsNO_RESPONSEon no response andCHILD_NS_FAILEDon unusable non-referral/non-NXDOMAIN authoritative behavior.- Referral responses trigger recursive fallback lookup and use resulting answer data if available.
- Otherwise accumulate child authoritative
owner/ippairs.
- If no in-domain address lookup path was usable for any in-domain NS name, emit
CHILD_ZONE_LAME, emitTEST_CASE_END, and return. - Compare in-domain glue against child address data, per NS name. Only names carrying at least one glue address take part; a name with no glue anywhere in the union is not compared, and is reported as missing glue by Delegation01 instead. For each such name, in sorted order:
- Child serves no address record for the name -> emit
MISSING_ADDRESS_CHILDwithns, and compare nothing further for that name. - Otherwise, glue addresses the child does not serve -> emit
IN_BAILIWICK_ADDR_MISMATCHwithns,parent_serversholding only those unconfirmed glue addresses, andzone_serversholding the child addresses for that name. - Independently, child addresses absent from that name’s glue accumulate into the aggregate
EXTRA_ADDRESS_CHILD. A name may therefore produce both an in-domain mismatch and a contribution to the extra-address list.
- For each not-in-domain NS name in extended glue:
- Recurse A and AAAA, build child/public
owner/ipset. - If any parent glue item for that name is missing from child/public set, emit
OUT_OF_BAILIWICK_ADDR_MISMATCH.
- If no address fault was found, emit
ADDRESSES_MATCH. A delegation carrying no glue at all reaches this point with nothing to disagree about and is reported as matching. The delegation NS-set tags from step 6 do not affect this guard. - Emit
TEST_CASE_END.
Parent Glue and Child Address Lookup (steps 2-10)
Domain-Relation Comparison and Final Emission (steps 11-15)
Emitted Tags (Possible Set)
| Tag | Emitted when |
|---|---|
ADDRESSES_MATCH | No address fault was found. A glueless delegation has nothing to disagree about and reaches this tag. |
CHILD_NS_FAILED | Child nameserver response for in-domain address lookup was unusable (non-AA/no referral/no accepted RCODE path). |
CHILD_ZONE_LAME | Every in-domain address lookup path failed for all in-domain NS names. |
DELEGATION_NS_SET | One distinct delegation NS name set (with the parent servers serving it), emitted per set when parents disagree. |
EXTRA_ADDRESS_CHILD | For names that have glue, the child serves addresses not present in that name’s glue. |
IN_BAILIWICK_ADDR_MISMATCH | An in-domain name’s glue contains addresses the child does not serve, while the child serves at least one address for it. Emitted once per affected name. |
MISSING_ADDRESS_CHILD | An in-domain name has glue in the delegation but the child zone serves no address record for it. Emitted once per affected name. |
MULTIPLE_DELEGATION_NS_SET | Responding parent nameservers serve more than one distinct delegation NS name set. |
NO_RESPONSE | A child nameserver did not return a response for an in-domain A/AAAA lookup. |
OUT_OF_BAILIWICK_ADDR_MISMATCH | Not-in-domain glue contains addresses not found in recursive public A/AAAA results. |
TEST_CASE_END | Testcase completion marker is emitted. |
TEST_CASE_START | Testcase start marker is emitted. |
Tag Arguments
| Tag | Argument key | Type | Meaning |
|---|---|---|---|
ADDRESSES_MATCH | - | - | No arguments. |
CHILD_NS_FAILED | ns | string | Child nameserver identity (ns name only; use address for IP) that failed authoritative child lookup requirements. |
CHILD_NS_FAILED | address | string | Nameserver IP address for the same endpoint. |
CHILD_ZONE_LAME | - | - | No arguments. |
DELEGATION_NS_SET | ns_set_servers | array<object> | Structured delegation NS-set elements, one { "ns": "..." } per NS name in the set. |
DELEGATION_NS_SET | servers | array<object> | Structured parent server endpoints that served this set. |
EXTRA_ADDRESS_CHILD | addresses | array<string> | Structured owner/ip entries found only in child authoritative data. |
IN_BAILIWICK_ADDR_MISMATCH | ns | string | The in-domain nameserver name this mismatch belongs to. |
IN_BAILIWICK_ADDR_MISMATCH | parent_servers | array<object> | Structured list of this name’s glue addresses that the child does not serve; each item is { "ns": "...", "address": "..." }. |
IN_BAILIWICK_ADDR_MISMATCH | zone_servers | array<object> | Structured list of the child authoritative addresses for the same name; each item is { "ns": "...", "address": "..." }. |
MISSING_ADDRESS_CHILD | ns | string | The in-domain nameserver name that has glue but no address record in the child zone. |
MULTIPLE_DELEGATION_NS_SET | count | int | Number of distinct delegation NS name sets observed. |
MULTIPLE_DELEGATION_NS_SET | ns_names | array<string> | Sorted NS names not served by every parent: the union of the observed sets minus their intersection. Never empty when the tag is emitted. |
NO_RESPONSE | ns | string | Child nameserver identity (ns name only; use address for IP) with no response. |
NO_RESPONSE | address | string | Nameserver IP address for the same endpoint. |
OUT_OF_BAILIWICK_ADDR_MISMATCH | parent_servers | array<object> | Structured parent not-in-domain glue endpoint list for one NS name. |
OUT_OF_BAILIWICK_ADDR_MISMATCH | zone_servers | array<object> | Structured recursively resolved endpoint list for the same NS name. |
TEST_CASE_END | testcase | string | Testcase display name (Consistency05). |
TEST_CASE_START | testcase | string | Testcase display name (Consistency05). |
Severity Levels Per Tag
| Tag | Level | Notes |
|---|---|---|
ADDRESSES_MATCH | INFO | Default from share/profile.json (test_levels.CONSISTENCY). |
CHILD_NS_FAILED | DEBUG | Default from share/profile.json (test_levels.CONSISTENCY). |
CHILD_ZONE_LAME | ERROR | Default from share/profile.json (test_levels.CONSISTENCY). |
DELEGATION_NS_SET | INFO | Default from share/profile.json (test_levels.CONSISTENCY). |
EXTRA_ADDRESS_CHILD | NOTICE | Default from share/profile.json (test_levels.CONSISTENCY). |
IN_BAILIWICK_ADDR_MISMATCH | ERROR | Default from share/profile.json (test_levels.CONSISTENCY). |
MISSING_ADDRESS_CHILD | NOTICE | Default from share/profile.json (test_levels.CONSISTENCY). |
MULTIPLE_DELEGATION_NS_SET | WARNING | Default from share/profile.json (test_levels.CONSISTENCY). |
NO_RESPONSE | DEBUG | Default from share/profile.json (test_levels.CONSISTENCY). |
OUT_OF_BAILIWICK_ADDR_MISMATCH | ERROR | Default from share/profile.json (test_levels.CONSISTENCY). |
TEST_CASE_END | DEBUG | Default from share/profile.json (test_levels.CONSISTENCY). |
TEST_CASE_START | DEBUG | Default from share/profile.json (test_levels.CONSISTENCY). |
Differences From Upstream
- Differences (Upstream vs Gonemaster):
- Upstream: does not explicitly define this detail. Gonemaster: In-domain processing queries all discovered in-domain child servers and emits one
NO_RESPONSEorCHILD_NS_FAILEDentry per failing nameserver before final mismatch classification. - Upstream: does not explicitly define this detail. Gonemaster: Referral handling explicitly falls back to recursive lookup for the same qtype and owner.
- Upstream: the short-circuit wording can be read per in-domain NS name. Gonemaster:
CHILD_ZONE_LAMEis emitted only when all in-domain address lookup paths fail, so disjoint parent/child NS sets can still be classified as address mismatches. - Upstream: does not explicitly define this detail. Gonemaster: If
AllNameserverscannot produce usable in-domain child NS endpoints, strict glue endpoints are used as a fallback for child-side address checks and child NS name discovery. - Upstream: does not compare delegations between parent nameservers in this test case. Gonemaster: groups responding parent servers by the delegation NS name set they serve and reports
MULTIPLE_DELEGATION_NS_SETplus per-setDELEGATION_NS_SETdetails when the sets differ, using the NS responses already collected for glue extraction (no extra queries).
- Upstream: does not explicitly define this detail. Gonemaster: In-domain processing queries all discovered in-domain child servers and emits one
- Potential upstream report:
no
Implementation Notes
The delegation comparison is bounded by what the protocol lets a server omit without signalling it. Four rules apply, and they differ by section and response type:
- RFC 9471 section 3.1: a referral MUST carry all available glue for in-domain names, or set TC=1 when it does not fit.
- RFC 9471 section 3.2: sibling-domain glue SHOULD be included; when it does not fit the server MAY set TC=1 but is not obliged to.
- RFC 9609 section 4.2: a priming response is an answer and not a referral, so RFC 9471 does not apply; addresses may be omitted from its additional section with no expectation that TC is set.
- RFC 2181 section 9: a response with TC=1 may carry the partial RRset that did not fit, so its body must not be consumed; the query is retried over a transport that fits the whole answer.
Deployed parents do omit in-domain referral glue with TC clear, contrary to RFC 9471 section 3.1, so neither lawful trimming nor a compliant TC signal can be assumed. Two consequences follow:
- Cross-parent equality uses the authority section only. An incomplete NS RRset can reach the client only together with TC=1, so a difference observed between TC-clear authority sections is real. Glue may arrive incomplete with no signal at all, so it cannot key a cross-parent equality check; glue faults are instead reported from the union of glue across all parents, where omission can only hide a fault and never invent one.
- TC-set responses are skipped by this testcase, not only by the transport. Truncated responses are normally replaced by a TCP retry (
resolver.defaults.fallback), but with fallback disabled the truncated UDP response is returned as is, and per RFC 2181 section 9 its partial authority section would otherwise fabricate a set difference.
The same asymmetry governs the address comparison:
- Glue is compared as a union across all parents, so a name’s glue is the set of addresses any parent supplied for it. Trimming can only shrink that union, never add to it, so it can hide a fault but cannot invent one.
- Names with no glue in the union are not compared at all. A parent that never had glue for a name cannot be told apart from parents that all trimmed the same name, so comparing such a name would report trimming as a fault. Glue absent from the delegation is reported once per name by Delegation01’s
IN_BAILIWICK_GLUE_MISSING. - A missing address record is not a wrong one. Glue that the child zone does not confirm misdirects resolvers and stays an ERROR. A glued name for which the child serves no address at all still resolves while the glue is served, and is reported separately at NOTICE.
Edge Cases And Limitations
- Glue is taken only from the additional section of a usable referral, so a parent name server that answers out-of-domain names (for example via a catch-all or wildcard zone) does not inject spurious glue and cannot trigger a false
OUT_OF_BAILIWICK_ADDR_MISMATCH. - A parent server that does not respond, or whose response is not a usable referral, is not part of any delegation NS set; non-response can never produce
MULTIPLE_DELEGATION_NS_SET. With fewer than two usable referrals the delegation comparison is skipped entirely. - The delegation NS-set comparison is silent when all responding parents agree; there is no positive confirmation tag, and
ADDRESSES_MATCHremains governed only by the address comparisons. - Glue trimmed from the additional section, whether lawfully or not, does not split the delegation, because the per-parent key holds NS names only.
- A parent that is also authoritative for the child zone answers from the answer section instead of referring.
arpais the live case: the root servers serve it directly. Such responses are not usable referrals and contribute no delegation set and no glue. - The root zone is its own parent, so a test of
.sends priming queries. Per RFC 9609 the responses are answers and not referrals, so they are not usable referrals: a test of the root produces no delegation NS-set finding. - Undelegated tests produce synthetic, identical delegations, so the delegation NS-set comparison stays silent there.
CHILD_ZONE_LAMEshort-circuits testcase execution and suppresses later mismatch checks when no usable in-domain address lookup path was found.- In-domain mismatch reporting is per NS name: a zone with several names carrying wrong glue produces one
IN_BAILIWICK_ADDR_MISMATCHper name, each naming only that name’s unconfirmed addresses. - A single name can produce both
IN_BAILIWICK_ADDR_MISMATCHand a contribution toEXTRA_ADDRESS_CHILD, when its glue and its child addresses each hold entries the other lacks. - A zone whose parents supply no usable glue, including the root zone and a delegation whose nameservers are all not-in-domain, has nothing to compare and reports
ADDRESSES_MATCH. - Not-in-domain mismatch reporting is per NS name group; each emission includes full parent list for that group.
- Disabled IP versions affect child authoritative probes indirectly by filtering queried child servers.