add -w option and timeout config
This commit is contained in:
170
Cargo.lock
generated
170
Cargo.lock
generated
@@ -27,15 +27,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-std"
|
name = "async-macros"
|
||||||
version = "0.99.4"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-std"
|
||||||
|
version = "0.99.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"async-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -133,6 +146,28 @@ dependencies = [
|
|||||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.6.6"
|
version = "0.6.6"
|
||||||
@@ -201,75 +236,32 @@ name = "fuchsia-zircon-sys"
|
|||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-channel-preview"
|
|
||||||
version = "0.3.0-alpha.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core-preview"
|
name = "futures-core-preview"
|
||||||
version = "0.3.0-alpha.18"
|
version = "0.3.0-alpha.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-executor-preview"
|
|
||||||
version = "0.3.0-alpha.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io-preview"
|
name = "futures-io-preview"
|
||||||
version = "0.3.0-alpha.18"
|
version = "0.3.0-alpha.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-preview"
|
|
||||||
version = "0.3.0-alpha.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-sink-preview"
|
|
||||||
version = "0.3.0-alpha.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-timer"
|
name = "futures-timer"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util-preview"
|
name = "futures-util-preview"
|
||||||
version = "0.3.0-alpha.18"
|
version = "0.3.0-alpha.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -292,6 +284,14 @@ dependencies = [
|
|||||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kv-log-macro"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -315,6 +315,14 @@ name = "memchr"
|
|||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.19"
|
version = "0.6.19"
|
||||||
@@ -478,6 +486,32 @@ name = "rustc-demangle"
|
|||||||
version = "0.1.16"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@@ -529,13 +563,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "updns"
|
name = "updns"
|
||||||
version = "0.0.4"
|
version = "0.0.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ace 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ace 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"async-std 0.99.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"async-std 0.99.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -583,7 +616,8 @@ dependencies = [
|
|||||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||||
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
|
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
|
||||||
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
|
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
|
||||||
"checksum async-std 0.99.4 (registry+https://github.com/rust-lang/crates.io-index)" = "95dbe66a9f8c59a70277214f98d39f25fe1f36f20f6e8412a8b33af0272a2c79"
|
"checksum async-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e421d59b24c1feea2496e409b3e0a8de23e5fc130a2ddc0b012e551f3b272bba"
|
||||||
|
"checksum async-std 0.99.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e274b0689dffa49d9c128a7bd1a86707b6bc8ea319af0899caae654e221656f4"
|
||||||
"checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced"
|
"checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced"
|
||||||
"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
|
"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
|
||||||
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
|
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
|
||||||
@@ -596,6 +630,8 @@ dependencies = [
|
|||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
|
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
|
||||||
"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
|
"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
|
||||||
|
"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
|
||||||
|
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
|
||||||
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
||||||
"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
|
"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
|
||||||
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
|
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
|
||||||
@@ -604,20 +640,18 @@ dependencies = [
|
|||||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
"checksum futures-channel-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "f477fd0292c4a4ae77044454e7f2b413207942ad405f759bb0b4698b7ace5b12"
|
"checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a"
|
||||||
"checksum futures-core-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2f26f774b81b3847dcda0c81bd4b6313acfb4f69e5a0390c7cb12c058953e9"
|
"checksum futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f4914ae450db1921a56c91bde97a27846287d062087d4a652efc09bb3a01ebda"
|
||||||
"checksum futures-executor-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "80705612926df8a1bc05f0057e77460e29318801f988bf7d803a734cf54e7528"
|
"checksum futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33"
|
||||||
"checksum futures-io-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7de0c1c9ed23f9457b0437fec7663ce64d9cc3c906597e714e529377b5ddd1"
|
"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
|
||||||
"checksum futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "efa8f90c4fb2328e381f8adfd4255b4a2b696f77d1c63a3dee6700b564c4e4b5"
|
|
||||||
"checksum futures-sink-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9b65a2481863d1b78e094a07e9c0eed458cc7dc6e72b22b7138b8a67d924859"
|
|
||||||
"checksum futures-timer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f9eb554aa23143abc64ec4d0016f038caf53bb7cbc3d91490835c54edc96550"
|
|
||||||
"checksum futures-util-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)" = "7df53daff1e98cc024bf2720f3ceb0414d96fbb0a94f3cad3a5c3bf3be1d261c"
|
|
||||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
|
"checksum kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb"
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
|
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
|
||||||
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
||||||
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
||||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
@@ -637,6 +671,10 @@ dependencies = [
|
|||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
|
"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
|
||||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||||
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "updns"
|
name = "updns"
|
||||||
version = "0.0.4"
|
version = "0.0.5"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
authors = ["wyhaya <wyhaya@gmail.com>"]
|
authors = ["wyhaya <wyhaya@gmail.com>"]
|
||||||
@@ -19,9 +19,8 @@ keywords = [
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ace = "0.0.2"
|
ace = "0.0.2"
|
||||||
async-std = "0.99.4"
|
async-std = "0.99.9"
|
||||||
dirs = "2.0.2"
|
dirs = "2.0.2"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = {version = "0.4.8", features = ["release_max_level_info"]}
|
|
||||||
regex = "1.3.1"
|
regex = "1.3.1"
|
||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
@@ -61,6 +61,7 @@ Command:
|
|||||||
|
|
||||||
Option:
|
Option:
|
||||||
-c Specify a config file
|
-c Specify a config file
|
||||||
|
-w Check the interval of the configuration file
|
||||||
```
|
```
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
@@ -73,10 +74,12 @@ You can update the config file at any time, updns will listen for file changes
|
|||||||
```ini
|
```ini
|
||||||
bind 0.0.0.0:53 # Binding address
|
bind 0.0.0.0:53 # Binding address
|
||||||
proxy 8.8.8.8:53 # Proxy address
|
proxy 8.8.8.8:53 # Proxy address
|
||||||
|
timeout 2000 # Proxy timeout (ms)
|
||||||
|
|
||||||
# Domain matching
|
# Domain matching
|
||||||
google.com 1.1.1.1
|
google.com 1.1.1.1
|
||||||
^(\w+.)?go+gle.com$ 2.2.2.2
|
^\w+.bing.com$ 2.2.2.2
|
||||||
|
github.com ::
|
||||||
|
|
||||||
# Import from other file
|
# Import from other file
|
||||||
import /other/hosts
|
import /other/hosts
|
||||||
|
|||||||
144
src/config.rs
144
src/config.rs
@@ -11,6 +11,7 @@ lazy_static! {
|
|||||||
static ref REG_IGNORE: Regex = Regex::new(r#"^\s*(#.*)?$"#).unwrap();
|
static ref REG_IGNORE: Regex = Regex::new(r#"^\s*(#.*)?$"#).unwrap();
|
||||||
static ref REG_BIND: Regex = Regex::new(r#"^\s*bind\s+(?P<val>[^\s#]+)"#).unwrap();
|
static ref REG_BIND: Regex = Regex::new(r#"^\s*bind\s+(?P<val>[^\s#]+)"#).unwrap();
|
||||||
static ref REG_PROXY: Regex = Regex::new(r#"^\s*proxy\s+(?P<val>[^\s#]+)"#).unwrap();
|
static ref REG_PROXY: Regex = Regex::new(r#"^\s*proxy\s+(?P<val>[^\s#]+)"#).unwrap();
|
||||||
|
static ref REG_TIMEOUT: Regex = Regex::new(r#"^\s*timeout\s+(?P<val>[^\s#]+)"#).unwrap();
|
||||||
// todo
|
// todo
|
||||||
// The path will also contain '#' and ' '
|
// The path will also contain '#' and ' '
|
||||||
static ref REG_IMPORT: Regex = Regex::new(r#"^\s*import\s+(?P<val>(.*))$"#).unwrap();
|
static ref REG_IMPORT: Regex = Regex::new(r#"^\s*import\s+(?P<val>(.*))$"#).unwrap();
|
||||||
@@ -67,18 +68,11 @@ fn cap_ip_addr(text: &str) -> Option<Result<(Regex, IpAddr), InvalidType>> {
|
|||||||
return Some(Ok((reg, ip)));
|
return Some(Ok((reg, ip)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Config {
|
|
||||||
path: PathBuf,
|
|
||||||
file: File,
|
|
||||||
content: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Invalid {
|
pub struct Invalid {
|
||||||
pub line: usize,
|
pub line: usize,
|
||||||
pub source: String,
|
pub source: String,
|
||||||
pub err: InvalidType,
|
pub kind: InvalidType,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -86,9 +80,37 @@ pub enum InvalidType {
|
|||||||
Regex,
|
Regex,
|
||||||
SocketAddr,
|
SocketAddr,
|
||||||
IpAddr,
|
IpAddr,
|
||||||
|
Timeout,
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InvalidType {
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
InvalidType::SocketAddr => "Cannot parse socket addr",
|
||||||
|
InvalidType::IpAddr => "Cannot parse ip addr",
|
||||||
|
InvalidType::Regex => "Cannot parse Regular expression",
|
||||||
|
InvalidType::Timeout => "Cannot parse timeout",
|
||||||
|
InvalidType::Other => "Invalid line",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ParseConfig {
|
||||||
|
pub bind: Vec<SocketAddr>,
|
||||||
|
pub proxy: Vec<SocketAddr>,
|
||||||
|
pub hosts: Hosts,
|
||||||
|
pub timeout: Option<u64>,
|
||||||
|
pub invalid: Vec<Invalid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Config {
|
||||||
|
path: PathBuf,
|
||||||
|
file: File,
|
||||||
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Config> {
|
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Config> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
@@ -96,37 +118,39 @@ impl Config {
|
|||||||
if let Some(dir) = path.parent() {
|
if let Some(dir) = path.parent() {
|
||||||
fs::create_dir_all(dir)?;
|
fs::create_dir_all(dir)?;
|
||||||
}
|
}
|
||||||
let mut file = fs::OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open(path)?;
|
|
||||||
|
|
||||||
let mut content = String::new();
|
|
||||||
file.read_to_string(&mut content)?;
|
|
||||||
|
|
||||||
Ok(Config {
|
Ok(Config {
|
||||||
file,
|
file: fs::OpenOptions::new()
|
||||||
content,
|
.read(true)
|
||||||
|
.append(true)
|
||||||
|
.create(true)
|
||||||
|
.open(path)?,
|
||||||
path: path.to_path_buf(),
|
path: path.to_path_buf(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, domain: &str, ip: &str) -> std::io::Result<()> {
|
fn read_to_string(&mut self) -> io::Result<String> {
|
||||||
if self.content.ends_with("\n") {
|
let mut content = String::new();
|
||||||
|
self.file.read_to_string(&mut content)?;
|
||||||
|
Ok(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, domain: &str, ip: &str) -> io::Result<()> {
|
||||||
|
if self.read_to_string()?.ends_with("\n") {
|
||||||
writeln!(self.file, "{} {}", domain, ip)
|
writeln!(self.file, "{} {}", domain, ip)
|
||||||
} else {
|
} else {
|
||||||
writeln!(self.file, "\n{} {}", domain, ip)
|
writeln!(self.file, "\n{} {}", domain, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&mut self) -> io::Result<(Vec<SocketAddr>, Vec<SocketAddr>, Hosts, Vec<Invalid>)> {
|
pub fn parse(&mut self) -> io::Result<ParseConfig> {
|
||||||
let mut hosts = Hosts::new();
|
let mut hosts = Hosts::new();
|
||||||
let mut binds = Vec::new();
|
let mut bind = Vec::new();
|
||||||
let mut proxy = Vec::new();
|
let mut proxy = Vec::new();
|
||||||
let mut errors = Vec::new();
|
let mut invalid = Vec::new();
|
||||||
|
let mut timeout = None;
|
||||||
|
|
||||||
for (n, line) in self.content.lines().enumerate() {
|
for (n, line) in self.read_to_string()?.lines().enumerate() {
|
||||||
// ignore
|
// ignore
|
||||||
if REG_IGNORE.is_match(&line) {
|
if REG_IGNORE.is_match(&line) {
|
||||||
continue;
|
continue;
|
||||||
@@ -135,12 +159,12 @@ impl Config {
|
|||||||
// bind
|
// bind
|
||||||
if let Some(addr) = cap_socket_addr(®_BIND, &line) {
|
if let Some(addr) = cap_socket_addr(®_BIND, &line) {
|
||||||
match addr {
|
match addr {
|
||||||
Ok(addr) => binds.push(addr),
|
Ok(addr) => bind.push(addr),
|
||||||
Err(err) => {
|
Err(kind) => {
|
||||||
errors.push(Invalid {
|
invalid.push(Invalid {
|
||||||
line: n + 1,
|
line: n + 1,
|
||||||
source: line.to_string(),
|
source: line.to_string(),
|
||||||
err,
|
kind,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,17 +175,33 @@ impl Config {
|
|||||||
if let Some(addr) = cap_socket_addr(®_PROXY, &line) {
|
if let Some(addr) = cap_socket_addr(®_PROXY, &line) {
|
||||||
match addr {
|
match addr {
|
||||||
Ok(addr) => proxy.push(addr),
|
Ok(addr) => proxy.push(addr),
|
||||||
Err(err) => {
|
Err(kind) => {
|
||||||
errors.push(Invalid {
|
invalid.push(Invalid {
|
||||||
line: n + 1,
|
line: n + 1,
|
||||||
source: line.to_string(),
|
source: line.to_string(),
|
||||||
err,
|
kind,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timeout
|
||||||
|
if let Some(cap) = REG_TIMEOUT.captures(&line) {
|
||||||
|
if let Some(time) = cap.name("val") {
|
||||||
|
if let Ok(t) = time.as_str().parse::<u64>() {
|
||||||
|
timeout = Some(t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invalid.push(Invalid {
|
||||||
|
line: n + 1,
|
||||||
|
source: line.to_string(),
|
||||||
|
kind: InvalidType::Timeout,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// import
|
// import
|
||||||
if let Some(cap) = REG_IMPORT.captures(&line) {
|
if let Some(cap) = REG_IMPORT.captures(&line) {
|
||||||
if let Some(m) = cap.name("val") {
|
if let Some(m) = cap.name("val") {
|
||||||
@@ -173,11 +213,11 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (b, p, h, e) = Config::new(p)?.parse()?;
|
let config = Config::new(p)?.parse()?;
|
||||||
binds.extend(b);
|
bind.extend(config.bind);
|
||||||
proxy.extend(p);
|
proxy.extend(config.proxy);
|
||||||
hosts.extend(h);
|
hosts.extend(config.hosts);
|
||||||
errors.extend(e);
|
invalid.extend(config.invalid);
|
||||||
} else {
|
} else {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
@@ -188,54 +228,60 @@ impl Config {
|
|||||||
if let Some(d) = cap_ip_addr(&line) {
|
if let Some(d) = cap_ip_addr(&line) {
|
||||||
match d {
|
match d {
|
||||||
Ok((domain, ip)) => hosts.push(domain, ip),
|
Ok((domain, ip)) => hosts.push(domain, ip),
|
||||||
Err(err) => {
|
Err(kind) => {
|
||||||
errors.push(Invalid {
|
invalid.push(Invalid {
|
||||||
line: n + 1,
|
line: n + 1,
|
||||||
source: line.to_string(),
|
source: line.to_string(),
|
||||||
err,
|
kind,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
errors.push(Invalid {
|
invalid.push(Invalid {
|
||||||
line: n + 1,
|
line: n + 1,
|
||||||
source: line.to_string(),
|
source: line.to_string(),
|
||||||
err: InvalidType::Other,
|
kind: InvalidType::Other,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((binds, proxy, hosts, errors))
|
Ok(ParseConfig {
|
||||||
|
bind,
|
||||||
|
proxy,
|
||||||
|
hosts,
|
||||||
|
timeout,
|
||||||
|
invalid,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Hosts {
|
pub struct Hosts {
|
||||||
list: Vec<(Regex, IpAddr)>,
|
record: Vec<(Regex, IpAddr)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hosts {
|
impl Hosts {
|
||||||
pub fn new() -> Hosts {
|
pub fn new() -> Hosts {
|
||||||
Hosts { list: Vec::new() }
|
Hosts { record: Vec::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, domain: Regex, ip: IpAddr) {
|
fn push(&mut self, domain: Regex, ip: IpAddr) {
|
||||||
self.list.push((domain, ip));
|
self.record.push((domain, ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend(&mut self, hosts: Hosts) {
|
fn extend(&mut self, hosts: Hosts) {
|
||||||
for item in hosts.list {
|
for item in hosts.record {
|
||||||
self.list.push(item);
|
self.record.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&mut self) -> Iter<(Regex, IpAddr)> {
|
pub fn iter(&mut self) -> Iter<(Regex, IpAddr)> {
|
||||||
self.list.iter()
|
self.record.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, domain: &str) -> Option<&IpAddr> {
|
pub fn get(&self, domain: &str) -> Option<&IpAddr> {
|
||||||
for (reg, ip) in &self.list {
|
for (reg, ip) in &self.record {
|
||||||
if reg.is_match(domain) {
|
if reg.is_match(domain) {
|
||||||
return Some(ip);
|
return Some(ip);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
|
|
||||||
|
|
||||||
static LOGGER: Logger = Logger;
|
|
||||||
|
|
||||||
pub fn init() -> Result<(), SetLoggerError> {
|
|
||||||
log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace))
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Logger;
|
|
||||||
|
|
||||||
impl log::Log for Logger {
|
|
||||||
fn enabled(&self, meta: &Metadata) -> bool {
|
|
||||||
meta.level() != Level::Trace
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log(&self, record: &Record) {
|
|
||||||
if self.enabled(record.metadata()) {
|
|
||||||
println!(
|
|
||||||
"{} {}: {}",
|
|
||||||
time::now().strftime("[%Y-%m-%d][%H:%M:%S]").unwrap(),
|
|
||||||
record.level(),
|
|
||||||
record.args()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&self) {}
|
|
||||||
}
|
|
||||||
151
src/main.rs
151
src/main.rs
@@ -3,17 +3,15 @@ extern crate lazy_static;
|
|||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod lib;
|
mod lib;
|
||||||
mod logger;
|
|
||||||
mod watch;
|
mod watch;
|
||||||
|
|
||||||
use ace::App;
|
use ace::App;
|
||||||
use async_std::io;
|
use async_std::io;
|
||||||
use async_std::net::UdpSocket;
|
use async_std::net::UdpSocket;
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
use config::{Config, Hosts, Invalid, InvalidType};
|
use config::{Config, Hosts, Invalid, ParseConfig};
|
||||||
use dirs;
|
use dirs;
|
||||||
use lib::*;
|
use lib::*;
|
||||||
use log::{error, info, warn};
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
@@ -22,13 +20,18 @@ use std::process::Command;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use watch::Watch;
|
use watch::Watch;
|
||||||
|
|
||||||
const CONFIG_FILE: [&str; 2] = [".updns", "config"];
|
const CONFIG_FILE: [&'static str; 2] = [".updns", "config"];
|
||||||
const DEFAULT_BIND: &str = "0.0.0.0:53";
|
const CONFIG_COMMAND: &'static str = "vim";
|
||||||
const DEFAULT_PROXY: [&str; 2] = ["8.8.8.8:53", "1.1.1.1:53"];
|
|
||||||
const PROXY_TIMEOUT: u64 = 2000;
|
const DEFAULT_BIND: &'static str = "0.0.0.0:53";
|
||||||
const WATCH_INTERVAL: u64 = 3000;
|
const DEFAULT_PROXY: [&'static str; 2] = ["8.8.8.8:53", "1.1.1.1:53"];
|
||||||
|
const DEFAULT_TIMEOUT: u64 = 2000;
|
||||||
|
|
||||||
static mut PROXY: Vec<SocketAddr> = Vec::new();
|
static mut PROXY: Vec<SocketAddr> = Vec::new();
|
||||||
static mut HOSTS: Option<Hosts> = None;
|
static mut HOSTS: Option<Hosts> = None;
|
||||||
|
static mut TIMEOUT: u64 = DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
const WATCH_INTERVAL: u64 = 5000;
|
||||||
|
|
||||||
macro_rules! exit {
|
macro_rules! exit {
|
||||||
($($arg:tt)*) => {
|
($($arg:tt)*) => {
|
||||||
@@ -38,18 +41,37 @@ macro_rules! exit {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
macro_rules! error {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
eprint!("{} ERROR ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
|
||||||
|
eprintln!($($arg)*);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! info {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
print!("{} INFO ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
|
||||||
|
println!($($arg)*);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
macro_rules! warn {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
print!("{} WARN ", time::now().strftime("[%Y-%m-%d %H:%M:%S]").unwrap());
|
||||||
|
println!($($arg)*);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _ = logger::init();
|
let cct = format!("Call '{}' to edit the configuration file", CONFIG_COMMAND);
|
||||||
let app = App::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
|
let app = App::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
|
||||||
.cmd("add", "Add a DNS record")
|
.cmd("add", "Add a DNS record")
|
||||||
.cmd("rm", "Remove a DNS record")
|
.cmd("rm", "Remove a DNS record")
|
||||||
.cmd("ls", "Print all configured DNS records")
|
.cmd("ls", "Print all configured DNS records")
|
||||||
.cmd("config", "Call vim to edit the configuration file")
|
.cmd("config", cct.as_str())
|
||||||
.cmd("path", "Print related directories")
|
.cmd("path", "Print related directories")
|
||||||
.cmd("help", "Print help information")
|
.cmd("help", "Print help information")
|
||||||
.cmd("version", "Print version information")
|
.cmd("version", "Print version information")
|
||||||
.opt("-c", "Specify a config file");
|
.opt("-c", "Specify a config file")
|
||||||
|
.opt("-w", "Check the interval of the configuration file");
|
||||||
|
|
||||||
let config_path = match app.value("-c") {
|
let config_path = match app.value("-c") {
|
||||||
Some(values) => {
|
Some(values) => {
|
||||||
@@ -64,6 +86,20 @@ fn main() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check profile interval
|
||||||
|
let watch_interval = match app.value("-w") {
|
||||||
|
Some(values) => {
|
||||||
|
if values.is_empty() {
|
||||||
|
exit!("'-w' value: [ms]");
|
||||||
|
}
|
||||||
|
match &values[0].parse::<u64>() {
|
||||||
|
Ok(t) => *t,
|
||||||
|
Err(_) => exit!("Cannot resolve '{}' to number", &values[0]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => WATCH_INTERVAL,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(cmd) = app.command() {
|
if let Some(cmd) = app.command() {
|
||||||
match cmd.as_str() {
|
match cmd.as_str() {
|
||||||
"add" => {
|
"add" => {
|
||||||
@@ -103,28 +139,35 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"ls" => {
|
"ls" => {
|
||||||
let (_, _, _, mut hosts) = config_parse(&config_path);
|
let mut config = config_parse(&config_path);
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
for (reg, _) in hosts.iter() {
|
for (reg, _) in config.hosts.iter() {
|
||||||
if reg.as_str().len() > n {
|
if reg.as_str().len() > n {
|
||||||
n = reg.as_str().len();
|
n = reg.as_str().len();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (domain, ip) in hosts.iter() {
|
for (domain, ip) in config.hosts.iter() {
|
||||||
println!("{:domain$} {}", domain.as_str(), ip, domain = n);
|
println!("{:domain$} {}", domain.as_str(), ip, domain = n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"config" => {
|
"config" => {
|
||||||
let cmd = Command::new("vim").arg(&config_path).status();
|
let cmd = Command::new(CONFIG_COMMAND).arg(&config_path).status();
|
||||||
match cmd {
|
match cmd {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
|
warn!(
|
||||||
|
"'{}' exits with a non-zero status code: {:?}",
|
||||||
|
CONFIG_COMMAND, status
|
||||||
|
);
|
||||||
if status.success() {
|
if status.success() {
|
||||||
config_parse(&config_path);
|
config_parse(&config_path);
|
||||||
} else {
|
} else {
|
||||||
warn!("Non-zero state exit\n{:?}", status);
|
warn!(
|
||||||
|
"'{}' exits with a non-zero status code: {:?}",
|
||||||
|
CONFIG_COMMAND, status
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => exit!("Call vim command failed\n{:?}", err),
|
Err(err) => exit!("Call '{}' command failed\n{:?}", CONFIG_COMMAND, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"path" => {
|
"path" => {
|
||||||
@@ -151,32 +194,32 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, mut binds, proxy, hosts) = config_parse(&config_path);
|
let mut parse = config_parse(&config_path);
|
||||||
if binds.is_empty() {
|
if parse.bind.is_empty() {
|
||||||
warn!("Will bind the default address '{}'", DEFAULT_BIND);
|
warn!("Will bind the default address '{}'", DEFAULT_BIND);
|
||||||
binds.push(DEFAULT_BIND.parse().unwrap());
|
parse.bind.push(DEFAULT_BIND.parse().unwrap());
|
||||||
}
|
}
|
||||||
if proxy.is_empty() {
|
if parse.proxy.is_empty() {
|
||||||
warn!(
|
warn!(
|
||||||
"Will use the default proxy address '{}'",
|
"Will use the default proxy address '{}'",
|
||||||
DEFAULT_PROXY.join(", ")
|
DEFAULT_PROXY.join(", ")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_config(proxy, hosts);
|
update_config(parse.proxy, parse.hosts, parse.timeout);
|
||||||
|
|
||||||
// Run server
|
// Run server
|
||||||
for addr in binds {
|
for addr in parse.bind {
|
||||||
task::spawn(run_server(addr.clone()));
|
task::spawn(run_server(addr.clone()));
|
||||||
}
|
}
|
||||||
// watch config
|
// watch config
|
||||||
task::block_on(watch_config(config_path));
|
task::block_on(watch_config(config_path, watch_interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ask(tips: &str) -> io::Result<bool> {
|
fn ask(text: &str) -> io::Result<bool> {
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
io::stdout().write(tips.as_bytes())?;
|
io::stdout().write(text.as_bytes())?;
|
||||||
io::stdout().flush()?;
|
io::stdout().flush()?;
|
||||||
|
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@@ -185,11 +228,11 @@ fn ask(tips: &str) -> io::Result<bool> {
|
|||||||
match s.to_uppercase().as_str() {
|
match s.to_uppercase().as_str() {
|
||||||
"Y\n" => Ok(true),
|
"Y\n" => Ok(true),
|
||||||
"N\n" => Ok(false),
|
"N\n" => Ok(false),
|
||||||
_ => Ok(ask(&tips)?),
|
_ => Ok(ask(&text)?),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_config(mut proxy: Vec<SocketAddr>, hosts: Hosts) {
|
fn update_config(mut proxy: Vec<SocketAddr>, hosts: Hosts, timeout: Option<u64>) {
|
||||||
if proxy.is_empty() {
|
if proxy.is_empty() {
|
||||||
proxy = DEFAULT_PROXY
|
proxy = DEFAULT_PROXY
|
||||||
.iter()
|
.iter()
|
||||||
@@ -199,48 +242,48 @@ fn update_config(mut proxy: Vec<SocketAddr>, hosts: Hosts) {
|
|||||||
unsafe {
|
unsafe {
|
||||||
PROXY = proxy;
|
PROXY = proxy;
|
||||||
HOSTS = Some(hosts);
|
HOSTS = Some(hosts);
|
||||||
|
TIMEOUT = match timeout {
|
||||||
|
Some(t) => t,
|
||||||
|
None => DEFAULT_TIMEOUT,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_parse(file: &PathBuf) -> (Config, Vec<SocketAddr>, Vec<SocketAddr>, Hosts) {
|
fn config_parse(file: &PathBuf) -> ParseConfig {
|
||||||
let mut config = match Config::new(file) {
|
let mut config = match Config::new(file) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(err) => exit!("Failed to read config file {:?}\n{:?}", file, err),
|
Err(err) => exit!("Failed to read config file {:?}\n{:?}", file, err),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (binds, proxy, hosts, errors) = match config.parse() {
|
let parse = match config.parse() {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(err) => exit!("Parsing config file failed\n{:?}", err),
|
Err(err) => exit!("Parsing config file failed\n{:?}", err),
|
||||||
};
|
};
|
||||||
output_invalid(errors);
|
output_invalid(&parse.invalid);
|
||||||
|
|
||||||
(config, binds, proxy, hosts)
|
parse
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_invalid(errors: Vec<Invalid>) {
|
fn output_invalid(errors: &Vec<Invalid>) {
|
||||||
if !errors.is_empty() {
|
for invalid in errors {
|
||||||
for invalid in errors {
|
error!(
|
||||||
let msg = match invalid.err {
|
"[line:{}] {} `{}`",
|
||||||
InvalidType::SocketAddr => "Cannot parse socket addr",
|
invalid.line,
|
||||||
InvalidType::IpAddr => "Cannot parse ip addr",
|
invalid.kind.as_str(),
|
||||||
InvalidType::Regex => "Cannot parse Regular expression",
|
invalid.source
|
||||||
InvalidType::Other => "Invalid line",
|
);
|
||||||
};
|
|
||||||
warn!("{}", msg);
|
|
||||||
info!("Line {}: {}", invalid.line, invalid.source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn watch_config(p: PathBuf) {
|
async fn watch_config(p: PathBuf, t: u64) {
|
||||||
let mut watch = Watch::new(p, WATCH_INTERVAL);
|
let mut watch = Watch::new(p, t);
|
||||||
watch
|
watch
|
||||||
.for_each(|c| {
|
.for_each(|c| {
|
||||||
info!("Reload the configuration file: {:?}", &c);
|
info!("Reload the configuration file: {:?}", &c);
|
||||||
if let Ok(mut config) = Config::new(c) {
|
if let Ok(mut config) = Config::new(c) {
|
||||||
if let Ok((_, proxy, hosts, errors)) = config.parse() {
|
if let Ok(parse) = config.parse() {
|
||||||
update_config(proxy, hosts);
|
update_config(parse.proxy, parse.hosts, parse.timeout);
|
||||||
output_invalid(errors);
|
output_invalid(&parse.invalid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -261,19 +304,19 @@ async fn run_server(addr: SocketAddr) {
|
|||||||
let (len, src) = match socket.recv_from(&mut req.buf).await {
|
let (len, src) = match socket.recv_from(&mut req.buf).await {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to receive message\n{:?}", err);
|
error!("Failed to receive message {:?}", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let res = match handle(req, len).await {
|
let res = match handle(req, len).await {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Processing request failed\n{:?}", err);
|
error!("Processing request failed {:?}", err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Err(err) = socket.send_to(&res, &src).await {
|
if let Err(err) = socket.send_to(&res, &src).await {
|
||||||
error!("Replying to '{}' failed\n{:?}", &src, err);
|
error!("Replying to '{}' failed {:?}", &src, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,7 +327,7 @@ async fn proxy(buf: &[u8]) -> io::Result<Vec<u8>> {
|
|||||||
for addr in proxy.iter() {
|
for addr in proxy.iter() {
|
||||||
let socket = UdpSocket::bind(("0.0.0.0", 0)).await?;
|
let socket = UdpSocket::bind(("0.0.0.0", 0)).await?;
|
||||||
|
|
||||||
let data = io::timeout(Duration::from_millis(PROXY_TIMEOUT), async {
|
let data = io::timeout(Duration::from_millis(unsafe { TIMEOUT }), async {
|
||||||
socket.send_to(&buf, addr).await?;
|
socket.send_to(&buf, addr).await?;
|
||||||
let mut res = [0; 512];
|
let mut res = [0; 512];
|
||||||
let len = socket.recv(&mut res).await?;
|
let len = socket.recv(&mut res).await?;
|
||||||
@@ -297,7 +340,7 @@ async fn proxy(buf: &[u8]) -> io::Result<Vec<u8>> {
|
|||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Agent request to {}\n{:?}", addr, err);
|
error!("Agent request to {} {:?}", addr, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use async_std::fs;
|
use async_std::fs;
|
||||||
use async_std::io;
|
use async_std::io;
|
||||||
|
use async_std::prelude::*;
|
||||||
use async_std::stream;
|
use async_std::stream;
|
||||||
use async_std::stream::Stream;
|
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|||||||
4
tests/lookup.rs
Normal file
4
tests/lookup.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// todo
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lookup() {}
|
||||||
Reference in New Issue
Block a user