diff --git a/Cargo.lock b/Cargo.lock index 9b01050..8787803 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,17 +82,6 @@ version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "atoi" version = "2.0.0" @@ -114,6 +103,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-lc-rs" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.8.9" @@ -233,6 +244,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -248,6 +261,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" version = "0.4.44" @@ -302,12 +326,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -323,6 +366,16 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -338,6 +391,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.4.0" @@ -385,7 +447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -445,6 +507,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "ed25519" version = "2.2.3" @@ -567,6 +635,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.32" @@ -696,6 +770,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", "wasip2", "wasip3", ] @@ -860,7 +935,6 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.7", ] [[package]] @@ -1021,12 +1095,12 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf39cc0423ee66021dc5eccface85580e4a001e0c5288bae8bea7ecb69225e90" +checksum = "c0a05c691e1fae256cf7013d99dad472dc52d5543322761f83ec8d47eab40d2b" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1059,6 +1133,65 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + [[package]] name = "js-sys" version = "0.3.98" @@ -1181,9 +1314,9 @@ dependencies = [ [[package]] name = "mdns-sd" -version = "0.15.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1856c9bb96761020572ccc972887318aafca947a441e7ee52cd2facb8f9af3be" +checksum = "c2bb8ce26633738d98ffcef71ec58bff967c6675be50229823c2835f6316e67e" dependencies = [ "fastrand", "flume", @@ -1223,38 +1356,134 @@ name = "ncro" version = "1.0.0" dependencies = [ "anyhow", - "async-trait", "axum", - "base64", - "bytes", - "chrono", "clap", - "ed25519-dalek", - "futures-util", "hex", - "http", - "http-body-util", - "humantime-serde", - "mdns-sd", - "prometheus", - "rand 0.8.6", - "reqwest", - "rmp-serde", - "serde", - "serde_json", - "serde_yaml", - "sqlx", + "ncro-config", + "ncro-db", + "ncro-discovery", + "ncro-health", + "ncro-mesh", + "ncro-metrics", + "ncro-router", + "ncro-server", "tempfile", - "thiserror 2.0.18", "tokio", - "tokio-util", "tower", - "tower-http", "tracing", "tracing-subscriber", +] + +[[package]] +name = "ncro-config" +version = "1.0.0" +dependencies = [ + "hex", + "humantime-serde", + "serde", + "serde_yaml", + "thiserror 2.0.18", "url", ] +[[package]] +name = "ncro-db" +version = "1.0.0" +dependencies = [ + "chrono", + "serde", + "sqlx", + "thiserror 2.0.18", + "tokio", +] + +[[package]] +name = "ncro-discovery" +version = "1.0.0" +dependencies = [ + "anyhow", + "mdns-sd", + "ncro-config", + "ncro-health", + "tokio", + "tracing", +] + +[[package]] +name = "ncro-health" +version = "1.0.0" +dependencies = [ + "ncro-config", + "reqwest", + "tokio", +] + +[[package]] +name = "ncro-mesh" +version = "1.0.0" +dependencies = [ + "chrono", + "ed25519-dalek", + "hex", + "ncro-db", + "rand 0.10.1", + "rmp-serde", + "serde", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "ncro-metrics" +version = "1.0.0" +dependencies = [ + "prometheus", +] + +[[package]] +name = "ncro-narinfo" +version = "1.0.0" +dependencies = [ + "base64", + "ed25519-dalek", + "rand 0.10.1", + "thiserror 2.0.18", +] + +[[package]] +name = "ncro-router" +version = "1.0.0" +dependencies = [ + "chrono", + "futures-util", + "ncro-db", + "ncro-health", + "ncro-metrics", + "ncro-narinfo", + "reqwest", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "ncro-server" +version = "1.0.0" +dependencies = [ + "axum", + "bytes", + "futures-util", + "ncro-config", + "ncro-db", + "ncro-health", + "ncro-metrics", + "ncro-router", + "reqwest", + "serde", + "tracing", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1322,6 +1551,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "parking" version = "2.2.1" @@ -1503,6 +1738,7 @@ version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", @@ -1574,6 +1810,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -1612,6 +1859,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "redox_syscall" version = "0.5.18" @@ -1649,9 +1902,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64", "bytes", @@ -1670,9 +1923,7 @@ dependencies = [ "quinn", "rustls", "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", + "rustls-platform-verifier", "sync_wrapper", "tokio", "tokio-rustls", @@ -1685,7 +1936,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.7", ] [[package]] @@ -1775,6 +2025,7 @@ version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "aws-lc-rs", "once_cell", "ring", "rustls-pki-types", @@ -1783,6 +2034,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.14.1" @@ -1793,12 +2056,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -1816,12 +2107,53 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.28" @@ -1914,7 +2246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -1925,7 +2257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -1964,6 +2296,22 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.12" @@ -2452,7 +2800,6 @@ dependencies = [ "tower", "tower-layer", "tower-service", - "tracing", "url", ] @@ -2642,6 +2989,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2760,9 +3117,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", @@ -2803,6 +3160,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" @@ -2831,6 +3197,15 @@ dependencies = [ "wasite", ] +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -2908,15 +3283,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" diff --git a/Cargo.toml b/Cargo.toml index dc1c9d7..c9f5acb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,49 +1,78 @@ -[package] -name = "ncro" -version = "1.0.0" +[workspace] +members = [ "crates/*" ] +resolver = "3" + +[workspace.package] edition = "2024" license = "MIT" +version = "1.0.0" + +[workspace.dependencies] +anyhow = "1.0.102" +axum = "0.8.9" +base64 = "0.22.1" +bytes = "1.11.1" +chrono = "0.4.44" +clap = "4.6.1" +ed25519-dalek = "2.2.0" +futures-util = "0.3.32" +hex = "0.4.3" +humantime-serde = "1.1.1" +mdns-sd = "0.19.1" +prometheus = "0.14.0" +rand = "0.10.1" +reqwest = { version = "0.13.3", default-features = false } +rmp-serde = "1.3.1" +serde = "1.0.228" +serde_json = "1.0.149" +serde_yaml = "0.9.34" +sqlx = { version = "0.8.6", default-features = false } +tempfile = "3.27.0" +thiserror = "2.0.18" +tokio = "1.52.3" +tower = "0.5.3" +tower-http = "0.6.10" +tracing = "0.1.44" +tracing-subscriber = "0.3.23" +url = "2.5.8" + +ncro-config = { path = "crates/config", version = "1.0.0" } +ncro-db = { path = "crates/db", version = "1.0.0" } +ncro-discovery = { path = "crates/discovery", version = "1.0.0" } +ncro-health = { path = "crates/health", version = "1.0.0" } +ncro-mesh = { path = "crates/mesh", version = "1.0.0" } +ncro-metrics = { path = "crates/metrics", version = "1.0.0" } +ncro-narinfo = { path = "crates/narinfo", version = "1.0.0" } +ncro-router = { path = "crates/router", version = "1.0.0" } +ncro-server = { path = "crates/server", version = "1.0.0" } + +[package] +name = "ncro" +version.workspace = true +edition.workspace = true +license.workspace = true [dependencies] -anyhow = "1.0.102" -async-trait = "0.1.89" -axum = { version = "0.8.9", features = [ "macros" ] } -base64 = "0.22.1" -bytes = "1.11.1" -chrono = { version = "0.4.44", features = [ "serde" ] } -clap = { version = "4.6.1", features = [ "derive", "env" ] } -ed25519-dalek = { version = "2.2.0", features = [ "rand_core" ] } -futures-util = "0.3.32" -hex = "0.4.3" -http = "1.4.0" -http-body-util = "0.1.3" -humantime-serde = "1.1.1" -mdns-sd = "0.15.2" -prometheus = "0.14.0" -rand = "0.8.6" -reqwest = { version = "0.12.28", default-features = false, features = [ "rustls-tls", "stream" ] } -rmp-serde = "1.3.1" -serde = { version = "1.0.228", features = [ "derive" ] } -serde_json = "1.0.149" -serde_yaml = "0.9.34" -sqlx = { version = "0.8.6", default-features = false, features = [ - "runtime-tokio-rustls", - "sqlite", - "macros", - "migrate", - "chrono", -] } -thiserror = "2.0.18" -tokio = { version = "1.52.3", features = [ "macros", "rt-multi-thread", "signal", "time", "net", "fs" ] } -tokio-util = { version = "0.7.18", features = [ "io" ] } -tower-http = { version = "0.6.10", features = [ "trace" ] } -tracing = "0.1.44" -tracing-subscriber = { version = "0.3.23", features = [ "env-filter", "json" ] } -url = "2.5.8" +anyhow.workspace = true +axum.workspace = true +clap = { workspace = true, features = [ "derive", "env" ] } +hex.workspace = true +tokio = { workspace = true, features = [ "macros", "rt-multi-thread", "signal", "time", "net", "fs" ] } +tracing.workspace = true +tracing-subscriber = { workspace = true, features = [ "env-filter", "json" ] } + +ncro-config.workspace = true +ncro-db.workspace = true +ncro-discovery.workspace = true +ncro-health.workspace = true +ncro-mesh.workspace = true +ncro-metrics.workspace = true +ncro-router.workspace = true +ncro-server.workspace = true [dev-dependencies] -tempfile = "3.27.0" -tower = { version = "0.5.3", features = [ "util" ] } +tempfile.workspace = true +tower = { workspace = true, features = [ "util" ] } # See: # diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml new file mode 100644 index 0000000..d160efb --- /dev/null +++ b/crates/config/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "ncro-config" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +hex.workspace = true +humantime-serde.workspace = true +serde = { workspace = true, features = [ "derive" ] } +serde_yaml.workspace = true +thiserror.workspace = true +url.workspace = true diff --git a/src/config.rs b/crates/config/src/lib.rs similarity index 100% rename from src/config.rs rename to crates/config/src/lib.rs diff --git a/crates/db/Cargo.toml b/crates/db/Cargo.toml new file mode 100644 index 0000000..696fdcf --- /dev/null +++ b/crates/db/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "ncro-db" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +chrono = { workspace = true, features = [ "serde" ] } +serde = { workspace = true, features = [ "derive" ] } +sqlx = { workspace = true, features = [ "runtime-tokio-rustls", "sqlite", "macros", "migrate", "chrono" ] } +thiserror.workspace = true +tokio = { workspace = true, features = [ "fs" ] } diff --git a/src/db.rs b/crates/db/src/lib.rs similarity index 100% rename from src/db.rs rename to crates/db/src/lib.rs diff --git a/crates/discovery/Cargo.toml b/crates/discovery/Cargo.toml new file mode 100644 index 0000000..abe0807 --- /dev/null +++ b/crates/discovery/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "ncro-discovery" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +anyhow.workspace = true +mdns-sd.workspace = true +ncro-config.workspace = true +ncro-health.workspace = true +tokio = { workspace = true, features = [ "rt", "sync", "time" ] } +tracing.workspace = true diff --git a/src/discovery.rs b/crates/discovery/src/lib.rs similarity index 97% rename from src/discovery.rs rename to crates/discovery/src/lib.rs index 9e24a25..45197aa 100644 --- a/src/discovery.rs +++ b/crates/discovery/src/lib.rs @@ -5,10 +5,10 @@ use std::{ }; use mdns_sd::{ServiceDaemon, ServiceEvent}; +use ncro_config::DiscoveryConfig; +use ncro_health::Prober; use tokio::sync::{Mutex, watch}; -use crate::{config::DiscoveryConfig, health::Prober}; - pub struct Discovery { cfg: DiscoveryConfig, prober: Prober, diff --git a/crates/health/Cargo.toml b/crates/health/Cargo.toml new file mode 100644 index 0000000..c3f82db --- /dev/null +++ b/crates/health/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "ncro-health" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +ncro-config.workspace = true +reqwest = { workspace = true, features = [ "rustls" ] } +tokio = { workspace = true, features = [ "sync", "time", "rt" ] } diff --git a/src/health.rs b/crates/health/src/lib.rs similarity index 99% rename from src/health.rs rename to crates/health/src/lib.rs index fdeb3aa..1948aaa 100644 --- a/src/health.rs +++ b/crates/health/src/lib.rs @@ -5,10 +5,9 @@ use std::{ time::{Duration, Instant}, }; +use ncro_config::UpstreamConfig; use tokio::sync::RwLock; -use crate::config::UpstreamConfig; - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Status { Active, diff --git a/crates/mesh/Cargo.toml b/crates/mesh/Cargo.toml new file mode 100644 index 0000000..c5ee11e --- /dev/null +++ b/crates/mesh/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ncro-mesh" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +chrono.workspace = true +ed25519-dalek = { workspace = true, features = [ "rand_core" ] } +hex.workspace = true +ncro-db.workspace = true +rand.workspace = true +rmp-serde.workspace = true +serde = { workspace = true, features = [ "derive" ] } +thiserror.workspace = true +tokio = { workspace = true, features = [ "fs", "net", "rt", "sync", "time" ] } +tracing.workspace = true diff --git a/src/mesh.rs b/crates/mesh/src/lib.rs similarity index 95% rename from src/mesh.rs rename to crates/mesh/src/lib.rs index a5b53c5..617333b 100644 --- a/src/mesh.rs +++ b/crates/mesh/src/lib.rs @@ -2,13 +2,12 @@ use std::{path::Path, sync::Arc}; use chrono::Utc; use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; -use rand::rngs::OsRng; +use ncro_db::{Db, RouteEntry}; +use rand::RngExt; use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio::{net::UdpSocket, time::Duration}; -use crate::db::{Db, RouteEntry}; - const MAX_PACKET_SIZE: usize = 65_536; const HEADER_SIZE: usize = 96; @@ -50,7 +49,7 @@ impl Node { pub async fn new(key_path: &str) -> Result { if key_path.is_empty() { return Ok(Self { - signing_key: Arc::new(SigningKey::generate(&mut OsRng)), + signing_key: Arc::new(SigningKey::from_bytes(&random_key_bytes())), }); } if let Ok(data) = tokio::fs::read(key_path).await @@ -66,7 +65,7 @@ impl Node { if let Some(parent) = Path::new(key_path).parent() { tokio::fs::create_dir_all(parent).await?; } - let key = SigningKey::generate(&mut OsRng); + let key = SigningKey::from_bytes(&random_key_bytes()); tokio::fs::write(key_path, key.to_bytes()).await?; Ok(Self { signing_key: Arc::new(key), @@ -88,6 +87,12 @@ impl Node { } } +fn random_key_bytes() -> [u8; 32] { + let mut bytes = [0_u8; 32]; + rand::rng().fill(&mut bytes); + bytes +} + pub fn verify(pubkey: &[u8], body: &[u8], sig: &[u8]) -> Result<(), MeshError> { let pubkey: [u8; 32] = pubkey.try_into().map_err(|_| MeshError::InvalidSignature)?; diff --git a/crates/metrics/Cargo.toml b/crates/metrics/Cargo.toml new file mode 100644 index 0000000..b487050 --- /dev/null +++ b/crates/metrics/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ncro-metrics" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +prometheus.workspace = true diff --git a/src/metrics.rs b/crates/metrics/src/lib.rs similarity index 100% rename from src/metrics.rs rename to crates/metrics/src/lib.rs diff --git a/crates/narinfo/Cargo.toml b/crates/narinfo/Cargo.toml new file mode 100644 index 0000000..3db2364 --- /dev/null +++ b/crates/narinfo/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "ncro-narinfo" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +base64.workspace = true +ed25519-dalek.workspace = true +thiserror.workspace = true + +[dev-dependencies] +ed25519-dalek = { workspace = true, features = [ "rand_core" ] } +rand.workspace = true diff --git a/src/narinfo.rs b/crates/narinfo/src/lib.rs similarity index 97% rename from src/narinfo.rs rename to crates/narinfo/src/lib.rs index a25b38a..fa9f0c4 100644 --- a/src/narinfo.rs +++ b/crates/narinfo/src/lib.rs @@ -31,7 +31,7 @@ pub enum NarInfoError { #[cfg(test)] mod tests { use ed25519_dalek::{Signer, SigningKey}; - use rand::rngs::OsRng; + use rand::RngExt; use super::*; @@ -50,7 +50,9 @@ mod tests { #[test] fn verifies_roundtrip_signature() -> Result<(), NarInfoError> { - let signing = SigningKey::generate(&mut OsRng); + let mut key_bytes = [0_u8; 32]; + rand::rng().fill(&mut key_bytes); + let signing = SigningKey::from_bytes(&key_bytes); let mut ni = NarInfo { store_path: "/nix/store/abc-test".into(), nar_hash: "sha256:abc".into(), diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml new file mode 100644 index 0000000..9aba987 --- /dev/null +++ b/crates/router/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ncro-router" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +chrono.workspace = true +futures-util.workspace = true +ncro-db.workspace = true +ncro-health.workspace = true +ncro-metrics.workspace = true +ncro-narinfo.workspace = true +reqwest = { workspace = true, features = [ "rustls" ] } +thiserror.workspace = true +tokio = { workspace = true, features = [ "sync", "time", "rt" ] } +tracing.workspace = true diff --git a/src/router.rs b/crates/router/src/lib.rs similarity index 95% rename from src/router.rs rename to crates/router/src/lib.rs index 3b4d72b..a881e7a 100644 --- a/src/router.rs +++ b/crates/router/src/lib.rs @@ -6,16 +6,12 @@ use std::{ use chrono::Utc; use futures_util::{StreamExt, stream::FuturesUnordered}; +use ncro_db::{Db, DbError, RouteEntry}; +use ncro_health::{Prober, Status}; +use ncro_narinfo::{NarInfo, NarInfoError, parse_public_key}; use thiserror::Error; use tokio::sync::{Mutex, RwLock}; -use crate::{ - db::{Db, RouteEntry}, - health::{Prober, Status}, - metrics, - narinfo::NarInfo, -}; - #[derive(Debug, Error)] pub enum RouterError { #[error("not found in any upstream")] @@ -27,7 +23,7 @@ pub enum RouterError { #[error("narinfo signature verification failed")] SignatureVerificationFailed, #[error(transparent)] - Db(#[from] crate::db::DbError), + Db(#[from] DbError), } #[derive(Debug, Clone)] @@ -89,8 +85,8 @@ impl Router { &self, url: String, public_key: String, - ) -> Result<(), crate::narinfo::NarInfoError> { - crate::narinfo::parse_public_key(&public_key)?; + ) -> Result<(), NarInfoError> { + parse_public_key(&public_key)?; self .inner .upstream_keys @@ -111,7 +107,7 @@ impl Router { if let Some(result) = self.valid_cached_route(store_hash).await? { return Ok(result); } - metrics::get().narinfo_cache_misses.inc(); + ncro_metrics::get().narinfo_cache_misses.inc(); let lock = { let mut inflight = self.inner.inflight.lock().await; @@ -153,7 +149,7 @@ impl Router { if !health.as_ref().is_none_or(|h| h.status == Status::Active) { return Ok(None); } - metrics::get().narinfo_cache_hits.inc(); + ncro_metrics::get().narinfo_cache_hits.inc(); Ok(Some(ResolveResult { url: entry.upstream_url, latency_ms: entry.latency_ema, @@ -219,11 +215,11 @@ impl Router { }; }; - metrics::get() + ncro_metrics::get() .upstream_race_wins .with_label_values(&[&winner.url]) .inc(); - metrics::get() + ncro_metrics::get() .upstream_latency .with_label_values(&[&winner.url]) .observe(winner.latency_ms / 1000.0); diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml new file mode 100644 index 0000000..a1eaa8c --- /dev/null +++ b/crates/server/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "ncro-server" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +axum = { workspace = true, features = [ "macros" ] } +bytes.workspace = true +futures-util.workspace = true +ncro-config.workspace = true +ncro-db.workspace = true +ncro-health.workspace = true +ncro-metrics.workspace = true +ncro-router.workspace = true +reqwest = { workspace = true, features = [ "rustls", "stream" ] } +serde = { workspace = true, features = [ "derive" ] } +tracing.workspace = true diff --git a/src/server.rs b/crates/server/src/lib.rs similarity index 96% rename from src/server.rs rename to crates/server/src/lib.rs index f921562..e3c49cf 100644 --- a/src/server.rs +++ b/crates/server/src/lib.rs @@ -10,16 +10,12 @@ use axum::{ }; use bytes::Bytes; use futures_util::TryStreamExt; +use ncro_config::UpstreamConfig; +use ncro_db::Db; +use ncro_health::{Prober, Status}; +use ncro_router::{Router, RouterError}; use serde::Serialize; -use crate::{ - config::UpstreamConfig, - db::Db, - health::{Prober, Status}, - metrics, - router::{Router, RouterError}, -}; - #[derive(Clone)] pub struct AppState { router: Router, @@ -113,7 +109,7 @@ async fn health(State(state): State>) -> Response { async fn metrics_endpoint() -> Response { ( [("content-type", "text/plain; version=0.0.4")], - metrics::gather(), + ncro_metrics::gather(), ) .into_response() } @@ -133,7 +129,7 @@ async fn narinfo( latency_ms = result.latency_ms, "narinfo routed" ); - metrics::get() + ncro_metrics::get() .narinfo_requests .with_label_values(&["200"]) .inc(); @@ -154,7 +150,7 @@ async fn narinfo( .await }, Err(RouterError::NotFound) => { - metrics::get() + ncro_metrics::get() .narinfo_requests .with_label_values(&["error"]) .inc(); @@ -162,7 +158,7 @@ async fn narinfo( }, Err(err) => { tracing::warn!(hash, error = %err, "narinfo resolve failed"); - metrics::get() + ncro_metrics::get() .narinfo_requests .with_label_values(&["error"]) .inc(); @@ -175,7 +171,7 @@ async fn nar( State(state): State>, req: Request, ) -> Response { - metrics::get().nar_requests.inc(); + ncro_metrics::get().nar_requests.inc(); let nar_url = req.uri().path().trim_start_matches('/').to_string(); if let Ok(Some(entry)) = state.db.get_route_by_nar_url(&nar_url).await && entry.is_valid() diff --git a/src/cli.rs b/src/cli.rs index ffe68a5..990b76a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,18 +1,12 @@ use clap::Parser; +use ncro_config::Config; +use ncro_db::Db; +use ncro_discovery::Discovery; +use ncro_health::Prober; +use ncro_router::Router; use tokio::net::TcpListener; use tracing_subscriber::{EnvFilter, fmt}; -use crate::{ - config::Config, - db::Db, - discovery::Discovery, - health::Prober, - mesh, - metrics, - router::Router, - server, -}; - #[derive(Debug, Parser)] #[command(name = "ncro", version, about = "Nix Cache Route Optimizer")] pub struct Args { @@ -26,7 +20,7 @@ pub async fn run() -> anyhow::Result<()> { cfg.validate()?; init_logging(&cfg.logging.level, &cfg.logging.format); - let _ = metrics::get(); + let _ = ncro_metrics::get(); let db = Db::open(&cfg.cache.db_path, cfg.cache.max_entries).await?; let prober = Prober::new(cfg.cache.latency_alpha); @@ -99,7 +93,7 @@ pub async fn run() -> anyhow::Result<()> { _ = ticker.tick() => { let _ = db_for_expiry.expire_old_routes().await; let _ = db_for_expiry.expire_negatives().await; - if let Ok(count) = db_for_expiry.route_count().await { metrics::get().route_entries.set(count); } + if let Ok(count) = db_for_expiry.route_count().await { ncro_metrics::get().route_entries.set(count); } } } } @@ -114,7 +108,7 @@ pub async fn run() -> anyhow::Result<()> { } if cfg.mesh.enabled { - let node = mesh::Node::new(&cfg.mesh.private_key_path).await?; + let node = ncro_mesh::Node::new(&cfg.mesh.private_key_path).await?; tracing::info!( node_id = node.id(), public_key = hex::encode(node.public_key()), @@ -126,7 +120,7 @@ pub async fn run() -> anyhow::Result<()> { .iter() .filter_map(|p| hex::decode(&p.public_key).ok()?.try_into().ok()) .collect::>(); - mesh::listen_and_serve( + ncro_mesh::listen_and_serve( &cfg.mesh.bind_addr, db.clone(), allowed, @@ -139,7 +133,7 @@ pub async fn run() -> anyhow::Result<()> { .iter() .map(|p| p.addr.clone()) .collect::>(); - tokio::spawn(mesh::run_gossip_loop( + tokio::spawn(ncro_mesh::run_gossip_loop( node, db.clone(), peers, @@ -148,7 +142,7 @@ pub async fn run() -> anyhow::Result<()> { )); } - let app = server::app( + let app = ncro_server::app( router, prober, db, diff --git a/src/main.rs b/src/main.rs index 8c4b7ed..7f868a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,4 @@ mod cli; -mod config; -mod db; -mod discovery; -mod health; -mod mesh; -mod metrics; -mod narinfo; -mod router; -mod server; #[tokio::main] async fn main() -> anyhow::Result<()> {