From 418ce1c64ddb147b542cc06bf7744da688264d9d Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sun, 4 Apr 2021 13:25:39 +0800 Subject: [PATCH] refactor: update to the latest `domain` crate * It turned out that `domain-core` is now deprecated --- Cargo.lock | 343 +++++--------------------------------------------- Cargo.toml | 6 +- src/client.rs | 65 ++++++---- src/server.rs | 38 +++--- src/util.rs | 9 +- 5 files changed, 105 insertions(+), 356 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6450fd..744d56d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "async_static" version = "0.1.3" @@ -28,66 +13,18 @@ dependencies = [ "syn", ] -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "backtrace" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - [[package]] name = "bumpalo" version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - [[package]] name = "cfg-if" version = "0.1.10" @@ -100,28 +37,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "console_error_panic_hook" version = "0.1.6" @@ -133,60 +48,25 @@ dependencies = [ ] [[package]] -name = "domain-core" -version = "0.4.0" +name = "domain" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f471390427d7c776fc89f60816b603efe679816d1140fd8f017cada2184043b" +checksum = "2eb073186f6285f852b9e71b544111306ab08da4a6b40c25a73f4c9ee3e3df29" dependencies = [ - "bytes", - "chrono", - "failure", - "failure_derive", "rand", - "void", ] [[package]] -name = "failure" -version = "0.1.8" +name = "getrandom" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "gimli" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ + "cfg-if 1.0.0", + "js-sys", "libc", + "wasi", + "wasm-bindgen", ] [[package]] @@ -225,47 +105,18 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg 1.0.1", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "object" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" - [[package]] name = "once_cell" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -286,125 +137,44 @@ dependencies = [ [[package]] name = "rand" -version = "0.6.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ - "autocfg 0.1.7", "libc", "rand_chacha", - "rand_core 0.4.2", + "rand_core", "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", ] [[package]] name = "rand_chacha" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", + "ppv-lite86", + "rand_core", ] [[package]] name = "rand_core" -version = "0.3.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" dependencies = [ - "rand_core 0.4.2", + "getrandom", ] -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_hc" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" dependencies = [ - "rand_core 0.3.1", + "rand_core", ] -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" - [[package]] name = "ryu" version = "1.0.5" @@ -453,41 +223,12 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "synstructure" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi", - "winapi", -] - [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -570,38 +311,16 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "workerns" version = "0.1.0" dependencies = [ "async_static", "base64", - "bytes", "cfg-if 1.0.0", "console_error_panic_hook", - "domain-core", + "domain", + "getrandom", "js-sys", "once_cell", "serde", diff --git a/Cargo.toml b/Cargo.toml index e21b576..7a209ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,12 @@ target = "wasm32-unknown-unknown" [dependencies] async_static = "0.1" base64 = "0.13" -bytes = "0.4" cfg-if = "1.0" console_error_panic_hook = { version = "0.1.6", optional = true } -domain-core = "0.4" +domain = "0.6" +# domain uses rand, which in turn uses getrandom +# we need to enable the `js` feature for it to build on WASM +getrandom = { version = "0.2", features = [ "js" ] } js-sys = "0.3" # Required by async_static once_cell = "1" diff --git a/src/client.rs b/src/client.rs index f96a4d1..a2bd06e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,10 +1,10 @@ -use domain_core::bits::message::Message; -use domain_core::bits::message_builder::MessageBuilder; -use domain_core::bits::question::Question; -use domain_core::bits::record::Record; -use domain_core::bits::{ParsedDname, SectionBuilder}; -use domain_core::iana::{Opcode, Rcode}; -use domain_core::rdata::AllRecordData; +use domain::base::iana::{Opcode, Rcode}; +use domain::base::message::Message; +use domain::base::message_builder::MessageBuilder; +use domain::base::question::Question; +use domain::base::rdata::UnknownRecordData; +use domain::base::record::Record; +use domain::base::{Dname, ParsedDname, ToDname}; use js_sys::{ArrayBuffer, Uint8Array}; use wasm_bindgen_futures::JsFuture; use web_sys::{Headers, Request, RequestInit, Response}; @@ -25,8 +25,8 @@ impl Client { pub async fn query( &self, - questions: Vec>, - ) -> Result>>, String> { + questions: Vec>>>, + ) -> Result>, UnknownRecordData>>>, String> { let msg = Self::build_query(questions)?; let upstream = self.select_upstream(); let resp = Self::do_query(&upstream, msg).await?; @@ -34,15 +34,15 @@ impl Client { match resp.header().rcode() { Rcode::NoError => Self::extract_answers(resp), Rcode::NXDomain => Ok(Vec::new()), - rcode => Err(format!("Server error: {}", rcode)) + rcode => Err(format!("Server error: {}", rcode)), } } pub async fn query_with_retry( &self, - questions: Vec>, + questions: Vec>>>, retries: usize, - ) -> Result>>, String> { + ) -> Result>, UnknownRecordData>>>, String> { let mut last_res = Err("Dummy".to_string()); for _ in 0..retries { last_res = self.query(questions.clone()).await; @@ -62,24 +62,26 @@ impl Client { // Build UDP wireformat query from a list of questions // We don't use the client's query directly because we want to validate // it first, and we also want to be able to do caching and overriding - fn build_query(questions: Vec>) -> Result { - let mut builder = MessageBuilder::new_udp(); + fn build_query(questions: Vec>>>) -> Result>, String> { + let mut builder = MessageBuilder::new_vec(); // Set up the header let header = builder.header_mut(); header.set_id(crate::util::random_range(0, u16::MAX)); header.set_qr(false); // For queries, QR = false header.set_opcode(Opcode::Query); header.set_rd(true); // Ask for recursive queries - // Set up the questions + + // Set up the questions + let mut question_builder = builder.question(); for q in questions { - builder + question_builder .push(q) .map_err(|_| "Size limit exceeded".to_string())?; } - Ok(builder.freeze()) + Ok(question_builder.into_message()) } - async fn do_query(upstream: &str, msg: Message) -> Result { + async fn do_query(upstream: &str, msg: Message>) -> Result>, String> { let body = Uint8Array::from(msg.as_slice()); let headers = Headers::new().map_err(|_| "Could not create headers".to_string())?; headers @@ -118,8 +120,8 @@ impl Client { } fn extract_answers( - msg: Message, - ) -> Result>>, String> { + msg: Message>, + ) -> Result>, UnknownRecordData>>>, String> { let answer_section = msg .answer() .map_err(|_| "Failed to parse DNS answer from upstream".to_string())?; @@ -128,14 +130,31 @@ impl Client { // this is different from the server impl let answers: Vec<_> = answer_section.collect(); - let mut ret: Vec>> = Vec::new(); + let mut ret: Vec>, UnknownRecordData>>> = Vec::new(); for a in answers { let parsed_record = a.map_err(|_| "Failed to parse DNS answer record".to_string())?; - let record: Record> = parsed_record + // Use UnknownRecordData here because we don't really care about the actual type of the record + // It saves time and saves sanity (because of the type signature of AllRecordData) + let record: Record>, UnknownRecordData<&[u8]>> = parsed_record .to_record() .map_err(|_| "Cannot parse record".to_string())? .ok_or("Cannot parse record".to_string())?; - ret.push(record); + // Convert everything to owned for sanity in type signature... + // We'll need to do a copy before returning outside of the main + // query function anyway + let owned_record = Record::new( + record + .owner() + .to_dname::>() + .map_err(|_| "Failed to parse Dname".to_string())?, + record.class(), + record.ttl(), + UnknownRecordData::from_octets( + record.data().rtype(), + record.data().data().to_vec(), + ), + ); + ret.push(owned_record); } Ok(ret) } diff --git a/src/server.rs b/src/server.rs index d8dbd5f..953365b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,11 +1,11 @@ use crate::client::*; use async_static::async_static; -use domain_core::bits::message::Message; -use domain_core::bits::message_builder::MessageBuilder; -use domain_core::bits::question::Question; -use domain_core::bits::record::Record; -use domain_core::bits::{ParsedDname, RecordSectionBuilder, SectionBuilder}; -use domain_core::rdata::AllRecordData; +use domain::base::message::Message; +use domain::base::message_builder::MessageBuilder; +use domain::base::question::Question; +use domain::base::rdata::UnknownRecordData; +use domain::base::record::Record; +use domain::base::{Dname, ToDname}; use js_sys::{ArrayBuffer, Uint8Array}; use serde::Deserialize; use std::borrow::Borrow; @@ -101,7 +101,7 @@ impl Server { return Response::new_with_opt_u8_array_and_init(Some(&mut resp_body), &resp_init).unwrap(); } - async fn parse_dns_body(req: &Request) -> Result { + async fn parse_dns_body(req: &Request) -> Result>, String> { let method = req.method(); if method == "GET" { // GET request -- DNS wireformat or JSON @@ -139,7 +139,7 @@ impl Server { } } - fn extract_questions(msg: Message) -> Result>, String> { + fn extract_questions(msg: Message>) -> Result>>>, String> { // Validate the header first let header = msg.header(); if header.qr() { @@ -155,9 +155,19 @@ impl Server { return Err("No question provided".to_string()); } - let mut ret: Vec> = Vec::new(); + let mut ret: Vec>>> = Vec::new(); for q in questions { - ret.push(q.map_err(|_| "Failed to parse domain name".to_string())?) + let parsed_question = q.map_err(|_| "Failed to parse domain name".to_string())?; + // Convert everything to owned for sanity... + let owned_question = Question::new( + parsed_question + .qname() + .to_dname::>() + .map_err(|_| "Cannot parse Dname".to_string())?, + parsed_question.qtype(), + parsed_question.qclass(), + ); + ret.push(owned_question) } Ok(ret) } @@ -177,9 +187,9 @@ impl Server { fn build_answer_wireformat( id: u16, - records: Vec>>, - ) -> Result { - let mut message_builder = MessageBuilder::new_udp(); + records: Vec>, UnknownRecordData>>>, + ) -> Result>, String> { + let mut message_builder = MessageBuilder::new_vec(); // Set up the response header let header = message_builder.header_mut(); header.set_id(id); @@ -194,6 +204,6 @@ impl Server { .push(r) .map_err(|_| "Max answer size exceeded".to_string())?; } - Ok(answer_builder.freeze()) + Ok(answer_builder.into_message()) } } diff --git a/src/util.rs b/src/util.rs index cf1cd5e..1c8bbf3 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,4 @@ -use bytes::Bytes; -use domain_core::bits::message::Message; +use domain::base::message::Message; use js_sys::{Math, Promise}; use std::ops::Add; use wasm_bindgen::prelude::*; @@ -16,9 +15,9 @@ extern "C" { fn fetch(req: &Request) -> Promise; } -pub fn parse_dns_wireformat(msg: &[u8]) -> Result { - let bytes = Bytes::from(msg); - Message::from_bytes(bytes).map_err(|_| "Failed to parse DNS wireformat message".to_string()) +pub fn parse_dns_wireformat(msg: &[u8]) -> Result>, String> { + Message::from_octets(msg.to_owned()) + .map_err(|_| "Failed to parse DNS wireformat message".to_string()) } // Rust wrapper around JS functions