mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +00:00
fix(ext/node): handle "ttl" option in "dns" module (#27676)
Closes #27669 --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
parent
6d0035411b
commit
1a171f10df
5 changed files with 130 additions and 67 deletions
|
@ -35,6 +35,7 @@ import {
|
||||||
const UDP_DGRAM_MAXSIZE = 65507;
|
const UDP_DGRAM_MAXSIZE = 65507;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
ArrayPrototypeMap,
|
||||||
Error,
|
Error,
|
||||||
Number,
|
Number,
|
||||||
NumberIsNaN,
|
NumberIsNaN,
|
||||||
|
@ -78,12 +79,13 @@ async function resolveDns(query, recordType, options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await op_dns_resolve({
|
const res = await op_dns_resolve({
|
||||||
cancelRid,
|
cancelRid,
|
||||||
query,
|
query,
|
||||||
recordType,
|
recordType,
|
||||||
options,
|
options,
|
||||||
});
|
});
|
||||||
|
return ArrayPrototypeMap(res, (recordWithTtl) => recordWithTtl.data);
|
||||||
} finally {
|
} finally {
|
||||||
if (options?.signal) {
|
if (options?.signal) {
|
||||||
options.signal[abortSignal.remove](abortHandler);
|
options.signal[abortSignal.remove](abortHandler);
|
||||||
|
|
105
ext/net/ops.rs
105
ext/net/ops.rs
|
@ -788,7 +788,7 @@ pub fn op_net_accept_vsock() -> Result<(), NetError> {
|
||||||
|
|
||||||
#[derive(Serialize, Eq, PartialEq, Debug)]
|
#[derive(Serialize, Eq, PartialEq, Debug)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum DnsReturnRecord {
|
pub enum DnsRecordData {
|
||||||
A(String),
|
A(String),
|
||||||
Aaaa(String),
|
Aaaa(String),
|
||||||
Aname(String),
|
Aname(String),
|
||||||
|
@ -830,6 +830,13 @@ pub enum DnsReturnRecord {
|
||||||
Txt(Vec<String>),
|
Txt(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Eq, PartialEq, Debug)]
|
||||||
|
#[serde()]
|
||||||
|
pub struct DnsRecordWithTtl {
|
||||||
|
pub data: DnsRecordData,
|
||||||
|
pub ttl: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ResolveAddrArgs {
|
pub struct ResolveAddrArgs {
|
||||||
|
@ -862,7 +869,7 @@ pub struct NameServer {
|
||||||
pub async fn op_dns_resolve<NP>(
|
pub async fn op_dns_resolve<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[serde] args: ResolveAddrArgs,
|
#[serde] args: ResolveAddrArgs,
|
||||||
) -> Result<Vec<DnsReturnRecord>, NetError>
|
) -> Result<Vec<DnsRecordWithTtl>, NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -947,9 +954,18 @@ where
|
||||||
}
|
}
|
||||||
_ => NetError::Dns(e),
|
_ => NetError::Dns(e),
|
||||||
})?
|
})?
|
||||||
|
.records()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|rdata| rdata_to_return_record(record_type)(rdata).transpose())
|
.filter_map(|rec| {
|
||||||
.collect::<Result<Vec<DnsReturnRecord>, NetError>>()
|
let r = format_rdata(record_type)(rec.data()).transpose();
|
||||||
|
r.map(|maybe_data| {
|
||||||
|
maybe_data.map(|data| DnsRecordWithTtl {
|
||||||
|
data,
|
||||||
|
ttl: rec.ttl(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<DnsRecordWithTtl>, NetError>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
|
@ -992,22 +1008,22 @@ pub fn op_set_keepalive_inner(
|
||||||
resource.set_keepalive(keepalive).map_err(NetError::Map)
|
resource.set_keepalive(keepalive).map_err(NetError::Map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rdata_to_return_record(
|
fn format_rdata(
|
||||||
ty: RecordType,
|
ty: RecordType,
|
||||||
) -> impl Fn(&RData) -> Result<Option<DnsReturnRecord>, NetError> {
|
) -> impl Fn(&RData) -> Result<Option<DnsRecordData>, NetError> {
|
||||||
use RecordType::*;
|
use RecordType::*;
|
||||||
move |r: &RData| -> Result<Option<DnsReturnRecord>, NetError> {
|
move |r: &RData| -> Result<Option<DnsRecordData>, NetError> {
|
||||||
let record = match ty {
|
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
|
AAAA => r
|
||||||
.as_aaaa()
|
.as_aaaa()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.map(DnsReturnRecord::Aaaa),
|
.map(DnsRecordData::Aaaa),
|
||||||
ANAME => r
|
ANAME => r
|
||||||
.as_aname()
|
.as_aname()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.map(DnsReturnRecord::Aname),
|
.map(DnsRecordData::Aname),
|
||||||
CAA => r.as_caa().map(|caa| DnsReturnRecord::Caa {
|
CAA => r.as_caa().map(|caa| DnsRecordData::Caa {
|
||||||
critical: caa.issuer_critical(),
|
critical: caa.issuer_critical(),
|
||||||
tag: caa.tag().to_string(),
|
tag: caa.tag().to_string(),
|
||||||
value: match caa.value() {
|
value: match caa.value() {
|
||||||
|
@ -1034,12 +1050,12 @@ fn rdata_to_return_record(
|
||||||
CNAME => r
|
CNAME => r
|
||||||
.as_cname()
|
.as_cname()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.map(DnsReturnRecord::Cname),
|
.map(DnsRecordData::Cname),
|
||||||
MX => r.as_mx().map(|mx| DnsReturnRecord::Mx {
|
MX => r.as_mx().map(|mx| DnsRecordData::Mx {
|
||||||
preference: mx.preference(),
|
preference: mx.preference(),
|
||||||
exchange: mx.exchange().to_string(),
|
exchange: mx.exchange().to_string(),
|
||||||
}),
|
}),
|
||||||
NAPTR => r.as_naptr().map(|naptr| DnsReturnRecord::Naptr {
|
NAPTR => r.as_naptr().map(|naptr| DnsRecordData::Naptr {
|
||||||
order: naptr.order(),
|
order: naptr.order(),
|
||||||
preference: naptr.preference(),
|
preference: naptr.preference(),
|
||||||
flags: String::from_utf8(naptr.flags().to_vec()).unwrap(),
|
flags: String::from_utf8(naptr.flags().to_vec()).unwrap(),
|
||||||
|
@ -1047,12 +1063,9 @@ fn rdata_to_return_record(
|
||||||
regexp: String::from_utf8(naptr.regexp().to_vec()).unwrap(),
|
regexp: String::from_utf8(naptr.regexp().to_vec()).unwrap(),
|
||||||
replacement: naptr.replacement().to_string(),
|
replacement: naptr.replacement().to_string(),
|
||||||
}),
|
}),
|
||||||
NS => r.as_ns().map(ToString::to_string).map(DnsReturnRecord::Ns),
|
NS => r.as_ns().map(ToString::to_string).map(DnsRecordData::Ns),
|
||||||
PTR => r
|
PTR => r.as_ptr().map(ToString::to_string).map(DnsRecordData::Ptr),
|
||||||
.as_ptr()
|
SOA => r.as_soa().map(|soa| DnsRecordData::Soa {
|
||||||
.map(ToString::to_string)
|
|
||||||
.map(DnsReturnRecord::Ptr),
|
|
||||||
SOA => r.as_soa().map(|soa| DnsReturnRecord::Soa {
|
|
||||||
mname: soa.mname().to_string(),
|
mname: soa.mname().to_string(),
|
||||||
rname: soa.rname().to_string(),
|
rname: soa.rname().to_string(),
|
||||||
serial: soa.serial(),
|
serial: soa.serial(),
|
||||||
|
@ -1061,7 +1074,7 @@ fn rdata_to_return_record(
|
||||||
expire: soa.expire(),
|
expire: soa.expire(),
|
||||||
minimum: soa.minimum(),
|
minimum: soa.minimum(),
|
||||||
}),
|
}),
|
||||||
SRV => r.as_srv().map(|srv| DnsReturnRecord::Srv {
|
SRV => r.as_srv().map(|srv| DnsRecordData::Srv {
|
||||||
priority: srv.priority(),
|
priority: srv.priority(),
|
||||||
weight: srv.weight(),
|
weight: srv.weight(),
|
||||||
port: srv.port(),
|
port: srv.port(),
|
||||||
|
@ -1075,7 +1088,7 @@ fn rdata_to_return_record(
|
||||||
bytes.iter().map(|&b| b as char).collect::<String>()
|
bytes.iter().map(|&b| b as char).collect::<String>()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
DnsReturnRecord::Txt(texts)
|
DnsRecordData::Txt(texts)
|
||||||
}),
|
}),
|
||||||
_ => return Err(NetError::UnsupportedRecordType),
|
_ => return Err(NetError::UnsupportedRecordType),
|
||||||
};
|
};
|
||||||
|
@ -1118,37 +1131,37 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_a() {
|
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)));
|
let rdata = RData::A(A(Ipv4Addr::new(127, 0, 0, 1)));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::A("127.0.0.1".to_string()))
|
Some(DnsRecordData::A("127.0.0.1".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_aaaa() {
|
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)));
|
let rdata = RData::AAAA(AAAA(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Aaaa("::1".to_string()))
|
Some(DnsRecordData::Aaaa("::1".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_aname() {
|
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()));
|
let rdata = RData::ANAME(ANAME(Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Aname("".to_string()))
|
Some(DnsRecordData::Aname("".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_caa() {
|
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(
|
let rdata = RData::CAA(CAA::new_issue(
|
||||||
false,
|
false,
|
||||||
Some(Name::parse("example.com", None).unwrap()),
|
Some(Name::parse("example.com", None).unwrap()),
|
||||||
|
@ -1156,7 +1169,7 @@ mod tests {
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Caa {
|
Some(DnsRecordData::Caa {
|
||||||
critical: false,
|
critical: false,
|
||||||
tag: "issue".to_string(),
|
tag: "issue".to_string(),
|
||||||
value: "example.com; account=123456".to_string(),
|
value: "example.com; account=123456".to_string(),
|
||||||
|
@ -1166,21 +1179,21 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_cname() {
|
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()));
|
let rdata = RData::CNAME(CNAME(Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Cname("".to_string()))
|
Some(DnsRecordData::Cname("".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_mx() {
|
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()));
|
let rdata = RData::MX(MX::new(10, Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Mx {
|
Some(DnsRecordData::Mx {
|
||||||
preference: 10,
|
preference: 10,
|
||||||
exchange: "".to_string()
|
exchange: "".to_string()
|
||||||
})
|
})
|
||||||
|
@ -1189,7 +1202,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_naptr() {
|
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(
|
let rdata = RData::NAPTR(NAPTR::new(
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
|
@ -1200,7 +1213,7 @@ mod tests {
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Naptr {
|
Some(DnsRecordData::Naptr {
|
||||||
order: 1,
|
order: 1,
|
||||||
preference: 2,
|
preference: 2,
|
||||||
flags: "".to_string(),
|
flags: "".to_string(),
|
||||||
|
@ -1213,27 +1226,27 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_ns() {
|
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()));
|
let rdata = RData::NS(NS(Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Ns("".to_string()))
|
Some(DnsRecordData::Ns("".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_ptr() {
|
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()));
|
let rdata = RData::PTR(PTR(Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Ptr("".to_string()))
|
Some(DnsRecordData::Ptr("".to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_soa() {
|
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(
|
let rdata = RData::SOA(SOA::new(
|
||||||
Name::new(),
|
Name::new(),
|
||||||
Name::new(),
|
Name::new(),
|
||||||
|
@ -1245,7 +1258,7 @@ mod tests {
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Soa {
|
Some(DnsRecordData::Soa {
|
||||||
mname: "".to_string(),
|
mname: "".to_string(),
|
||||||
rname: "".to_string(),
|
rname: "".to_string(),
|
||||||
serial: 0,
|
serial: 0,
|
||||||
|
@ -1259,11 +1272,11 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_srv() {
|
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()));
|
let rdata = RData::SRV(SRV::new(1, 2, 3, Name::new()));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Srv {
|
Some(DnsRecordData::Srv {
|
||||||
priority: 1,
|
priority: 1,
|
||||||
weight: 2,
|
weight: 2,
|
||||||
port: 3,
|
port: 3,
|
||||||
|
@ -1274,7 +1287,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_txt() {
|
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![
|
let rdata = RData::TXT(TXT::from_bytes(vec![
|
||||||
"foo".as_bytes(),
|
"foo".as_bytes(),
|
||||||
"bar".as_bytes(),
|
"bar".as_bytes(),
|
||||||
|
@ -1283,7 +1296,7 @@ mod tests {
|
||||||
]));
|
]));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
func(&rdata).unwrap(),
|
func(&rdata).unwrap(),
|
||||||
Some(DnsReturnRecord::Txt(vec);
|
const err = this._handle[bindingName](req, domainToASCII(name));
|
||||||
|
|
|
@ -37,6 +37,7 @@ import {
|
||||||
import { ares_strerror } from "ext:deno_node/internal_binding/ares.ts";
|
import { ares_strerror } from "ext:deno_node/internal_binding/ares.ts";
|
||||||
import { notImplemented } from "ext:deno_node/_utils.ts";
|
import { notImplemented } from "ext:deno_node/_utils.ts";
|
||||||
import {
|
import {
|
||||||
|
op_dns_resolve,
|
||||||
op_net_get_ips_from_perm_token,
|
op_net_get_ips_from_perm_token,
|
||||||
op_node_getaddrinfo,
|
op_node_getaddrinfo,
|
||||||
} from "ext:core/ops";
|
} from "ext:core/ops";
|
||||||
|
@ -198,9 +199,7 @@ export class ChannelWrap extends AsyncWrap implements ChannelWrapQuery {
|
||||||
this.#tries = tries;
|
this.#tries = tries;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #query(query: string, recordType: Deno.RecordType) {
|
async #query(query: string, recordType: Deno.RecordType, ttl?: boolean) {
|
||||||
// TODO(@bartlomieju): TTL logic.
|
|
||||||
|
|
||||||
let code: number;
|
let code: number;
|
||||||
let ret: Awaited<ReturnType<typeof Deno.resolveDns>>;
|
let ret: Awaited<ReturnType<typeof Deno.resolveDns>>;
|
||||||
|
|
||||||
|
@ -217,6 +216,7 @@ export class ChannelWrap extends AsyncWrap implements ChannelWrapQuery {
|
||||||
query,
|
query,
|
||||||
recordType,
|
recordType,
|
||||||
resolveOptions,
|
resolveOptions,
|
||||||
|
ttl,
|
||||||
));
|
));
|
||||||
|
|
||||||
if (code === 0 || code === codeMap.get("EAI_NODATA")!) {
|
if (code === 0 || code === codeMap.get("EAI_NODATA")!) {
|
||||||
|
@ -224,7 +224,7 @@ export class ChannelWrap extends AsyncWrap implements ChannelWrapQuery {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
({ code, ret } = await this.#resolve(query, recordType));
|
({ code, ret } = await this.#resolve(query, recordType, null, ttl));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { code: code!, ret: ret! };
|
return { code: code!, ret: ret! };
|
||||||
|
@ -234,15 +234,26 @@ export class ChannelWrap extends AsyncWrap implements ChannelWrapQuery {
|
||||||
query: string,
|
query: string,
|
||||||
recordType: Deno.RecordType,
|
recordType: Deno.RecordType,
|
||||||
resolveOptions?: Deno.ResolveDnsOptions,
|
resolveOptions?: Deno.ResolveDnsOptions,
|
||||||
|
ttl?: boolean,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
code: number;
|
code: number;
|
||||||
ret: Awaited<ReturnType<typeof Deno.resolveDns>>;
|
// deno-lint-ignore no-explicit-any
|
||||||
|
ret: any[];
|
||||||
}> {
|
}> {
|
||||||
let ret: Awaited<ReturnType<typeof Deno.resolveDns>> = [];
|
let ret = [];
|
||||||
let code = 0;
|
let code = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ret = await Deno.resolveDns(query, recordType, resolveOptions);
|
const res = await op_dns_resolve({
|
||||||
|
query,
|
||||||
|
recordType,
|
||||||
|
options: resolveOptions,
|
||||||
|
});
|
||||||
|
if (ttl) {
|
||||||
|
ret = res;
|
||||||
|
} else {
|
||||||
|
ret = res.map((recordWithTtl) => recordWithTtl.data);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Deno.errors.NotFound) {
|
if (e instanceof Deno.errors.NotFound) {
|
||||||
code = codeMap.get("EAI_NODATA")!;
|
code = codeMap.get("EAI_NODATA")!;
|
||||||
|
@ -363,18 +374,34 @@ export class ChannelWrap extends AsyncWrap implements ChannelWrapQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
queryA(req: QueryReqWrap, name: string): number {
|
queryA(req: QueryReqWrap, name: string): number {
|
||||||
this.#query(name, "A").then(({ code, ret }) => {
|
this.#query(name, "A", req.ttl).then(({ code, ret }) => {
|
||||||
req.oncomplete(code, ret);
|
let recordsWithTtl;
|
||||||
|
if (req.ttl) {
|
||||||
|
recordsWithTtl = (ret as Deno.RecordWithTtl[]).map((val) => ({
|
||||||
|
address: val?.data,
|
||||||
|
ttl: val?.ttl,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
req.oncomplete(code, recordsWithTtl ?? ret);
|
||||||
});
|
});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryAaaa(req: QueryReqWrap, name: string): number {
|
queryAaaa(req: QueryReqWrap, name: string): number {
|
||||||
this.#query(name, "AAAA").then(({ code, ret }) => {
|
this.#query(name, "AAAA", req.ttl).then(({ code, ret }) => {
|
||||||
const records = (ret as string[]).map((record) => compressIPv6(record));
|
let recordsWithTtl;
|
||||||
|
if (req.ttl) {
|
||||||
|
recordsWithTtl = (ret as Deno.RecordWithTtl[]).map((val) => ({
|
||||||
|
address: compressIPv6(val?.data as string),
|
||||||
|
ttl: val?.ttl,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
ret = (ret as string[]).map((record) => compressIPv6(record));
|
||||||
|
}
|
||||||
|
|
||||||
req.oncomplete(code, records);
|
req.oncomplete(code, recordsWithTtl ?? ret);
|
||||||
});
|
});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||||
|
|
||||||
// deno-lint-ignore-file no-console
|
|
||||||
|
|
||||||
import * as net from "node:net";
|
import * as net from "node:net";
|
||||||
import { assert, assertEquals } from "@std/assert";
|
import { assert, assertEquals } from "@std/assert";
|
||||||
import * as path from "@std/path";
|
import * as path from "@std/path";
|
||||||
import * as http from "node:http";
|
import * as http from "node:http";
|
||||||
|
import * as dns from "node:dns";
|
||||||
|
import console from "node:console";
|
||||||
|
|
||||||
Deno.test("[node/net] close event emits after error event - when host is not found", async () => {
|
Deno.test("[node/net] close event emits after error event - when host is not found", async () => {
|
||||||
const socket = net.createConnection(27009, "doesnotexist");
|
const socket = net.createConnection(27009, "doesnotexist");
|
||||||
|
@ -247,3 +247,30 @@ Deno.test("[node/net] net.Server can listen on the same port immediately after i
|
||||||
});
|
});
|
||||||
await serverClosed.promise;
|
await serverClosed.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("dns.resolve with ttl", async () => {
|
||||||
|
const d1 = Promise.withResolvers();
|
||||||
|
dns.resolve4("www.example.com", { ttl: true }, (err, addresses) => {
|
||||||
|
if (err) {
|
||||||
|
d1.reject(err);
|
||||||
|
} else {
|
||||||
|
d1.resolve(addresses);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
const ret1 = await d1.promise as any[];
|
||||||
|
assert(ret1.length > 0);
|
||||||
|
assert(typeof ret1[0].ttl === "number");
|
||||||
|
|
||||||
|
const d2 = Promise.withResolvers();
|
||||||
|
dns.resolve4("www.example.com", (err, addresses) => {
|
||||||
|
if (err) {
|
||||||
|
d2.reject(err);
|
||||||
|
} else {
|
||||||
|
d2.resolve(addresses);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const ret2 = await d2.promise as string[];
|
||||||
|
assert(ret2.length > 0);
|
||||||
|
assert(typeof ret2[0] === "string");
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue