diff --git a/ext/net/ops.rs b/ext/net/ops.rs index 768dd33135..ba6c256fe7 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -561,7 +561,7 @@ where #[derive(Serialize, Eq, PartialEq, Debug)] #[serde(untagged)] -pub enum DnsReturnRecord { +pub enum DnsRecordData { A(String), Aaaa(String), Aname(String), @@ -603,6 +603,20 @@ pub enum DnsReturnRecord { Txt(Vec), } +#[derive(Serialize, Eq, PartialEq, Debug)] +#[serde()] +pub struct DnsRecordWithTtl { + pub data: DnsRecordData, + pub ttl: u32, +} + +#[derive(Serialize, Eq, PartialEq, Debug)] +#[serde(untagged)] +pub enum DnsReturnRecord { + WithoutTtl(DnsRecordData), + WithTtl(DnsRecordWithTtl), +} + #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct ResolveAddrArgs { @@ -616,6 +630,7 @@ pub struct ResolveAddrArgs { #[serde(rename_all = "camelCase")] pub struct ResolveDnsOption { name_server: Option, + ttl: Option, } fn default_port() -> u16 { @@ -662,6 +677,8 @@ where system_conf::read_system_conf()? }; + let ttl = options.as_ref().and_then(|o| o.ttl).unwrap_or(false); + { let mut s = state.borrow_mut(); let perm = s.borrow_mut::(); @@ -720,8 +737,20 @@ where } _ => NetError::Dns(e), })? + .records() .iter() - .filter_map(|rdata| rdata_to_return_record(record_type)(rdata).transpose()) + .filter_map(|rec| { + let data = format_rdata(record_type)(rec.data()).unwrap(); + if ttl { + Some(DnsReturnRecord::WithTtl(DnsRecordWithTtl { + data: data?, + ttl: rec.ttl(), + })) + } else { + Some(DnsReturnRecord::WithoutTtl(data?)) + } + }) + .map(Ok) .collect::, NetError>>() } @@ -765,22 +794,22 @@ pub fn op_set_keepalive_inner( resource.set_keepalive(keepalive).map_err(NetError::Map) } -fn rdata_to_return_record( +fn format_rdata( ty: RecordType, -) -> impl Fn(&RData) -> Result, NetError> { +) -> impl Fn(&RData) -> Result, NetError> { use RecordType::*; - move |r: &RData| -> Result, NetError> { + move |r: &RData| -> Result, NetError> { let record = match ty { - A => r.as_a().map(ToString::to_string).map(DnsReturnRecord::A), + A => r.as_a().map(ToString::to_string).map(DnsRecordData::A), AAAA => r .as_aaaa() .map(ToString::to_string) - .map(DnsReturnRecord::Aaaa), + .map(DnsRecordData::Aaaa), ANAME => r .as_aname() .map(ToString::to_string) - .map(DnsReturnRecord::Aname), - CAA => r.as_caa().map(|caa| DnsReturnRecord::Caa { + .map(DnsRecordData::Aname), + CAA => r.as_caa().map(|caa| DnsRecordData::Caa { critical: caa.issuer_critical(), tag: caa.tag().to_string(), value: match caa.value() { @@ -807,12 +836,12 @@ fn rdata_to_return_record( CNAME => r .as_cname() .map(ToString::to_string) - .map(DnsReturnRecord::Cname), - MX => r.as_mx().map(|mx| DnsReturnRecord::Mx { + .map(DnsRecordData::Cname), + MX => r.as_mx().map(|mx| DnsRecordData::Mx { preference: mx.preference(), exchange: mx.exchange().to_string(), }), - NAPTR => r.as_naptr().map(|naptr| DnsReturnRecord::Naptr { + NAPTR => r.as_naptr().map(|naptr| DnsRecordData::Naptr { order: naptr.order(), preference: naptr.preference(), flags: String::from_utf8(naptr.flags().to_vec()).unwrap(), @@ -820,12 +849,9 @@ fn rdata_to_return_record( regexp: String::from_utf8(naptr.regexp().to_vec()).unwrap(), replacement: naptr.replacement().to_string(), }), - NS => r.as_ns().map(ToString::to_string).map(DnsReturnRecord::Ns), - PTR => r - .as_ptr() - .map(ToString::to_string) - .map(DnsReturnRecord::Ptr), - SOA => r.as_soa().map(|soa| DnsReturnRecord::Soa { + NS => r.as_ns().map(ToString::to_string).map(DnsRecordData::Ns), + PTR => r.as_ptr().map(ToString::to_string).map(DnsRecordData::Ptr), + SOA => r.as_soa().map(|soa| DnsRecordData::Soa { mname: soa.mname().to_string(), rname: soa.rname().to_string(), serial: soa.serial(), @@ -834,7 +860,7 @@ fn rdata_to_return_record( expire: soa.expire(), minimum: soa.minimum(), }), - SRV => r.as_srv().map(|srv| DnsReturnRecord::Srv { + SRV => r.as_srv().map(|srv| DnsRecordData::Srv { priority: srv.priority(), weight: srv.weight(), port: srv.port(), @@ -848,7 +874,7 @@ fn rdata_to_return_record( bytes.iter().map(|&b| b as char).collect::() }) .collect(); - DnsReturnRecord::Txt(texts) + DnsRecordData::Txt(texts) }), _ => return Err(NetError::UnsupportedRecordType), }; @@ -891,37 +917,37 @@ mod tests { #[test] fn rdata_to_return_record_a() { - let func = rdata_to_return_record(RecordType::A); + let func = format_rdata(RecordType::A); let rdata = RData::A(A(Ipv4Addr::new(127, 0, 0, 1))); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::A("127.0.0.1".to_string())) + Some(DnsRecordData::A("127.0.0.1".to_string())) ); } #[test] fn rdata_to_return_record_aaaa() { - let func = rdata_to_return_record(RecordType::AAAA); + let func = format_rdata(RecordType::AAAA); let rdata = RData::AAAA(AAAA(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Aaaa("::1".to_string())) + Some(DnsRecordData::Aaaa("::1".to_string())) ); } #[test] fn rdata_to_return_record_aname() { - let func = rdata_to_return_record(RecordType::ANAME); + let func = format_rdata(RecordType::ANAME); let rdata = RData::ANAME(ANAME(Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Aname("".to_string())) + Some(DnsRecordData::Aname("".to_string())) ); } #[test] fn rdata_to_return_record_caa() { - let func = rdata_to_return_record(RecordType::CAA); + let func = format_rdata(RecordType::CAA); let rdata = RData::CAA(CAA::new_issue( false, Some(Name::parse("example.com", None).unwrap()), @@ -929,7 +955,7 @@ mod tests { )); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Caa { + Some(DnsRecordData::Caa { critical: false, tag: "issue".to_string(), value: "example.com; account=123456".to_string(), @@ -939,21 +965,21 @@ mod tests { #[test] fn rdata_to_return_record_cname() { - let func = rdata_to_return_record(RecordType::CNAME); + let func = format_rdata(RecordType::CNAME); let rdata = RData::CNAME(CNAME(Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Cname("".to_string())) + Some(DnsRecordData::Cname("".to_string())) ); } #[test] fn rdata_to_return_record_mx() { - let func = rdata_to_return_record(RecordType::MX); + let func = format_rdata(RecordType::MX); let rdata = RData::MX(MX::new(10, Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Mx { + Some(DnsRecordData::Mx { preference: 10, exchange: "".to_string() }) @@ -962,7 +988,7 @@ mod tests { #[test] fn rdata_to_return_record_naptr() { - let func = rdata_to_return_record(RecordType::NAPTR); + let func = format_rdata(RecordType::NAPTR); let rdata = RData::NAPTR(NAPTR::new( 1, 2, @@ -973,7 +999,7 @@ mod tests { )); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Naptr { + Some(DnsRecordData::Naptr { order: 1, preference: 2, flags: "".to_string(), @@ -986,27 +1012,27 @@ mod tests { #[test] fn rdata_to_return_record_ns() { - let func = rdata_to_return_record(RecordType::NS); + let func = format_rdata(RecordType::NS); let rdata = RData::NS(NS(Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Ns("".to_string())) + Some(DnsRecordData::Ns("".to_string())) ); } #[test] fn rdata_to_return_record_ptr() { - let func = rdata_to_return_record(RecordType::PTR); + let func = format_rdata(RecordType::PTR); let rdata = RData::PTR(PTR(Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Ptr("".to_string())) + Some(DnsRecordData::Ptr("".to_string())) ); } #[test] fn rdata_to_return_record_soa() { - let func = rdata_to_return_record(RecordType::SOA); + let func = format_rdata(RecordType::SOA); let rdata = RData::SOA(SOA::new( Name::new(), Name::new(), @@ -1018,7 +1044,7 @@ mod tests { )); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Soa { + Some(DnsRecordData::Soa { mname: "".to_string(), rname: "".to_string(), serial: 0, @@ -1032,11 +1058,11 @@ mod tests { #[test] fn rdata_to_return_record_srv() { - let func = rdata_to_return_record(RecordType::SRV); + let func = format_rdata(RecordType::SRV); let rdata = RData::SRV(SRV::new(1, 2, 3, Name::new())); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Srv { + Some(DnsRecordData::Srv { priority: 1, weight: 2, port: 3, @@ -1047,7 +1073,7 @@ mod tests { #[test] fn rdata_to_return_record_txt() { - let func = rdata_to_return_record(RecordType::TXT); + let func = format_rdata(RecordType::TXT); let rdata = RData::TXT(TXT::from_bytes(vec![ "foo".as_bytes(), "bar".as_bytes(), @@ -1056,7 +1082,7 @@ mod tests { ])); assert_eq!( func(&rdata).unwrap(), - Some(DnsReturnRecord::Txt(vec![ + Some(DnsRecordData::Txt(vec![ "foo".to_string(), "bar".to_string(), "£".to_string(),