// MoonDNS - Pure MoonBit Authoritative DNS Server
// Copyright 2026 chgttyyr
// Licensed under the Apache-2.0 License.
///|
/// Complete DNS Message structure (RFC 1035 Section 4.1)
pub(all) struct Message {
header : Header
questions : Array[Question]
answers : Array[Record]
authorities : Array[Record]
additionals : Array[Record]
} derive(Debug, Eq)
///|
/// Constructor for an empty Message with default header
pub fn Message::new() -> Message {
{
header: Header::new_query(0),
questions: [],
answers: [],
authorities: [],
additionals: [],
}
}
///|
/// Construct a standard DNS query message for a domain and type
pub fn Message::new_query(id : UInt16, name : String, qtype : RType) -> Message {
let header = Header::new_query(id)
let q = Question::new(name, qtype, IN)
{ header, questions: [q], answers: [], authorities: [], additionals: [], }
}
///|
/// Construct a response message referencing an incoming query
pub fn Message::new_response(
query : Message,
aa : Bool,
rcode : RCode,
) -> Message {
let qdcount = query.questions.length().to_uint16()
let header = Header::new_response(
query.header.id,
aa,
rcode,
qdcount,
0,
0,
0,
)
// Copy recursion desired flag from query if requested
header.rd = query.header.rd
{
header,
questions: query.questions,
answers: [],
authorities: [],
additionals: [],
}
}
///|
/// Synchronize counts in header with actual record arrays
pub fn Message::sync_counts(self : Message) -> Unit {
self.header.qdcount = self.questions.length().to_uint16()
self.header.ancount = self.answers.length().to_uint16()
self.header.nscount = self.authorities.length().to_uint16()
self.header.arcount = self.additionals.length().to_uint16()
}
///|
/// Append an answer record
pub fn Message::add_answer(self : Message, record : Record) -> Unit {
self.answers.push(record)
self.header.ancount = self.answers.length().to_uint16()
}
///|
/// Append an authority record
pub fn Message::add_authority(self : Message, record : Record) -> Unit {
self.authorities.push(record)
self.header.nscount = self.authorities.length().to_uint16()
}
///|
/// Append an additional record
pub fn Message::add_additional(self : Message, record : Record) -> Unit {
self.additionals.push(record)
self.header.arcount = self.additionals.length().to_uint16()
}