High-level DNS resolver with caching, CNAME following, search list expansion, server failover, retry, and response validation. Ties together dns.message, dns.name, dns.cache, and dns.transport.* into a single resolve() call.
| Name | Signature |
|---|---|
parse_resolv_conf | parse_resolv_conf(path) -> config, err |
resolver:resolve | resolver:resolve(qname, qtype) -> records, err |
resolver:query | resolver:query(raw_bytes) -> msg, err |
resolver:close | resolver:close() |
new | new(cfg) -> resolver, err |
parse_resolv_conf(
path) ->config,err
Parse /etc/resolv.conf and return a config table
Reads and parses a resolv.conf file, returning a table suitable for
passing to (or merging into) dns.client.new() configuration.
Parsed directives:
nameserver lines become servers entries as {host = "ip"} tables
search / domain lines become the search list (trailing-dot normalized)
options ndots:N becomes ndots
options timeout:N becomes timeout
options attempts:N becomes retries
Fields are only present in the result when found in the file, allowing
the caller to merge with their own defaults. Server entries have no
port since standard resolv.conf has no port syntax; the transport
default applies.
path defaults to "/etc/resolv.conf".
local dns_client = require("dns.client")
-- Use system resolvers
local sys = dns_client.parse_resolv_conf()
local r = dns_client.new(sys)
-- Merge with overrides
local sys = dns_client.parse_resolv_conf()
sys.timeout = 3
sys.use_tls = true
local r = dns_client.new(sys)
resolver:resolve(
qname,qtype) ->records,err
Resolve a domain name to records of the specified type
Resolves qname by querying upstream servers with retry, failover,
and optional caching. Follows CNAME chains (depth limit 10) and
applies search list expansion based on ndots.
qtype is a record type as a string ("A", "AAAA", "MX") or
number (1, 28, 15). String matching is case-insensitive.
Returns a list of matching answer records on success, each with
name, type, class, ttl, and rdata fields. Returns
nil, err on failure (NXDOMAIN, timeout, no servers, etc.).
local answers, err = resolver:resolve("example.com", "A")
if not answers then
print("error: " .. err)
else
for _, rr in ipairs(answers) do
print(rr.rdata.address, "TTL", rr.ttl)
end
end
-- MX records
local mx, err = resolver:resolve("gmail.com", "MX")
if mx then
for _, rr in ipairs(mx) do
print(rr.rdata.preference, rr.rdata.exchange)
end
end
resolver:query(
raw_bytes) ->msg,err
Send a pre-encoded DNS query and return the decoded response
Lower-level query interface. Sends raw_bytes as a DNS message to
configured servers with retry and failover, returns the decoded
response message table. No caching, no CNAME following, no
response validation beyond successful decode.
resolver:close()
Close the resolver and release transport resources
new(
cfg) ->resolver,err
Create a new DNS resolver
Configuration fields:
servers — list of upstream DNS servers (required); entries
can be IP strings ("1.1.1.1") or tables
({ host = "1.1.1.1", port = 5353 }); port is
optional and defaults to 53 (or 853 for TLS)
timeout — socket timeout in seconds (default 5)
retries — retry attempts per query (default 2)
use_tcp — force TCP for all queries (default false)
use_tls — use DNS-over-TLS on port 853 (default false)
ndots — search list dot threshold (default 1)
search — search domain list (default {})
edns_buffer_size — EDNS advertised UDP payload size (default 4096)
use_0x20 — enable 0x20 query name encoding (default false)
cache — dns.cache instance for caching (default nil, no caching)
server_name — TLS SNI hostname (TLS only)
cafile — path to CA certificate bundle (TLS only)
capath — path to CA certificate directory (TLS only)
verify — enable TLS certificate verification (default true)
local dns_client = require("dns.client")
local dns_cache = require("dns.cache")
-- Simple resolver
local r = dns_client.new({ servers = { "1.1.1.1", "8.8.8.8" } })
local answers, err = r:resolve("example.com", "A")
-- Per-server port
local r = dns_client.new({
servers = { { host = "127.0.0.1", port = 5353 }, "8.8.8.8" },
})
-- From system resolv.conf
local sys = dns_client.parse_resolv_conf()
local r = dns_client.new(sys)
-- DNS-over-TLS
local r = dns_client.new({
servers = { "1.1.1.1" },
use_tls = true,
})