diff --git a/core/Cargo.lock b/core/Cargo.lock index 0e96d08e4..739b886cf 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -153,24 +153,24 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] name = "ar_archive_writer" -version = "0.2.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" +checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" dependencies = [ - "object 0.32.2", + "object", ] [[package]] name = "arc-swap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" +checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73" dependencies = [ "rustversion", ] @@ -232,7 +232,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "synstructure", ] @@ -244,7 +244,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -306,9 +306,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d10e4f991a553474232bc0a31799f6d24b034a84c0971d80d2e2f78b2e576e40" +checksum = "68650b7df54f0293fd061972a0fb05aaf4fc0879d3b3d21a638a182c5c543b9f" dependencies = [ "compression-codecs", "compression-core", @@ -385,7 +385,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -425,7 +425,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -442,7 +442,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -468,9 +468,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.3" +version = "1.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86" +checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" dependencies = [ "aws-lc-sys", "zeroize", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.36.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8" +checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" dependencies = [ "cc", "cmake", @@ -553,7 +553,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.37.3", + "object", "rustc-demangle", "windows-link", ] @@ -829,9 +829,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" [[package]] name = "byteorder" @@ -847,15 +847,15 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.53" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -959,9 +959,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" dependencies = [ "clap_builder", "clap_derive", @@ -969,9 +969,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" dependencies = [ "anstream", "anstyle", @@ -982,21 +982,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "clipboard-win" @@ -1412,9 +1412,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -1496,7 +1496,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1539,14 +1539,14 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" dependencies = [ "powerfmt", ] @@ -1570,7 +1570,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1629,7 +1629,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1655,7 +1655,7 @@ checksum = "6e39034cee21a2f5bbb66ba0e3689819c4bb5d00382a282006e802a7ffa6c41d" dependencies = [ "cfg-if", "libc", - "socket2 0.6.1", + "socket2 0.6.2", "windows-sys 0.60.2", ] @@ -1815,9 +1815,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] @@ -1852,7 +1852,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -1873,7 +1873,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2002,21 +2002,20 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixedbitset" @@ -2026,9 +2025,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2193,7 +2192,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -2248,9 +2247,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -2324,6 +2323,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + [[package]] name = "gimli" version = "0.32.3" @@ -2345,8 +2357,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.13", - "regex-syntax 0.8.8", + "regex-automata 0.4.14", + "regex-syntax 0.8.9", ] [[package]] @@ -2539,7 +2551,7 @@ dependencies = [ "rand 0.9.2", "ring", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tokio", "tracing", @@ -2563,7 +2575,7 @@ dependencies = [ "resolv-conf", "serde", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -2585,7 +2597,7 @@ dependencies = [ "ipnet", "prefix-trie", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -2724,7 +2736,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] @@ -2758,14 +2770,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", @@ -2774,7 +2785,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.6.2", "system-configuration", "tokio", "tower-service", @@ -2784,9 +2795,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2887,6 +2898,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "id-pool" version = "0.2.2" @@ -2940,7 +2957,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.13", + "regex-automata 0.4.14", "same-file", "walkdir", "winapi-util", @@ -2984,9 +3001,9 @@ dependencies = [ [[package]] name = "imbl-value" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2a5f88a75295785a3b4a752db1d45a3b83b9f3a4b13dc70a5aaa6c16d859b3" +checksum = "2722c61df925c481ef6e78c66c451c8ff8514430ec9bacfa02613d8c126205dd" dependencies = [ "imbl", "serde", @@ -2997,8 +3014,8 @@ dependencies = [ [[package]] name = "imbl-value" -version = "0.4.3" -source = "git+https://github.com/Start9Labs/imbl-value.git#27f9bb38cd87290ce4732a2ef3034ea1c7340560" +version = "0.4.4" +source = "git+https://github.com/Start9Labs/imbl-value.git#ffb4901d55c7771489599b21314c08663328c8c2" dependencies = [ "imbl", "serde", @@ -3315,7 +3332,7 @@ dependencies = [ "regex", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", ] @@ -3333,7 +3350,7 @@ dependencies = [ name = "json-patch" version = "0.2.7-alpha.0" dependencies = [ - "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "imbl-value 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "json-ptr", "serde", ] @@ -3343,9 +3360,9 @@ name = "json-ptr" version = "0.1.0" dependencies = [ "imbl", - "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "imbl-value 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3353,7 +3370,7 @@ name = "jsonpath_lib" version = "0.3.0" source = "git+https://github.com/Start9Labs/jsonpath.git#1cacbd64afa2e1941a21fef06bad14317ba92f30" dependencies = [ - "imbl-value 0.4.3 (git+https://github.com/Start9Labs/imbl-value.git)", + "imbl-value 0.4.4 (git+https://github.com/Start9Labs/imbl-value.git)", "log", "serde", "serde_json", @@ -3388,7 +3405,7 @@ dependencies = [ "petgraph", "pico-args", "regex", - "regex-syntax 0.8.8", + "regex-syntax 0.8.9", "string_cache", "term", "tiny-keccak", @@ -3402,7 +3419,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex-automata 0.4.13", + "regex-automata 0.4.14", ] [[package]] @@ -3436,6 +3453,12 @@ dependencies = [ "spin", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "lettre" version = "0.11.19" @@ -3459,7 +3482,7 @@ dependencies = [ "quoted_printable", "rustls 0.23.36", "rustls-platform-verifier", - "socket2 0.6.1", + "socket2 0.6.2", "tokio", "tokio-rustls 0.26.4", "url", @@ -3480,9 +3503,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.180" +version = "0.2.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "libloading" @@ -3496,9 +3519,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libmimalloc-sys" @@ -3518,7 +3541,7 @@ checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall 0.7.0", + "redox_syscall 0.7.1", ] [[package]] @@ -3616,7 +3639,7 @@ dependencies = [ "bitvec 1.0.1", "serde", "serde-big-array", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3631,9 +3654,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -3698,7 +3721,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -3746,9 +3769,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.12" +version = "0.12.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" +checksum = "b4ac832c50ced444ef6be0767a008b02c106a909ba79d1d830501e94b96f6b7e" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -3773,9 +3796,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "6cdede44f9a69cab2899a2049e2c3bd49bf911a157f6a3353d4a91c61abbce44" dependencies = [ "libc", "log", @@ -3956,9 +3979,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -4030,7 +4053,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4068,15 +4091,6 @@ dependencies = [ "objc", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "object" version = "0.37.3" @@ -4175,7 +4189,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4186,15 +4200,15 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-probe" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-src" -version = "300.5.4+3.5.4" +version = "300.5.5+3.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" +checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" dependencies = [ "cc", ] @@ -4334,7 +4348,7 @@ dependencies = [ "fd-lock-rs", "futures", "imbl", - "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "imbl-value 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "json-patch", "json-ptr", "lazy_static", @@ -4342,7 +4356,7 @@ dependencies = [ "patch-db-macro", "serde", "serde_cbor 0.11.1", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "tracing-error", @@ -4404,9 +4418,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ "memchr", "ucd-trie", @@ -4414,9 +4428,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" dependencies = [ "pest", "pest_generator", @@ -4424,22 +4438,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "pest_meta" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ "pest", "sha2 0.10.9", @@ -4485,7 +4499,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4520,7 +4534,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4602,9 +4616,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-pty" @@ -4677,6 +4691,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.115", +] + [[package]] name = "prettytable-rs" version = "0.10.0" @@ -4711,9 +4735,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -4744,9 +4768,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", @@ -4755,7 +4779,7 @@ dependencies = [ "rand 0.9.2", "rand_chacha 0.9.0", "rand_xorshift", - "regex-syntax 0.8.8", + "regex-syntax 0.8.9", "rusty-fork", "tempfile", "unarray", @@ -4769,7 +4793,7 @@ checksum = "fb6dc647500e84a25a85b100e76c85b8ace114c209432dc174f20aac11d4ed6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4792,7 +4816,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -4812,9 +4836,9 @@ checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" [[package]] name = "psm" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01" +checksum = "3852766467df634d74f0b2d7819bf8dc483a0eb2e3b0f50f756f9cfe8b0d18d8" dependencies = [ "ar_archive_writer", "cc", @@ -4885,8 +4909,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls 0.23.36", - "socket2 0.6.1", - "thiserror 2.0.17", + "socket2 0.6.2", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -4907,7 +4931,7 @@ dependencies = [ "rustls 0.23.36", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -4922,16 +4946,16 @@ dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.6.2", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -4986,7 +5010,7 @@ dependencies = [ "strum_macros", "syntect", "textwrap", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "tracing-appender", @@ -5169,9 +5193,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" dependencies = [ "bitflags 2.10.0", ] @@ -5189,14 +5213,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.13", - "regex-syntax 0.8.8", + "regex-automata 0.4.14", + "regex-syntax 0.8.9", ] [[package]] @@ -5210,13 +5234,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.8", + "regex-syntax 0.8.9", ] [[package]] @@ -5227,9 +5251,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "reqwest" @@ -5277,7 +5301,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] @@ -5345,7 +5369,7 @@ dependencies = [ "futures", "http", "http-body-util", - "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "imbl-value 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.14.0", "lazy_format", "lazy_static", @@ -5355,7 +5379,7 @@ dependencies = [ "serde", "serde_cbor 0.11.2", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "url", @@ -5433,7 +5457,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5551,7 +5575,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe 0.2.0", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", "security-framework 3.5.1", @@ -5646,9 +5670,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -5794,7 +5818,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -5841,7 +5865,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6052,15 +6076,15 @@ checksum = "c11532d9d241904f095185f35dcdaf930b1427a94d5b01d7002d74ba19b44cc4" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "sled" @@ -6143,9 +6167,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -6160,7 +6184,7 @@ dependencies = [ "async-trait", "bytes", "percent-encoding", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", ] @@ -6219,7 +6243,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "tracing", @@ -6237,7 +6261,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6258,7 +6282,7 @@ dependencies = [ "sha2 0.10.9", "sqlx-core", "sqlx-postgres", - "syn 2.0.114", + "syn 2.0.115", "tokio", "url", ] @@ -6295,7 +6319,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "whoami", ] @@ -6323,7 +6347,7 @@ dependencies = [ "quote", "regex-syntax 0.6.29", "strsim", - "syn 2.0.114", + "syn 2.0.115", "unicode-width 0.1.14", ] @@ -6377,9 +6401,9 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stacker" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" +checksum = "08d74a23609d509411d10e2176dc2a4346e3b4aea2e7b1869f19fdedbc71c013" dependencies = [ "cc", "cfg-if", @@ -6437,7 +6461,7 @@ dependencies = [ "id-pool", "iddqd", "imbl", - "imbl-value 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "imbl-value 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "include_dir", "indexmap 2.13.0", "indicatif", @@ -6495,7 +6519,7 @@ dependencies = [ "sha-crypt", "sha2 0.10.9", "signal-hook", - "socket2 0.6.1", + "socket2 0.6.2", "socks5-impl", "sqlx", "sscanf", @@ -6503,14 +6527,14 @@ dependencies = [ "tar", "termion", "textwrap", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-rustls 0.26.4", "tokio-stream", "tokio-tar", "tokio-tungstenite 0.26.2", "tokio-util", - "toml 0.9.11+spec-1.1.0", + "toml 0.9.12+spec-1.1.0", "tower-service", "tracing", "tracing-error", @@ -6593,7 +6617,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6636,9 +6660,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" dependencies = [ "proc-macro2", "quote", @@ -6662,7 +6686,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6677,20 +6701,20 @@ dependencies = [ "once_cell", "onig", "plist", - "regex-syntax 0.8.8", + "regex-syntax 0.8.9", "serde", "serde_derive", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "walkdir", "yaml-rust", ] [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ "bitflags 2.10.0", "core-foundation 0.9.4", @@ -6732,12 +6756,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.1", "once_cell", "rustix 1.1.3", "windows-sys 0.61.2", @@ -6805,11 +6829,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -6820,18 +6844,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -6845,9 +6869,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -6860,15 +6884,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -6920,7 +6944,7 @@ dependencies = [ "parking_lot 0.12.5", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.2", "tokio-macros", "tracing", "windows-sys 0.61.2", @@ -6934,7 +6958,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -7056,9 +7080,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.11+spec-1.1.0" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap 2.13.0", "serde_core", @@ -7115,9 +7139,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.0.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "0742ff5ff03ea7e67c8ae6c93cac239e0d9784833362da3f9a9c1da8dfefcbdc" dependencies = [ "winnow", ] @@ -7136,9 +7160,9 @@ checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tonic" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +checksum = "a286e33f82f8a1ee2df63f4fa35c0becf4a85a0cb03091a15fd7bf0b402dc94a" dependencies = [ "async-trait", "axum", @@ -7153,7 +7177,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2 0.6.1", + "socket2 0.6.2", "sync_wrapper", "tokio", "tokio-stream", @@ -7165,9 +7189,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +checksum = "d6c55a2d6a14174563de34409c9f92ff981d006f56da9c6ecd40d9d4a31500b0" dependencies = [ "bytes", "prost", @@ -7242,7 +7266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tracing-subscriber", ] @@ -7255,7 +7279,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -7353,7 +7377,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "termcolor", ] @@ -7371,7 +7395,7 @@ dependencies = [ "native-tls", "rand 0.9.2", "sha1", - "thiserror 2.0.17", + "thiserror 2.0.18", "url", "utf-8", ] @@ -7389,7 +7413,7 @@ dependencies = [ "log", "rand 0.9.2", "sha1", - "thiserror 2.0.17", + "thiserror 2.0.18", "utf-8", ] @@ -7410,7 +7434,7 @@ checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -7456,9 +7480,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-linebreak" @@ -7562,9 +7586,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -7616,7 +7640,7 @@ checksum = "2a3bfb04fd13da4fc8df24709b7a0949667f43c63691d9fecddf1d3be8af5099" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -7677,6 +7701,15 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasite" version = "0.1.0" @@ -7729,7 +7762,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "wasm-bindgen-shared", ] @@ -7742,6 +7775,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + [[package]] name = "wasm-streams" version = "0.4.2" @@ -7755,6 +7810,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver", +] + [[package]] name = "wayland-client" version = "0.29.5" @@ -7850,9 +7917,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" dependencies = [ "rustls-pki-types", ] @@ -7863,14 +7930,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.5", + "webpki-roots 1.0.6", ] [[package]] name = "webpki-roots" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" dependencies = [ "rustls-pki-types", ] @@ -7964,7 +8031,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -7975,7 +8042,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -8343,6 +8410,88 @@ name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.115", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.115", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" @@ -8531,15 +8680,15 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "synstructure", ] [[package]] name = "zbus" -version = "5.13.1" +version = "5.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f79257df967b6779afa536788657777a0001f5b42524fcaf5038d4344df40b" +checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1" dependencies = [ "async-broadcast", "async-executor", @@ -8572,14 +8721,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.13.1" +version = "5.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad23e2d2f91cae771c7af7a630a49e755f1eb74f8a46e9f6d5f7a146edf5a37" +checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "zbus_names", "zvariant", "zvariant_utils", @@ -8598,22 +8747,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -8633,7 +8782,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "synstructure", ] @@ -8654,7 +8803,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] @@ -8687,14 +8836,14 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", ] [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zstd" @@ -8726,9 +8875,9 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.9.1" +version = "5.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "326aaed414f04fe839777b4c443d4e94c74e7b3621093bd9c5e649ac8aa96543" +checksum = "68b64ef4f40c7951337ddc7023dd03528a57a3ce3408ee9da5e948bd29b232c4" dependencies = [ "endi", "enumflags2", @@ -8740,14 +8889,14 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.9.1" +version = "5.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba44e1f8f4da9e6e2d25d2a60b116ef8b9d0be174a7685e55bb12a99866279a7" +checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.115", "zvariant_utils", ] @@ -8760,6 +8909,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.114", + "syn 2.0.115", "winnow", ] diff --git a/core/build/build-ts.sh b/core/build/build-ts.sh index 9f659af24..9bed2f19f 100755 --- a/core/build/build-ts.sh +++ b/core/build/build-ts.sh @@ -11,7 +11,7 @@ PROFILE=${PROFILE:-debug} if [ "${PROFILE}" = "release" ]; then BUILD_FLAGS="--release" else - if [ "$PROFILE" != "debug"]; then + if [ "$PROFILE" != "debug" ]; then >&2 echo "Unknown profile $PROFILE: falling back to debug..." PROFILE=debug fi diff --git a/core/src/db/model/public.rs b/core/src/db/model/public.rs index 0cdf868c9..831f5d4a8 100644 --- a/core/src/db/model/public.rs +++ b/core/src/db/model/public.rs @@ -20,8 +20,9 @@ use crate::db::model::Database; use crate::db::model::package::AllPackageData; use crate::net::acme::AcmeProvider; use crate::net::host::Host; -use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, Bindings, DerivedAddressInfo, NetInfo}; -use crate::net::utils::ipv6_is_local; +use crate::net::host::binding::{ + AddSslOptions, BindInfo, BindOptions, Bindings, DerivedAddressInfo, NetInfo, +}; use crate::net::vhost::AlpnInfo; use crate::prelude::*; use crate::progress::FullProgress; @@ -91,7 +92,7 @@ impl Public { .collect(), ), public_domains: BTreeMap::new(), - private_domains: BTreeSet::new(), + private_domains: BTreeMap::new(), }, wifi: WifiInfo { enabled: true, @@ -242,44 +243,12 @@ pub struct DnsSettings { #[ts(export)] pub struct NetworkInterfaceInfo { pub name: Option, - #[ts(skip)] - pub public: Option, pub secure: Option, pub ip_info: Option>, #[serde(default, rename = "type")] pub gateway_type: Option, } impl NetworkInterfaceInfo { - pub fn public(&self) -> bool { - self.public.unwrap_or_else(|| { - !self.ip_info.as_ref().map_or(true, |ip_info| { - let ip4s = ip_info - .subnets - .iter() - .filter_map(|ipnet| { - if let IpAddr::V4(ip4) = ipnet.addr() { - Some(ip4) - } else { - None - } - }) - .collect::>(); - if !ip4s.is_empty() { - return ip4s - .iter() - .all(|ip4| ip4.is_loopback() || ip4.is_private() || ip4.is_link_local()); - } - ip_info.subnets.iter().all(|ipnet| { - if let IpAddr::V6(ip6) = ipnet.addr() { - ipv6_is_local(ip6) - } else { - true - } - }) - }) - }) - } - pub fn secure(&self) -> bool { self.secure.unwrap_or(false) } @@ -316,7 +285,20 @@ pub enum NetworkInterfaceType { Loopback, } -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS, clap::ValueEnum)] +#[derive( + Clone, + Copy, + Debug, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Deserialize, + Serialize, + TS, + clap::ValueEnum, +)] #[ts(export)] #[serde(rename_all = "kebab-case")] pub enum GatewayType { diff --git a/core/src/middleware/auth/signature.rs b/core/src/middleware/auth/signature.rs index 22af16182..1536ea4a1 100644 --- a/core/src/middleware/auth/signature.rs +++ b/core/src/middleware/auth/signature.rs @@ -71,7 +71,7 @@ impl SignatureAuthContext for RpcContext { .as_network() .as_host() .as_private_domains() - .de() + .keys() .map(|k| k.into_iter()) .transpose(), ) diff --git a/core/src/net/dns.rs b/core/src/net/dns.rs index 84c5cb3a4..cb435624d 100644 --- a/core/src/net/dns.rs +++ b/core/src/net/dns.rs @@ -10,7 +10,7 @@ use color_eyre::eyre::eyre; use futures::{FutureExt, StreamExt, TryStreamExt}; use hickory_server::authority::{AuthorityObject, Catalog, MessageResponseBuilder}; use hickory_server::proto::op::{Header, ResponseCode}; -use hickory_server::proto::rr::{LowerName, Name, Record, RecordType}; +use hickory_server::proto::rr::{Name, Record, RecordType}; use hickory_server::resolver::config::{ResolverConfig, ResolverOpts}; use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseInfo}; use hickory_server::store::forwarder::{ForwardAuthority, ForwardConfig}; diff --git a/core/src/net/gateway.rs b/core/src/net/gateway.rs index c9c91c188..e10f2cb73 100644 --- a/core/src/net/gateway.rs +++ b/core/src/net/gateway.rs @@ -56,7 +56,7 @@ pub fn gateway_api() -> ParentHandler { } let mut table = Table::new(); - table.add_row(row![bc => "INTERFACE", "TYPE", "PUBLIC", "ADDRESSES", "WAN IP"]); + table.add_row(row![bc => "INTERFACE", "TYPE", "ADDRESSES", "WAN IP"]); for (iface, info) in res { table.add_row(row![ iface, @@ -64,7 +64,6 @@ pub fn gateway_api() -> ParentHandler { .as_ref() .and_then(|ip_info| ip_info.device_type) .map_or_else(|| "UNKNOWN".to_owned(), |ty| format!("{ty:?}")), - info.public(), info.ip_info.as_ref().map_or_else( || "".to_owned(), |ip_info| ip_info @@ -94,22 +93,6 @@ pub fn gateway_api() -> ParentHandler { .with_about("about.show-gateways-startos-can-listen-on") .with_call_remote::(), ) - .subcommand( - "set-public", - from_fn_async(set_public) - .with_metadata("sync_db", Value::Bool(true)) - .no_display() - .with_about("about.indicate-gateway-inbound-access-from-wan") - .with_call_remote::(), - ) - .subcommand( - "unset-public", - from_fn_async(unset_public) - .with_metadata("sync_db", Value::Bool(true)) - .no_display() - .with_about("about.allow-gateway-infer-inbound-access-from-wan") - .with_call_remote::(), - ) .subcommand( "forget", from_fn_async(forget_iface) @@ -134,40 +117,6 @@ async fn list_interfaces( Ok(ctx.net_controller.net_iface.watcher.ip_info()) } -#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] -struct NetworkInterfaceSetPublicParams { - #[arg(help = "help.arg.gateway-id")] - gateway: GatewayId, - #[arg(help = "help.arg.is-public")] - public: Option, -} - -async fn set_public( - ctx: RpcContext, - NetworkInterfaceSetPublicParams { gateway, public }: NetworkInterfaceSetPublicParams, -) -> Result<(), Error> { - ctx.net_controller - .net_iface - .set_public(&gateway, Some(public.unwrap_or(true))) - .await -} - -#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] -struct UnsetPublicParams { - #[arg(help = "help.arg.gateway-id")] - gateway: GatewayId, -} - -async fn unset_public( - ctx: RpcContext, - UnsetPublicParams { gateway }: UnsetPublicParams, -) -> Result<(), Error> { - ctx.net_controller - .net_iface - .set_public(&gateway, None) - .await -} - #[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)] struct ForgetGatewayParams { #[arg(help = "help.arg.gateway-id")] @@ -910,12 +859,11 @@ async fn watch_ip( write_to.send_if_modified( |m: &mut OrdMap| { - let (name, public, secure, gateway_type, prev_wan_ip) = m + let (name, secure, gateway_type, prev_wan_ip) = m .get(&iface) - .map_or((None, None, None, None, None), |i| { + .map_or((None, None, None, None), |i| { ( i.name.clone(), - i.public, i.secure, i.gateway_type, i.ip_info @@ -929,7 +877,6 @@ async fn watch_ip( iface.clone(), NetworkInterfaceInfo { name, - public, secure, ip_info: Some(ip_info.clone()), gateway_type, @@ -1192,43 +1139,6 @@ impl NetworkInterfaceController { } } - pub async fn set_public( - &self, - interface: &GatewayId, - public: Option, - ) -> Result<(), Error> { - let mut sub = self - .db - .subscribe( - "/public/serverInfo/network/gateways" - .parse::>() - .with_kind(ErrorKind::Database)?, - ) - .await; - let mut err = None; - let changed = self.watcher.ip_info.send_if_modified(|ip_info| { - let prev = std::mem::replace( - &mut match ip_info.get_mut(interface).or_not_found(interface) { - Ok(a) => a, - Err(e) => { - err = Some(e); - return false; - } - } - .public, - public, - ); - prev != public - }); - if let Some(e) = err { - return Err(e); - } - if changed { - sub.recv().await; - } - Ok(()) - } - pub async fn forget(&self, interface: &GatewayId) -> Result<(), Error> { let mut sub = self .db diff --git a/core/src/net/host/address.rs b/core/src/net/host/address.rs index 33c32073b..e7f5d8518 100644 --- a/core/src/net/host/address.rs +++ b/core/src/net/host/address.rs @@ -20,7 +20,7 @@ use crate::util::serde::{HandlerExtSerde, display_serializable}; pub struct HostAddress { pub address: InternedString, pub public: Option, - pub private: bool, + pub private: Option>, } #[derive(Debug, Clone, Deserialize, Serialize, TS)] @@ -53,7 +53,7 @@ fn handle_duplicates(db: &mut DatabaseModel) -> Result<(), Error> { for domain in &public { check_domain(&mut domains, domain.clone())?; } - for domain in host.as_private_domains().de()? { + for domain in host.as_private_domains().keys()? { if !public.contains(&domain) { check_domain(&mut domains, domain)?; } @@ -63,13 +63,13 @@ fn handle_duplicates(db: &mut DatabaseModel) -> Result<(), Error> { host.as_public_domains_mut() .mutate(|d| Ok(d.retain(|d, _| !domains.contains(d))))?; host.as_private_domains_mut() - .mutate(|d| Ok(d.retain(|d| !domains.contains(d))))?; + .mutate(|d| Ok(d.retain(|d, _| !domains.contains(d))))?; let public = host.as_public_domains().keys()?; for domain in &public { check_domain(&mut domains, domain.clone())?; } - for domain in host.as_private_domains().de()? { + for domain in host.as_private_domains().keys()? { if !public.contains(&domain) { check_domain(&mut domains, domain)?; } @@ -146,21 +146,7 @@ pub fn address_api() } let mut table = Table::new(); - table.add_row(row![bc => "ADDRESS", "PUBLIC", "ACME PROVIDER"]); - for entry in &res { - if let Some(PublicDomainConfig { gateway, acme }) = &entry.public { - table.add_row(row![ - entry.address, - &format!( - "{} ({gateway})", - if entry.private { "YES" } else { "ONLY" } - ), - acme.as_ref().map(|a| a.0.as_str()).unwrap_or("NONE") - ]); - } else { - table.add_row(row![entry.address, &format!("NO"), "N/A"]); - } - } + todo!("find a good way to represent this"); table.print_tty(false)?; @@ -248,18 +234,20 @@ pub async fn remove_public_domain( pub struct AddPrivateDomainParams { #[arg(help = "help.arg.fqdn")] pub fqdn: InternedString, + pub gateway: GatewayId, } pub async fn add_private_domain( ctx: RpcContext, - AddPrivateDomainParams { fqdn }: AddPrivateDomainParams, + AddPrivateDomainParams { fqdn, gateway }: AddPrivateDomainParams, inheritance: Kind::Inheritance, ) -> Result<(), Error> { ctx.db .mutate(|db| { Kind::host_for(&inheritance, db)? .as_private_domains_mut() - .mutate(|d| Ok(d.insert(fqdn)))?; + .upsert(&fqdn, || Ok(BTreeSet::new()))? + .mutate(|d| Ok(d.insert(gateway)))?; handle_duplicates(db) }) .await diff --git a/core/src/net/host/binding.rs b/core/src/net/host/binding.rs index 8db806399..bd9bfe766 100644 --- a/core/src/net/host/binding.rs +++ b/core/src/net/host/binding.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, BTreeSet}; +use std::net::SocketAddr; use std::str::FromStr; use clap::Parser; @@ -7,6 +8,7 @@ use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_f use serde::{Deserialize, Serialize}; use ts_rs::TS; +use crate::HostId; use crate::context::{CliContext, RpcContext}; use crate::db::prelude::Map; use crate::net::forward::AvailablePorts; @@ -16,7 +18,6 @@ use crate::net::vhost::AlpnInfo; use crate::prelude::*; use crate::util::FromStrParser; use crate::util::serde::{HandlerExtSerde, display_serializable}; -use crate::HostId; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)] #[ts(export)] @@ -49,31 +50,36 @@ impl FromStr for BindId { #[ts(export)] #[model = "Model"] pub struct DerivedAddressInfo { - /// User-controlled: private addresses the user has disabled - pub private_disabled: BTreeSet, - /// User-controlled: public addresses the user has enabled - pub public_enabled: BTreeSet, + /// User override: enable these addresses (only for public IP & port) + pub enabled: BTreeSet, + /// User override: disable these addresses (only for domains and private IP & port) + pub disabled: BTreeSet<(InternedString, u16)>, /// COMPUTED: NetServiceData::update — all possible addresses for this binding - pub possible: BTreeSet, + pub available: BTreeSet, } impl DerivedAddressInfo { - /// Returns addresses that are currently enabled. - /// Private addresses are enabled by default (disabled if in private_disabled). - /// Public addresses are disabled by default (enabled if in public_enabled). + /// Returns addresses that are currently enabled after applying overrides. + /// Default: public IPs are disabled, everything else is enabled. + /// Explicit `enabled`/`disabled` overrides take precedence. pub fn enabled(&self) -> BTreeSet<&HostnameInfo> { - self.possible + self.available .iter() .filter(|h| { - if h.public { - self.public_enabled.contains(h) + if h.public && h.metadata.is_ip() { + // Public IPs: disabled by default, explicitly enabled via SocketAddr + h.to_socket_addr().map_or( + true, // should never happen, but would rather see them if it does + |sa| self.enabled.contains(&sa), + ) } else { - !self.private_disabled.contains(h) + !self + .disabled + .contains(&(h.host.clone(), h.port.unwrap_or_default())) // disablable addresses will always have a port } }) .collect() } - } #[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] @@ -199,9 +205,9 @@ impl BindInfo { options, net: lan, addresses: DerivedAddressInfo { - private_disabled: addresses.private_disabled, - public_enabled: addresses.public_enabled, - possible: BTreeSet::new(), + enabled: addresses.enabled, + disabled: addresses.disabled, + available: BTreeSet::new(), }, }) } @@ -328,17 +334,27 @@ pub async fn set_address_enabled( .as_bindings_mut() .mutate(|b| { let bind = b.get_mut(&internal_port).or_not_found(internal_port)?; - if address.public { + if address.public && address.metadata.is_ip() { + // Public IPs: toggle via SocketAddr in `enabled` set + let sa = address.to_socket_addr().ok_or_else(|| { + Error::new( + eyre!("cannot convert address to socket addr"), + ErrorKind::InvalidRequest, + ) + })?; if enabled { - bind.addresses.public_enabled.insert(address.clone()); + bind.addresses.enabled.insert(sa); } else { - bind.addresses.public_enabled.remove(&address); + bind.addresses.enabled.remove(&sa); } } else { + // Domains and private IPs: toggle via (host, port) in `disabled` set + let port = address.port.unwrap_or(if address.ssl { 443 } else { 80 }); + let key = (address.host.clone(), port); if enabled { - bind.addresses.private_disabled.remove(&address); + bind.addresses.disabled.remove(&key); } else { - bind.addresses.private_disabled.insert(address.clone()); + bind.addresses.disabled.insert(key); } } Ok(()) diff --git a/core/src/net/host/mod.rs b/core/src/net/host/mod.rs index ef06313dd..b6b8fb45d 100644 --- a/core/src/net/host/mod.rs +++ b/core/src/net/host/mod.rs @@ -3,19 +3,23 @@ use std::future::Future; use std::panic::RefUnwindSafe; use clap::Parser; +use imbl::OrdMap; use imbl_value::InternedString; use itertools::Itertools; +use patch_db::DestructureMut; use rpc_toolkit::{Context, Empty, HandlerExt, OrEmpty, ParentHandler, from_fn_async}; use serde::{Deserialize, Serialize}; use ts_rs::TS; use crate::context::RpcContext; use crate::db::model::DatabaseModel; +use crate::db::model::public::NetworkInterfaceInfo; use crate::net::forward::AvailablePorts; use crate::net::host::address::{HostAddress, PublicDomainConfig, address_api}; use crate::net::host::binding::{BindInfo, BindOptions, Bindings, binding}; +use crate::net::service_interface::{HostnameInfo, HostnameMetadata}; use crate::prelude::*; -use crate::{HostId, PackageId}; +use crate::{GatewayId, HostId, PackageId}; pub mod address; pub mod binding; @@ -27,7 +31,7 @@ pub mod binding; pub struct Host { pub bindings: Bindings, pub public_domains: BTreeMap, - pub private_domains: BTreeSet, + pub private_domains: BTreeMap>, } impl AsRef for Host { @@ -45,20 +49,183 @@ impl Host { .map(|(address, config)| HostAddress { address: address.clone(), public: Some(config.clone()), - private: self.private_domains.contains(address), + private: self.private_domains.get(address).cloned(), }) .chain( self.private_domains .iter() - .filter(|a| !self.public_domains.contains_key(*a)) - .map(|address| HostAddress { - address: address.clone(), + .filter(|(domain, _)| !self.public_domains.contains_key(*domain)) + .map(|(domain, gateways)| HostAddress { + address: domain.clone(), public: None, - private: true, + private: Some(gateways.clone()), }), ) } } +impl Model { + pub fn update_addresses( + &mut self, + gateways: &OrdMap, + available_ports: &AvailablePorts, + ) -> Result<(), Error> { + let this = self.destructure_mut(); + for (_, bind) in this.bindings.as_entries_mut()? { + let net = bind.as_net().de()?; + let opt = bind.as_options().de()?; + let mut available = BTreeSet::new(); + for (gid, g) in gateways { + let Some(ip_info) = &g.ip_info else { + continue; + }; + let gateway_secure = g.secure(); + for subnet in &ip_info.subnets { + let host = InternedString::from_display(&subnet.addr()); + let metadata = if subnet.addr().is_ipv4() { + HostnameMetadata::Ipv4 { + gateway: gid.clone(), + } + } else { + HostnameMetadata::Ipv6 { + gateway: gid.clone(), + scope_id: ip_info.scope_id, + } + }; + if let Some(port) = net.assigned_port.filter(|_| { + opt.secure + .map_or(gateway_secure, |s| !(s.ssl && opt.add_ssl.is_some())) + }) { + available.insert(HostnameInfo { + ssl: opt.secure.map_or(false, |s| s.ssl), + public: false, + host: host.clone(), + port: Some(port), + metadata: metadata.clone(), + }); + } + if let Some(port) = net.assigned_ssl_port { + available.insert(HostnameInfo { + ssl: true, + public: false, + host: host.clone(), + port: Some(port), + metadata, + }); + } + } + if let Some(wan_ip) = &ip_info.wan_ip { + let host = InternedString::from_display(&wan_ip); + let metadata = HostnameMetadata::Ipv4 { + gateway: gid.clone(), + }; + if let Some(port) = net.assigned_port.filter(|_| { + opt.secure.map_or( + false, // the public internet is never secure + |s| !(s.ssl && opt.add_ssl.is_some()), + ) + }) { + available.insert(HostnameInfo { + ssl: opt.secure.map_or(false, |s| s.ssl), + public: true, + host: host.clone(), + port: Some(port), + metadata: metadata.clone(), + }); + } + if let Some(port) = net.assigned_ssl_port { + available.insert(HostnameInfo { + ssl: true, + public: true, + host: host.clone(), + port: Some(port), + metadata, + }); + } + } + } + for (domain, info) in this.public_domains.de()? { + let metadata = HostnameMetadata::PublicDomain { + gateway: info.gateway.clone(), + }; + if let Some(port) = net.assigned_port.filter(|_| { + opt.secure.map_or( + false, // the public internet is never secure + |s| !(s.ssl && opt.add_ssl.is_some()), + ) + }) { + available.insert(HostnameInfo { + ssl: opt.secure.map_or(false, |s| s.ssl), + public: true, + host: domain.clone(), + port: Some(port), + metadata: metadata.clone(), + }); + } + if let Some(mut port) = net.assigned_ssl_port { + if let Some(preferred) = opt + .add_ssl + .as_ref() + .map(|s| s.preferred_external_port) + .filter(|p| available_ports.is_ssl(*p)) + { + port = preferred; + } + available.insert(HostnameInfo { + ssl: true, + public: true, + host: domain.clone(), + port: Some(port), + metadata, + }); + } + } + for (domain, domain_gateways) in this.private_domains.de()? { + if let Some(port) = net.assigned_port.filter(|_| { + opt.secure + .map_or(true, |s| !(s.ssl && opt.add_ssl.is_some())) + }) { + let gateways = if opt.secure.is_some() { + domain_gateways.clone() + } else { + domain_gateways + .iter() + .cloned() + .filter(|g| gateways.get(g).map_or(false, |g| g.secure())) + .collect() + }; + available.insert(HostnameInfo { + ssl: opt.secure.map_or(false, |s| s.ssl), + public: true, + host: domain.clone(), + port: Some(port), + metadata: HostnameMetadata::PrivateDomain { gateways }, + }); + } + if let Some(mut port) = net.assigned_ssl_port { + if let Some(preferred) = opt + .add_ssl + .as_ref() + .map(|s| s.preferred_external_port) + .filter(|p| available_ports.is_ssl(*p)) + { + port = preferred; + } + available.insert(HostnameInfo { + ssl: true, + public: true, + host: domain.clone(), + port: Some(port), + metadata: HostnameMetadata::PrivateDomain { + gateways: domain_gateways, + }, + }); + } + } + bind.as_addresses_mut().as_available_mut().ser(&available)?; + } + Ok(()) + } +} #[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)] #[model = "Model"] diff --git a/core/src/net/net_controller.rs b/core/src/net/net_controller.rs index 37c63f333..5c8e27682 100644 --- a/core/src/net/net_controller.rs +++ b/core/src/net/net_controller.rs @@ -23,7 +23,7 @@ use crate::net::gateway::NetworkInterfaceController; use crate::net::host::address::HostAddress; use crate::net::host::binding::{AddSslOptions, BindId, BindOptions}; use crate::net::host::{Host, Hosts, host_for}; -use crate::net::service_interface::{GatewayInfo, HostnameInfo, IpHostname}; +use crate::net::service_interface::{HostnameInfo, HostnameMetadata}; use crate::net::socks::SocksController; use crate::net::utils::ipv6_is_local; use crate::net::vhost::{AlpnInfo, DynVHostTarget, ProxyTarget, VHostController}; @@ -261,10 +261,7 @@ impl NetServiceData { let mut private_dns: BTreeSet = BTreeSet::new(); let binds = self.binds.entry(id.clone()).or_default(); - let peek = ctrl.db.peek().await; - let server_info = peek.as_public().as_server_info(); let net_ifaces = ctrl.net_iface.watcher.ip_info(); - let hostname = server_info.as_hostname().de()?; let host_addresses: Vec<_> = host.addresses().collect(); // Collect private DNS entries (domains without public config) @@ -277,7 +274,7 @@ impl NetServiceData { } } - // ── Phase 1: Compute possible addresses ── + // ── Phase 1: Compute available addresses ── for (_port, bind) in host.bindings.iter_mut() { if !bind.enabled { continue; @@ -286,7 +283,83 @@ impl NetServiceData { continue; } - bind.addresses.possible.clear(); + bind.addresses.available.clear(); + + // Domain port: non-SSL port for domains (secure-filtered, gateway-independent) + let domain_base_port = bind.net.assigned_port.filter(|_| { + bind.options + .secure + .map_or(false, |s| !s.ssl || bind.options.add_ssl.is_none()) + }); + let (domain_port, domain_ssl_port) = if bind + .options + .add_ssl + .as_ref() + .map_or(false, |ssl| ssl.preferred_external_port == 443) + { + (None, Some(443)) + } else { + (domain_base_port, bind.net.assigned_ssl_port) + }; + + // Domain addresses + for HostAddress { + address, public, .. + } in host_addresses.iter().cloned() + { + // Public domain entry + if let Some(pub_config) = &public { + let metadata = HostnameMetadata::PublicDomain { + gateway: pub_config.gateway.clone(), + }; + if let Some(p) = domain_port { + bind.addresses.available.insert(HostnameInfo { + ssl: false, + public: true, + host: address.clone(), + port: Some(p), + metadata: metadata.clone(), + }); + } + if let Some(sp) = domain_ssl_port { + bind.addresses.available.insert(HostnameInfo { + ssl: true, + public: true, + host: address.clone(), + port: Some(sp), + metadata, + }); + } + } + // Private domain entry + if let Some(gateways) = host.private_domains.get(&address) { + if !gateways.is_empty() { + let metadata = HostnameMetadata::PrivateDomain { + gateways: gateways.clone(), + }; + if let Some(p) = domain_port { + bind.addresses.available.insert(HostnameInfo { + ssl: false, + public: false, + host: address.clone(), + port: Some(p), + metadata: metadata.clone(), + }); + } + if let Some(sp) = domain_ssl_port { + bind.addresses.available.insert(HostnameInfo { + ssl: true, + public: false, + host: address.clone(), + port: Some(sp), + metadata, + }); + } + } + } + } + + // IP addresses (per-gateway) for (gateway_id, info) in net_ifaces .iter() .filter(|(_, info)| { @@ -296,111 +369,97 @@ impl NetServiceData { }) .filter(|(_, info)| info.ip_info.is_some()) { - let gateway = GatewayInfo { - id: gateway_id.clone(), - name: info - .name - .clone() - .or_else(|| info.ip_info.as_ref().map(|i| i.name.clone())) - .unwrap_or_else(|| gateway_id.clone().into()), - public: info.public(), - }; let port = bind.net.assigned_port.filter(|_| { bind.options.secure.map_or(false, |s| { !(s.ssl && bind.options.add_ssl.is_some()) || info.secure() }) }); - // .local addresses (private only, non-public, non-wireguard gateways) - if !info.public() - && info.ip_info.as_ref().map_or(false, |i| { - i.device_type != Some(NetworkInterfaceType::Wireguard) - }) - { - bind.addresses.possible.insert(HostnameInfo { - gateway: gateway.clone(), - public: false, - hostname: IpHostname::Local { - value: InternedString::from_display(&{ - let hostname = &hostname; - lazy_format!("{hostname}.local") - }), - port, - ssl_port: bind.net.assigned_ssl_port, - }, - }); - } - // Domain addresses - for HostAddress { - address, - public, - private, - } in host_addresses.iter().cloned() - { - let private = private && !info.public(); - let public = - public.as_ref().map_or(false, |p| &p.gateway == gateway_id); - if public || private { - let (domain_port, domain_ssl_port) = if bind - .options - .add_ssl - .as_ref() - .map_or(false, |ssl| ssl.preferred_external_port == 443) - { - (None, Some(443)) - } else { - (port, bind.net.assigned_ssl_port) - }; - bind.addresses.possible.insert(HostnameInfo { - gateway: gateway.clone(), - public, - hostname: IpHostname::Domain { - value: address.clone(), - port: domain_port, - ssl_port: domain_ssl_port, - }, - }); - } - } - // IP addresses + if let Some(ip_info) = &info.ip_info { let public = info.public(); + // WAN IP (public) if let Some(wan_ip) = ip_info.wan_ip { - bind.addresses.possible.insert(HostnameInfo { - gateway: gateway.clone(), - public: true, - hostname: IpHostname::Ipv4 { - value: wan_ip, - port, - ssl_port: bind.net.assigned_ssl_port, - }, - }); + let host_str = InternedString::from_display(&wan_ip); + if let Some(p) = port { + bind.addresses.available.insert(HostnameInfo { + ssl: false, + public: true, + host: host_str.clone(), + port: Some(p), + metadata: HostnameMetadata::Ipv4 { + gateway: gateway_id.clone(), + }, + }); + } + if let Some(sp) = bind.net.assigned_ssl_port { + bind.addresses.available.insert(HostnameInfo { + ssl: true, + public: true, + host: host_str, + port: Some(sp), + metadata: HostnameMetadata::Ipv4 { + gateway: gateway_id.clone(), + }, + }); + } } + // Subnet IPs for ipnet in &ip_info.subnets { match ipnet { IpNet::V4(net) => { if !public { - bind.addresses.possible.insert(HostnameInfo { - gateway: gateway.clone(), - public, - hostname: IpHostname::Ipv4 { - value: net.addr(), - port, - ssl_port: bind.net.assigned_ssl_port, - }, - }); + let host_str = InternedString::from_display(&net.addr()); + if let Some(p) = port { + bind.addresses.available.insert(HostnameInfo { + ssl: false, + public: false, + host: host_str.clone(), + port: Some(p), + metadata: HostnameMetadata::Ipv4 { + gateway: gateway_id.clone(), + }, + }); + } + if let Some(sp) = bind.net.assigned_ssl_port { + bind.addresses.available.insert(HostnameInfo { + ssl: true, + public: false, + host: host_str, + port: Some(sp), + metadata: HostnameMetadata::Ipv4 { + gateway: gateway_id.clone(), + }, + }); + } } } IpNet::V6(net) => { - bind.addresses.possible.insert(HostnameInfo { - gateway: gateway.clone(), - public: public && !ipv6_is_local(net.addr()), - hostname: IpHostname::Ipv6 { - value: net.addr(), - scope_id: ip_info.scope_id, - port, - ssl_port: bind.net.assigned_ssl_port, - }, - }); + let is_public = public && !ipv6_is_local(net.addr()); + let host_str = InternedString::from_display(&net.addr()); + if let Some(p) = port { + bind.addresses.available.insert(HostnameInfo { + ssl: false, + public: is_public, + host: host_str.clone(), + port: Some(p), + metadata: HostnameMetadata::Ipv6 { + gateway: gateway_id.clone(), + scope_id: ip_info.scope_id, + }, + }); + } + if let Some(sp) = bind.net.assigned_ssl_port { + bind.addresses.available.insert(HostnameInfo { + ssl: true, + public: is_public, + host: host_str, + port: Some(sp), + metadata: HostnameMetadata::Ipv6 { + gateway: gateway_id.clone(), + scope_id: ip_info.scope_id, + }, + }); + } } } } @@ -435,11 +494,8 @@ impl NetServiceData { let server_private_ips: BTreeSet = enabled_addresses .iter() .filter(|a| !a.public) - .filter_map(|a| { - net_ifaces - .get(&a.gateway.id) - .and_then(|info| info.ip_info.as_ref()) - }) + .flat_map(|a| a.metadata.gateways()) + .filter_map(|gw| net_ifaces.get(gw).and_then(|info| info.ip_info.as_ref())) .flat_map(|ip_info| ip_info.subnets.iter().map(|s| s.addr())) .collect(); @@ -465,32 +521,36 @@ impl NetServiceData { // Domain vhosts: group by (domain, ssl_port), merge public/private sets for addr_info in &enabled_addresses { - if let IpHostname::Domain { - value: domain, - ssl_port: Some(domain_ssl_port), - .. - } = &addr_info.hostname - { - let key = (Some(domain.clone()), *domain_ssl_port); - let target = vhosts.entry(key).or_insert_with(|| ProxyTarget { - public: BTreeSet::new(), - private: BTreeSet::new(), - acme: host_addresses - .iter() - .find(|a| &a.address == domain) - .and_then(|a| a.public.as_ref()) - .and_then(|p| p.acme.clone()), - addr, - add_x_forwarded_headers: ssl.add_x_forwarded_headers, - connect_ssl: connect_ssl - .clone() - .map(|_| ctrl.tls_client_config.clone()), - }); - if addr_info.public { - target.public.insert(addr_info.gateway.id.clone()); - } else { - // Add interface IPs for this gateway to private set - if let Some(info) = net_ifaces.get(&addr_info.gateway.id) { + if !addr_info.ssl { + continue; + } + match &addr_info.metadata { + HostnameMetadata::PublicDomain { .. } + | HostnameMetadata::PrivateDomain { .. } => {} + _ => continue, + } + let domain = &addr_info.host; + let domain_ssl_port = addr_info.port.unwrap_or(443); + let key = (Some(domain.clone()), domain_ssl_port); + let target = vhosts.entry(key).or_insert_with(|| ProxyTarget { + public: BTreeSet::new(), + private: BTreeSet::new(), + acme: host_addresses + .iter() + .find(|a| a.address == *domain) + .and_then(|a| a.public.as_ref()) + .and_then(|p| p.acme.clone()), + addr, + add_x_forwarded_headers: ssl.add_x_forwarded_headers, + connect_ssl: connect_ssl.clone().map(|_| ctrl.tls_client_config.clone()), + }); + if addr_info.public { + for gw in addr_info.metadata.gateways() { + target.public.insert(gw.clone()); + } + } else { + for gw in addr_info.metadata.gateways() { + if let Some(info) = net_ifaces.get(gw) { if let Some(ip_info) = &info.ip_info { for subnet in &ip_info.subnets { target.private.insert(subnet.addr()); @@ -512,16 +572,14 @@ impl NetServiceData { let fwd_public: BTreeSet = enabled_addresses .iter() .filter(|a| a.public) - .map(|a| a.gateway.id.clone()) + .flat_map(|a| a.metadata.gateways()) + .cloned() .collect(); let fwd_private: BTreeSet = enabled_addresses .iter() .filter(|a| !a.public) - .filter_map(|a| { - net_ifaces - .get(&a.gateway.id) - .and_then(|i| i.ip_info.as_ref()) - }) + .flat_map(|a| a.metadata.gateways()) + .filter_map(|gw| net_ifaces.get(gw).and_then(|i| i.ip_info.as_ref())) .flat_map(|ip| ip.subnets.iter().map(|s| s.addr())) .collect(); forwards.insert( @@ -634,8 +692,8 @@ impl NetServiceData { for (port, bind) in host.bindings.0 { if let Some(b) = bindings.as_idx_mut(&port) { b.as_addresses_mut() - .as_possible_mut() - .ser(&bind.addresses.possible)?; + .as_available_mut() + .ser(&bind.addresses.available)?; } } Ok(()) diff --git a/core/src/net/service_interface.rs b/core/src/net/service_interface.rs index 1eae3ebca..6a1fb9009 100644 --- a/core/src/net/service_interface.rs +++ b/core/src/net/service_interface.rs @@ -1,22 +1,74 @@ -use std::net::{Ipv4Addr, Ipv6Addr}; +use std::collections::BTreeSet; +use std::net::SocketAddr; -use imbl_value::InternedString; +use imbl_value::{InOMap, InternedString}; use serde::{Deserialize, Serialize}; use ts_rs::TS; -use crate::{GatewayId, HostId, ServiceInterfaceId}; +use crate::prelude::*; +use crate::{GatewayId, HostId, PackageId, ServiceInterfaceId}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] #[ts(export)] #[serde(rename_all = "camelCase")] pub struct HostnameInfo { - pub gateway: GatewayInfo, + pub ssl: bool, pub public: bool, - pub hostname: IpHostname, + pub host: InternedString, + pub port: Option, + pub metadata: HostnameMetadata, } + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] +#[ts(export)] +#[serde(rename_all = "kebab-case")] +#[serde(rename_all_fields = "camelCase")] +#[serde(tag = "kind")] +pub enum HostnameMetadata { + Ipv4 { + gateway: GatewayId, + }, + Ipv6 { + gateway: GatewayId, + scope_id: u32, + }, + PrivateDomain { + gateways: BTreeSet, + }, + PublicDomain { + gateway: GatewayId, + }, + Plugin { + package: PackageId, + #[serde(flatten)] + extra: InOMap, + }, +} + impl HostnameInfo { + pub fn to_socket_addr(&self) -> Option { + let ip = self.host.parse().ok()?; + Some(SocketAddr::new(ip, self.port?)) + } + pub fn to_san_hostname(&self) -> InternedString { - self.hostname.to_san_hostname() + self.host.clone() + } +} + +impl HostnameMetadata { + pub fn is_ip(&self) -> bool { + matches!(self, Self::Ipv4 { .. } | Self::Ipv6 { .. }) + } + + pub fn gateways(&self) -> Box + '_> { + match self { + Self::Ipv4 { gateway } + | Self::Ipv6 { gateway, .. } + | Self::PublicDomain { gateway } => Box::new(std::iter::once(gateway)), + Self::PrivateDomain { gateways } => Box::new(gateways.iter()), + Self::Plugin { .. } => Box::new(std::iter::empty()), + } } } @@ -29,48 +81,6 @@ pub struct GatewayInfo { pub public: bool, } -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)] -#[ts(export)] -#[serde(rename_all = "camelCase")] -#[serde(rename_all_fields = "camelCase")] -#[serde(tag = "kind")] -pub enum IpHostname { - Ipv4 { - value: Ipv4Addr, - port: Option, - ssl_port: Option, - }, - Ipv6 { - value: Ipv6Addr, - #[serde(default)] - scope_id: u32, - port: Option, - ssl_port: Option, - }, - Local { - #[ts(type = "string")] - value: InternedString, - port: Option, - ssl_port: Option, - }, - Domain { - #[ts(type = "string")] - value: InternedString, - port: Option, - ssl_port: Option, - }, -} -impl IpHostname { - pub fn to_san_hostname(&self) -> InternedString { - match self { - Self::Ipv4 { value, .. } => InternedString::from_display(value), - Self::Ipv6 { value, .. } => InternedString::from_display(value), - Self::Local { value, .. } => value.clone(), - Self::Domain { value, .. } => value.clone(), - } - } -} - #[derive(Clone, Debug, Deserialize, Serialize, TS)] #[ts(export)] #[serde(rename_all = "camelCase")] diff --git a/core/src/net/tunnel.rs b/core/src/net/tunnel.rs index deb7ec6a3..3c782a10e 100644 --- a/core/src/net/tunnel.rs +++ b/core/src/net/tunnel.rs @@ -82,7 +82,6 @@ pub async fn add_tunnel( iface.clone(), NetworkInterfaceInfo { name: Some(name), - public: None, secure: None, ip_info: None, gateway_type, @@ -193,15 +192,12 @@ pub async fn remove_tunnel( .mutate(|db| { for host in all_hosts(db) { let host = host?; - host.as_bindings_mut().mutate(|b| { - Ok(b.values_mut().for_each(|v| { - v.addresses - .private_disabled - .retain(|h| h.gateway.id != id); - v.addresses - .public_enabled - .retain(|h| h.gateway.id != id); - })) + host.as_private_domains_mut().mutate(|d| { + for gateways in d.values_mut() { + gateways.remove(&id); + } + d.retain(|_, gateways| !gateways.is_empty()); + Ok(()) })?; } diff --git a/core/src/service/effects/net/ssl.rs b/core/src/service/effects/net/ssl.rs index 7de40aed6..f19f4faf2 100644 --- a/core/src/service/effects/net/ssl.rs +++ b/core/src/service/effects/net/ssl.rs @@ -58,12 +58,12 @@ pub async fn get_ssl_certificate( Ok(m.as_public_domains() .keys()? .into_iter() - .chain(m.as_private_domains().de()?) + .chain(m.as_private_domains().keys()?) .chain( m.as_bindings() .de()? .values() - .flat_map(|b| b.addresses.possible.iter().cloned()) + .flat_map(|b| b.addresses.available.iter().cloned()) .map(|h| h.to_san_hostname()), ) .collect::>()) @@ -182,12 +182,12 @@ pub async fn get_ssl_key( Ok(m.as_public_domains() .keys()? .into_iter() - .chain(m.as_private_domains().de()?) + .chain(m.as_private_domains().keys()?) .chain( m.as_bindings() .de()? .values() - .flat_map(|b| b.addresses.possible.iter().cloned()) + .flat_map(|b| b.addresses.available.iter().cloned()) .map(|h| h.to_san_hostname()), ) .collect::>()) diff --git a/core/src/version/v0_4_0_alpha_20.rs b/core/src/version/v0_4_0_alpha_20.rs index 625d72a51..273114ae3 100644 --- a/core/src/version/v0_4_0_alpha_20.rs +++ b/core/src/version/v0_4_0_alpha_20.rs @@ -164,6 +164,19 @@ fn migrate_host(host: Option<&mut Value>) { // Remove hostnameInfo from host host.remove("hostnameInfo"); + // Migrate privateDomains from array to object (BTreeSet -> BTreeMap<_, BTreeSet>) + if let Some(private_domains) = host.get("privateDomains").and_then(|v| v.as_array()).cloned() { + let mut new_pd: Value = serde_json::json!({}).into(); + for domain in private_domains { + if let Some(d) = domain.as_str() { + if let Some(obj) = new_pd.as_object_mut() { + obj.insert(d.into(), serde_json::json!([]).into()); + } + } + } + host.insert("privateDomains".into(), new_pd); + } + // For each binding: add "addresses" field, remove gateway-level fields from "net" if let Some(bindings) = host.get_mut("bindings").and_then(|b| b.as_object_mut()) { for (_, binding) in bindings.iter_mut() { @@ -173,9 +186,9 @@ fn migrate_host(host: Option<&mut Value>) { binding_obj.insert( "addresses".into(), serde_json::json!({ - "privateDisabled": [], - "publicEnabled": [], - "possible": [] + "enabled": [], + "disabled": [], + "available": [] }) .into(), ); diff --git a/sdk/base/lib/osBindings/DerivedAddressInfo.ts b/sdk/base/lib/osBindings/DerivedAddressInfo.ts index 19926d44a..464d17e25 100644 --- a/sdk/base/lib/osBindings/DerivedAddressInfo.ts +++ b/sdk/base/lib/osBindings/DerivedAddressInfo.ts @@ -5,11 +5,11 @@ export type DerivedAddressInfo = { /** * User-controlled: private addresses the user has disabled */ - privateDisabled: Array + enabled: Array /** * User-controlled: public addresses the user has enabled */ - publicEnabled: Array + disabled: Array /** * COMPUTED: NetServiceData::update — all possible addresses for this binding */ diff --git a/sdk/base/lib/util/getServiceInterface.ts b/sdk/base/lib/util/getServiceInterface.ts index bc22e70c6..6cbf72215 100644 --- a/sdk/base/lib/util/getServiceInterface.ts +++ b/sdk/base/lib/util/getServiceInterface.ts @@ -226,12 +226,16 @@ function filterRec( return hostnames } +function isDefaultEnabled(h: HostnameInfo): boolean { + return !(h.public && (h.hostname.kind === 'ipv4' || h.hostname.kind === 'ipv6')) +} + function enabledAddresses(addr: DerivedAddressInfo): HostnameInfo[] { - return addr.possible.filter((h) => - h.public - ? addr.publicEnabled.some((e) => deepEqual(e, h)) - : !addr.privateDisabled.some((d) => deepEqual(d, h)), - ) + return addr.possible.filter((h) => { + if (addr.enabled.some((e) => deepEqual(e, h))) return true + if (addr.disabled.some((d) => deepEqual(d, h))) return false + return isDefaultEnabled(h) + }) } export const filledAddress = ( diff --git a/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts b/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts index 6e05c02d9..f75d045ee 100644 --- a/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts +++ b/web/projects/ui/src/app/routes/portal/components/interfaces/interface.service.ts @@ -257,9 +257,9 @@ export class InterfaceService { if (!binding) return [] const addr = binding.addresses const enabled = addr.possible.filter(h => - h.public - ? addr.publicEnabled.some(e => utils.deepEqual(e, h)) - : !addr.privateDisabled.some(d => utils.deepEqual(d, h)), + addr.enabled.some(e => utils.deepEqual(e, h)) || + (!addr.disabled.some(d => utils.deepEqual(d, h)) && + !(h.public && (h.hostname.kind === 'ipv4' || h.hostname.kind === 'ipv6'))), ) return enabled.filter( h => diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts index 03ec3d3ee..1daf86b01 100644 --- a/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts @@ -134,9 +134,12 @@ export default class ServiceInterfaceRoute { gateways: gateways.map(g => ({ enabled: - (g.public - ? binding?.addresses.publicEnabled.some(a => a.gateway.id === g.id) - : !binding?.addresses.privateDisabled.some(a => a.gateway.id === g.id)) ?? false, + (binding?.addresses.enabled.some(a => a.gateway.id === g.id) || + (!binding?.addresses.disabled.some(a => a.gateway.id === g.id) && + binding?.addresses.possible.some(a => + a.gateway.id === g.id && + !(a.public && (a.hostname.kind === 'ipv4' || a.hostname.kind === 'ipv6')) + ))) ?? false, ...g, })) || [], publicDomains: getPublicDomains(host.publicDomains, gateways), diff --git a/web/projects/ui/src/app/routes/portal/routes/system/routes/startos-ui/startos-ui.component.ts b/web/projects/ui/src/app/routes/portal/routes/system/routes/startos-ui/startos-ui.component.ts index 6d2246f98..11934da5b 100644 --- a/web/projects/ui/src/app/routes/portal/routes/system/routes/startos-ui/startos-ui.component.ts +++ b/web/projects/ui/src/app/routes/portal/routes/system/routes/startos-ui/startos-ui.component.ts @@ -95,9 +95,12 @@ export default class StartOsUiComponent { ), gateways: gateways.map(g => ({ enabled: - (g.public - ? binding?.addresses.publicEnabled.some(a => a.gateway.id === g.id) - : !binding?.addresses.privateDisabled.some(a => a.gateway.id === g.id)) ?? false, + (binding?.addresses.enabled.some(a => a.gateway.id === g.id) || + (!binding?.addresses.disabled.some(a => a.gateway.id === g.id) && + binding?.addresses.possible.some(a => + a.gateway.id === g.id && + !(a.public && (a.hostname.kind === 'ipv4' || a.hostname.kind === 'ipv6')) + ))) ?? false, ...g, })), publicDomains: getPublicDomains(network.host.publicDomains, gateways), diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 7e092ef80..8461c98f8 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -2128,8 +2128,8 @@ export namespace Mock { assignedSslPort: 443, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [ { gateway: { id: 'eth0', name: 'Ethernet', public: false }, @@ -2214,8 +2214,8 @@ export namespace Mock { assignedSslPort: null, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [], }, options: { @@ -2237,8 +2237,8 @@ export namespace Mock { assignedSslPort: null, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [], }, options: { diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index d3484fefc..4f225a7fb 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -40,8 +40,8 @@ export const mockPatchData: DataModel = { assignedSslPort: 443, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [ { gateway: { id: 'eth0', name: 'Ethernet', public: false }, @@ -516,8 +516,8 @@ export const mockPatchData: DataModel = { assignedSslPort: 443, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [ { gateway: { id: 'eth0', name: 'Ethernet', public: false }, @@ -602,8 +602,8 @@ export const mockPatchData: DataModel = { assignedSslPort: null, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [], }, options: { @@ -625,8 +625,8 @@ export const mockPatchData: DataModel = { assignedSslPort: null, }, addresses: { - privateDisabled: [], - publicEnabled: [], + enabled: [], + disabled: [], possible: [], }, options: {