Added DNS-over-HTTPS support for forwarded queries.
This commit is contained in:
Generated
+252
@@ -101,6 +101,7 @@ dependencies = [
|
|||||||
"thread-priority",
|
"thread-priority",
|
||||||
"tinyfiledialogs",
|
"tinyfiledialogs",
|
||||||
"toml",
|
"toml",
|
||||||
|
"ureq",
|
||||||
"uuid",
|
"uuid",
|
||||||
"web-view",
|
"web-view",
|
||||||
"winapi",
|
"winapi",
|
||||||
@@ -183,6 +184,12 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
|
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
@@ -250,6 +257,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chunked_transfer"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cipher"
|
name = "cipher"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@@ -402,6 +415,16 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk-pixbuf-sys"
|
name = "gdk-pixbuf-sys"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -585,6 +608,17 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@@ -600,6 +634,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -621,6 +664,12 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matches"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.7.13"
|
version = "0.7.13"
|
||||||
@@ -692,6 +741,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -726,6 +781,12 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34"
|
checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.1.3"
|
version = "2.1.3"
|
||||||
@@ -868,6 +929,21 @@ dependencies = [
|
|||||||
"rand_core 0.6.2",
|
"rand_core 0.6.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"spin",
|
||||||
|
"untrusted",
|
||||||
|
"web-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@@ -877,12 +953,35 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@@ -996,6 +1095,12 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlite"
|
name = "sqlite"
|
||||||
version = "0.26.0"
|
version = "0.26.0"
|
||||||
@@ -1147,6 +1252,21 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.8"
|
version = "0.5.8"
|
||||||
@@ -1168,6 +1288,21 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
@@ -1196,6 +1331,40 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3131cd6cb18488da91da1d10ed31e966f453c06b65bf010d35638456976a3fd7"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"chunked_transfer",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"rustls",
|
||||||
|
"url",
|
||||||
|
"webpki",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urlencoding"
|
name = "urlencoding"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@@ -1236,6 +1405,70 @@ version = "0.10.2+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-view"
|
name = "web-view"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
@@ -1270,6 +1503,25 @@ dependencies = [
|
|||||||
"soup-sys",
|
"soup-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.21.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
|
||||||
|
dependencies = [
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webview-sys"
|
name = "webview-sys"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ rand-old = { package = "rand", version = "0.7.0" } # For ed25519-dalek
|
|||||||
sqlite = "0.26.0"
|
sqlite = "0.26.0"
|
||||||
uuid = { version = "0.8.2", features = ["serde", "v4"] }
|
uuid = { version = "0.8.2", features = ["serde", "v4"] }
|
||||||
mio = { version = "0.7.13", features = ["os-poll", "net"] }
|
mio = { version = "0.7.13", features = ["os-poll", "net"] }
|
||||||
|
ureq = "2.2"
|
||||||
derive_more = "0.99.16"
|
derive_more = "0.99.16"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -23,9 +23,9 @@ listen = "127.0.0.1:53"
|
|||||||
# How many threads to spawn by DNS server
|
# How many threads to spawn by DNS server
|
||||||
threads = 50
|
threads = 50
|
||||||
# AdGuard DNS servers to filter ads and trackers
|
# AdGuard DNS servers to filter ads and trackers
|
||||||
forwarders = ["94.140.14.14:53", "94.140.15.15:53"]
|
forwarders = ["https://dns.adguard.com/dns-query", "94.140.14.14:53", "94.140.15.15:53"]
|
||||||
# Cloudflare servers
|
# Cloudflare servers
|
||||||
#forwarders = ["1.1.1.1:53", "1.0.0.1:53"]
|
#forwarders = ["https://cloudflare-dns.com/dns-query", "1.1.1.1:53", "1.0.0.1:53"]
|
||||||
|
|
||||||
# Hosts file support (resolve local names or block ads)
|
# Hosts file support (resolve local names or block ads)
|
||||||
#hosts = ["system", "adblock.txt"]
|
#hosts = ["system", "adblock.txt"]
|
||||||
|
|||||||
+96
-4
@@ -1,6 +1,6 @@
|
|||||||
//! client for sending DNS queries to other servers
|
//! client for sending DNS queries to other servers
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::{Write, Read};
|
||||||
use std::marker::{Send, Sync};
|
use std::marker::{Send, Sync};
|
||||||
use std::net::{SocketAddr, TcpStream, ToSocketAddrs, UdpSocket};
|
use std::net::{SocketAddr, TcpStream, ToSocketAddrs, UdpSocket};
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
@@ -12,7 +12,10 @@ use std::time::Duration as SleepDuration;
|
|||||||
use chrono::*;
|
use chrono::*;
|
||||||
use derive_more::{Display, Error, From};
|
use derive_more::{Display, Error, From};
|
||||||
|
|
||||||
use crate::dns::buffer::{BytePacketBuffer, PacketBuffer, StreamPacketBuffer};
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use crate::dns::buffer::{BytePacketBuffer, PacketBuffer, StreamPacketBuffer, VectorPacketBuffer};
|
||||||
use crate::dns::netutil::{read_packet_length, write_packet_length};
|
use crate::dns::netutil::{read_packet_length, write_packet_length};
|
||||||
use crate::dns::protocol::{DnsPacket, DnsQuestion, QueryType};
|
use crate::dns::protocol::{DnsPacket, DnsQuestion, QueryType};
|
||||||
|
|
||||||
@@ -38,7 +41,7 @@ pub trait DnsClient {
|
|||||||
/// The UDP client
|
/// The UDP client
|
||||||
///
|
///
|
||||||
/// This includes a fair bit of synchronization due to the stateless nature of UDP.
|
/// This includes a fair bit of synchronization due to the stateless nature of UDP.
|
||||||
/// When many queries are sent in parallell, the response packets can come back
|
/// When many queries are sent in parallel, the response packets can come back
|
||||||
/// in any order. For that reason, we fire off replies on the sending thread, but
|
/// in any order. For that reason, we fire off replies on the sending thread, but
|
||||||
/// handle replies on a single thread. A channel is created for every response,
|
/// handle replies on a single thread. A channel is created for every response,
|
||||||
/// and the caller will block on the channel until the a response is received.
|
/// and the caller will block on the channel until the a response is received.
|
||||||
@@ -337,11 +340,100 @@ impl DnsClient for DnsNetworkClient {
|
|||||||
return Ok(packet);
|
return Ok(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Truncated response - resending as TCP");
|
info!("Truncated response - resending as TCP");
|
||||||
self.send_tcp_query(qname, qtype, server, recursive)
|
self.send_tcp_query(qname, qtype, server, recursive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct HttpsDnsClient {
|
||||||
|
agent: ureq::Agent,
|
||||||
|
/// Counter for assigning packet ids
|
||||||
|
seq: AtomicUsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HttpsDnsClient {
|
||||||
|
pub(crate) fn new() -> Self {
|
||||||
|
let client_name = format!("ALFIS/{}", env!("CARGO_PKG_VERSION"));
|
||||||
|
let agent = ureq::AgentBuilder::new()
|
||||||
|
.user_agent(&client_name)
|
||||||
|
.timeout(std::time::Duration::from_secs(3))
|
||||||
|
.build();
|
||||||
|
Self { agent, seq: AtomicUsize::new(1) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DnsClient for HttpsDnsClient {
|
||||||
|
fn get_sent_count(&self) -> usize {
|
||||||
|
// No statistics for now
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_failed_count(&self) -> usize {
|
||||||
|
// No statistics for now
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self) -> Result<()> {
|
||||||
|
debug!("Started DoH client");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_query(&self, qname: &str, qtype: QueryType, doh_url: &str, recursive: bool) -> Result<DnsPacket> {
|
||||||
|
// Create DnsPacket
|
||||||
|
let mut packet = DnsPacket::new();
|
||||||
|
packet.header.id = self.seq.fetch_add(1, Ordering::SeqCst) as u16;
|
||||||
|
if packet.header.id + 1 == 0xFFFF {
|
||||||
|
let _ = self.seq.compare_exchange(0xFFFF, 0, Ordering::SeqCst, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.header.questions = 1;
|
||||||
|
packet.header.recursion_desired = recursive;
|
||||||
|
packet.questions.push(DnsQuestion::new(String::from(qname), qtype));
|
||||||
|
|
||||||
|
let mut req_buffer = VectorPacketBuffer::new();
|
||||||
|
packet.write(&mut req_buffer, 512).expect("Preparing DnsPacket failed!");
|
||||||
|
|
||||||
|
let response = self.agent
|
||||||
|
.post(doh_url)
|
||||||
|
.set("Content-Type", "application/dns-message")
|
||||||
|
.send_bytes(&req_buffer.buffer.as_slice());
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(response) => {
|
||||||
|
trace!("Response: Code {}, Type: {}, Headers: {:?}", response.status(), response.content_type(), response.headers_names());
|
||||||
|
match response.status() {
|
||||||
|
200 => {
|
||||||
|
match response.header("Content-Length") {
|
||||||
|
None => warn!("No 'Content-Length' header in DoH response!"),
|
||||||
|
Some(str) => {
|
||||||
|
match str.parse::<usize>() {
|
||||||
|
Ok(size) => {
|
||||||
|
let mut bytes: Vec<u8> = Vec::with_capacity(size);
|
||||||
|
response.into_reader()
|
||||||
|
.take(4096)
|
||||||
|
.read_to_end(&mut bytes)?;
|
||||||
|
let mut buffer = VectorPacketBuffer::new();
|
||||||
|
buffer.buffer.extend_from_slice(&bytes.as_slice());
|
||||||
|
if let Ok(packet) = DnsPacket::from_buffer(&mut buffer) {
|
||||||
|
trace!("Packet parsed successfully: {:?}", &packet);
|
||||||
|
return Ok(packet);
|
||||||
|
}
|
||||||
|
warn!("Error parsing DoH result!");
|
||||||
|
}
|
||||||
|
Err(e) => warn!("Error parsing 'Content-Length' in DoH response! {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => warn!("Error getting DoH response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => warn!("DoH error: {}", &e.to_string())
|
||||||
|
}
|
||||||
|
Err(ClientError::LookupFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+10
-5
@@ -7,7 +7,7 @@ use derive_more::{Display, Error, From};
|
|||||||
|
|
||||||
use crate::dns::authority::Authority;
|
use crate::dns::authority::Authority;
|
||||||
use crate::dns::cache::SynchronizedCache;
|
use crate::dns::cache::SynchronizedCache;
|
||||||
use crate::dns::client::{DnsClient, DnsNetworkClient};
|
use crate::dns::client::{DnsClient, DnsNetworkClient, HttpsDnsClient};
|
||||||
use crate::dns::filter::DnsFilter;
|
use crate::dns::filter::DnsFilter;
|
||||||
use crate::dns::resolve::{DnsResolver, ForwardingDnsResolver, RecursiveDnsResolver};
|
use crate::dns::resolve::{DnsResolver, ForwardingDnsResolver, RecursiveDnsResolver};
|
||||||
|
|
||||||
@@ -44,7 +44,8 @@ pub struct ServerContext {
|
|||||||
pub authority: Authority,
|
pub authority: Authority,
|
||||||
pub cache: SynchronizedCache,
|
pub cache: SynchronizedCache,
|
||||||
pub filters: Vec<Box<dyn DnsFilter + Sync + Send>>,
|
pub filters: Vec<Box<dyn DnsFilter + Sync + Send>>,
|
||||||
pub client: Box<dyn DnsClient + Sync + Send>,
|
pub old_client: Box<dyn DnsClient + Sync + Send>,
|
||||||
|
pub doh_client: Box<dyn DnsClient + Sync + Send>,
|
||||||
pub dns_listen: String,
|
pub dns_listen: String,
|
||||||
pub api_port: u16,
|
pub api_port: u16,
|
||||||
pub resolve_strategy: ResolveStrategy,
|
pub resolve_strategy: ResolveStrategy,
|
||||||
@@ -68,7 +69,8 @@ impl ServerContext {
|
|||||||
authority: Authority::new(),
|
authority: Authority::new(),
|
||||||
cache: SynchronizedCache::new(),
|
cache: SynchronizedCache::new(),
|
||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
client: Box::new(DnsNetworkClient::new(10000 + (rand::random::<u16>() % 20000))),
|
old_client: Box::new(DnsNetworkClient::new(10000 + (rand::random::<u16>() % 20000))),
|
||||||
|
doh_client: Box::new(HttpsDnsClient::new()),
|
||||||
dns_listen: String::from("0.0.0.0:53"),
|
dns_listen: String::from("0.0.0.0:53"),
|
||||||
api_port: 5380,
|
api_port: 5380,
|
||||||
resolve_strategy: ResolveStrategy::Recursive,
|
resolve_strategy: ResolveStrategy::Recursive,
|
||||||
@@ -83,7 +85,9 @@ impl ServerContext {
|
|||||||
|
|
||||||
pub fn initialize(&mut self) -> Result<()> {
|
pub fn initialize(&mut self) -> Result<()> {
|
||||||
// Start UDP client thread
|
// Start UDP client thread
|
||||||
self.client.run()?;
|
self.old_client.run()?;
|
||||||
|
// Start DoH client
|
||||||
|
self.doh_client.run()?;
|
||||||
|
|
||||||
// Load authority data
|
// Load authority data
|
||||||
self.authority.load()?;
|
self.authority.load()?;
|
||||||
@@ -117,7 +121,8 @@ pub mod tests {
|
|||||||
authority: Authority::new(),
|
authority: Authority::new(),
|
||||||
cache: SynchronizedCache::new(),
|
cache: SynchronizedCache::new(),
|
||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
client: Box::new(DnsStubClient::new(callback)),
|
old_client: Box::new(DnsStubClient::new(callback)),
|
||||||
|
doh_client: Box::new(HttpsDnsClient::new()),
|
||||||
dns_listen: String::from("0.0.0.0:53"),
|
dns_listen: String::from("0.0.0.0:53"),
|
||||||
api_port: 5380,
|
api_port: 5380,
|
||||||
resolve_strategy: ResolveStrategy::Recursive,
|
resolve_strategy: ResolveStrategy::Recursive,
|
||||||
|
|||||||
+12
-2
@@ -87,7 +87,13 @@ impl DnsResolver for ForwardingDnsResolver {
|
|||||||
let mut random = rand::thread_rng();
|
let mut random = rand::thread_rng();
|
||||||
let upstream = self.upstreams.iter().choose(&mut random).unwrap();
|
let upstream = self.upstreams.iter().choose(&mut random).unwrap();
|
||||||
let result = match self.context.cache.lookup(qname, qtype) {
|
let result = match self.context.cache.lookup(qname, qtype) {
|
||||||
None => self.context.client.send_query(qname, qtype, upstream, true)?,
|
None => {
|
||||||
|
if is_url(upstream) {
|
||||||
|
self.context.doh_client.send_query(qname, qtype, upstream, true)?
|
||||||
|
} else {
|
||||||
|
self.context.old_client.send_query(qname, qtype, upstream, true)?
|
||||||
|
}
|
||||||
|
},
|
||||||
Some(packet) => packet
|
Some(packet) => packet
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,7 +156,7 @@ impl DnsResolver for RecursiveDnsResolver {
|
|||||||
let ns_copy = ns.clone();
|
let ns_copy = ns.clone();
|
||||||
|
|
||||||
let server = format!("{}:{}", ns_copy.as_str(), 53);
|
let server = format!("{}:{}", ns_copy.as_str(), 53);
|
||||||
let response = self.context.client.send_query(qname, qtype.clone(), &server, false)?;
|
let response = self.context.old_client.send_query(qname, qtype.clone(), &server, false)?;
|
||||||
|
|
||||||
// If we've got an actual answer, we're done!
|
// If we've got an actual answer, we're done!
|
||||||
if !response.answers.is_empty() && response.header.rescode == ResultCode::NOERROR {
|
if !response.answers.is_empty() && response.header.rescode == ResultCode::NOERROR {
|
||||||
@@ -198,6 +204,10 @@ impl DnsResolver for RecursiveDnsResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_url(url: &str) -> bool {
|
||||||
|
url.starts_with("https://")
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user