# DNS
`dns/*` 直接暴露系统解析器:主机名 → 地址(`getaddrinfo`)、地址 →
主机名(`getnameinfo`),以及字面量地址辅助函数。它与 `net/connect`、
`http/*` 和 `http/ws-*` 内部使用的是同一个解析器,因此 `/etc/hosts`、
`/etc/resolv.conf`、nsswitch 和搜索域都会生效。
查询是同步的——调用会在查询持续期间阻塞 VM 线程,与
`net/connect` 的内部解析完全一样。目前还没有返回 Future 的变体。
## `dns/*` 标准库函数
| 函数 | 返回值 | 用途 |
|---|---|---|
| `[dns/lookup $host ?$opts]` | 地址字符串向量 | 解析主机名 |
| `[dns/addr-info $host ?$opts]` | 记录映射向量 | 完整的 `getaddrinfo` 记录 |
| `[dns/reverse $addr ?$opts]` | 主机名字符串 | IP 字面量的 PTR 查询 |
| `[dns/hostname]` | 字符串 | 本地主机名 |
| `[dns/local-addresses ?$opts]` | 地址字符串向量 | 接口地址 |
| `[dns/servers]` | 地址字符串向量 | 来自 `/etc/resolv.conf` 的域名服务器 |
| `[dns/parse $s]` | 规范地址字符串 | 规范化 IP 字面量 |
| `[dns/ip? $s]` | 布尔值 | 是 IPv4 还是 IPv6 字面量? |
| `[dns/ipv4? $s]` | 布尔值 | 是 IPv4 字面量? |
| `[dns/ipv6? $s]` | 布尔值 | 是 IPv6 字面量? |
错误返回 `%Err{ :message "..." }`(解析器失败时为 `gai_strerror`
文本)。
## 选项
`dns/lookup`、`dns/addr-info` 和 `dns/local-addresses` 接受一个
选项映射。术语沿用 bun 的 `dns.zig`:
| 键 | 值 | 默认值 |
|---|---|---|
| `:family` | `:ipv4`、`:ipv6`、`:any` | `:any` |
| `:socktype` | `:stream`、`:dgram`、`:any` | `:stream` |
| `:protocol` | `:tcp`、`:udp`、`:any` | `:any` |
| `:flags` | 由 `:passive`、`:canonname`、`:numerichost`、`:numericserv`、`:v4mapped`、`:all`、`:addrconfig` 组成的向量 | 无 |
| `:port` | 0..65535 | 未设置 |
| `:backend` | `:system` / `:libc` | `:system` |
`:stream` 是默认的套接字类型,以兼容 Node/bun(它可避免解析器返回
重复条目)。`:backend :c-ares` 可被识别但不支持——deft 没有内置的
c-ares,因此返回 `%Err`。未知的选项键会被忽略。
## 解析
[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` 保留 `dns/lookup` 丢弃的元数据:
[dns/addr-info "example.com" %{ :port 443 }] # => @{ %{ :address "93.184.216.34" :family :ipv4 :socktype :stream # :protocol :tcp :port 443 } ... }
记录不携带 TTL——`getaddrinfo` 不暴露 TTL。
## 反向解析与本地名称
[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` 需要 IP 字面量并使用 `NI_NAMEREQD`,因此没有 PTR
记录的地址会返回 `%Err`,而不是数字形式。`dns/servers` 仅供参考:
平台解析器自行读取 `/etc/resolv.conf`,因此该列表无法在运行时
覆盖。
## 字面量辅助函数
[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` 返回规范形式(最长的零段被缩短,不含端口);谓词是
纯 `inet_pton` 检查,不进行网络访问。
## 快速参考
| 形式 | 用途 |
|---|---|
| `[dns/lookup $host ?$opts]` | 主机名 → 地址 |
| `[dns/addr-info $host ?$opts]` | 主机名 → 完整记录 |
| `[dns/reverse $addr ?$opts]` | 地址 → 主机名 |
| `[dns/hostname]` | 本地主机名 |
| `[dns/local-addresses ?$opts]` | 接口地址 |
| `[dns/servers]` | 已配置的域名服务器 |
| `[dns/parse $s]` | 规范 IP 字面量 |
| `[dns/ip? $s]` / `[dns/ipv4? $s]` / `[dns/ipv6? $s]` | 字面量谓词 |