diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-06-30 19:14:57 -0400 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-06-30 19:14:57 -0400 |
commit | ba934210b7f7e98ee85ae3d50cc830bce6aa65a1 (patch) | |
tree | 8d45937ef90cc1660b4e6dedc745493d169affa1 | |
parent | b44737f714f36bf508d8f7f9fd81d998fcf9cddd (diff) |
Fetching data and storing metrics
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 686 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | src/main.rs | 193 |
4 files changed, 863 insertions, 21 deletions
@@ -1 +1,2 @@ /target +.env @@ -3,6 +3,17 @@ version = 3 [[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] name = "async-trait" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -14,24 +25,66 @@ dependencies = [ ] [[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -52,6 +105,30 @@ dependencies = [ ] [[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" + +[[package]] name = "crossbeam" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -121,23 +198,89 @@ dependencies = [ ] [[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] name = "data-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" [[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] name = "dns-server" version = "0.1.0" dependencies = [ + "dotenvy", "fast_log", "futures-util", + "hostname", + "lazy_static", "log", + "sqlx", "tokio", "trust-dns-proto", ] [[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e851a83c30366fd01d75b913588e95e74a1705c1ecc5d58b1f8e1a6d556525f" +dependencies = [ + "dirs", +] + +[[package]] +name = "either" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" + +[[package]] name = "enum-as-inner" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -150,6 +293,12 @@ dependencies = [ ] [[package]] +name = "event-listener" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" + +[[package]] name = "fast_log" version = "1.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -182,6 +331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -191,6 +341,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] +name = "futures-intrusive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] name = "futures-io" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -208,6 +369,12 @@ dependencies = [ ] [[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] name = "futures-task" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -221,6 +388,7 @@ checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-core", "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", @@ -228,6 +396,16 @@ dependencies = [ ] [[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "getrandom" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -239,10 +417,31 @@ dependencies = [ ] [[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452c155cb93fecdfb02a73dd57b5d8e442c2063bd7aac72f1bc5e4263a43086" +dependencies = [ + "hashbrown", +] + +[[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -254,6 +453,41 @@ dependencies = [ ] [[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] name = "idna" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -265,18 +499,55 @@ dependencies = [ ] [[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] name = "ipnet" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] name = "itoa" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] +name = "js-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +dependencies = [ + "wasm-bindgen", +] + +[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -308,12 +579,27 @@ dependencies = [ ] [[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] name = "matches" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] +name = "md-5" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" +dependencies = [ + "digest", +] + +[[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -329,6 +615,12 @@ dependencies = [ ] [[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] name = "mio" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -341,6 +633,16 @@ dependencies = [ ] [[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] name = "num-integer" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -377,12 +679,37 @@ checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.3", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] @@ -399,6 +726,12 @@ dependencies = [ ] [[package]] +name = "paste" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" + +[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -480,6 +813,53 @@ dependencies = [ ] [[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustls" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +dependencies = [ + "base64", +] + +[[package]] name = "ryu" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -492,6 +872,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] name = "serde" version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -523,6 +913,28 @@ dependencies = [ ] [[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] name = "signal-hook-registry" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -554,6 +966,131 @@ dependencies = [ ] [[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f82cbe94f41641d6c410ded25bbf5097c240cefdf8e3b06d04198d0a96af6a4" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b69bf218860335ddda60d6ce85ee39f6cf6e5630e300e19757d1de15886a093" +dependencies = [ + "ahash", + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dirs", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "hkdf", + "hmac", + "indexmap", + "itoa", + "libc", + "log", + "md-5", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rand", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "sha-1", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots", + "whoami", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40c63177cf23d356b159b60acd27c54af7423f1736988502e36bae9a712118f" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874e93a365a598dc3dadb197565952cb143ae4aa716f7bcc933a8d836f6bf89f" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] name = "syn" version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -622,7 +1159,7 @@ dependencies = [ "mio", "num_cpus", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -642,6 +1179,28 @@ dependencies = [ ] [[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] name = "trust-dns-proto" version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -667,6 +1226,12 @@ dependencies = [ ] [[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] name = "unicode-bidi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -688,6 +1253,24 @@ dependencies = [ ] [[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] name = "url" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -700,6 +1283,12 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -712,6 +1301,99 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] +name = "wasm-bindgen" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" + +[[package]] +name = "web-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +dependencies = [ + "webpki", +] + +[[package]] +name = "whoami" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7,8 +7,12 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +dotenvy = "0.15.1" fast_log = "1.5.17" futures-util = "0.3.21" +hostname = "0.3.1" +lazy_static = "1.4.0" log = "0.4.17" +sqlx = { version = "0.6.0", features = ["postgres", "runtime-tokio-rustls"] } tokio = { version = "1.19.2", features = ["full"] } trust-dns-proto = "0.21.2" diff --git a/src/main.rs b/src/main.rs index 8c27974..3bdf40d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,50 @@ -#![deny(unsafe_code)] - -use std::net::{Ipv4Addr, SocketAddr}; - use futures_util::StreamExt; +use lazy_static::lazy_static; +use sqlx::postgres::PgPoolOptions; +use sqlx::FromRow; +use sqlx::{Pool, Postgres}; +use std::env; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::str::FromStr; use std::sync::{Arc, Mutex}; +use std::time::Instant; use tokio::net::UdpSocket; -use trust_dns_proto::op::{Message, MessageType}; -use trust_dns_proto::rr::{DNSClass, RData, Record, RecordType}; +use trust_dns_proto::op::{Message, MessageType, ResponseCode}; +use trust_dns_proto::rr::rdata::SOA; +use trust_dns_proto::rr::{DNSClass, Name, RData, Record, RecordType}; use trust_dns_proto::udp::UdpStream; use trust_dns_proto::xfer::SerialMessage; use trust_dns_proto::{BufDnsStreamHandle, DnsStreamHandle}; +lazy_static! { + // TODO: Investigate performance of checking type in SQL and needing two queries vs checking type in code + static ref GET_DOMAIN_SQL: &'static str = + "SELECT name,type,content,ttl FROM records WHERE name = $1"; + static ref GET_ZONE_SQL: &'static str = + "SELECT count(id) FROM zones WHERE $1 LIKE '%' || id"; + static ref INSERT_METRICS_SQL: &'static str = + "INSERT INTO queries (ip, qname, qtype, rcode, duration_us, host) VALUES ($1, $2, $3, $4, $5, $6)"; +} + +#[derive(Clone, FromRow)] +pub struct FdnsRecord { + pub name: String, + #[sqlx(rename = "type")] + pub record_type: String, + pub content: String, + pub ttl: i32, +} +struct Metrics { + source_ip: String, + qname: String, + qtype: String, + rcode: String, + duration_us: i64, +} + #[tokio::main] async fn main() { + dotenvy::dotenv().ok(); fast_log::fast_log::init( fast_log::Config::new() .console() @@ -20,7 +52,22 @@ async fn main() { ) .unwrap(); - let addr = String::from("127.0.0.1:53") + let pg_pool = Arc::new( + PgPoolOptions::new() + .max_connections(12) + .connect(&env::var("DATABASE_URL").expect("DATABASE_URL not set")) + .await + .unwrap(), + ); + let metrics_pool = Arc::new( + PgPoolOptions::new() + .max_connections(12) + .connect(&env::var("METRICS_URL").expect("METRICS_URL not set")) + .await + .unwrap(), + ); + + let addr = String::from("127.0.0.1:5353") .parse::<SocketAddr>() .expect("Unable to parse bind address"); @@ -41,8 +88,26 @@ async fn main() { match packet { Ok(raw_message) => { let sender = Arc::clone(&sender); + let pg_pool = Arc::clone(&pg_pool); + let metrics_pool = Arc::clone(&metrics_pool); tokio::spawn(async move { - handle_message(raw_message, sender).await; + let metrics = handle_message(raw_message, &pg_pool, sender).await; + if let Ok(metrics) = metrics { + if let Err(e) = sqlx::query(&INSERT_METRICS_SQL) + .bind(&metrics.source_ip) + .bind(&metrics.qname) + .bind(&metrics.qtype) + .bind(&metrics.rcode) + .bind(metrics.duration_us) + .bind(match hostname::get() { + Ok(hostname) => hostname.to_str().unwrap_or("unknown").to_owned(), + Err(_) => String::from("unknown"), + }) + .execute(&*metrics_pool) + .await { + log::error!("{e}"); + } + } }); } Err(e) => { @@ -53,29 +118,84 @@ async fn main() { } } -async fn handle_message(raw_message: SerialMessage, sender: Arc<Mutex<BufDnsStreamHandle>>) { +async fn handle_message( + raw_message: SerialMessage, + postgres: &Pool<Postgres>, + sender: Arc<Mutex<BufDnsStreamHandle>>, +) -> Result<Metrics, ()> { let src = raw_message.addr(); + let start = Instant::now(); log::debug!("Recieved packet from {src}"); let mut message = match Message::from_vec(raw_message.bytes()) { Ok(message) => message, Err(e) => { log::error!("{e}"); - return; + return Err(()); } }; - for query in message.clone().queries() { - if query.name().to_string() == "example.com." { - message.add_answer( + let query = message.queries().get(0).unwrap().to_owned(); + + let qname = query.name().to_string(); + let qtype = query.query_type().to_string(); + + let records = sqlx::query_as::<_, FdnsRecord>(&GET_DOMAIN_SQL) + .bind(&qname) + .fetch_all(postgres) + .await + .unwrap(); + + message.add_answers( + records + .iter() + .filter(|r| r.record_type == qtype) + .map(|r| { Record::new() - .set_ttl(60) + .set_ttl(r.ttl.try_into().unwrap()) .set_dns_class(DNSClass::IN) - .set_rr_type(RecordType::A) - .set_name(query.name().clone()) - .set_data(Some(RData::A(Ipv4Addr::new(127, 0, 0, 1)))) - .clone(), - ); + .set_rr_type(RecordType::from_str(&r.record_type).unwrap()) + .set_name(Name::from_str(&r.name).unwrap()) + .set_data(match RecordType::from_str(&r.record_type).unwrap() { + // TODO: Uhh log these errors just in case + RecordType::A => match r.content.parse::<Ipv4Addr>() { + Ok(addr) => Some(RData::A(addr)), + Err(_) => None, + }, + RecordType::AAAA => match r.content.parse::<Ipv6Addr>() { + Ok(addr) => Some(RData::AAAA(addr)), + Err(_) => None, + }, + RecordType::CNAME => match r.content.parse::<Name>() { + Ok(name) => Some(RData::CNAME(name)), + Err(_) => None, + }, + RecordType::NS => match r.content.parse::<Name>() { + Ok(name) => Some(RData::NS(name)), + Err(_) => None, + }, + RecordType::SOA => match parse_soa(&r.content) { + Ok(soa) => Some(RData::SOA(soa)), + Err(_) => None, + }, + _ => None, + }) + .clone() + }) + .filter(|r| r.data().is_some()), + ); + + if message.answers().is_empty() { + let zone_count: (i64,) = sqlx::query_as(&GET_ZONE_SQL) + .bind(&qname) + .fetch_one(postgres) + .await + .unwrap(); + if zone_count.0 == 0 { + message.set_response_code(ResponseCode::Refused); + } else { + message.set_response_code(ResponseCode::NXDomain); + // TODO: Set additional SOA } } @@ -94,4 +214,39 @@ async fn handle_message(raw_message: SerialMessage, sender: Arc<Mutex<BufDnsStre log::error!("{e}"); } }; + + Ok(Metrics { + source_ip: src.ip().to_string(), + qname, + qtype, + rcode: message.response_code().to_string(), + duration_us: start.elapsed().as_micros().try_into().unwrap(), + }) +} + +fn parse_soa(content: &str) -> Result<SOA, ()> { + let parts: Vec<String> = content + .split_whitespace() + .into_iter() + .map(|s| s.to_owned()) + .collect(); + Ok(SOA::new( + get(&parts, 0)?, + get(&parts, 1)?, + get(&parts, 2)?, + get(&parts, 3)?, + get(&parts, 4)?, + get(&parts, 5)?, + get(&parts, 6)?, + )) +} + +fn get<T: FromStr>(parts: &[String], index: usize) -> Result<T, ()> { + match parts.get(index) { + Some(part) => match part.parse::<T>() { + Ok(name) => Ok(name), + Err(_) => Err(()), + }, + None => Err(()), + } } |