Skip to content

SYSTEM Cited by 1 source

glibc getaddrinfo

getaddrinfo(3) is the POSIX-standard hostname-to-address resolution function; on Linux it is supplied by GNU libc (glibc) and is the default DNS resolution path for any Linux process that does not bundle its own resolver library. It is a stub resolver: it forwards queries to the system-configured recursive resolver (from /etc/resolv.conf) and parses the response, it does not itself perform recursive resolution.

getanswer_r — sequential expected-name parse

The response-parsing implementation inside glibc's nss_dns/getanswer_r walks the answer section sequentially, tracking a single expected_name variable. Each record is classified:

  • If rtype == T_CNAME: record the CNAME target as the new expected_name (advance the chain).
  • Else if rtype == qtype (e.g. A/AAAA) and the owner name matches expected_name: accept the address.
  • Else: ignore the record.
for (; ancount > 0; --ancount) {
  // ... parse record ...
  if (rr.rtype == T_CNAME) {
    /* Record the CNAME target as the new expected name. */
    expected_name = name_buffer;
  } else if (rr.rtype == qtype
             && __ns_samebinaryname(rr.rname, expected_name)
             && rr.rdlength == rrtype_to_rdata_length(qtype)) {
    /* Address record matches - store it */
    ptrlist_add(...);
  }
}

This is a single-pass parser and therefore depends on CNAMEs appearing before the A/AAAA records they alias. If the A record appears first, its owner name does not match the initial QNAME (because the answer is actually for the aliased target, not the queried name), so it is discarded; the CNAME comes later and updates expected_name but by then the A record has already been skipped and is never revisited.

Observed breakage: 2026-01-08 1.1.1.1 incident

glibc getaddrinfo was the canonical broken client in the 2026-01-08 1.1.1.1 partial outage. Cloudflare's systems/cloudflare-1-1-1-1-resolver|1.1.1.1 shipped a memory optimisation that reordered partial-CNAME-chain responses so A records preceded CNAMEs; every Linux process using the default resolver path — which is most of them — failed to resolve affected hostnames for ~47 minutes of severe impact (17:40 UTC → 18:27 UTC revert start).

Contrast with systems/systemd-resolved

systems/systemd-resolved, the other common Linux stub resolver, parses records into an ordered set first (DnsAnswerItemDnsAnswer.items) and searches the full set when following the CNAME chain — so the on-wire order does not matter. Applications linked against systemd-resolved's NSS module (nss-resolve) or resolving via its D-Bus/Varlink API were not affected.

Why the sequential parser survives

The getanswer_r design predates glibc's involvement in modern DNS extensions and hasn't been rewritten to tolerate record reordering because RFC 1034's "preface" language historically implied CNAMEs would come first, and no public resolver had sent them in the other order until the Cloudflare regression. Cloudflare's reverted change and the draft-jabley-dnsop-ordered-answer-section Internet-Draft both acknowledge that fixing the spec is the route forward, not expecting the long tail of deployed glibc copies to be rebuilt.

Seen in

Last updated · 200 distilled / 1,178 read