mirror of
https://github.com/zaphar/durnitisp.git
synced 2025-07-21 18:10:27 -04:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
d32c27b31c | |||
![]() |
4755513f5d | ||
![]() |
feb6684e8f | ||
5341153a86 | |||
f609dcfef3 | |||
390b61ee86 | |||
b45b29e22d | |||
347ac8147a | |||
ca9ce99d49 | |||
b7aafbce25 | |||
a91e316aec | |||
3dc6ded1b0 | |||
2cea3a294e | |||
26ac114f88 | |||
425ab1e959 | |||
39d90db9ab | |||
0835ea3ade | |||
278ef8da04 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
target/
|
||||
.vscode/
|
||||
.vscode/
|
||||
result
|
712
Cargo.lock
generated
712
Cargo.lock
generated
@ -1,12 +1,26 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -28,27 +42,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.11"
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"termion",
|
||||
"winapi",
|
||||
]
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@ -62,25 +77,34 @@ 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 = "chunked_transfer"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7477065d45a8fe57167bf3cf8bcd3729b54cfcb81cca49bda2d038ea89ae82ca"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.18"
|
||||
@ -88,40 +112,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10bcb9d7dcbf7002aaffbb53eac22906b64cdcc127971dcc387d8eb7c95d5560"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "durnitisp"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gflags",
|
||||
"icmp-socket",
|
||||
"log 0.4.14",
|
||||
"metrics",
|
||||
"metrics-exporter-prometheus",
|
||||
"nursery",
|
||||
"prometheus",
|
||||
"resolve",
|
||||
"socket2",
|
||||
"stderrlog",
|
||||
"socket2 0.5.1",
|
||||
"tiny_http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.0"
|
||||
name = "foldhash"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
@ -149,7 +170,7 @@ checksum = "07ab1d33648a58677c98ee6ed81ce592e108d4e9847ce62a15302da7e5bfd437"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -160,17 +181,32 @@ checksum = "1a5bcf1bbeab73aa4cf2fde60a846858dc036163c7c33bec309f8d17de785479"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icmp-socket"
|
||||
version = "0.1.1"
|
||||
name = "hashbrown"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c83b37323293113bad20766377951f5b51e0b23fc7cc6694b6b93e6ff02ecf8"
|
||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "icmp-socket"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98bc3daf82cd6b2f02709427c17f75e1023471f59bc74726bbd27d8a907af605"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"socket2",
|
||||
"socket2 0.4.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -185,23 +221,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.0"
|
||||
name = "indexmap"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -223,7 +249,16 @@ checksum = "75c094e94816723ab936484666968f5b58060492e880f3c8d00489a1e244fa51"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -234,18 +269,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.84"
|
||||
version = "0.2.161"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@ -272,35 +298,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
name = "memoffset"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numtoa"
|
||||
version = "0.1.0"
|
||||
name = "metrics"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||
checksum = "8ae428771d17306715c5091d446327d1cfdedc82185c65ba8423ab404e45bf10"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metrics-exporter-prometheus"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b6f8152da6d7892ff1b7a1c0fa3f435e92b5918ad67035c3bb432111d9a29b"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"indexmap",
|
||||
"metrics",
|
||||
"metrics-util",
|
||||
"quanta",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metrics-util"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"hashbrown",
|
||||
"metrics",
|
||||
"quanta",
|
||||
"sketches-ddsketch",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nursery"
|
||||
@ -309,71 +351,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4bd2d4e0cd7c6bb256afbc59a5921c3ead56f05d7696c92e05b6978858b6fa5"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.1"
|
||||
name = "once_cell"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.2"
|
||||
name = "quanta"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
|
||||
checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"crossbeam-utils",
|
||||
"libc",
|
||||
"redox_syscall 0.1.57",
|
||||
"smallvec",
|
||||
"once_cell",
|
||||
"raw-cpuid",
|
||||
"wasi",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prometheus"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8425533e7122f0c3cc7a37e6244b16ad3a2cc32ae7ac6276e2a75da0d9c200d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
"protobuf",
|
||||
"regex",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86473d5f16580f10b131a0bf0afb68f8e029d1835d33a00f37281b05694e5312"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.8"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -416,6 +439,15 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "11.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
@ -425,30 +457,6 @@ dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
|
||||
dependencies = [
|
||||
"redox_syscall 0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.6"
|
||||
@ -466,34 +474,16 @@ checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
|
||||
[[package]]
|
||||
name = "resolve"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19526b305899bea65f26edda78a64f5313958494321ee0ab66bd94b32958614a"
|
||||
dependencies = [
|
||||
"idna 0.1.5",
|
||||
"idna",
|
||||
"libc",
|
||||
"log 0.3.9",
|
||||
"rand 0.3.23",
|
||||
@ -506,33 +496,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sketches-ddsketch"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.19"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
|
||||
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stderrlog"
|
||||
name = "socket2"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45a53e2eff3e94a019afa6265e8ee04cb05b9d33fe9f5078b14e4e391d155a38"
|
||||
checksum = "bc8d618c6641ae355025c449427f9e96b98abf99a772be3cef6708d15c77147a"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
"log 0.4.14",
|
||||
"termcolor",
|
||||
"thread_local",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -547,24 +548,14 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"numtoa",
|
||||
"redox_syscall 0.2.4",
|
||||
"redox_termios",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -584,40 +575,28 @@ checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny_http"
|
||||
version = "0.8.0"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eded47106b8e52d8ed8119f0ea6e8c0f5881e69783e0297b5a8462958f334bc1"
|
||||
checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"chrono",
|
||||
"chunked_transfer",
|
||||
"httpdate",
|
||||
"log 0.4.14",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -635,6 +614,64 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log 0.4.14",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
@ -644,6 +681,12 @@ dependencies = [
|
||||
"matches",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.16"
|
||||
@ -660,22 +703,86 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.0"
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna 0.2.0",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log 0.4.14",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.60",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.60",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
@ -693,17 +800,94 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[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 = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
]
|
||||
|
17
Cargo.toml
17
Cargo.toml
@ -1,19 +1,20 @@
|
||||
[package]
|
||||
name = "durnitisp"
|
||||
version = "0.2.0"
|
||||
version = "0.2.3"
|
||||
authors = ["Jeremy Wall <jeremy@marzhillstudios.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tracing = "0.1.35"
|
||||
tracing-subscriber = "0.3.14"
|
||||
anyhow = "1"
|
||||
gflags = "^0.3"
|
||||
log = "0.4"
|
||||
nursery = "^0.0.1"
|
||||
prometheus = "0.11.0"
|
||||
stderrlog = "0.5.1"
|
||||
tiny_http = "0.8.0"
|
||||
socket2 = "0.3.19"
|
||||
icmp-socket = "0.1.1"
|
||||
resolve = "^0.2.0"
|
||||
metrics = "0.24.0"
|
||||
metrics-exporter-prometheus = {version = "0.16.0", default-features = false}
|
||||
tiny_http = "0.12.0"
|
||||
socket2 = "0.5.1"
|
||||
icmp-socket = "0.2.0"
|
||||
resolve = "^0.2.0"
|
||||
|
11
default.nix
Normal file
11
default.nix
Normal file
@ -0,0 +1,11 @@
|
||||
let
|
||||
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||
in
|
||||
(import (
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
) {
|
||||
src = ./.;
|
||||
}).defaultNix
|
76
flake.lock
generated
Normal file
76
flake.lock
generated
Normal file
@ -0,0 +1,76 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1641205782,
|
||||
"narHash": "sha256-4jY7RCWUoZ9cKD8co0/4tFARpWB+57+r1bLLvXNJliY=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "b7547d3eed6f32d06102ead8991ec52ab0a4f1a7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1644229661,
|
||||
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1671096816,
|
||||
"narHash": "sha256-ezQCsNgmpUHdZANDCILm3RvtO1xH8uujk/+EqNvzIOg=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "d998160d6a076cfe8f9741e56aeec7e267e3e114",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1678724065,
|
||||
"narHash": "sha256-MjeRjunqfGTBGU401nxIjs7PC9PZZ1FBCZp/bRB3C2M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b8afc8489dc96f29f69bec50fdc51e27883f89c1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"naersk": "naersk"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
21
flake.nix
Normal file
21
flake.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
flake-compat = { url = github:edolstra/flake-compat; flake = false; };
|
||||
};
|
||||
|
||||
outputs = {self, flake-utils, naersk, flake-compat}:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
naersk-lib = naersk.lib."${system}";
|
||||
in
|
||||
{
|
||||
defaultPackage = naersk-lib.buildPackage rec {
|
||||
pname = "kitchen";
|
||||
src = ./.;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
}
|
417
src/icmp.rs
417
src/icmp.rs
@ -14,7 +14,7 @@
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::ops::Sub;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
collections::{BTreeMap, HashMap},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
@ -25,8 +25,9 @@ use icmp_socket::{
|
||||
packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest},
|
||||
IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet,
|
||||
};
|
||||
use log::{debug, error, info};
|
||||
use prometheus::{CounterVec, GaugeVec};
|
||||
use metrics::{counter, gauge, histogram};
|
||||
use nursery::{thread, Nursery};
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
|
||||
gflags::define! {
|
||||
/// The payload to use for the ping requests.
|
||||
@ -34,8 +35,8 @@ gflags::define! {
|
||||
}
|
||||
|
||||
gflags::define! {
|
||||
/// The timeout for ping requests.
|
||||
--pingTimeout: u64 = 2048
|
||||
/// The timeout for ping requests in seconds.
|
||||
--pingTimeout: u64 = 3
|
||||
}
|
||||
|
||||
gflags::define! {
|
||||
@ -60,16 +61,90 @@ fn resolve_host_address(host: &str) -> String {
|
||||
}
|
||||
|
||||
struct State<AddrType> {
|
||||
sequence: u16,
|
||||
destinations: HashMap<u16, (String, AddrType)>, // domain, address
|
||||
time_tracker: HashMap<u16, Instant>,
|
||||
latency_guage: GaugeVec,
|
||||
ping_counter: CounterVec,
|
||||
time_tracker: BTreeMap<u16, BTreeMap<u16, Instant>>,
|
||||
destination_counter: BTreeMap<u16, u16>,
|
||||
// TODO(jwall): Add histogram for latency as well.
|
||||
}
|
||||
|
||||
fn make_ping_count_labels(domain_name: &str, result: &str) -> [(&'static str, String); 2] {
|
||||
[
|
||||
("domain", domain_name.to_owned()),
|
||||
("result", result.to_owned()),
|
||||
]
|
||||
}
|
||||
|
||||
impl<AddrType: std::fmt::Display> State<AddrType> {
|
||||
fn handle_echo_reply(&mut self, identifier: u16, sequence: u16) -> bool {
|
||||
if let Some((domain_name, dest)) = self.destinations.get(&identifier) {
|
||||
let time_tracker = self.time_tracker.get_mut(&identifier);
|
||||
let mut result = false;
|
||||
if let Some(Some(send_time)) = time_tracker.as_ref().map(|m| m.get(&sequence)) {
|
||||
let elapsed = Instant::now().sub(send_time.clone()).as_micros() as f64 / 1000.00;
|
||||
// We make a copy here to avoid the borrow above sticking around for too long.
|
||||
info!(
|
||||
domain=domain_name,
|
||||
%dest,
|
||||
time = elapsed,
|
||||
seq = sequence,
|
||||
"Reply",
|
||||
);
|
||||
counter!("ping_counter", &make_ping_count_labels(domain_name, "ok")).increment(1);
|
||||
if elapsed as i32 != 0 {
|
||||
let labels = [("domain", domain_name.to_owned())];
|
||||
let latency = gauge!("ping_latency", &labels);
|
||||
latency.increment(elapsed);
|
||||
let latency_hist = histogram!("ping_latency_hist_ms", &labels);
|
||||
latency_hist.record(elapsed);
|
||||
}
|
||||
self.time_tracker
|
||||
.get_mut(&identifier)
|
||||
.and_then(|m| m.remove(&sequence));
|
||||
result = true;
|
||||
} else {
|
||||
error!(sequence, "Discarding unexpected sequence",);
|
||||
};
|
||||
// Check all the other sequences to see if they have expired timeouts yet.
|
||||
// Record timeout for the expired sequences.
|
||||
// Remove the timeouts for the expired sequences.
|
||||
let expired_sequences = self.time_tracker.get(&identifier).map(|m| {
|
||||
let mut for_delete = Vec::with_capacity(m.len());
|
||||
let m = m.clone();
|
||||
{
|
||||
for (k, send_time) in m.iter() {
|
||||
if Instant::now().sub(*send_time) >= Duration::from_secs(PINGTIMEOUT.flag) {
|
||||
info!(
|
||||
domain=domain_name,
|
||||
%dest,
|
||||
seq = sequence,
|
||||
"Dropped"
|
||||
);
|
||||
counter!(
|
||||
"ping_counter",
|
||||
&make_ping_count_labels(domain_name, "dropped")
|
||||
)
|
||||
.increment(1);
|
||||
for_delete.push(*k);
|
||||
}
|
||||
}
|
||||
}
|
||||
for_delete
|
||||
});
|
||||
for k in expired_sequences.unwrap_or_default() {
|
||||
self.time_tracker
|
||||
.get_mut(&identifier)
|
||||
.and_then(|m| m.remove(&k));
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
warn!(identifier, "Discarding wrong identifier");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct PingerImpl<Sock: IcmpSocket> {
|
||||
sock: Sock,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
trait PacketHandler<PacketType, AddrType>
|
||||
@ -86,7 +161,9 @@ impl<'a> PacketHandler<Icmpv6Packet, Ipv6Addr> for &'a mut State<Ipv6Addr> {
|
||||
return self;
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn handle_pkt(&mut self, pkt: Icmpv6Packet) -> bool {
|
||||
debug!("handling packet");
|
||||
match pkt.message {
|
||||
Icmpv6Message::Unreachable {
|
||||
_unused,
|
||||
@ -105,15 +182,17 @@ impl<'a> PacketHandler<Icmpv6Packet, Ipv6Addr> for &'a mut State<Ipv6Addr> {
|
||||
},
|
||||
}) => {
|
||||
if let Some((domain_name, _addr)) = self.destinations.get(&identifier) {
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "unreachable", "domain" => domain_name})
|
||||
.inc();
|
||||
counter!(
|
||||
"ping_counter",
|
||||
&make_ping_count_labels(domain_name, "unreachable")
|
||||
)
|
||||
.increment(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// We ignore these as well but log it.
|
||||
error!("ICMP: Error parsing Unreachable invoking packet {:?}", e);
|
||||
error!(err = ?e, "Error parsing Unreachable");
|
||||
}
|
||||
_ => {
|
||||
// We ignore these
|
||||
@ -131,21 +210,16 @@ impl<'a> PacketHandler<Icmpv6Packet, Ipv6Addr> for &'a mut State<Ipv6Addr> {
|
||||
checksum: _,
|
||||
message:
|
||||
Icmpv6Message::EchoRequest {
|
||||
identifier,
|
||||
identifier: _,
|
||||
sequence: _,
|
||||
payload: _,
|
||||
},
|
||||
}) => {
|
||||
if let Some((domain_name, _addr)) = self.destinations.get(&identifier) {
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "parameter_problem", "domain" => domain_name})
|
||||
.inc();
|
||||
return true;
|
||||
}
|
||||
// TODO log but otherwise ignore this.
|
||||
}
|
||||
Err(e) => {
|
||||
// We ignore these as well but log it.
|
||||
error!("ICMP: Error parsing Unreachable invoking packet {:?}", e);
|
||||
error!(err = ?e, "Error parsing ParameterProblem");
|
||||
}
|
||||
_ => {
|
||||
// We ignore these
|
||||
@ -157,32 +231,7 @@ impl<'a> PacketHandler<Icmpv6Packet, Ipv6Addr> for &'a mut State<Ipv6Addr> {
|
||||
sequence,
|
||||
payload: _,
|
||||
} => {
|
||||
if let Some((domain_name, dest)) = self.destinations.get(&identifier) {
|
||||
if self.sequence != sequence {
|
||||
error!("ICMP: Discarding sequence {}", sequence);
|
||||
return false;
|
||||
}
|
||||
let elapsed = if let Some(send_time) = self.time_tracker.get(&identifier) {
|
||||
Instant::now().sub(send_time.clone()).as_micros() as f64 / 1000.00
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
info!(
|
||||
"ICMP: Reply from {}({}): time={}ms, seq={}",
|
||||
domain_name, dest, elapsed, sequence,
|
||||
);
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "ok", "domain" => domain_name})
|
||||
.inc();
|
||||
if elapsed as i32 != 0 {
|
||||
self.latency_guage
|
||||
.with(&prometheus::labels! {"domain" => domain_name.as_str()})
|
||||
.set(elapsed);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
info!("ICMP: Discarding wrong identifier {}", identifier);
|
||||
}
|
||||
return self.handle_echo_reply(identifier, sequence);
|
||||
}
|
||||
_ => {
|
||||
// We ignore the rest.
|
||||
@ -197,67 +246,20 @@ impl<'a> PacketHandler<Icmpv4Packet, Ipv4Addr> for &'a mut State<Ipv4Addr> {
|
||||
return self;
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn handle_pkt(&mut self, pkt: Icmpv4Packet) -> bool {
|
||||
debug!("handling packet");
|
||||
match pkt.message {
|
||||
Icmpv4Message::ParameterProblem {
|
||||
pointer: _,
|
||||
padding: _,
|
||||
header: _,
|
||||
} => {
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "parameter_problem", "domain" => "unknown"})
|
||||
.inc();
|
||||
}
|
||||
Icmpv4Message::Unreachable { padding: _, header } => {
|
||||
let dest_addr = Ipv4Addr::new(header[16], header[17], header[18], header[19]);
|
||||
info!("ICMP: Destination Unreachable response from {}", dest_addr,);
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "unreachable", "domain" => "unknown"})
|
||||
.inc();
|
||||
}
|
||||
Icmpv4Message::TimeExceeded { padding: _, header } => {
|
||||
let dest_addr = Ipv4Addr::new(header[16], header[17], header[18], header[19]);
|
||||
info!("ICMP: Timeout for {}", dest_addr);
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "timeout", "domain" => "unknown"})
|
||||
.inc();
|
||||
}
|
||||
Icmpv4Message::EchoReply {
|
||||
identifier,
|
||||
sequence,
|
||||
payload: _,
|
||||
} => {
|
||||
if let Some((domain_name, dest)) = self.destinations.get(&identifier) {
|
||||
let elapsed = if let Some(send_time) = self.time_tracker.get(&identifier) {
|
||||
Instant::now().sub(send_time.clone()).as_micros() as f64 / 1000.00
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
if self.sequence != sequence {
|
||||
error!(
|
||||
"ICMP: Discarding sequence {}, expected sequence {}",
|
||||
sequence, self.sequence
|
||||
);
|
||||
return false;
|
||||
}
|
||||
info!(
|
||||
"ICMP: Reply from {}({}): time={}ms, seq={}",
|
||||
domain_name, dest, elapsed, sequence,
|
||||
);
|
||||
self.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "ok", "domain" => domain_name})
|
||||
.inc();
|
||||
self.latency_guage
|
||||
.with(&prometheus::labels! {"domain" => domain_name.as_str()})
|
||||
.set(elapsed);
|
||||
return true;
|
||||
} else {
|
||||
info!("ICMP: Discarding wrong identifier {}", identifier);
|
||||
}
|
||||
return self.handle_echo_reply(identifier, sequence);
|
||||
}
|
||||
p => {
|
||||
_ => {
|
||||
// We ignore the rest.
|
||||
info!("ICMP Unhandled packet {:?}", p);
|
||||
info!("Unhandled packet");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -279,6 +281,41 @@ where
|
||||
|
||||
fn recv_pkt(&mut self) -> std::io::Result<PacketType>;
|
||||
fn recv_all<H: PacketHandler<PacketType, AddrType>>(&mut self, handler: H);
|
||||
|
||||
fn send_pkt(
|
||||
&mut self,
|
||||
state: &mut State<AddrType>,
|
||||
identifier: u16,
|
||||
dest: AddrType,
|
||||
domain_name: &String,
|
||||
) -> std::io::Result<()> {
|
||||
let sequence = *state.destination_counter.entry(identifier).or_insert(0);
|
||||
debug!(
|
||||
domain=domain_name, %dest, sequence,
|
||||
"Sending echo request",
|
||||
);
|
||||
match self.send_to_destination(dest, identifier, sequence) {
|
||||
Err(e) => {
|
||||
counter!("ping_counter", &make_ping_count_labels(domain_name, "err")).increment(1);
|
||||
error!(
|
||||
domain=domain_name, %dest, err=?e,
|
||||
"Error sending. Trying again later",
|
||||
);
|
||||
}
|
||||
Ok(send_time) => {
|
||||
state
|
||||
.time_tracker
|
||||
.entry(identifier)
|
||||
.or_insert_with(|| BTreeMap::new())
|
||||
.insert(sequence, send_time);
|
||||
}
|
||||
}
|
||||
state
|
||||
.destination_counter
|
||||
.get_mut(&identifier)
|
||||
.map(|v| *v = v.wrapping_add(1));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Sock> Pinger<Sock::AddrType, Sock::PacketType> for PingerImpl<Sock>
|
||||
@ -287,27 +324,14 @@ where
|
||||
Sock::AddrType: std::fmt::Display + Copy,
|
||||
Sock::PacketType: WithEchoRequest<Packet = Sock::PacketType>,
|
||||
{
|
||||
#[instrument(skip_all)]
|
||||
fn send_all(&mut self, state: &mut State<Sock::AddrType>) -> std::io::Result<()> {
|
||||
self.sock.set_timeout(self.timeout)?;
|
||||
let destinations = state.destinations.clone();
|
||||
debug!("Attempting to send packets for all domains");
|
||||
for (identifier, (domain_name, dest)) in destinations.into_iter() {
|
||||
debug!("ICMP: sending echo request to {}({})", domain_name, dest);
|
||||
match self.send_to_destination(dest, identifier, state.sequence) {
|
||||
Err(e) => {
|
||||
state
|
||||
.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "err", "type" => "send"})
|
||||
.inc();
|
||||
error!(
|
||||
"ICMP: error sending to domain: {} and address: {} failed: {:?}, Trying again later",
|
||||
domain_name, &dest, e
|
||||
);
|
||||
}
|
||||
Ok(send_time) => {
|
||||
state.time_tracker.insert(identifier, send_time);
|
||||
}
|
||||
}
|
||||
self.send_pkt(state, identifier, dest, &domain_name)?;
|
||||
}
|
||||
debug!("Finished sending for domains");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -333,39 +357,76 @@ where
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, handler))]
|
||||
fn recv_all<H: PacketHandler<Sock::PacketType, Sock::AddrType>>(&mut self, mut handler: H) {
|
||||
let expected_len = handler.get_mut_state().time_tracker.len();
|
||||
for _ in 0..expected_len {
|
||||
loop {
|
||||
// Receive loop
|
||||
match self.recv_pkt() {
|
||||
Ok(pkt) => {
|
||||
if handler.handle_pkt(pkt) {
|
||||
// break out of the recv loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error receiving packet: {:?}", e);
|
||||
handler
|
||||
.get_mut_state()
|
||||
.ping_counter
|
||||
.with(&prometheus::labels! {"result" => "err", "domain" => "unknown"})
|
||||
.inc();
|
||||
if handler.get_mut_state().destinations.is_empty() {
|
||||
debug!("Nothing to send to so skipping for this socket");
|
||||
return;
|
||||
};
|
||||
if handler
|
||||
.get_mut_state()
|
||||
.time_tracker
|
||||
.values()
|
||||
.find(|item| !item.is_empty())
|
||||
.is_none()
|
||||
{
|
||||
// nothing has been sent yet so no need to try to recv packets
|
||||
debug!("Nothing to recieve so skipping for this socket");
|
||||
return;
|
||||
}
|
||||
self.sock.set_timeout(None);
|
||||
let loop_start_time = Instant::now();
|
||||
loop {
|
||||
// Receive loop
|
||||
debug!("Attempting to recieve packets on socket");
|
||||
match self.recv_pkt() {
|
||||
Ok(pkt) => {
|
||||
if handler.handle_pkt(pkt) {
|
||||
// break out of the recv loop
|
||||
debug!("Recieved Packet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!(err = ?e, "Error receiving packet");
|
||||
counter!("ping_counter", &make_ping_count_labels("unknown", "err"))
|
||||
.increment(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Instant::now() - loop_start_time) > Duration::from_secs(PINGTIMEOUT.flag) {
|
||||
info!("Timing out on recieve loop");
|
||||
return;
|
||||
}
|
||||
}
|
||||
let mut state = handler.get_mut_state();
|
||||
state.sequence = state.sequence.wrapping_add(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_echo_loop(
|
||||
domain_names: &Vec<&str>,
|
||||
ping_latency_guage: GaugeVec,
|
||||
ping_counter: CounterVec,
|
||||
) {
|
||||
struct Multi {
|
||||
v4_state: State<Ipv4Addr>,
|
||||
v6_state: State<Ipv6Addr>,
|
||||
v4_pinger: PingerImpl<IcmpSocket4>,
|
||||
v6_pinger: PingerImpl<IcmpSocket6>,
|
||||
}
|
||||
|
||||
impl Multi {
|
||||
fn send_all(&mut self) {
|
||||
self.v4_pinger
|
||||
.send_all(&mut self.v4_state)
|
||||
.expect("Error sending packets on socket");
|
||||
self.v6_pinger
|
||||
.send_all(&mut self.v6_state)
|
||||
.expect("Error sending packets on socket");
|
||||
}
|
||||
|
||||
fn recv_all(&mut self) {
|
||||
self.v4_pinger.recv_all(&mut self.v4_state);
|
||||
self.v6_pinger.recv_all(&mut self.v6_state);
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(name = "ICMP", skip_all)]
|
||||
pub fn schedule_echo_server(domain_names: &Vec<&str>, parent: &mut Nursery) {
|
||||
let resolved: Vec<(String, IpAddr)> = domain_names
|
||||
.iter()
|
||||
.map(|domain_name| {
|
||||
@ -392,48 +453,66 @@ pub fn start_echo_loop(
|
||||
let mut v4_destinations = HashMap::new();
|
||||
let mut v4_id_counter = 42;
|
||||
for target in v4_targets {
|
||||
info!("ICMP: Attempting ping to {}({})", target.0, target.1);
|
||||
info!(
|
||||
domain_name = target.0,
|
||||
address = %target.1,
|
||||
"Attempting ping"
|
||||
);
|
||||
v4_destinations.insert(v4_id_counter, target.clone());
|
||||
v4_id_counter += 1;
|
||||
}
|
||||
let mut v4_state = State {
|
||||
sequence: 0,
|
||||
let v4_state = State {
|
||||
destinations: v4_destinations,
|
||||
time_tracker: HashMap::new(),
|
||||
latency_guage: ping_latency_guage.clone(),
|
||||
ping_counter: ping_counter.clone(),
|
||||
time_tracker: BTreeMap::new(),
|
||||
destination_counter: BTreeMap::new(),
|
||||
};
|
||||
let mut v6_destinations = HashMap::new();
|
||||
let mut v6_id_counter = 42;
|
||||
for target in v6_targets {
|
||||
info!("ICMP: Attempting ping to {}({})", target.0, target.1);
|
||||
info!(
|
||||
domain_name = target.0,
|
||||
address = %target.1,
|
||||
"Attempting ping"
|
||||
);
|
||||
v6_destinations.insert(v6_id_counter, target.clone());
|
||||
v6_id_counter += 1;
|
||||
}
|
||||
let mut v4_pinger = PingerImpl {
|
||||
let v4_pinger = PingerImpl {
|
||||
sock: IcmpSocket4::new().expect("Failed to open Icmpv4 Socket"),
|
||||
timeout: Duration::from_secs(1),
|
||||
};
|
||||
let mut v6_state = State {
|
||||
sequence: 0,
|
||||
let v6_state = State {
|
||||
destinations: v6_destinations,
|
||||
time_tracker: HashMap::new(),
|
||||
latency_guage: ping_latency_guage,
|
||||
ping_counter,
|
||||
time_tracker: BTreeMap::new(),
|
||||
destination_counter: BTreeMap::new(),
|
||||
};
|
||||
let mut v6_pinger = PingerImpl {
|
||||
let v6_pinger = PingerImpl {
|
||||
sock: IcmpSocket6::new().expect("Failed to open Icmpv6 Socket"),
|
||||
timeout: Duration::from_secs(1),
|
||||
};
|
||||
loop {
|
||||
v4_pinger
|
||||
.send_all(&mut v4_state)
|
||||
.expect("Error sending packets on socket");
|
||||
v6_pinger
|
||||
.send_all(&mut v6_state)
|
||||
.expect("Error sending packets on socket");
|
||||
v4_pinger.recv_all(&mut v4_state);
|
||||
v6_pinger.recv_all(&mut v6_state);
|
||||
std::thread::sleep(Duration::from_secs(PINGDELAY.flag))
|
||||
}
|
||||
let multi = std::sync::Arc::new(std::sync::Mutex::new(Multi {
|
||||
v4_pinger,
|
||||
v6_pinger,
|
||||
v4_state,
|
||||
v6_state,
|
||||
}));
|
||||
let send_multi = multi.clone();
|
||||
let send_thread = thread::Pending::new(move || {
|
||||
info!("Starting send thread");
|
||||
loop {
|
||||
{
|
||||
send_multi.lock().unwrap().send_all();
|
||||
}
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
let recv_thread = thread::Pending::new(move || {
|
||||
info!("Starting recv thread");
|
||||
loop {
|
||||
{
|
||||
multi.lock().unwrap().recv_all();
|
||||
}
|
||||
std::thread::sleep(Duration::from_millis(5));
|
||||
}
|
||||
});
|
||||
parent.schedule(Box::new(send_thread));
|
||||
parent.schedule(Box::new(recv_thread));
|
||||
}
|
||||
|
131
src/main.rs
131
src/main.rs
@ -11,18 +11,16 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::convert::Into;
|
||||
use std::sync::Arc;
|
||||
|
||||
use gflags;
|
||||
use log::{debug, error, info};
|
||||
use metrics_exporter_prometheus;
|
||||
use nursery::thread;
|
||||
use nursery::{Nursery, Waitable};
|
||||
use prometheus::{self, GaugeVec};
|
||||
use prometheus::{CounterVec, Encoder, IntGaugeVec, Opts, Registry, TextEncoder};
|
||||
use stderrlog;
|
||||
use tiny_http;
|
||||
use tracing::{debug, error, info, instrument, Level};
|
||||
use tracing_subscriber::FmtSubscriber;
|
||||
|
||||
mod icmp;
|
||||
mod stun;
|
||||
@ -43,6 +41,11 @@ gflags::define! {
|
||||
--debug = false
|
||||
}
|
||||
|
||||
gflags::define! {
|
||||
/// Enable trace logging
|
||||
--trace = false
|
||||
}
|
||||
|
||||
gflags::define! {
|
||||
/// Comma separated list of hosts to ping
|
||||
--pingHosts = "google.com"
|
||||
@ -53,9 +56,10 @@ gflags::define! {
|
||||
--stunHosts = "stun.l.google.com:19302,stun.ekiga.net:3478,stun.xten.com:3478,stun.ideasip.com:3478,stun.rixtelecom.se:3478,stun.schlund.de:3478,stun.softjoys.com:3478,stun.stunprotocol.org:3478,stun.voiparound.com:3478,stun.voipbuster.com:3478,stun.voipstunt.com:3478,stun1.noc.ams-ix.net:3478"
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn main() -> anyhow::Result<()> {
|
||||
gflags::parse();
|
||||
let stun_servers: Vec<&str> = dbg!(STUNHOSTS.flag).split(",").collect();
|
||||
let stun_servers: Vec<&str> = STUNHOSTS.flag.split(",").collect();
|
||||
|
||||
if HELP.flag {
|
||||
println!("durnitisp <options> <list of hostname:port>");
|
||||
@ -67,60 +71,32 @@ fn main() -> anyhow::Result<()> {
|
||||
gflags::print_help_and_exit(0);
|
||||
}
|
||||
|
||||
let level = if DEBUG.flag || cfg!(debug_assertions) {
|
||||
3
|
||||
let subscriber_builder = if DEBUG.flag {
|
||||
FmtSubscriber::builder()
|
||||
// all spans/events with a level higher than debug
|
||||
// will be written to stdout.
|
||||
.with_max_level(Level::DEBUG)
|
||||
} else if TRACE.flag {
|
||||
FmtSubscriber::builder()
|
||||
// all spans/events with a level will be written to stdout.
|
||||
.with_max_level(Level::TRACE)
|
||||
} else {
|
||||
2
|
||||
FmtSubscriber::builder()
|
||||
// all spans/events with a level higher than info (e.g, error, info, warn, etc.)
|
||||
// will be written to stdout.
|
||||
.with_max_level(Level::INFO)
|
||||
};
|
||||
|
||||
stderrlog::new()
|
||||
.verbosity(level)
|
||||
.timestamp(stderrlog::Timestamp::Millisecond)
|
||||
.init()?;
|
||||
tracing::subscriber::set_global_default(subscriber_builder.finish())
|
||||
.expect("setting default subscriber failed");
|
||||
|
||||
let ping_hosts: Vec<&str> = dbg!(PINGHOSTS.flag).split(",").collect();
|
||||
let ping_hosts: Vec<&str> = PINGHOSTS.flag.split(",").collect();
|
||||
|
||||
dbg!(&ping_hosts);
|
||||
let builder = metrics_exporter_prometheus::PrometheusBuilder::new();
|
||||
let prom_handle = builder
|
||||
.install_recorder()
|
||||
.expect("Failed to install prometheus exporter");
|
||||
// Create a Registry and register metrics.
|
||||
let r = Registry::new();
|
||||
let stun_counter_vec = CounterVec::new(
|
||||
Opts::new(
|
||||
"stun_attempt_counter",
|
||||
"Counter for the good, bad, and total attempts to connect to stun server.",
|
||||
),
|
||||
&["result", "domain"],
|
||||
)
|
||||
.unwrap();
|
||||
let stun_success_vec = IntGaugeVec::new(
|
||||
Opts::new("stun_success", "Stun probe successes"),
|
||||
&["domain"],
|
||||
)
|
||||
.unwrap();
|
||||
let stun_latency_vec = IntGaugeVec::new(
|
||||
Opts::new(
|
||||
"stun_attempt_latency_ms",
|
||||
"Latency guage in millis per stun domain.",
|
||||
),
|
||||
&["domain"],
|
||||
)
|
||||
.unwrap();
|
||||
let ping_latency_vec =
|
||||
GaugeVec::new(Opts::new("ping_latency", "ICMP Ping latency"), &["domain"]).unwrap();
|
||||
let ping_counter_vec = CounterVec::new(
|
||||
Opts::new("ping_counter", "Ping Request Counter"),
|
||||
&["result", "domain"],
|
||||
)
|
||||
.unwrap();
|
||||
r.register(Box::new(stun_counter_vec.clone()))
|
||||
.expect("Failed to register stun connection counter");
|
||||
r.register(Box::new(stun_latency_vec.clone()))
|
||||
.expect("Failed to register stun latency guage");
|
||||
r.register(Box::new(stun_success_vec.clone()))
|
||||
.expect("Failed to register stun success gauge");
|
||||
r.register(Box::new(ping_latency_vec.clone()))
|
||||
.expect("Failed to register ping latency guage");
|
||||
r.register(Box::new(ping_counter_vec.clone()))
|
||||
.expect("Failed to register ping counter");
|
||||
let stun_socket_addrs = util::resolve_socket_addrs(&stun_servers).unwrap();
|
||||
let stun_servers = Arc::new(stun_servers);
|
||||
let ping_hosts = Arc::new(ping_hosts);
|
||||
@ -131,33 +107,33 @@ fn main() -> anyhow::Result<()> {
|
||||
// Introduce a new scope for our Arc to clone before moving it into the thread.
|
||||
// thread::Handle starts the thread immediately so the render thread will usually start first.
|
||||
let render_thread = thread::Handle::new(move || {
|
||||
debug!("attempting to start server on {}", LISTENHOST.flag);
|
||||
debug!(listenhost = LISTENHOST.flag, "attempting to start server");
|
||||
let server = match tiny_http::Server::http(LISTENHOST.flag) {
|
||||
Ok(server) => server,
|
||||
Err(err) => {
|
||||
error!("Error starting render thread {}", err);
|
||||
error!("Shutting down all threads...");
|
||||
error!(
|
||||
?err,
|
||||
"Error starting render thread. Shutting down all thread.",
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
info!("Listening for metrics request on {}", LISTENHOST.flag);
|
||||
info!(
|
||||
listenthost = LISTENHOST.flag,
|
||||
"Listening for metrics request on"
|
||||
);
|
||||
loop {
|
||||
info!("Waiting for request");
|
||||
match server.recv() {
|
||||
Ok(req) => {
|
||||
let mut buffer = vec![];
|
||||
// Gather the metrics.
|
||||
let encoder = TextEncoder::new();
|
||||
let metric_families = r.gather();
|
||||
encoder.encode(&metric_families, &mut buffer).unwrap();
|
||||
|
||||
let response = tiny_http::Response::from_data(buffer).with_status_code(200);
|
||||
let response = tiny_http::Response::from_data(prom_handle.render())
|
||||
.with_status_code(200);
|
||||
if let Err(e) = req.respond(response) {
|
||||
error!("Error responding to request {}", e);
|
||||
error!(err = ?e, "Error responding to request");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Invalid http request! {}", e);
|
||||
error!(err = ?e, "Invalid http request!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,30 +141,15 @@ fn main() -> anyhow::Result<()> {
|
||||
parent.adopt(Box::new(render_thread));
|
||||
}
|
||||
{
|
||||
let ping_latency_vec = ping_latency_vec.clone();
|
||||
let ping_counter_vec = ping_counter_vec.clone();
|
||||
let ping_thread = thread::Pending::new(move || {
|
||||
icmp::start_echo_loop(&ping_hosts, ping_latency_vec, ping_counter_vec);
|
||||
});
|
||||
parent.schedule(Box::new(ping_thread));
|
||||
icmp::schedule_echo_server(&ping_hosts, &mut parent);
|
||||
}
|
||||
// Then we attempt to start connections to each stun server.
|
||||
for (i, s) in stun_socket_addrs.iter().enumerate() {
|
||||
let stun_servers_copy = stun_servers.clone();
|
||||
let stun_counter_vec_copy = stun_counter_vec.clone();
|
||||
let stun_latency_vec_copy = stun_latency_vec.clone();
|
||||
let stun_success_vec_copy = stun_success_vec.clone();
|
||||
if let Some(s) = s.clone() {
|
||||
let domain_name = *stun_servers_copy.get(i).unwrap();
|
||||
let connect_thread = thread::Pending::new(move || {
|
||||
stun::start_listen_thread(
|
||||
domain_name,
|
||||
s.into(),
|
||||
stun_counter_vec_copy,
|
||||
stun_latency_vec_copy,
|
||||
stun_success_vec_copy,
|
||||
)
|
||||
});
|
||||
let connect_thread =
|
||||
thread::Pending::new(move || stun::start_listen_thread(domain_name, s.into()));
|
||||
parent.schedule(Box::new(connect_thread));
|
||||
// Spread the probe threads out so they're somewhat uniformly distributed.
|
||||
std::thread::sleep(std::time::Duration::from_micros(
|
||||
|
110
src/stun.rs
110
src/stun.rs
@ -13,12 +13,12 @@
|
||||
// limitations under the License.
|
||||
|
||||
use gflags;
|
||||
use log::{debug, error, info};
|
||||
use prometheus::{CounterVec, IntGaugeVec};
|
||||
use metrics::{counter, gauge};
|
||||
use std::convert::From;
|
||||
use std::io;
|
||||
use std::net::{SocketAddr, UdpSocket};
|
||||
use std::time::SystemTime;
|
||||
use tracing::{debug, error, info, instrument};
|
||||
|
||||
gflags::define! {
|
||||
/// Read timeout for the stun server udp receive
|
||||
@ -70,61 +70,81 @@ fn attempt_stun_connect(addr: SocketAddr) -> Result<SystemTime, ConnectError> {
|
||||
Ok(SystemTime::now())
|
||||
}
|
||||
|
||||
pub fn start_listen_thread(
|
||||
domain_name: &str,
|
||||
s: SocketAddr,
|
||||
stun_counter_vec_copy: CounterVec,
|
||||
stun_latency_vec_copy: IntGaugeVec,
|
||||
stun_success_vec_copy: IntGaugeVec,
|
||||
) {
|
||||
debug!("started thread for {}", domain_name);
|
||||
fn make_count_labels(domain_name: &str, result: &str) -> [(&'static str, String); 2] {
|
||||
[
|
||||
("domain", domain_name.to_owned()),
|
||||
("result", result.to_owned()),
|
||||
]
|
||||
}
|
||||
|
||||
#[instrument(
|
||||
name = "STUN",
|
||||
fields(domain=domain_name, socket=%s),
|
||||
)]
|
||||
pub fn start_listen_thread(domain_name: &str, s: SocketAddr) {
|
||||
let labels: [(&str, String); 1] = [("domain", domain_name.to_owned())];
|
||||
let success = gauge!("stun_success", &labels);
|
||||
|
||||
debug!("starting thread");
|
||||
loop {
|
||||
let now = SystemTime::now();
|
||||
info!("Attempting to connect to {}", domain_name);
|
||||
info!("Attempting to connect");
|
||||
match attempt_stun_connect(s) {
|
||||
Ok(finish_time) => {
|
||||
info!("Success! connecting to {}", domain_name);
|
||||
stun_counter_vec_copy
|
||||
.with(&prometheus::labels! {"result" => "ok", "domain" => domain_name})
|
||||
.inc();
|
||||
stun_latency_vec_copy
|
||||
.with(&prometheus::labels! {"domain" => domain_name})
|
||||
// Technically this could be lossy but we'll chance it anyway.
|
||||
.set(finish_time.duration_since(now).unwrap().as_millis() as i64);
|
||||
stun_success_vec_copy
|
||||
.with(&prometheus::labels! {"domain" => domain_name})
|
||||
.set(1);
|
||||
info!(
|
||||
timeout = false,
|
||||
success = true,
|
||||
millis = finish_time.duration_since(now).unwrap().as_millis(),
|
||||
conn_type = "Stun connection",
|
||||
);
|
||||
counter!(
|
||||
"stun_attempt_counter",
|
||||
&make_count_labels(domain_name, "ok")
|
||||
)
|
||||
.increment(1);
|
||||
gauge!("stun_attempt_latency_ms", &labels)
|
||||
.increment(finish_time.duration_since(now).unwrap().as_millis() as f64);
|
||||
success.set(1);
|
||||
}
|
||||
Err(ConnectError::Timeout(finish_time)) => {
|
||||
info!(
|
||||
"Stun connection to {} timedout after {} millis",
|
||||
domain_name,
|
||||
finish_time.duration_since(now).unwrap().as_millis()
|
||||
timeout = true,
|
||||
success = false,
|
||||
millis = finish_time.duration_since(now).unwrap().as_millis(),
|
||||
conn_type = "Stun connection",
|
||||
);
|
||||
stun_counter_vec_copy
|
||||
.with(&prometheus::labels! {"result" => "timeout", "domain" => domain_name})
|
||||
.inc();
|
||||
stun_success_vec_copy
|
||||
.with(&prometheus::labels! {"domain" => domain_name})
|
||||
.set(0);
|
||||
counter!(
|
||||
"stun_attempt_counter",
|
||||
&make_count_labels(domain_name, "timeout")
|
||||
)
|
||||
.increment(1);
|
||||
success.set(0);
|
||||
}
|
||||
Err(ConnectError::Err(e)) => {
|
||||
error!("Error connecting to {}: {}", domain_name, e);
|
||||
stun_counter_vec_copy
|
||||
.with(&prometheus::labels! {"result" => "err", "domain" => domain_name})
|
||||
.inc();
|
||||
stun_success_vec_copy
|
||||
.with(&prometheus::labels! {"domain" => domain_name})
|
||||
.set(0);
|
||||
error!(
|
||||
timeout=true, success=false, err = ?e,
|
||||
conn_type="Stun connection",
|
||||
);
|
||||
counter!(
|
||||
"stun_attempt_counter",
|
||||
&make_count_labels(domain_name, "err")
|
||||
)
|
||||
.increment(1);
|
||||
success.set(0);
|
||||
}
|
||||
Err(ConnectError::Incomplete) => {
|
||||
error!("Connection to {} was incomplete", domain_name);
|
||||
stun_counter_vec_copy
|
||||
.with(&prometheus::labels! {"result" => "incomplete", "domain" => domain_name})
|
||||
.inc();
|
||||
stun_success_vec_copy
|
||||
.with(&prometheus::labels! {"domain" => domain_name})
|
||||
.set(0);
|
||||
error!(
|
||||
timeout = true,
|
||||
success = false,
|
||||
err = "Incomplete",
|
||||
conn_type = "Stun connection",
|
||||
);
|
||||
counter!(
|
||||
"stun_attempt_counter",
|
||||
&make_count_labels(domain_name, "incomplete")
|
||||
)
|
||||
.increment(1);
|
||||
success.set(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
18
src/util.rs
18
src/util.rs
@ -17,9 +17,9 @@ use std::net::IpAddr;
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
|
||||
use gflags;
|
||||
use log::info;
|
||||
use resolve::config::DnsConfig;
|
||||
use resolve::resolver::DnsResolver;
|
||||
use tracing::{error, instrument};
|
||||
|
||||
gflags::define! {
|
||||
/// Allow IPv6 addresses for domain name lookups.
|
||||
@ -32,13 +32,21 @@ pub fn resolve_hosts<'a>(servers: &'a Vec<&str>) -> io::Result<Vec<Option<IpAddr
|
||||
config.use_inet6 = ALLOWIPV6.flag;
|
||||
let resolver = DnsResolver::new(config)?;
|
||||
for name in servers.iter().cloned() {
|
||||
// TODO for resolution errors return a more valid error with the domain name.
|
||||
let mut iter = resolver.resolve_host(name)?;
|
||||
results.push(iter.next());
|
||||
match name.parse::<IpAddr>() {
|
||||
Ok(ip) => {
|
||||
results.push(Some(ip));
|
||||
}
|
||||
Err(_) => {
|
||||
// TODO for resolution errors return a more valid error with the domain name.
|
||||
let mut iter = resolver.resolve_host(name)?;
|
||||
results.push(iter.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ok(results);
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub fn resolve_socket_addrs<'a>(servers: &'a Vec<&str>) -> io::Result<Vec<Option<SocketAddr>>> {
|
||||
let mut results = Vec::new();
|
||||
for name in servers.iter().cloned() {
|
||||
@ -46,7 +54,7 @@ pub fn resolve_socket_addrs<'a>(servers: &'a Vec<&str>) -> io::Result<Vec<Option
|
||||
match name.to_socket_addrs() {
|
||||
Ok(addr) => results.push(addr.into_iter().next()),
|
||||
Err(e) => {
|
||||
info!("Failed to resolve {} with error {}", name, e);
|
||||
error!(name, err = ?e, "Failed to resolve");
|
||||
results.push(None);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user