Merge pull request #120 from razvandimescu/feat/named-record-types
feat(question): name SVCB/LOC/NAPTR record types in logs
This commit was merged in pull request #120.
This commit is contained in:
11
src/ctx.rs
11
src/ctx.rs
@@ -511,13 +511,12 @@ fn strip_dnssec_records(pkt: &mut DnsPacket) {
|
|||||||
pkt.resources.retain(|r| !is_dnssec_record(r));
|
pkt.resources.retain(|r| !is_dnssec_record(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
const SVCB_QTYPE: u16 = 64;
|
|
||||||
|
|
||||||
fn strip_svcb_ipv6_hints(pkt: &mut DnsPacket) {
|
fn strip_svcb_ipv6_hints(pkt: &mut DnsPacket) {
|
||||||
let https_qtype = QueryType::HTTPS.to_num();
|
let https_qtype = QueryType::HTTPS.to_num();
|
||||||
|
let svcb_qtype = QueryType::SVCB.to_num();
|
||||||
pkt.for_each_record_mut(|rec| {
|
pkt.for_each_record_mut(|rec| {
|
||||||
if let DnsRecord::UNKNOWN { qtype, data, .. } = rec {
|
if let DnsRecord::UNKNOWN { qtype, data, .. } = rec {
|
||||||
if *qtype == https_qtype || *qtype == SVCB_QTYPE {
|
if *qtype == https_qtype || *qtype == svcb_qtype {
|
||||||
if let Some(new_data) = crate::svcb::strip_ipv6hint(data) {
|
if let Some(new_data) = crate::svcb::strip_ipv6hint(data) {
|
||||||
*data = new_data;
|
*data = new_data;
|
||||||
}
|
}
|
||||||
@@ -1307,7 +1306,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut svcb_pkt = pkt.clone();
|
let mut svcb_pkt = pkt.clone();
|
||||||
svcb_pkt.questions[0].name = "svc.test".to_string();
|
svcb_pkt.questions[0].name = "svc.test".to_string();
|
||||||
svcb_pkt.questions[0].qtype = QueryType::UNKNOWN(64);
|
svcb_pkt.questions[0].qtype = QueryType::SVCB;
|
||||||
if let DnsRecord::UNKNOWN { domain, qtype, .. } = &mut svcb_pkt.answers[0] {
|
if let DnsRecord::UNKNOWN { domain, qtype, .. } = &mut svcb_pkt.answers[0] {
|
||||||
*domain = "svc.test".to_string();
|
*domain = "svc.test".to_string();
|
||||||
*qtype = 64;
|
*qtype = 64;
|
||||||
@@ -1322,12 +1321,12 @@ mod tests {
|
|||||||
ctx.cache
|
ctx.cache
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert("svc.test", QueryType::UNKNOWN(64), &svcb_pkt);
|
.insert("svc.test", QueryType::SVCB, &svcb_pkt);
|
||||||
let ctx = Arc::new(ctx);
|
let ctx = Arc::new(ctx);
|
||||||
|
|
||||||
for (name, qtype, label) in [
|
for (name, qtype, label) in [
|
||||||
("hints.test", QueryType::HTTPS, "HTTPS"),
|
("hints.test", QueryType::HTTPS, "HTTPS"),
|
||||||
("svc.test", QueryType::UNKNOWN(64), "SVCB"),
|
("svc.test", QueryType::SVCB, "SVCB"),
|
||||||
] {
|
] {
|
||||||
let (resp, path) = resolve_in_test(&ctx, name, qtype).await;
|
let (resp, path) = resolve_in_test(&ctx, name, qtype).await;
|
||||||
assert_eq!(path, QueryPath::Cached, "{label}");
|
assert_eq!(path, QueryPath::Cached, "{label}");
|
||||||
|
|||||||
164
src/question.rs
164
src/question.rs
@@ -1,114 +1,66 @@
|
|||||||
use crate::buffer::BytePacketBuffer;
|
use crate::buffer::BytePacketBuffer;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
|
macro_rules! define_qtypes {
|
||||||
pub enum QueryType {
|
( $( $variant:ident = $num:literal, $str:literal ),* $(,)? ) => {
|
||||||
UNKNOWN(u16),
|
#[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)]
|
||||||
A, // 1
|
pub enum QueryType {
|
||||||
NS, // 2
|
UNKNOWN(u16),
|
||||||
CNAME, // 5
|
$( $variant, )*
|
||||||
SOA, // 6
|
}
|
||||||
PTR, // 12
|
|
||||||
MX, // 15
|
impl QueryType {
|
||||||
TXT, // 16
|
pub fn to_num(&self) -> u16 {
|
||||||
AAAA, // 28
|
match *self {
|
||||||
SRV, // 33
|
QueryType::UNKNOWN(x) => x,
|
||||||
DS, // 43
|
$( QueryType::$variant => $num, )*
|
||||||
RRSIG, // 46
|
}
|
||||||
NSEC, // 47
|
}
|
||||||
DNSKEY, // 48
|
|
||||||
NSEC3, // 50
|
pub fn from_num(num: u16) -> QueryType {
|
||||||
OPT, // 41 (EDNS0 pseudo-type)
|
match num {
|
||||||
HTTPS, // 65
|
$( $num => QueryType::$variant, )*
|
||||||
|
_ => QueryType::UNKNOWN(num),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
QueryType::UNKNOWN(_) => "UNKNOWN",
|
||||||
|
$( QueryType::$variant => $str, )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_str(s: &str) -> Option<QueryType> {
|
||||||
|
match s.to_ascii_uppercase().as_str() {
|
||||||
|
$( $str => Some(QueryType::$variant), )*
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueryType {
|
define_qtypes! {
|
||||||
pub fn to_num(&self) -> u16 {
|
A = 1, "A",
|
||||||
match *self {
|
NS = 2, "NS",
|
||||||
QueryType::UNKNOWN(x) => x,
|
CNAME = 5, "CNAME",
|
||||||
QueryType::A => 1,
|
SOA = 6, "SOA",
|
||||||
QueryType::NS => 2,
|
PTR = 12, "PTR",
|
||||||
QueryType::CNAME => 5,
|
MX = 15, "MX",
|
||||||
QueryType::SOA => 6,
|
TXT = 16, "TXT",
|
||||||
QueryType::PTR => 12,
|
AAAA = 28, "AAAA",
|
||||||
QueryType::MX => 15,
|
LOC = 29, "LOC",
|
||||||
QueryType::TXT => 16,
|
SRV = 33, "SRV",
|
||||||
QueryType::AAAA => 28,
|
NAPTR = 35, "NAPTR",
|
||||||
QueryType::SRV => 33,
|
OPT = 41, "OPT",
|
||||||
QueryType::OPT => 41,
|
DS = 43, "DS",
|
||||||
QueryType::DS => 43,
|
RRSIG = 46, "RRSIG",
|
||||||
QueryType::RRSIG => 46,
|
NSEC = 47, "NSEC",
|
||||||
QueryType::NSEC => 47,
|
DNSKEY = 48, "DNSKEY",
|
||||||
QueryType::DNSKEY => 48,
|
NSEC3 = 50, "NSEC3",
|
||||||
QueryType::NSEC3 => 50,
|
SVCB = 64, "SVCB",
|
||||||
QueryType::HTTPS => 65,
|
HTTPS = 65, "HTTPS",
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_num(num: u16) -> QueryType {
|
|
||||||
match num {
|
|
||||||
1 => QueryType::A,
|
|
||||||
2 => QueryType::NS,
|
|
||||||
5 => QueryType::CNAME,
|
|
||||||
6 => QueryType::SOA,
|
|
||||||
12 => QueryType::PTR,
|
|
||||||
15 => QueryType::MX,
|
|
||||||
16 => QueryType::TXT,
|
|
||||||
28 => QueryType::AAAA,
|
|
||||||
33 => QueryType::SRV,
|
|
||||||
41 => QueryType::OPT,
|
|
||||||
43 => QueryType::DS,
|
|
||||||
46 => QueryType::RRSIG,
|
|
||||||
47 => QueryType::NSEC,
|
|
||||||
48 => QueryType::DNSKEY,
|
|
||||||
50 => QueryType::NSEC3,
|
|
||||||
65 => QueryType::HTTPS,
|
|
||||||
_ => QueryType::UNKNOWN(num),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_str(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
QueryType::A => "A",
|
|
||||||
QueryType::NS => "NS",
|
|
||||||
QueryType::CNAME => "CNAME",
|
|
||||||
QueryType::SOA => "SOA",
|
|
||||||
QueryType::PTR => "PTR",
|
|
||||||
QueryType::MX => "MX",
|
|
||||||
QueryType::TXT => "TXT",
|
|
||||||
QueryType::AAAA => "AAAA",
|
|
||||||
QueryType::SRV => "SRV",
|
|
||||||
QueryType::OPT => "OPT",
|
|
||||||
QueryType::DS => "DS",
|
|
||||||
QueryType::RRSIG => "RRSIG",
|
|
||||||
QueryType::NSEC => "NSEC",
|
|
||||||
QueryType::DNSKEY => "DNSKEY",
|
|
||||||
QueryType::NSEC3 => "NSEC3",
|
|
||||||
QueryType::HTTPS => "HTTPS",
|
|
||||||
QueryType::UNKNOWN(_) => "UNKNOWN",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_str(s: &str) -> Option<QueryType> {
|
|
||||||
match s.to_ascii_uppercase().as_str() {
|
|
||||||
"A" => Some(QueryType::A),
|
|
||||||
"NS" => Some(QueryType::NS),
|
|
||||||
"CNAME" => Some(QueryType::CNAME),
|
|
||||||
"SOA" => Some(QueryType::SOA),
|
|
||||||
"PTR" => Some(QueryType::PTR),
|
|
||||||
"MX" => Some(QueryType::MX),
|
|
||||||
"TXT" => Some(QueryType::TXT),
|
|
||||||
"AAAA" => Some(QueryType::AAAA),
|
|
||||||
"SRV" => Some(QueryType::SRV),
|
|
||||||
"DS" => Some(QueryType::DS),
|
|
||||||
"RRSIG" => Some(QueryType::RRSIG),
|
|
||||||
"DNSKEY" => Some(QueryType::DNSKEY),
|
|
||||||
"NSEC" => Some(QueryType::NSEC),
|
|
||||||
"NSEC3" => Some(QueryType::NSEC3),
|
|
||||||
"HTTPS" => Some(QueryType::HTTPS),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|||||||
Reference in New Issue
Block a user