From e3954df8c5f8a5dab7102ebae77dfc217fb9f098 Mon Sep 17 00:00:00 2001
From: Thanapat Chotipun <66824385+PatrickChoDev@users.noreply.github.com>
Date: Wed, 4 May 2022 01:04:20 +0700
Subject: [PATCH] feat(ext/net): add "NS" record support in Deno.resolveDns API
 (#14372)

---
 Cargo.lock                            | 104 +++++++++++++++-----------
 cli/Cargo.toml                        |   4 +-
 cli/dts/lib.deno.ns.d.ts              |   3 +-
 cli/tests/integration/mod.rs          |  14 +++-
 cli/tests/testdata/resolve_dns.ts     |   6 +-
 cli/tests/testdata/resolve_dns.ts.out |   2 +
 ext/net/Cargo.toml                    |   4 +-
 ext/net/ops.rs                        |   9 +++
 8 files changed, 94 insertions(+), 52 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 37bf27edee..6ae97ab6b2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -411,7 +411,7 @@ dependencies = [
  "libc",
  "num-integer",
  "num-traits",
- "time",
+ "time 0.1.44",
  "winapi 0.3.9",
 ]
 
@@ -751,7 +751,7 @@ dependencies = [
  "dprint-plugin-markdown",
  "dprint-plugin-typescript",
  "encoding_rs",
- "env_logger",
+ "env_logger 0.8.4",
  "eszip",
  "fancy-regex",
  "flaky_test",
@@ -1009,7 +1009,7 @@ dependencies = [
  "deno_tls",
  "log",
  "serde",
- "socket2 0.4.4",
+ "socket2",
  "tokio",
  "trust-dns-proto",
  "trust-dns-resolver",
@@ -1372,9 +1372,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
 
 [[package]]
 name = "enum-as-inner"
-version = "0.3.3"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
+checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73"
 dependencies = [
  "heck",
  "proc-macro2 1.0.36",
@@ -1407,6 +1407,19 @@ dependencies = [
  "termcolor",
 ]
 
+[[package]]
+name = "env_logger"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
 [[package]]
 name = "errno"
 version = "0.1.8"
@@ -1854,12 +1867,9 @@ dependencies = [
 
 [[package]]
 name = "heck"
-version = "0.3.3"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
-dependencies = [
- "unicode-segmentation",
-]
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
 
 [[package]]
 name = "hermit-abi"
@@ -1954,7 +1964,7 @@ dependencies = [
  "httpdate",
  "itoa 0.4.8",
  "pin-project-lite",
- "socket2 0.4.4",
+ "socket2",
  "tokio",
  "tower-service",
  "tracing",
@@ -2058,14 +2068,14 @@ dependencies = [
 
 [[package]]
 name = "ipconfig"
-version = "0.2.2"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
+checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98"
 dependencies = [
- "socket2 0.3.19",
+ "socket2",
  "widestring",
  "winapi 0.3.9",
- "winreg 0.6.2",
+ "winreg 0.7.0",
 ]
 
 [[package]]
@@ -2622,6 +2632,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "num_threads"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "objc"
 version = "0.2.7"
@@ -3674,17 +3693,6 @@ version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
 
-[[package]]
-name = "socket2"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
-dependencies = [
- "cfg-if",
- "libc",
- "winapi 0.3.9",
-]
-
 [[package]]
 name = "socket2"
 version = "0.4.4"
@@ -4381,6 +4389,16 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "time"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
+dependencies = [
+ "libc",
+ "num_threads",
+]
+
 [[package]]
 name = "tinyvec"
 version = "1.5.1"
@@ -4411,7 +4429,7 @@ dependencies = [
  "parking_lot 0.12.0",
  "pin-project-lite",
  "signal-hook-registry",
- "socket2 0.4.4",
+ "socket2",
  "tokio-macros",
  "winapi 0.3.9",
 ]
@@ -4596,12 +4614,11 @@ dependencies = [
 
 [[package]]
 name = "trust-dns-client"
-version = "0.20.3"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fea72219106741b56ebab5e58e506beb657e1ed5d568a987141a9659124474f9"
+checksum = "a6d9ba1c6079f6f9b4664e482db1700bd53d2ee77b1c9752c1d7a66c0c8bda99"
 dependencies = [
  "cfg-if",
- "chrono",
  "data-encoding",
  "futures-channel",
  "futures-util",
@@ -4610,15 +4627,16 @@ dependencies = [
  "radix_trie",
  "rand",
  "thiserror",
+ "time 0.3.9",
  "tokio",
  "trust-dns-proto",
 ]
 
 [[package]]
 name = "trust-dns-proto"
-version = "0.20.3"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad0d7f5db438199a6e2609debe3f69f808d074e0a2888ee0bccb45fe234d03f4"
+checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d"
 dependencies = [
  "async-trait",
  "cfg-if",
@@ -4642,9 +4660,9 @@ dependencies = [
 
 [[package]]
 name = "trust-dns-resolver"
-version = "0.20.3"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ad17b608a64bd0735e67bde16b0636f8aa8591f831a25d18443ed00a699770"
+checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558"
 dependencies = [
  "cfg-if",
  "futures-util",
@@ -4652,7 +4670,7 @@ dependencies = [
  "lazy_static",
  "log",
  "lru-cache",
- "parking_lot 0.11.2",
+ "parking_lot 0.12.0",
  "resolv-conf",
  "serde",
  "smallvec",
@@ -4663,21 +4681,21 @@ dependencies = [
 
 [[package]]
 name = "trust-dns-server"
-version = "0.20.3"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a29ad5a3b1d988b4dfc6b428578366c4fabf484aece2b3c3a15cab9c272cc0a"
+checksum = "a395a2e0fd8aac9b4613767a5b4ba4b2040de1b767fa03ace8c9d6f351d60b2d"
 dependencies = [
  "async-trait",
  "bytes",
  "cfg-if",
- "chrono",
  "enum-as-inner",
- "env_logger",
+ "env_logger 0.9.0",
  "futures-executor",
  "futures-util",
  "log",
  "serde",
  "thiserror",
+ "time 0.3.9",
  "tokio",
  "toml",
  "trust-dns-client",
@@ -5153,9 +5171,9 @@ dependencies = [
 
 [[package]]
 name = "widestring"
-version = "0.4.3"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
+checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983"
 
 [[package]]
 name = "winapi"
@@ -5288,9 +5306,9 @@ checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
 
 [[package]]
 name = "winreg"
-version = "0.6.2"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
+checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
 dependencies = [
  "winapi 0.3.9",
 ]
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index c673dd3d39..394ace96ec 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -111,8 +111,8 @@ flaky_test = "=0.1.0"
 os_pipe = "=1.0.1"
 pretty_assertions = "=1.2.0"
 test_util = { path = "../test_util" }
-trust-dns-client = "=0.20.3"
-trust-dns-server = "=0.20.3"
+trust-dns-client = "0.21.2"
+trust-dns-server = "0.21.2"
 
 [target.'cfg(unix)'.dev-dependencies]
 nix = "=0.23.0"
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts
index 2caf05085e..8d7f5f269d 100644
--- a/cli/dts/lib.deno.ns.d.ts
+++ b/cli/dts/lib.deno.ns.d.ts
@@ -2955,6 +2955,7 @@ declare namespace Deno {
     | "ANAME"
     | "CNAME"
     | "MX"
+    | "NS"
     | "PTR"
     | "SRV"
     | "TXT";
@@ -2987,7 +2988,7 @@ declare namespace Deno {
 
   export function resolveDns(
     query: string,
-    recordType: "A" | "AAAA" | "ANAME" | "CNAME" | "PTR",
+    recordType: "A" | "AAAA" | "ANAME" | "CNAME" | "NS" | "PTR",
     options?: ResolveDnsOptions,
   ): Promise<string[]>;
 
diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs
index ffd7e35961..3de33b381f 100644
--- a/cli/tests/integration/mod.rs
+++ b/cli/tests/integration/mod.rs
@@ -817,7 +817,6 @@ async fn test_resolve_dns() {
   use std::net::SocketAddr;
   use std::str::FromStr;
   use std::sync::Arc;
-  use std::sync::RwLock;
   use std::time::Duration;
   use tokio::net::TcpListener;
   use tokio::net::UdpSocket;
@@ -910,6 +909,15 @@ async fn test_resolve_dns() {
           record_set,
         );
 
+        // Inserts NS record
+        let rdata = RData::NS(Name::from_str("ns1.ns.com").unwrap());
+        let record = Record::from_rdata(lookup_name.clone(), u32::MAX, rdata);
+        let record_set = RecordSet::from(record);
+        map.insert(
+          RrKey::new(lookup_name_lower.clone(), RecordType::NS),
+          record_set,
+        );
+
         // Inserts PTR record
         let rdata = RData::PTR(Name::from_str("ptr.com").unwrap());
         let record = Record::from_rdata(
@@ -951,7 +959,7 @@ async fn test_resolve_dns() {
         map
       };
 
-      let authority = Box::new(Arc::new(RwLock::new(
+      let authority = Box::new(Arc::new(
         InMemoryAuthority::new(
           Name::from_str("com").unwrap(),
           records,
@@ -959,7 +967,7 @@ async fn test_resolve_dns() {
           false,
         )
         .unwrap(),
-      )));
+      ));
       let mut c = Catalog::new();
       c.upsert(Name::root().into(), authority);
       c
diff --git a/cli/tests/testdata/resolve_dns.ts b/cli/tests/testdata/resolve_dns.ts
index 1757c938ef..9b43643117 100644
--- a/cli/tests/testdata/resolve_dns.ts
+++ b/cli/tests/testdata/resolve_dns.ts
@@ -1,11 +1,12 @@
 const nameServer = { nameServer: { ipAddr: "127.0.0.1", port: 4553 } };
 
-const [a, aaaa, aname, cname, mx, ptr, srv, txt] = await Promise.all([
+const [a, aaaa, aname, cname, mx, ns, ptr, srv, txt] = await Promise.all([
   Deno.resolveDns("www.example.com", "A", nameServer),
   Deno.resolveDns("www.example.com", "AAAA", nameServer),
   Deno.resolveDns("www.example.com", "ANAME", nameServer),
   Deno.resolveDns("foo", "CNAME", nameServer),
   Deno.resolveDns("www.example.com", "MX", nameServer),
+  Deno.resolveDns("www.example.com", "NS", nameServer),
   Deno.resolveDns("5.6.7.8", "PTR", nameServer),
   Deno.resolveDns("_Service._TCP.example.com", "SRV", nameServer),
   Deno.resolveDns("www.example.com", "TXT", nameServer),
@@ -26,6 +27,9 @@ console.log(JSON.stringify(cname));
 console.log("MX");
 console.log(JSON.stringify(mx));
 
+console.log("NS");
+console.log(JSON.stringify(ns));
+
 console.log("PTR");
 console.log(JSON.stringify(ptr));
 
diff --git a/cli/tests/testdata/resolve_dns.ts.out b/cli/tests/testdata/resolve_dns.ts.out
index 8b378ce71b..2b56d72ae0 100644
--- a/cli/tests/testdata/resolve_dns.ts.out
+++ b/cli/tests/testdata/resolve_dns.ts.out
@@ -8,6 +8,8 @@ CNAME
 ["cname.com."]
 MX
 [{"preference":0,"exchange":"mx.com."}]
+NS
+["ns1.ns.com."]
 PTR
 ["ptr.com."]
 SRV
diff --git a/ext/net/Cargo.toml b/ext/net/Cargo.toml
index f833a22e57..18e3636e33 100644
--- a/ext/net/Cargo.toml
+++ b/ext/net/Cargo.toml
@@ -20,5 +20,5 @@ log = "0.4.14"
 serde = { version = "1.0.129", features = ["derive"] }
 socket2 = "0.4.2"
 tokio = { version = "1.17", features = ["full"] }
-trust-dns-proto = "0.20.3"
-trust-dns-resolver = { version = "0.20.3", features = ["tokio-runtime", "serde-config"] }
+trust-dns-proto = "=0.21.2"
+trust-dns-resolver = { version = "=0.21.2", features = ["tokio-runtime", "serde-config"] }
diff --git a/ext/net/ops.rs b/ext/net/ops.rs
index 0167448ddd..4fef389853 100644
--- a/ext/net/ops.rs
+++ b/ext/net/ops.rs
@@ -579,6 +579,7 @@ pub enum DnsReturnRecord {
     preference: u16,
     exchange: String,
   },
+  Ns(String),
   Ptr(String),
   Srv {
     priority: u16,
@@ -730,6 +731,7 @@ fn rdata_to_return_record(
         preference: mx.preference(),
         exchange: mx.exchange().to_string(),
       }),
+      NS => r.as_ns().map(ToString::to_string).map(DnsReturnRecord::Ns),
       PTR => r
         .as_ptr()
         .map(ToString::to_string)
@@ -817,6 +819,13 @@ mod tests {
     );
   }
 
+  #[test]
+  fn rdata_to_return_record_ns() {
+    let func = rdata_to_return_record(RecordType::NS);
+    let rdata = RData::NS(Name::new());
+    assert_eq!(func(&rdata), Some(DnsReturnRecord::Ns("".to_string())));
+  }
+
   #[test]
   fn rdata_to_return_record_ptr() {
     let func = rdata_to_return_record(RecordType::PTR);