Skip to content

DnsBuildQuery

Description

Build a single-question DNS query (recursion desired) into out.

Parameters

Name Direction Description
out out Caller-managed Vec(u8). Buffer is cleared and repopulated.
id in Caller-supplied transaction id, echoed back by the nameserver. Pick randomly for cache-poisoning resistance.
name in Hostname to encode, e.g. “example.com”. Prefer Str *; Zstr accepted. Trailing dot is optional. Each label must be 1..63 bytes; total wire length must be < 255.
type in Question type (typically DNS_TYPE_A or DNS_TYPE_AAAA).

Success

Returns true. out contains a valid wire query.

Failure

Returns false on invalid arguments, label-length violations, or Vec growth failure. out is left with whatever was written.

Usage example (Cross-references)

Usage examples (Cross-references)
        DnsWireBuf query = VecInitT(query, &scratch);
        u16        id    = random_query_id();
        if (!DnsBuildQuery(&query, id, hostname, qtype)) {
            VecDeinit(&query);
            ArenaAllocatorDeinit(&scratch);
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 0x1234, "example.com", DNS_TYPE_A);
    
        // Expected wire bytes (29 bytes total):
        DnsWireBuf no_dot = VecInitT(no_dot, a);
        DnsWireBuf w_dot  = VecInitT(w_dot, a);
        bool ok = DnsBuildQuery(&no_dot, 1, "a.b.c", DNS_TYPE_AAAA) && DnsBuildQuery(&w_dot, 1, "a.b.c.", DNS_TYPE_AAAA);
    
        bool match = ok && BufLength(&no_dot) == BufLength(&w_dot);
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 0x1234, "www.example.com", DNS_TYPE_A);
    
        static const u8 expected[] = {0x12, 0x34, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 0x0001, "", DNS_TYPE_A);
    
        // header(12) + qname(just 0x00) + qtype(2) + qclass(2) = 17 bytes.
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 1, label, DNS_TYPE_A);
    
        // header(12) + [63]+63 label bytes + 0 term + 4 = 12+64+1+4 = 81; first
        DnsWireBuf no_dot = VecInitT(no_dot, a);
        DnsWireBuf w_dot  = VecInitT(w_dot, a);
        bool       ok     = DnsBuildQuery(&no_dot, 7, "a.b", DNS_TYPE_A) && DnsBuildQuery(&w_dot, 7, "a.b.", DNS_TYPE_A);
    
        bool match = ok && BufLength(&no_dot) == BufLength(&w_dot) && BufLength(&no_dot) > 0;
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 1, name, DNS_TYPE_A);
    
        // header(12) + wire 220 + 1 terminator + 4 = 237.
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 1, name, DNS_TYPE_A);
    
        // header(12) + wire 254 + 1 terminator + 4 = 271.
        Str        name = StrInitFromZstr("example.com", a);
        DnsWireBuf buf  = VecInitT(buf, a);
        bool       ok   = DnsBuildQuery(&buf, 0x1234, &name, DNS_TYPE_A);
    
        static const u8 expected[] = {0x12, 0x34, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    
        DnsWireBuf buf = VecInitT(buf, a);
        bool       ok  = DnsBuildQuery(&buf, 0x1234, "a..b", DNS_TYPE_A);
    
        bool match = !ok; // empty internal label must be rejected.
Last updated on