diff --git a/Cargo.lock b/Cargo.lock index 8e896c4048..bc47d03a6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arc-swap" @@ -246,7 +246,7 @@ dependencies = [ "axum-macros", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "http-body-util", "hyper", @@ -262,9 +262,9 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -279,13 +279,13 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.2", + "sync_wrapper", "tower-layer", "tower-service", "tracing", @@ -311,7 +311,7 @@ dependencies = [ "arc-swap", "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "http-body-util", "hyper", @@ -447,9 +447,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -485,9 +485,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -536,9 +536,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cobs" @@ -1200,9 +1200,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" @@ -1365,7 +1365,7 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" dependencies = [ - "fastrand 2.2.0", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -1562,7 +1562,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", + "http 1.2.0", "indexmap", "slab", "tokio", @@ -1641,14 +1641,14 @@ dependencies = [ "futures-io", "futures-util", "h2", - "http 1.1.0", + "http 1.2.0", "idna", "ipnet", "once_cell", "rand", "rustls", "serde", - "thiserror 2.0.3", + "thiserror 2.0.6", "tinyvec", "tokio", "tokio-rustls", @@ -1674,7 +1674,7 @@ dependencies = [ "rustls", "serde", "smallvec", - "thiserror 2.0.3", + "thiserror 2.0.6", "tokio", "tokio-rustls", "tracing", @@ -1695,12 +1695,12 @@ dependencies = [ "h2", "hickory-proto", "hickory-resolver", - "http 1.1.0", + "http 1.2.0", "ipnet", "prefix-trie", "rustls", "serde", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-rustls", @@ -1729,9 +1729,9 @@ dependencies = [ [[package]] name = "hmac-sha256" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3688e69b38018fec1557254f64c8dc2cc8ec502890182f395dbb0aa997aa5735" +checksum = "4a8575493d277c9092b988c780c94737fb9fd8651a1001e16bee3eccfc1baedb" [[package]] name = "hostname" @@ -1774,9 +1774,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -1790,7 +1790,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -1801,7 +1801,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "pin-project-lite", ] @@ -1844,7 +1844,7 @@ dependencies = [ "futures-channel", "futures-util", "h2", - "http 1.1.0", + "http 1.2.0", "http-body", "httparse", "httpdate", @@ -1862,7 +1862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 1.1.0", + "http 1.2.0", "hyper", "hyper-util", "rustls", @@ -1882,7 +1882,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "hyper", "pin-project-lite", @@ -2064,7 +2064,7 @@ dependencies = [ "attohttpc", "bytes", "futures", - "http 1.1.0", + "http 1.2.0", "http-body-util", "hyper", "hyper-util", @@ -2163,7 +2163,7 @@ dependencies = [ "hex", "hickory-resolver", "hostname 0.4.0", - "http 1.1.0", + "http 1.2.0", "http-body-util", "hyper", "hyper-util", @@ -2211,7 +2211,7 @@ dependencies = [ "surge-ping", "swarm-discovery", "testresult", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-rustls", @@ -2253,7 +2253,7 @@ dependencies = [ "serde_json", "serde_test", "ssh-key", - "thiserror 2.0.3", + "thiserror 2.0.6", "ttl_cache", "url", "zeroize", @@ -2310,7 +2310,7 @@ dependencies = [ "governor 0.6.3", "hickory-resolver", "hickory-server", - "http 1.1.0", + "http 1.2.0", "humantime-serde", "iroh", "iroh-metrics", @@ -2461,7 +2461,7 @@ dependencies = [ "hickory-proto", "hickory-resolver", "hostname 0.4.0", - "http 1.1.0", + "http 1.2.0", "http-body-util", "hyper", "hyper-util", @@ -2480,9 +2480,12 @@ dependencies = [ "rand_chacha", "rcgen", "regex", + "reloadable-state", "reqwest", "ring", "rustls", + "rustls-cert-file-reader", + "rustls-cert-reloadable-resolver", "rustls-pemfile", "rustls-webpki", "serde", @@ -2491,7 +2494,7 @@ dependencies = [ "socket2", "stun-rs", "testresult", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-rustls", @@ -2582,9 +2585,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ "once_cell", "wasm-bindgen", @@ -2601,9 +2604,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.167" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libm" @@ -2635,9 +2638,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "litrs" @@ -2897,9 +2900,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" +checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" dependencies = [ "bytes", "futures", @@ -2932,7 +2935,7 @@ dependencies = [ "rtnetlink 0.14.1", "serde", "socket2", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-util", @@ -3260,20 +3263,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -3281,9 +3284,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", @@ -3294,9 +3297,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -3491,7 +3494,7 @@ dependencies = [ "serde", "smallvec", "socket2", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-util", @@ -3728,7 +3731,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.3", + "thiserror 2.0.6", "tokio", "tracing", ] @@ -3747,7 +3750,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.3", + "thiserror 2.0.6", "tinyvec", "tracing", "web-time", @@ -3755,9 +3758,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" +checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" dependencies = [ "cfg_aliases", "libc", @@ -3869,18 +3872,18 @@ dependencies = [ [[package]] name = "redb" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b1de48a7cf7ba193e81e078d17ee2b786236eed1d3f7c60f8a09545efc4925" +checksum = "a7c2a94325f9c5826b17c42af11067230f503747f870117a28180e85696e21ba" dependencies = [ "libc", ] [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -3946,6 +3949,23 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "reloadable-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dc20ac1418988b60072d783c9f68e28a173fb63493c127952f6face3b40c6e0" + +[[package]] +name = "reloadable-state" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3853ef78d45b50f8b989896304a85239539d39b7f866a000e8846b9b72d74ce8" +dependencies = [ + "arc-swap", + "reloadable-core", + "tokio", +] + [[package]] name = "reqwest" version = "0.12.9" @@ -3956,7 +3976,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.1.0", + "http 1.2.0", "http-body", "http-body-util", "hyper", @@ -3976,7 +3996,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.2", + "sync_wrapper", "tokio", "tokio-rustls", "tower-service", @@ -4112,22 +4132,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.41" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "log", "once_cell", @@ -4138,6 +4158,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-cert-file-reader" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f351eaf1dd003022222d2b1399caac198fefeab45c46b0f98bb03fc7cda9bb27" +dependencies = [ + "rustls-cert-read", + "rustls-pemfile", + "rustls-pki-types", + "thiserror 2.0.6", + "tokio", +] + +[[package]] +name = "rustls-cert-read" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd46e8c5ae4de3345c4786a83f99ec7aff287209b9e26fa883c473aeb28f19d5" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-cert-reloadable-resolver" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe1baa8a3a1f05eaa9fc55aed4342867f70e5c170ea3bfed1b38c51a4857c0c8" +dependencies = [ + "futures-util", + "reloadable-state", + "rustls", + "rustls-cert-read", + "thiserror 2.0.6", +] + [[package]] name = "rustls-native-certs" version = "0.7.3" @@ -4310,9 +4365,9 @@ dependencies = [ [[package]] name = "self_cell" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" +checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe" [[package]] name = "semver" @@ -4322,9 +4377,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -4350,9 +4405,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -4750,12 +4805,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.2" @@ -4810,7 +4859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", - "fastrand 2.2.0", + "fastrand 2.3.0", "once_cell", "rustix", "windows-sys 0.59.0", @@ -4833,11 +4882,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl 2.0.6", ] [[package]] @@ -4853,9 +4902,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", @@ -4874,9 +4923,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -4897,9 +4946,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -4942,9 +4991,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -4971,12 +5020,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] @@ -5001,7 +5049,7 @@ dependencies = [ "rustls", "serde", "serde_json", - "thiserror 2.0.3", + "thiserror 2.0.6", "time", "tokio", "tokio-rustls", @@ -5011,9 +5059,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -5040,7 +5088,7 @@ checksum = "8e57a65894797a018b28345fa298a00c450a574aa9671e50b18218a6292a55ac" dependencies = [ "futures-channel", "futures-util", - "http 1.1.0", + "http 1.2.0", "httparse", "js-sys", "thiserror 1.0.69", @@ -5052,9 +5100,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -5116,14 +5164,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -5138,7 +5186,7 @@ checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "bitflags 2.6.0", "bytes", - "http 1.1.0", + "http 1.2.0", "http-body", "pin-project-lite", "tower-layer", @@ -5167,10 +5215,10 @@ dependencies = [ "axum", "forwarded-header-value", "governor 0.6.3", - "http 1.1.0", + "http 1.2.0", "pin-project", "thiserror 1.0.69", - "tower 0.5.1", + "tower 0.5.2", "tracing", ] @@ -5267,7 +5315,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", "rand", @@ -5355,20 +5403,17 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.11.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30e6f97efe1fa43535ee241ee76967d3ff6ff3953ebb430d8d55c5393029e7b" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64", - "litemap", "log", "once_cell", "rustls", "rustls-pki-types", "url", "webpki-roots", - "yoke", - "zerofrom", ] [[package]] @@ -5470,9 +5515,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -5481,13 +5526,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.90", @@ -5496,9 +5540,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.47" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", @@ -5509,9 +5553,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5519,9 +5563,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -5532,9 +5576,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "watchable" @@ -5550,9 +5594,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -5886,15 +5930,15 @@ dependencies = [ [[package]] name = "wmi" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70df482bbec7017ce4132154233642de658000b24b805345572036782a66ad55" +checksum = "dc47c0776cc6c00d2f7a874a0c846d94d45535936e5a1187693a24f23b4dd701" dependencies = [ "chrono", "futures", "log", "serde", - "thiserror 1.0.69", + "thiserror 2.0.6", "windows 0.58.0", "windows-core 0.58.0", ] @@ -5930,9 +5974,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" +checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" [[package]] name = "xmltree" @@ -5960,9 +6004,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -6011,9 +6055,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index b2134edb40..6199a2d2bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,4 +40,4 @@ missing_debug_implementations = "warn" unexpected_cfgs = { level = "warn", check-cfg = ["cfg(iroh_docsrs)"] } [workspace.lints.clippy] -unused-async = "warn" +unused-async = "warn" \ No newline at end of file diff --git a/iroh-relay/Cargo.toml b/iroh-relay/Cargo.toml index 1cd06d53ef..62b722b27e 100644 --- a/iroh-relay/Cargo.toml +++ b/iroh-relay/Cargo.toml @@ -54,11 +54,14 @@ quinn-proto = { package = "iroh-quinn-proto", version = "0.12.0" } rand = "0.8" rcgen = { version = "0.13", optional = true } regex = { version = "1.7.1", optional = true } +reloadable-state = { version = "0.1", optional = true } reqwest = { version = "0.12", default-features = false, features = [ "rustls-tls", ] } ring = "0.17" rustls = { version = "0.23", default-features = false, features = ["ring"] } +rustls-cert-reloadable-resolver = { version = "0.7.1", optional = true } +rustls-cert-file-reader = { version = "0.4.1", optional = true } rustls-pemfile = { version = "2.1", optional = true } serde = { version = "1", features = ["derive", "rc"] } smallvec = "1.11.1" @@ -124,6 +127,9 @@ server = [ "dep:regex", "dep:tracing-subscriber", "dep:rcgen", + "dep:reloadable-state", + "dep:rustls-cert-reloadable-resolver", + "dep:rustls-cert-file-reader", ] metrics = ["iroh-metrics/metrics"] test-utils = [] @@ -135,4 +141,4 @@ required-features = ["server"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "iroh_docsrs"] +rustdoc-args = ["--cfg", "iroh_docsrs"] \ No newline at end of file diff --git a/iroh-relay/src/main.rs b/iroh-relay/src/main.rs index 73d8825cb3..481bca569f 100644 --- a/iroh-relay/src/main.rs +++ b/iroh-relay/src/main.rs @@ -6,6 +6,7 @@ use std::{ net::{Ipv6Addr, SocketAddr}, path::{Path, PathBuf}, + sync::Arc, }; use anyhow::{bail, Context as _, Result}; @@ -56,6 +57,8 @@ struct Cli { enum CertMode { Manual, LetsEncrypt, + #[cfg(feature = "server")] + Reloading, } fn load_certs( @@ -468,6 +471,39 @@ async fn maybe_load_tls( let server_config = server_config.with_cert_resolver(resolver); (relay::CertConfig::LetsEncrypt { state }, server_config) } + #[cfg(feature = "server")] + CertMode::Reloading => { + use rustls_cert_file_reader::FileReader; + use rustls_cert_reloadable_resolver::{key_provider::Dyn, CertifiedKeyLoader}; + use webpki::types::{CertificateDer, PrivateKeyDer}; + + let cert_path = tls.cert_path(); + let key_path = tls.key_path(); + let interval = std::time::Duration::from_secs(relay::DEFAULT_CERT_RELOAD_INTERVAL); + + let key_reader = rustls_cert_file_reader::FileReader::new( + key_path, + rustls_cert_file_reader::Format::DER, + ); + let certs_reader = rustls_cert_file_reader::FileReader::new( + cert_path, + rustls_cert_file_reader::Format::DER, + ); + + let loader: CertifiedKeyLoader< + Dyn, + FileReader>, + FileReader>>, + > = CertifiedKeyLoader { + key_provider: Dyn(server_config.crypto_provider().key_provider), + key_reader, + certs_reader, + }; + + let resolver = Arc::new(relay::ReloadingResolver::init(loader, interval).await?); + let server_config = server_config.with_cert_resolver(resolver); + (relay::CertConfig::Reloading, server_config) + } }; Ok(Some(relay::TlsConfig { https_bind_addr: tls.https_bind_addr(cfg), diff --git a/iroh-relay/src/server.rs b/iroh-relay/src/server.rs index 96eaa20d1e..160a9d3e0d 100644 --- a/iroh-relay/src/server.rs +++ b/iroh-relay/src/server.rs @@ -46,12 +46,14 @@ pub(crate) mod client_conn; mod clients; mod http_server; mod metrics; +pub(crate) mod resolver; pub(crate) mod streams; #[cfg(feature = "test-utils")] pub mod testing; pub use self::{ metrics::{Metrics, StunMetrics}, + resolver::{ReloadingResolver, DEFAULT_CERT_RELOAD_INTERVAL}, streams::MaybeTlsStream as MaybeTlsStreamServer, }; @@ -198,6 +200,8 @@ pub enum CertConfig { /// The TLS certificate chain. certs: Vec>, }, + /// Use a TLS key and certificate chain that can be reloaded. + Reloading, } /// A running Relay + STUN server. @@ -279,6 +283,7 @@ impl Server { relay.tls.as_ref().and_then(|tls| match tls.cert { CertConfig::LetsEncrypt { .. } => None, CertConfig::Manual { ref certs, .. } => Some(certs.clone()), + CertConfig::Reloading { .. } => None, }) }); @@ -335,7 +340,7 @@ impl Server { acceptor, }) } - CertConfig::Manual { .. } => { + CertConfig::Manual { .. } | CertConfig::Reloading { .. } => { let server_config = Arc::new(tls_config.server_config); let acceptor = tokio_rustls::TlsAcceptor::from(server_config.clone()); diff --git a/iroh-relay/src/server/resolver.rs b/iroh-relay/src/server/resolver.rs new file mode 100644 index 0000000000..18cecaf1e3 --- /dev/null +++ b/iroh-relay/src/server/resolver.rs @@ -0,0 +1,93 @@ +use std::{sync::Arc, time::Duration}; + +use anyhow::{anyhow, Result}; +use reloadable_state::Reloadable; +use rustls::{ + server::{ClientHello, ResolvesServerCert}, + sign::CertifiedKey, +}; +use tokio_util::{sync::CancellationToken, task::AbortOnDropHandle}; + +/// The default certificate reload interval. +pub const DEFAULT_CERT_RELOAD_INTERVAL: u64 = 60 * 60 * 24; + +/// A Certificate resolver that reloads the certificate every interval +#[derive(Debug)] +pub struct ReloadingResolver { + /// The inner reloadable value. + reloadable: Arc>, + /// The handle to the task that reloads the certificate. + _handle: AbortOnDropHandle<()>, + /// Cancel token to shutdown the resolver. + cancel_token: CancellationToken, +} + +impl ReloadingResolver +where + Loader: Send + reloadable_state::core::Loader + 'static, +{ + /// Perform the initial load and construct the [`ReloadingResolver`]. + pub async fn init(loader: Loader, interval: Duration) -> Result { + let (reloadable, _) = Reloadable::init_load(loader) + .await + .map_err(|_| anyhow!("Failed to load the certificate"))?; + let reloadable = Arc::new(reloadable); + + let cancel_token = CancellationToken::new(); + + // Spawn a task to reload the certificate every interval. + let _reloadable = reloadable.clone(); + let _cancel_token = cancel_token.clone(); + let _handle = tokio::spawn(async move { + let mut interval = tokio::time::interval(interval); + loop { + tokio::select! { + _ = interval.tick() => { + let _ = _reloadable.reload().await; + tracing::info!("Reloaded the certificate"); + }, + _ = _cancel_token.cancelled() => { + tracing::trace!("shutting down"); + break; + } + } + } + }); + let _handle = AbortOnDropHandle::new(_handle); + + Ok(Self { + reloadable, + _handle, + cancel_token, + }) + } + + /// Shutdown the resolver. + pub fn shutdown(self) { + self.cancel_token.cancel(); + } + + /// Reload the certificate. + pub async fn reload(&self) { + let _ = self.reloadable.reload().await; + } +} + +impl ResolvesServerCert for ReloadingResolver +where + Loader: reloadable_state::core::Loader, + Loader: Send, + Loader: std::fmt::Debug, +{ + fn resolve(&self, _client_hello: ClientHello) -> Option> { + Some(self.reloadable.get()) + } +} + +impl std::ops::Deref for ReloadingResolver { + type Target = Reloadable; + + fn deref(&self) -> &Self::Target { + &self.reloadable + } +}