// MoonDNS Core Types (RFC 1035)
///|
/// DNS Resource Record Types
pub(all) enum RType {
A
NS
CNAME
SOA
MX
TXT
AAAA
OPT
Unknown(UInt16)
} derive(Debug, Eq, Compare)
///|
pub impl Show for RType with output(self, logger) {
let s = match self {
A => "A"
NS => "NS"
CNAME => "CNAME"
SOA => "SOA"
MX => "MX"
TXT => "TXT"
AAAA => "AAAA"
OPT => "OPT"
Unknown(val) => "TYPE\{val.to_int()}"
}
logger.write_string(s)
}
///|
pub fn RType::to_uint16(self : RType) -> UInt16 {
match self {
A => Int::to_uint16(1)
NS => Int::to_uint16(2)
CNAME => Int::to_uint16(5)
SOA => Int::to_uint16(6)
MX => Int::to_uint16(15)
TXT => Int::to_uint16(16)
AAAA => Int::to_uint16(28)
OPT => Int::to_uint16(41)
Unknown(val) => val
}
}
///|
pub fn RType::from_uint16(val : UInt16) -> RType {
let v = val.to_int()
match v {
1 => A
2 => NS
5 => CNAME
6 => SOA
15 => MX
16 => TXT
28 => AAAA
41 => OPT
_ => Unknown(val)
}
}
///|
/// DNS Resource Record Classes
pub(all) enum RClass {
IN
CS
CH
HS
ANY
Unknown(UInt16)
} derive(Debug, Eq, Compare)
///|
pub impl Show for RClass with output(self, logger) {
let s = match self {
IN => "IN"
CS => "CS"
CH => "CH"
HS => "HS"
ANY => "ANY"
Unknown(val) => "CLASS\{val.to_int()}"
}
logger.write_string(s)
}
///|
pub fn RClass::to_uint16(self : RClass) -> UInt16 {
match self {
IN => Int::to_uint16(1)
CS => Int::to_uint16(2)
CH => Int::to_uint16(3)
HS => Int::to_uint16(4)
ANY => Int::to_uint16(255)
Unknown(val) => val
}
}
///|
pub fn RClass::from_uint16(val : UInt16) -> RClass {
let v = val.to_int()
match v {
1 => IN
2 => CS
3 => CH
4 => HS
255 => ANY
_ => Unknown(val)
}
}
///|
/// DNS Header (12 bytes, RFC 1035 Section 4.1.1)
pub(all) struct Header {
id : UInt16
qr : Bool
opcode : Int
aa : Bool
tc : Bool
rd : Bool
ra : Bool
z : Int
rcode : Int
qdcount : UInt16
ancount : UInt16
nscount : UInt16
arcount : UInt16
} derive(Debug, Eq)
///|
pub fn Header::new(
id : UInt16,
qr : Bool,
opcode : Int,
aa : Bool,
tc : Bool,
rd : Bool,
ra : Bool,
z : Int,
rcode : Int,
qdcount : UInt16,
ancount : UInt16,
nscount : UInt16,
arcount : UInt16,
) -> Header {
{
id,
qr,
opcode,
aa,
tc,
rd,
ra,
z,
rcode,
qdcount,
ancount,
nscount,
arcount,
}
}
///|
/// DNS Question (RFC 1035 Section 4.1.2)
pub(all) struct Question {
name : String
qtype : RType
qclass : RClass
} derive(Debug, Eq)
///|
pub fn Question::new(name : String, qtype : RType, qclass : RClass) -> Question {
{ name, qtype, qclass }
}
///|
/// DNS Resource Record Data
pub(all) enum RData {
A(UInt)
AAAA(FixedArray[Byte])
CNAME(String)
NS(String)
MX(UInt16, String)
TXT(Array[String])
SOA(
mname~ : String,
rname~ : String,
serial~ : UInt,
refresh~ : UInt,
retry~ : UInt,
expire~ : UInt,
minimum~ : UInt,
)
OPT(FixedArray[Byte])
Raw(FixedArray[Byte])
} derive(Debug, Eq)
///|
/// DNS Resource Record (RFC 1035 Section 4.1.3)
pub(all) struct Record {
name : String
rtype : RType
rclass : RClass
ttl : UInt
rdata : RData
} derive(Debug, Eq)
///|
pub fn Record::new(
name : String,
rtype : RType,
rclass : RClass,
ttl : UInt,
rdata : RData,
) -> Record {
{ name, rtype, rclass, ttl, rdata }
}
///|
/// Complete DNS Message
pub(all) struct Message {
header : Header
questions : Array[Question]
answers : Array[Record]
authorities : Array[Record]
additionals : Array[Record]
} derive(Debug, Eq)
///|
pub fn Message::new(
header : Header,
questions : Array[Question],
answers : Array[Record],
authorities : Array[Record],
additionals : Array[Record],
) -> Message {
{ header, questions, answers, authorities, additionals }
}
///|
/// DNS Parsing and Protocol Errors
pub(all) enum DnsError {
BufferUnderflow
MalformedPacket(String)
PointerLoop(String)
PointerOutOfBounds(String)
PointerJumpLimitExceeded
InvalidLabelLength(Int)
InvalidDomainName(String)
UnexpectedEof
Other(String)
} derive(Debug, Eq)