Native DNS wire format codec and async stub resolver. Supports A/AAAA/MX/SRV/TXT/CNAME/NS/PTR/SOA with name compression, UDP/TCP fallback, CNAME chain, and TTL cache.
Dependencies
moon check --target native --warn-list +73 --deny-warn
moon run --target native src/cmd/main -- resolve example.com A --server 1.1.1.1:53 --short
moon run --target native src/cmd/main -- resolve example.com MX --server 8.8.8.8 --verbose
moon run --target native src/cmd/main -- resolve example.com AAAA --json
moon run --target native src/examples/a_aaaa -- --server 1.1.1.1:53
moon run --target native src/examples/mx_srv -- --server 8.8.8.8:53moon add jinshengmeng46/moon-dns-stub@0.1.0resolve <name> <A|AAAA|MX|NS|CNAME|TXT|SOA|PTR|SRV>
[--server <host[:port]|[ipv6]:port>]
[--timeout <milliseconds>]
[--short|--verbose|--json]import {
"jinshengmeng46/moon-dns-stub" @dns,
"moonbitlang/async",
}
supported_targets = "native"
pkgtype(kind: "executable")async fn main {
let resolver = @dns.Resolver::new(
options=@dns.ResolveOptions::new(
server="1.1.1.1:53",
timeout_ms=3000,
retries=1,
),
)
match resolver.resolve_a("example.com") {
Ok(addresses) => println(addresses.join(", "))
Err(error) =>
raise Failure::Failure("DNS query failed: \{to_repr(error)}")
}
}| 方法 | 成功结果 |
|---|---|
| resolve(name, qtype) | 原始 DnsResult(RR answers 与 CNAME 链) |
| resolve_a / resolve_aaaa | Array[String] 地址 |
| resolve_ipv4 | 第一个 IPv4 地址 String |
| resolve_mx | Array[(Int, String)],按 preference 升序 |
| resolve_ns / resolve_cname / resolve_txt / resolve_ptr | Array[String] |
| resolve_soa | Array[SoaResult] |
| resolve_srv | Array[SrvResult],按 priority 升序、同 priority 按 weight 降序 |
| cache_stats() | 当前 resolver 的 CacheStats(hit、miss、entry 数) |
// request_over_doh 接收并返回完整 DNS wire message。
let transport = @dns.DnsTransport::from_request(
payload => request_over_doh(payload),
udp_payload_size=1232,
)
let resolver = @dns.Resolver::with_transport(transport~)
let answers = resolver.resolve_aaaa("example.com")moon check --target native --warn-list +73 --deny-warn
moon build --target native --warn-list +73 --deny-warn
moon test --target native --warn-list +73 --deny-warn -v
moon fmt --check
moon package --list
bash scripts/cli_failure_smoke.sh
DNS_DIFF_REQUIRED=1 bash scripts/dig_diff.sh
DNS_DIFF_REQUIRED=1 bash scripts/dig_diff_doh.shfn DnsCache::put_negative(self : DnsCache, name : String, qtype : UInt16, kind : NegativeCacheKind, ttl_seconds : Int, now_ms : Int) -> Unitpub(all) struct DnsTransport {
request : async (Array[Byte]) -> Result[Array[Byte], TransportError]
udp_payload_size : UInt16
}fn DnsTransport::from_request(request : async (Array[Byte]) -> Result[Array[Byte], TransportError], udp_payload_size? : UInt16) -> DnsTransportasync fn DnsTransport::send(self : DnsTransport, payload : Array[Byte]) -> Result[Array[Byte], TransportError]async fn FallbackTransport::send(self : FallbackTransport, payload : Array[Byte]) -> Result[Array[Byte], TransportError]fn FallbackTransport::with_options(server : String, timeout_ms : Int, retries : Int, udp_payload_size? : UInt16) -> FallbackTransportpub struct Header {
id : UInt16
flags : UInt16
qdcount : UInt16
ancount : UInt16
nscount : UInt16
arcount : UInt16
}pub struct Question {
name : String
qtype : UInt16
qclass : UInt16
}pub struct RR {
name : String
rtype : UInt16
rclass : UInt16
ttl : UInt
rdlength : UInt16
rdata : RData
}pub(all) struct ResolveOptions {
server : String
timeout_ms : Int
retries : Int
recurse : Bool
max_cname_depth : Int
}fn ResolveOptions::new(server~ : String, timeout_ms? : Int, retries? : Int, recurse? : Bool, max_depth? : Int) -> ResolveOptionspub struct Resolver {
transport : DnsTransport
cache : DnsCache
recurse : Bool
max_cname_depth : Int
clock : () -> Int64
}async fn Resolver::resolve(self : Resolver, name : String, qtype : UInt16) -> Result[DnsResult, ResolveError]async fn Resolver::resolve_aaaa(self : Resolver, name : String) -> Result[Array[String], ResolveError]async fn Resolver::resolve_cname(self : Resolver, name : String) -> Result[Array[String], ResolveError]async fn Resolver::resolve_mx(self : Resolver, name : String) -> Result[Array[(Int, String)], ResolveError]async fn Resolver::resolve_ns(self : Resolver, name : String) -> Result[Array[String], ResolveError]async fn Resolver::resolve_ptr(self : Resolver, name : String) -> Result[Array[String], ResolveError]async fn Resolver::resolve_soa(self : Resolver, name : String) -> Result[Array[SoaResult], ResolveError]async fn Resolver::resolve_srv(self : Resolver, name : String) -> Result[Array[SrvResult], ResolveError]async fn Resolver::resolve_txt(self : Resolver, name : String) -> Result[Array[String], ResolveError]fn Resolver::with_transport_and_clock(transport~ : DnsTransport, clock~ : () -> Int, options? : ResolveOptions) -> Resolverfn Resolver::with_transport_and_clock64(transport~ : DnsTransport, clock~ : () -> Int64, options? : ResolveOptions) -> Resolverpub struct RrTypeInfo {
rtype : UInt16
name : String
description : String
is_domain_based : Bool
}pub(all) struct SoaResult {
mname : String
rname : String
serial : UInt
refresh : UInt
retry : UInt
expire : UInt
minimum : UInt
}pub(all) struct SrvResult {
priority : UInt
weight : UInt
port : UInt
target : String
}pub struct TcpTransport {
server : String
timeout_ms : Int
max_retries : Int
}async fn TcpTransport::send(self : TcpTransport, payload : Array[Byte]) -> Result[Array[Byte], TransportError]pub struct UdpTransport {
server : String
timeout_ms : Int
max_retries : Int
udp_payload_size : UInt16
}async fn UdpTransport::send(self : UdpTransport, payload : Array[Byte]) -> Result[Array[Byte], TransportError]fn UdpTransport::with_options(server : String, timeout_ms : Int, max_retries : Int, udp_payload_size? : UInt16) -> UdpTransportfn pretty_print_result_json(result : DnsResult, name : String, qtype : UInt16, server : String) -> Stringfn rr_soa(name : String, mname : String, rname : String, serial : UInt, refresh : UInt, retry : UInt, expire : UInt, minimum : UInt, ttl? : UInt) -> RRfn rr_srv(name : String, priority : UInt, weight : UInt, port : UInt, target : String, ttl? : UInt) -> RRNative DNS wire format codec and async stub resolver. Supports A/AAAA/MX/SRV/TXT/CNAME/NS/PTR/SOA with name compression, UDP/TCP fallback, CNAME chain, and TTL cache.
Dependencies