dns.iter — Lilush API

←index

← dns

Overview

Iterative DNS resolution helpers. Provides functions for walking the DNS hierarchy from root servers to authoritative answers with RD=0 queries, inspecting each delegation step along the way. Useful for diagnostics, debugging, and understanding DNS resolution chains.

Functions

NameSignature
extract_referralextract_referral(resp) -> zone, ns, glue
classifyclassify(resp, qtype, qname) -> kind, info
query_serverquery_server(host, qname, qtype, opts) -> resp, err
tracetrace(qname, qtype, opts) -> steps, err

extract_referral(resp) -> zone, ns, glue

Extract referral details from a DNS response

Parses the authority and additional sections of a decoded DNS response to extract delegation information.

Returns three values:

local iter = require("dns.iter")
local resp = iter.query_server("198.41.0.4", "example.com.", "A")
local zone, ns, glue = iter.extract_referral(resp)
-- zone: "com."
-- ns: {{name = "a.gtld-servers.net."}, ...}
-- glue: {["a.gtld-servers.net."] = {ipv4 = "192.5.6.30"}, ...}

classify(resp, qtype, qname) -> kind, info

Classify a decoded DNS response

Classifies a decoded DNS response message into one of six categories. qtype is the numeric query type used in the original query.

Returns kind (string) and info (table) where kind is one of:

local iter = require("dns.iter")
local resp = iter.query_server("198.41.0.4", "example.com.", "A")
local kind, info = iter.classify(resp, 1) -- 1 = TYPE.A

query_server(host, qname, qtype, opts) -> resp, err

Send a single iterative (RD=0) DNS query to a specific server

Sends one DNS query with RD=0 (Recursion Desired off) to the server at host. Returns the full decoded response message including all sections (header, question, answer, authority, additional, edns).

qtype may be a string ("A", "AAAA", "NS", "MX") or a numeric type code.

Optional opts fields:

Automatically retries over TCP when the response has the TC (truncation) bit set.

local iter = require("dns.iter")
local resp, err = iter.query_server("198.41.0.4", "example.com.", "A")
if resp then
    local kind, info = iter.classify(resp, 1)
    print(kind)  -- "referral"
end

trace(qname, qtype, opts) -> steps, err

Trace iterative DNS resolution from root servers to authoritative answer

Walks the DNS hierarchy starting from root servers, following referrals through TLD and authoritative nameservers until an answer (or terminal error) is reached. Each step in the resolution chain is recorded and returned.

Returns a list of step tables on success:

{
    server = "198.41.0.4",              -- IP address queried
    server_name = "a.root-servers.net.",-- name if known, nil otherwise
    zone = ".",                         -- zone this server is authoritative for
    qname = "example.com.",            -- domain queried
    qtype = "A",                       -- record type queried (string)
    kind = "referral",                 -- classification (see classify())
    info = { ... },                    -- info table from classify()
    response = <decoded msg>,          -- full decoded DNS message
    rtt_ms = 12,                       -- round-trip time in milliseconds
}

The last step in the list contains the terminal result: "answer", "nxdomain", "nodata", or "error". Intermediate steps are typically "referral" or "cname".

Optional opts fields:

When a referral lacks glue records for all NS names, the trace resolves the glueless NS name by launching a recursive sub-trace for its A record. The sub-trace steps are stored on the referral step as info.glue_trace. Nesting depth is bounded by max_glue_depth to prevent infinite loops.

local iter = require("dns.iter")
local steps, err = iter.trace("example.com", "A")
if steps then
    for i, step in ipairs(steps) do
        print(i, step.server, step.kind, step.zone)
    end
end