# DNS `dns/*` exposes the system resolver directly: hostname → address (`getaddrinfo`), address → hostname (`getnameinfo`), plus literal-address helpers. It is the same resolver `net/connect`, `http/*`, and `http/ws-*` use internally, so `/etc/hosts`, `/etc/resolv.conf`, nsswitch, and search domains all apply. Lookups are **synchronous** — a call blocks the VM thread for the duration of the lookup, exactly like `net/connect`'s internal resolution. There is no Future-returning variant yet. ## `dns/*` Stdlib functions | Function | Returns | Purpose | |---|---|---| | `[dns/lookup $host ?$opts]` | vector of address strings | Resolve a hostname | | `[dns/addr-info $host ?$opts]` | vector of record maps | Full `getaddrinfo` records | | `[dns/reverse $addr ?$opts]` | hostname string | PTR lookup for an IP literal | | `[dns/hostname]` | string | Local hostname | | `[dns/local-addresses ?$opts]` | vector of address strings | Interface addresses | | `[dns/servers]` | vector of address strings | Nameservers from `/etc/resolv.conf` | | `[dns/parse $s]` | canonical address string | Normalise an IP literal | | `[dns/ip? $s]` | bool | IPv4 or IPv6 literal? | | `[dns/ipv4? $s]` | bool | IPv4 literal? | | `[dns/ipv6? $s]` | bool | IPv6 literal? | Errors return `%Err{ :message "..." }` (the `gai_strerror` text for resolver failures). ## Options `dns/lookup`, `dns/addr-info`, and `dns/local-addresses` accept an option map. The vocabulary follows bun's `dns.zig`: | Key | Values | Default | |---|---|---| | `:family` | `:ipv4`, `:ipv6`, `:any` | `:any` | | `:socktype` | `:stream`, `:dgram`, `:any` | `:stream` | | `:protocol` | `:tcp`, `:udp`, `:any` | `:any` | | `:flags` | vector of `:passive`, `:canonname`, `:numerichost`, `:numericserv`, `:v4mapped`, `:all`, `:addrconfig` | none | | `:port` | 0..65535 | unset | | `:backend` | `:system` / `:libc` | `:system` | `:stream` is the default socket type for Node/bun compatibility (it keeps the resolver from returning duplicate entries). `:backend :c-ares` is recognised but unsupported — deft has no vendored c-ares, so it returns an `%Err`. Unknown option keys are ignored. ## Resolving
 [dns/lookup "example.com"]
# => @{ "93.184.216.34" "2606:2800:220:1:248:1893:25c8:1946" }

[dns/lookup "localhost" %{ :family :ipv4 }]
# => @{ "127.0.0.1" }

# Literal fast path — no resolver traffic:
[dns/lookup "127.0.0.1" %{ :flags @{ :numerichost } }]
# => @{ "127.0.0.1" } 
`dns/addr-info` keeps the metadata `dns/lookup` drops:
 [dns/addr-info "example.com" %{ :port 443 }]
# => @{ %{ :address "93.184.216.34" :family :ipv4 :socktype :stream
#         :protocol :tcp :port 443 } ... } 
Records carry no TTL — `getaddrinfo` does not expose one. ## Reverse and local names
 [dns/reverse "8.8.8.8"]                        # => "dns.google"
[dns/reverse "127.0.0.1" %{ :numeric true }]   # => "127.0.0.1" (no PTR)

[dns/hostname]                                 # => "plotinus"
[dns/local-addresses %{ :family :ipv4 }]       # => @{ "127.0.0.1" "192.168.1.20" ... }
[dns/servers]                                  # => @{ "127.0.0.53" } 
`dns/reverse` requires an IP literal and uses `NI_NAMEREQD`, so an address without a PTR record is an `%Err` rather than the numeric form. `dns/servers` is informational: the platform resolver reads `/etc/resolv.conf` itself, so the list cannot be overridden at runtime. ## Literal helpers
 [dns/parse "0:0:0:0:0:0:0:1"]   # => "::1"
[dns/ip? "::1"]                 # => true
[dns/ipv4? "::1"]               # => false
[dns/ipv6? "::1"]               # => true 
`dns/parse` returns the canonical form (longest zero run shortened, no port); predicates are pure `inet_pton` checks with no network access. ## Quick Reference | Form | Purpose | |---|---| | `[dns/lookup $host ?$opts]` | Hostname → addresses | | `[dns/addr-info $host ?$opts]` | Hostname → full records | | `[dns/reverse $addr ?$opts]` | Address → hostname | | `[dns/hostname]` | Local hostname | | `[dns/local-addresses ?$opts]` | Interface addresses | | `[dns/servers]` | Configured nameservers | | `[dns/parse $s]` | Canonical IP literal | | `[dns/ip? $s]` / `[dns/ipv4? $s]` / `[dns/ipv6? $s]` | Literal predicates |