mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
feat(ext/net): add CAA
DNS record support in Deno.resolveDns() API (#14624)
This commit is contained in:
parent
eb5ffab1cb
commit
10a68a5635
5 changed files with 90 additions and 14 deletions
15
cli/dts/lib.deno.ns.d.ts
vendored
15
cli/dts/lib.deno.ns.d.ts
vendored
|
@ -2953,6 +2953,7 @@ declare namespace Deno {
|
||||||
| "A"
|
| "A"
|
||||||
| "AAAA"
|
| "AAAA"
|
||||||
| "ANAME"
|
| "ANAME"
|
||||||
|
| "CAA"
|
||||||
| "CNAME"
|
| "CNAME"
|
||||||
| "MX"
|
| "MX"
|
||||||
| "NAPTR"
|
| "NAPTR"
|
||||||
|
@ -2974,6 +2975,13 @@ declare namespace Deno {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** If `resolveDns` is called with "CAA" record type specified, it will return an array of this interface. */
|
||||||
|
export interface CAARecord {
|
||||||
|
critical: boolean;
|
||||||
|
tag: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
/** If `resolveDns` is called with "MX" record type specified, it will return an array of this interface. */
|
/** If `resolveDns` is called with "MX" record type specified, it will return an array of this interface. */
|
||||||
export interface MXRecord {
|
export interface MXRecord {
|
||||||
preference: number;
|
preference: number;
|
||||||
|
@ -3015,6 +3023,12 @@ declare namespace Deno {
|
||||||
options?: ResolveDnsOptions,
|
options?: ResolveDnsOptions,
|
||||||
): Promise<string[]>;
|
): Promise<string[]>;
|
||||||
|
|
||||||
|
export function resolveDns(
|
||||||
|
query: string,
|
||||||
|
recordType: "CAA",
|
||||||
|
options?: ResolveDnsOptions,
|
||||||
|
): Promise<CAARecord[]>;
|
||||||
|
|
||||||
export function resolveDns(
|
export function resolveDns(
|
||||||
query: string,
|
query: string,
|
||||||
recordType: "MX",
|
recordType: "MX",
|
||||||
|
@ -3068,6 +3082,7 @@ declare namespace Deno {
|
||||||
options?: ResolveDnsOptions,
|
options?: ResolveDnsOptions,
|
||||||
): Promise<
|
): Promise<
|
||||||
| string[]
|
| string[]
|
||||||
|
| CAARecord[]
|
||||||
| MXRecord[]
|
| MXRecord[]
|
||||||
| NAPTRRecord[]
|
| NAPTRRecord[]
|
||||||
| SOARecord[]
|
| SOARecord[]
|
||||||
|
|
33
cli/tests/testdata/resolve_dns.ts
vendored
33
cli/tests/testdata/resolve_dns.ts
vendored
|
@ -1,19 +1,21 @@
|
||||||
const nameServer = { nameServer: { ipAddr: "127.0.0.1", port: 4553 } };
|
const nameServer = { nameServer: { ipAddr: "127.0.0.1", port: 4553 } };
|
||||||
|
|
||||||
const [a, aaaa, aname, cname, mx, naptr, ns, ptr, soa, srv, txt] = await Promise
|
const [a, aaaa, aname, caa, cname, mx, naptr, ns, ptr, soa, srv, txt] =
|
||||||
.all([
|
await Promise
|
||||||
Deno.resolveDns("www.example.com", "A", nameServer),
|
.all([
|
||||||
Deno.resolveDns("www.example.com", "AAAA", nameServer),
|
Deno.resolveDns("www.example.com", "A", nameServer),
|
||||||
Deno.resolveDns("www.example.com", "ANAME", nameServer),
|
Deno.resolveDns("www.example.com", "AAAA", nameServer),
|
||||||
Deno.resolveDns("alias.example.com", "CNAME", nameServer),
|
Deno.resolveDns("www.example.com", "ANAME", nameServer),
|
||||||
Deno.resolveDns("example.com", "MX", nameServer),
|
Deno.resolveDns("example.com", "CAA", nameServer),
|
||||||
Deno.resolveDns("example.com", "NAPTR", nameServer),
|
Deno.resolveDns("alias.example.com", "CNAME", nameServer),
|
||||||
Deno.resolveDns("example.com", "NS", nameServer),
|
Deno.resolveDns("example.com", "MX", nameServer),
|
||||||
Deno.resolveDns("1.2.3.4.IN-ADDR.ARPA.", "PTR", nameServer),
|
Deno.resolveDns("example.com", "NAPTR", nameServer),
|
||||||
Deno.resolveDns("example.com", "SOA", nameServer),
|
Deno.resolveDns("example.com", "NS", nameServer),
|
||||||
Deno.resolveDns("_service._tcp.example.com", "SRV", nameServer),
|
Deno.resolveDns("1.2.3.4.IN-ADDR.ARPA.", "PTR", nameServer),
|
||||||
Deno.resolveDns("example.com", "TXT", nameServer),
|
Deno.resolveDns("example.com", "SOA", nameServer),
|
||||||
]);
|
Deno.resolveDns("_service._tcp.example.com", "SRV", nameServer),
|
||||||
|
Deno.resolveDns("example.com", "TXT", nameServer),
|
||||||
|
]);
|
||||||
|
|
||||||
console.log("A");
|
console.log("A");
|
||||||
console.log(JSON.stringify(a));
|
console.log(JSON.stringify(a));
|
||||||
|
@ -24,6 +26,9 @@ console.log(JSON.stringify(aaaa));
|
||||||
console.log("ANAME");
|
console.log("ANAME");
|
||||||
console.log(JSON.stringify(aname));
|
console.log(JSON.stringify(aname));
|
||||||
|
|
||||||
|
console.log("CAA");
|
||||||
|
console.log(JSON.stringify(caa));
|
||||||
|
|
||||||
console.log("CNAME");
|
console.log("CNAME");
|
||||||
console.log(JSON.stringify(cname));
|
console.log(JSON.stringify(cname));
|
||||||
|
|
||||||
|
|
2
cli/tests/testdata/resolve_dns.ts.out
vendored
2
cli/tests/testdata/resolve_dns.ts.out
vendored
|
@ -4,6 +4,8 @@ AAAA
|
||||||
["1:2:3:4:5:6:7:8"]
|
["1:2:3:4:5:6:7:8"]
|
||||||
ANAME
|
ANAME
|
||||||
["aname.example.com."]
|
["aname.example.com."]
|
||||||
|
CAA
|
||||||
|
[{"critical":false,"tag":"issue","value":"ca.example.net"},{"critical":false,"tag":"issue","value":"ca2.example.net; account=123456"},{"critical":false,"tag":"issuewild","value":";"},{"critical":false,"tag":"iodef","value":"mailto:security@example.com"},{"critical":true,"tag":"tbs","value":"Unknown"}]
|
||||||
CNAME
|
CNAME
|
||||||
["cname.example.com."]
|
["cname.example.com."]
|
||||||
MX
|
MX
|
||||||
|
|
5
cli/tests/testdata/resolve_dns.zone.in
vendored
5
cli/tests/testdata/resolve_dns.zone.in
vendored
|
@ -4,6 +4,11 @@
|
||||||
600 ; RETRY
|
600 ; RETRY
|
||||||
3600000; EXPIRE
|
3600000; EXPIRE
|
||||||
60) ; MINIMUM
|
60) ; MINIMUM
|
||||||
|
@ IN CAA 0 issue "ca.example.net"
|
||||||
|
@ IN CAA 0 issue "ca2.example.net; account=123456"
|
||||||
|
@ IN CAA 0 issuewild ";"
|
||||||
|
@ IN CAA 0 iodef "mailto:security@example.com"
|
||||||
|
@ IN CAA 128 tbs "Unknown"
|
||||||
NS ns1.ns.com.
|
NS ns1.ns.com.
|
||||||
NS ns2.ns.com.
|
NS ns2.ns.com.
|
||||||
NS ns3.ns.com.
|
NS ns3.ns.com.
|
||||||
|
|
|
@ -34,6 +34,7 @@ use std::rc::Rc;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
use trust_dns_proto::rr::rdata::caa::Value;
|
||||||
use trust_dns_proto::rr::record_data::RData;
|
use trust_dns_proto::rr::record_data::RData;
|
||||||
use trust_dns_proto::rr::record_type::RecordType;
|
use trust_dns_proto::rr::record_type::RecordType;
|
||||||
use trust_dns_resolver::config::NameServerConfigGroup;
|
use trust_dns_resolver::config::NameServerConfigGroup;
|
||||||
|
@ -574,6 +575,11 @@ pub enum DnsReturnRecord {
|
||||||
A(String),
|
A(String),
|
||||||
Aaaa(String),
|
Aaaa(String),
|
||||||
Aname(String),
|
Aname(String),
|
||||||
|
Caa {
|
||||||
|
critical: bool,
|
||||||
|
tag: String,
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
Cname(String),
|
Cname(String),
|
||||||
Mx {
|
Mx {
|
||||||
preference: u16,
|
preference: u16,
|
||||||
|
@ -740,6 +746,29 @@ fn rdata_to_return_record(
|
||||||
.as_aname()
|
.as_aname()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.map(DnsReturnRecord::Aname),
|
.map(DnsReturnRecord::Aname),
|
||||||
|
CAA => r.as_caa().map(|caa| DnsReturnRecord::Caa {
|
||||||
|
critical: caa.issuer_critical(),
|
||||||
|
tag: caa.tag().to_string(),
|
||||||
|
value: match caa.value() {
|
||||||
|
Value::Issuer(name, key_values) => {
|
||||||
|
let mut s = String::new();
|
||||||
|
|
||||||
|
if let Some(name) = name {
|
||||||
|
s.push_str(&format!("{}", name));
|
||||||
|
} else if name.is_none() && key_values.is_empty() {
|
||||||
|
s.push(';');
|
||||||
|
}
|
||||||
|
|
||||||
|
for key_value in key_values {
|
||||||
|
s.push_str(&format!("; {}", key_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
Value::Url(url) => url.to_string(),
|
||||||
|
Value::Unknown(data) => String::from_utf8(data.to_vec()).unwrap(),
|
||||||
|
},
|
||||||
|
}),
|
||||||
CNAME => r
|
CNAME => r
|
||||||
.as_cname()
|
.as_cname()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
|
@ -803,6 +832,8 @@ mod tests {
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::net::Ipv6Addr;
|
use std::net::Ipv6Addr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use trust_dns_proto::rr::rdata::caa::KeyValue;
|
||||||
|
use trust_dns_proto::rr::rdata::caa::CAA;
|
||||||
use trust_dns_proto::rr::rdata::mx::MX;
|
use trust_dns_proto::rr::rdata::mx::MX;
|
||||||
use trust_dns_proto::rr::rdata::naptr::NAPTR;
|
use trust_dns_proto::rr::rdata::naptr::NAPTR;
|
||||||
use trust_dns_proto::rr::rdata::srv::SRV;
|
use trust_dns_proto::rr::rdata::srv::SRV;
|
||||||
|
@ -835,6 +866,24 @@ mod tests {
|
||||||
assert_eq!(func(&rdata), Some(DnsReturnRecord::Aname("".to_string())));
|
assert_eq!(func(&rdata), Some(DnsReturnRecord::Aname("".to_string())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rdata_to_return_record_caa() {
|
||||||
|
let func = rdata_to_return_record(RecordType::CAA);
|
||||||
|
let rdata = RData::CAA(CAA::new_issue(
|
||||||
|
false,
|
||||||
|
Some(Name::parse("example.com", None).unwrap()),
|
||||||
|
vec![KeyValue::new("account", "123456")],
|
||||||
|
));
|
||||||
|
assert_eq!(
|
||||||
|
func(&rdata),
|
||||||
|
Some(DnsReturnRecord::Caa {
|
||||||
|
critical: false,
|
||||||
|
tag: "issue".to_string(),
|
||||||
|
value: "example.com; account=123456".to_string(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rdata_to_return_record_cname() {
|
fn rdata_to_return_record_cname() {
|
||||||
let func = rdata_to_return_record(RecordType::CNAME);
|
let func = rdata_to_return_record(RecordType::CNAME);
|
||||||
|
|
Loading…
Reference in a new issue