diff --git a/Cargo.lock b/Cargo.lock index 7b27fd1..ef7000e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,12 +92,16 @@ name = "ascertain" version = "0.1.0" dependencies = [ "anyhow", - "base64", + "base64 0.22.1", + "cfg-if", "chrono", "clap", "futures", "hex", "openssl", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry_sdk", "serde", "serde_json", "serde_with", @@ -106,15 +110,94 @@ dependencies = [ "tokio-openssl", "toml", "tracing", + "tracing-opentelemetry", "tracing-subscriber", ] +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -130,6 +213,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -239,6 +328,21 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "darling" version = "0.20.8" @@ -284,6 +388,12 @@ dependencies = [ "serde", ] +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + [[package]] name = "equivalent" version = "1.0.1" @@ -400,12 +510,48 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -439,6 +585,76 @@ dependencies = [ "serde", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -496,6 +712,15 @@ version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -539,12 +764,24 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -653,6 +890,90 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900d57987be3f2aeb70d385fff9b27fb74c5723cc9a52d904d4f9c807a0667bf" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a016b8d9495c639af2145ac22387dcb88e44118e45320d9238fbf4e7889abcb" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "prost", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8fddc9b68f5b80dae9d6f510b88e02396f006ad48cac349411fbecc80caae4" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ab5bd6c42fb9349dcf28af2ba9a0667f697f9bdcca045d39f2cec5543e2910" + +[[package]] +name = "opentelemetry_sdk" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e90c7113be649e31e9a0f8b5ee24ed7a16923b322c3c5ab6367469c049d6b7e" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "once_cell", + "opentelemetry", + "ordered-float", + "percent-encoding", + "rand", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + [[package]] name = "overload" version = "0.1.1" @@ -682,6 +1003,32 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -706,6 +1053,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.81" @@ -715,6 +1068,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "quote" version = "1.0.36" @@ -724,6 +1100,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -739,6 +1145,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.17" @@ -797,7 +1209,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", @@ -878,6 +1290,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "thiserror" version = "1.0.59" @@ -957,6 +1375,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "2.2.0" @@ -980,6 +1408,30 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.8.12" @@ -1014,6 +1466,65 @@ dependencies = [ "winnow", ] +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" @@ -1057,6 +1568,24 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9be14ba1bbe4ab79e9229f7f89fab8d120b865859f10527f31c033e599d2284" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" @@ -1071,12 +1600,24 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8parse" version = "0.2.1" @@ -1095,6 +1636,15 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1155,6 +1705,16 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index e3c9483..541028f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,21 @@ name = "ascertain" version = "0.1.0" edition = "2021" +[features] +otlp = [ "dep:opentelemetry-otlp", "dep:opentelemetry_sdk", "dep:tracing-opentelemetry"] + [dependencies] anyhow = "1.0.82" base64 = "0.22.1" +cfg-if = "1.0.0" chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5.4", features = ["derive", "cargo"] } futures = "0.3.30" hex = { version = "0.4.3", features = ["serde"] } openssl = "0.10.64" +opentelemetry = { version = "0.22.0", features = ["logs"] } +opentelemetry-otlp = { version = "0.15.0", optional = true, features = ["logs"] } +opentelemetry_sdk = { version = "0.22.1", optional = true, features = ["logs", "rt-tokio"] } serde = { version = "1.0.200", features = ["derive", "rc"] } serde_json = "1.0.116" serde_with = { version = "3.8.1", features = ["base64"] } @@ -19,4 +26,5 @@ tokio = { version = "1.37.0", features = ["rt-multi-thread", "fs", "io-util", "n tokio-openssl = "0.6.4" toml = "0.8.12" tracing = { version = "0.1.40" } +tracing-opentelemetry = { version = "0.23.0", optional = true } tracing-subscriber = "0.3.18" diff --git a/local.toml b/local.toml index 2f5b32f..7e5b398 100644 --- a/local.toml +++ b/local.toml @@ -1,6 +1,9 @@ [targets] hosts = ["10.24.74.8/24"] ports = [443, 80, 8443, 636] +live_port = 22 +connect_timeout = 2 +handshake_timeout = 2 [output] format = "json" diff --git a/src/main.rs b/src/main.rs index 13fa659..e2ea097 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,10 @@ use std::path::PathBuf; use std::time::Duration; use clap::Parser; use tokio::time::Instant; -use tracing::Level; -use ascertain::{report, config}; +use tracing_subscriber::fmt; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; +use ascertain::config; pub mod scanner; @@ -15,16 +17,39 @@ struct Cli { config: PathBuf, } -#[tokio::main] -async fn main() -> anyhow::Result<()> { + +fn main() -> anyhow::Result<()> { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .max_blocking_threads(1000) + .build().unwrap() + .block_on(main_tokio()) +} + +async fn main_tokio() -> anyhow::Result<()> { + openssl::init(); let args = Cli::parse(); let config = config::TopConfig::load(args.config)?; // Set up logging - tracing_subscriber::fmt().with_ansi(true) - .init(); + let subscriber = tracing_subscriber::registry() + .with(fmt::layer() + .with_ansi(true)); + + #[cfg(feature = "otlp")] + let subscriber = subscriber.with( + tracing_opentelemetry::layer() + .with_tracer(opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter(opentelemetry_otlp::new_exporter().tonic()) + .with_batch_config(opentelemetry_sdk::trace::BatchConfig::default()) + .install_batch(opentelemetry_sdk::runtime::Tokio)? + ) + ); + + subscriber.init(); // TODO: add args to twiddle the config let config = config.compile()?; @@ -53,5 +78,11 @@ async fn main() -> anyhow::Result<()> { reporting_backend.await?; eprintln!("Completed in {:?}", Instant::now() - start_time); + #[cfg(feature = "otlp")] + { + opentelemetry::global::shutdown_tracer_provider(); + opentelemetry::global::shutdown_logger_provider(); + } + Ok(()) } diff --git a/src/scanner.rs b/src/scanner.rs index d99626a..fb90640 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -1,7 +1,6 @@ use std::future::ready; use std::io::ErrorKind; use std::net::{IpAddr, SocketAddr}; -use std::os::linux::raw::stat; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -15,7 +14,7 @@ use tokio::select; use tokio::sync::{mpsc, oneshot}; use tokio::task::JoinHandle; use tokio_openssl::SslStream; -use tracing::{error, info, trace, warn}; +use tracing::{error, info, instrument, trace, warn}; use ascertain::config::{Host, ProbeConfig}; use ascertain::report::{CertInfo, ProbeReport, ReportError, ReportPayload, VerificationState}; @@ -65,28 +64,48 @@ struct ScannerBackend { impl ScannerBackend { + #[instrument(skip(probe_config, stats))] async fn scan_probe(addr: SocketAddr, probe_config: &ProbeConfig, stats: &StatsInternal, do_ssl: bool) -> anyhow::Result<()> { // serial scan let scan_date = chrono::Local::now(); let connection_token = probe_config.global_semaphore.acquire().await?; - let conn = match tokio::net::TcpStream::connect(addr).await { - Ok(conn) => conn, - Err(error) => match error.kind() { - ErrorKind::ConnectionRefused => bail!(ReportError::ConnectionRefused), - ErrorKind::TimedOut => { - let err = ReportError::ConnectionTimeout; - probe_config.reporter.report_probe(ProbeReport { - host: addr, - scan_date, - result: ReportPayload::Error {msg: err}, - }).await?; - bail!(err); + let socket = if addr.is_ipv4() { + tokio::net::TcpSocket::new_v4()? + } else { + tokio::net::TcpSocket::new_v6()? + }; + socket. + + let conn = tokio::select! { + result = tokio::net::TcpStream::connect(addr) => + match result { + Ok(conn) => conn, + Err(error) => match error.kind() { + ErrorKind::ConnectionRefused => bail!(ReportError::ConnectionRefused), + ErrorKind::TimedOut => { + let err = ReportError::ConnectionTimeout; + probe_config.reporter.report_probe(ProbeReport { + host: addr, + scan_date, + result: ReportPayload::Error {msg: err}, + }).await?; + bail!(err); + }, + _ => { + error!(%error, "Connection failed for unexpected reason"); + bail!(error); + } + } }, - _ => { - error!(%error, "Connection failed for unexpected reason"); - bail!(error); - } + _ = tokio::time::sleep(probe_config.connect_timeout) => { + let err = ReportError::ConnectionTimeout; + probe_config.reporter.report_probe(ProbeReport { + host: addr, + scan_date, + result: ReportPayload::Error {msg: err}, + }).await?; + bail!(err); } }; @@ -153,6 +172,7 @@ impl ScannerBackend { Ok(()) } + #[instrument(skip(probe_config, stats, host), fields(host = %host.ip))] async fn scan_host_internal(host: &mut Host, probe_config: &ProbeConfig, stats: &StatsInternal) -> anyhow::Result<()> { // TODO: allow multiple liveness ports (e.g., for scanning both Windows and Linux hosts) if let Some(port) = host.live_port { @@ -183,7 +203,8 @@ impl ScannerBackend { } } - async fn scan_host(mut host: Host, probe_config: ProbeConfig, stats: Arc) -> (IpAddr, anyhow::Result<()>) { + #[instrument(skip(parent, probe_config, stats, host), fields(host=%host.ip), parent=parent)] + async fn scan_host(parent: Option, mut host: Host, probe_config: ProbeConfig, stats: Arc) -> (IpAddr, anyhow::Result<()>) { let ip = host.ip; let results = Self::scan_host_internal(&mut host, &probe_config, &*stats).await; // remove aborted probes from total @@ -191,17 +212,19 @@ impl ScannerBackend { (ip, results) } + #[instrument(skip(self))] async fn run(mut self) -> anyhow::Result { let mut tasks = tokio::task::JoinSet::new(); let host_scale = self.probe_config.global_semaphore.available_permits(); let host_scale = host_scale + host_scale / 16; // allow an extra 6% to cover for inefficiency in respawning hosts. + let id = tracing::span::Span::current().id(); // Spawn the initial set of host probes for _ in 0..host_scale { if let Some(host) = self.hosts.pop() { - tasks.spawn(Self::scan_host(host, self.probe_config.clone(), self.stats.clone())); + tasks.spawn(Self::scan_host(id.clone(), host, self.probe_config.clone(), self.stats.clone())); } else { break } @@ -228,7 +251,7 @@ impl ScannerBackend { if let Some(host) = self.hosts.pop() { // start the next one, if there is one // If not, eventually the task set will drain and the branch will be disabled. - tasks.spawn(Self::scan_host(host, self.probe_config.clone(), self.stats.clone())); + tasks.spawn(Self::scan_host(id.clone(), host, self.probe_config.clone(), self.stats.clone())); } if self.hosts.is_empty() && tasks.is_empty() { break;