refactor: update to the latest `domain` crate

* It turned out that `domain-core` is now deprecated
This commit is contained in:
Peter Cai 2021-04-04 13:25:39 +08:00
parent 667ec60159
commit 418ce1c64d
5 changed files with 105 additions and 356 deletions

343
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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<Question<ParsedDname>>,
) -> Result<Vec<Record<ParsedDname, AllRecordData<ParsedDname>>>, String> {
questions: Vec<Question<Dname<Vec<u8>>>>,
) -> Result<Vec<Record<Dname<Vec<u8>>, UnknownRecordData<Vec<u8>>>>, 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<Question<ParsedDname>>,
questions: Vec<Question<Dname<Vec<u8>>>>,
retries: usize,
) -> Result<Vec<Record<ParsedDname, AllRecordData<ParsedDname>>>, String> {
) -> Result<Vec<Record<Dname<Vec<u8>>, UnknownRecordData<Vec<u8>>>>, 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<Question<ParsedDname>>) -> Result<Message, String> {
let mut builder = MessageBuilder::new_udp();
fn build_query(questions: Vec<Question<Dname<Vec<u8>>>>) -> Result<Message<Vec<u8>>, 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<Message, String> {
async fn do_query(upstream: &str, msg: Message<Vec<u8>>) -> Result<Message<Vec<u8>>, 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<Vec<Record<ParsedDname, AllRecordData<ParsedDname>>>, String> {
msg: Message<Vec<u8>>,
) -> Result<Vec<Record<Dname<Vec<u8>>, UnknownRecordData<Vec<u8>>>>, 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<Record<ParsedDname, AllRecordData<ParsedDname>>> = Vec::new();
let mut ret: Vec<Record<Dname<Vec<u8>>, UnknownRecordData<Vec<u8>>>> = Vec::new();
for a in answers {
let parsed_record = a.map_err(|_| "Failed to parse DNS answer record".to_string())?;
let record: Record<ParsedDname, AllRecordData<ParsedDname>> = 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<ParsedDname<&Vec<u8>>, 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::<Vec<u8>>()
.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)
}

View File

@ -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<Message, String> {
async fn parse_dns_body(req: &Request) -> Result<Message<Vec<u8>>, 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<Vec<Question<ParsedDname>>, String> {
fn extract_questions(msg: Message<Vec<u8>>) -> Result<Vec<Question<Dname<Vec<u8>>>>, 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<Question<ParsedDname>> = Vec::new();
let mut ret: Vec<Question<Dname<Vec<u8>>>> = 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::<Vec<u8>>()
.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<Record<ParsedDname, AllRecordData<ParsedDname>>>,
) -> Result<Message, String> {
let mut message_builder = MessageBuilder::new_udp();
records: Vec<Record<Dname<Vec<u8>>, UnknownRecordData<Vec<u8>>>>,
) -> Result<Message<Vec<u8>>, 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())
}
}

View File

@ -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<Message, String> {
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<Message<Vec<u8>>, String> {
Message::from_octets(msg.to_owned())
.map_err(|_| "Failed to parse DNS wireformat message".to_string())
}
// Rust wrapper around JS functions