From 36f1fc4f9d64520d99830c08b25e9328a28882aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kl=C3=A4hn?= <39526136+Septias@users.noreply.github.com> Date: Fri, 17 May 2024 22:13:21 +0200 Subject: [PATCH] feat: ephemeral peer channels (#5346) Co-authored-by: link2xt Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com> --- .gitignore | 1 - Cargo.lock | 1913 +++++++++++++++++++- Cargo.toml | 9 +- benches/contacts.rs | 1 + benches/create_account.rs | 1 + benches/get_chat_msgs.rs | 1 + benches/get_chatlist.rs | 1 + benches/receive_emails.rs | 1 + benches/search_msgs.rs | 1 + benches/send_events.rs | 1 + deltachat-ffi/src/lib.rs | 9 +- deltachat-jsonrpc/src/api.rs | 36 +- deltachat-jsonrpc/src/api/types/events.rs | 8 + deltachat-jsonrpc/src/api/types/message.rs | 4 + deltachat-jsonrpc/src/lib.rs | 1 + deltachat-jsonrpc/src/webserver.rs | 1 + deltachat-repl/src/main.rs | 1 + deltachat-rpc-server/src/main.rs | 1 + deny.toml | 29 + src/config.rs | 5 +- src/context.rs | 11 +- src/events/payload.rs | 9 + src/headerdef.rs | 6 + src/imap.rs | 26 +- src/imex/transfer.rs | 1 + src/lib.rs | 1 + src/mimefactory.rs | 20 +- src/mimeparser.rs | 3 + src/peer_channels.rs | 711 ++++++++ src/qr.rs | 1 + src/receive_imf.rs | 34 +- src/sql/migrations.rs | 24 + 32 files changed, 2761 insertions(+), 111 deletions(-) create mode 100644 src/peer_channels.rs diff --git a/.gitignore b/.gitignore index aab1ac6f08..853667202d 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,6 @@ deltachat-ffi/xml coverage/ .DS_Store .vscode -.vscode/launch.json python/accounts.txt python/all-testaccounts.txt tmp/ diff --git a/Cargo.lock b/Cargo.lock index fd80a486fb..32675afdbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,6 +30,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "bytes", + "crypto-common", + "generic-array", +] + [[package]] name = "aes" version = "0.8.4" @@ -194,8 +205,24 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", + "asn1-rs-derive 0.4.0", + "asn1-rs-impl 0.1.0", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.34", +] + +[[package]] +name = "asn1-rs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" +dependencies = [ + "asn1-rs-derive 0.5.0", + "asn1-rs-impl 0.2.0", "displaydoc", "nom", "num-traits", @@ -213,7 +240,19 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", + "synstructure 0.13.1", ] [[package]] @@ -227,6 +266,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "async-broadcast" version = "0.7.0" @@ -361,6 +411,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "attohttpc" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" +dependencies = [ + "http 0.2.12", + "log", + "url", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -378,10 +439,10 @@ dependencies = [ "base64 0.21.7", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", - "hyper", + "hyper 1.2.0", "hyper-util", "itoa", "matchit", @@ -413,8 +474,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", "mime", "pin-project-lite", @@ -425,6 +486,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom 0.2.12", + "instant", + "rand 0.8.5", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -440,6 +512,23 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "bao-tree" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f7a89a8ee5889d2593ae422ce6e1bb03e48a0e8a16e4fa0882dfcbe7e182ef" +dependencies = [ + "bytes", + "futures-lite 2.3.0", + "genawaiter", + "iroh-blake3", + "iroh-io", + "positioned-io", + "range-collections", + "self_cell", + "smallvec", +] + [[package]] name = "base16ct" version = "0.1.1" @@ -488,6 +577,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "binary-merge" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597bb81c80a54b6a4381b23faba8d7774b144c94cbd1d6fe3f1329bd776554ab" + [[package]] name = "bincode" version = "1.3.3" @@ -515,6 +610,18 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake3" version = "1.5.0" @@ -565,6 +672,12 @@ dependencies = [ "cipher", ] +[[package]] +name = "bounded-integer" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78a6932c88f1d2c29533a3b8a5f5a2f84cc19c3339b431677c3160c5c2e6ca85" + [[package]] name = "brotli" version = "6.0.0" @@ -628,6 +741,9 @@ name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] [[package]] name = "camellia" @@ -712,6 +828,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "charset" version = "0.1.3" @@ -732,8 +859,9 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -771,6 +899,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -903,6 +1032,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc24" version = "0.1.6" @@ -1018,9 +1162,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto_box" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16182b4f39a82ec8a6851155cc4c0cda3065bb1db33651726a29e1951de0f009" +dependencies = [ + "aead", + "chacha20", + "crypto_secretbox", + "curve25519-dalek 4.1.2", + "salsa20", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto_secretbox" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d6cf87adf719ddf43a805e92c6870a531aedda35ff640442cbaf8674e141e1" +dependencies = [ + "aead", + "chacha20", + "cipher", + "generic-array", + "poly1305", + "salsa20", + "subtle", + "zeroize", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1132,6 +1309,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1144,15 +1334,15 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4898b43aed56499fad6b294d15b3e76a51df68079bf492e5daae38ca084e003" dependencies = [ - "dlopen2", + "dlopen2 0.4.1", "libc", "memalloc", - "netlink-packet-core", - "netlink-packet-route", + "netlink-packet-core 0.5.0", + "netlink-packet-route 0.15.0", "netlink-sys", "once_cell", - "system-configuration", - "windows", + "system-configuration 0.5.1", + "windows 0.32.0", ] [[package]] @@ -1182,12 +1372,14 @@ dependencies = [ "fd-lock", "format-flowed", "futures", - "futures-lite", + "futures-lite 2.3.0", "hex", "hickory-resolver", "humansize", "image", "iroh", + "iroh-gossip", + "iroh-net", "kamadak-exif", "lettre_email", "libc", @@ -1207,6 +1399,7 @@ dependencies = [ "proptest", "qrcodegen", "quick-xml", + "quinn", "quoted_printable", "rand 0.8.5", "ratelimit", @@ -1296,7 +1489,7 @@ dependencies = [ "deltachat", "deltachat-jsonrpc", "env_logger 0.11.3", - "futures-lite", + "futures-lite 2.3.0", "log", "serde", "serde_json", @@ -1342,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", - "der_derive", + "der_derive 0.6.1", "pem-rfc7468 0.6.0", "zeroize", ] @@ -1354,6 +1547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", + "der_derive 0.7.2", "pem-rfc7468 0.7.0", "zeroize", ] @@ -1364,7 +1558,21 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs", + "asn1-rs 0.5.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs 0.6.1", "displaydoc", "nom", "num-bigint", @@ -1378,12 +1586,23 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ef71ddb5b3a1f53dee24817c8f70dfa1cb29e804c18d88c228d4bc9c86ee3b9" dependencies = [ - "proc-macro-error", + "proc-macro-error 1.0.4", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "der_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "deranged" version = "0.3.11" @@ -1391,6 +1610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1437,6 +1657,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7abbfc297053be59290e3152f8cbcd52c8642e0728b69ee187d991d4c1af08d" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bba3e9872d7c58ce7ef0fcf1844fcc3e23ef2a58377b50df35dd98e42a5726e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", + "unicode-xid", +] + [[package]] name = "des" version = "0.8.1" @@ -1538,6 +1779,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "libc", + "once_cell", + "winapi", +] + [[package]] name = "dlopen2_derive" version = "0.2.0" @@ -1565,6 +1817,24 @@ dependencies = [ "zeroize", ] +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "duct" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab5718d1224b63252cd0c6f74f6480f9ffeb117438a2e0f5cf6d9a4798929c" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -1614,6 +1884,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", + "serde", "signature 2.2.0", ] @@ -1640,6 +1911,7 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek 4.1.2", "ed25519 2.2.3", + "rand_core 0.6.4", "serde", "sha2 0.10.8", "subtle", @@ -1848,6 +2120,26 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "enumflags2" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "env_filter" version = "0.1.0" @@ -1890,6 +2182,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "erased_set" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a5aa24577083f8190ad401e376b55887c7cd9083ae95d83ceec5d28ea78125" + [[package]] name = "errno" version = "0.3.8" @@ -1921,6 +2228,17 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "event-listener" version = "5.2.0" @@ -1977,6 +2295,15 @@ dependencies = [ "ascii_utils", ] +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -2097,6 +2424,12 @@ dependencies = [ name = "format-flowed" version = "1.0.0" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.30" @@ -2112,6 +2445,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-buffered" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02dcae03ee5afa5ea17b1aebc793806b8ddfc6dc500e0b8e8e1eb30b9dad22c0" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -2122,6 +2466,20 @@ dependencies = [ "futures-sink", ] +[[package]] +name = "futures-concurrency" +version = "7.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ee14e256b9143bfafbf2fddeede6f396650bacf95d06fc1b3f2b503df129a0" +dependencies = [ + "bitvec", + "futures-core", + "futures-lite 1.13.0", + "pin-project", + "slab", + "smallvec", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -2147,11 +2505,26 @@ checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" -version = "2.3.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.0.1", "futures-core", "futures-io", "parking", @@ -2181,6 +2554,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.30" @@ -2199,6 +2578,37 @@ dependencies = [ "slab", ] +[[package]] +name = "genawaiter" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" +dependencies = [ + "futures-core", + "genawaiter-macro", + "genawaiter-proc-macro", + "proc-macro-hack", +] + +[[package]] +name = "genawaiter-macro" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc" + +[[package]] +name = "genawaiter-proc-macro" +version = "0.99.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" +dependencies = [ + "proc-macro-error 0.4.12", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2250,6 +2660,32 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.12.1" @@ -2274,16 +2710,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.4" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -2401,6 +2837,22 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac-sha1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b05da5b9e5d4720bfb691eebb2b9d42da3570745da71eac8a1f5bb7e59aab88" +dependencies = [ + "hmac", + "sha1", +] + +[[package]] +name = "hmac-sha256" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3688e69b38018fec1557254f64c8dc2cc8ec502890182f395dbb0aa997aa5735" + [[package]] name = "home" version = "0.5.9" @@ -2421,6 +2873,23 @@ dependencies = [ "winapi", ] +[[package]] +name = "hostname-validator" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -2432,6 +2901,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.0" @@ -2439,7 +2919,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -2450,8 +2930,8 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" dependencies = [ "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -2496,6 +2976,30 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.2.0" @@ -2505,9 +3009,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "httparse", "httpdate", "itoa", @@ -2517,20 +3020,31 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.28", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "http-body-util", - "hyper", - "hyper-util", + "hyper 0.14.28", "native-tls", "tokio", "tokio-native-tls", - "tower-service", ] [[package]] @@ -2540,17 +3054,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", - "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", "pin-project-lite", "socket2", "tokio", - "tower", - "tower-service", - "tracing", ] [[package]] @@ -2564,7 +3074,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -2611,6 +3121,25 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "igd-next" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http 0.2.12", + "hyper 0.14.28", + "log", + "rand 0.8.5", + "tokio", + "url", + "xmltree", +] + [[package]] name = "image" version = "0.25.1" @@ -2666,6 +3195,24 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inplace-vec-builder" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf64c2edc8226891a71f127587a2861b132d2b942310843814d5001d99a1d307" +dependencies = [ + "smallvec", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "ipconfig" version = "0.3.2" @@ -2697,7 +3244,7 @@ dependencies = [ "bytes", "default-net", "der 0.6.1", - "derive_more", + "derive_more 0.99.17", "dirs-next", "ed25519-dalek 1.0.1", "futures", @@ -2708,13 +3255,13 @@ dependencies = [ "quic-rpc", "quinn", "rand 0.7.3", - "rcgen", + "rcgen 0.10.0", "ring 0.16.20", "rustls", "rustls-webpki", "serde", "serde-error", - "ssh-key", + "ssh-key 0.5.1", "tempfile", "thiserror", "tokio", @@ -2724,10 +3271,231 @@ dependencies = [ "tracing-futures", "tracing-subscriber", "walkdir", - "x509-parser", + "x509-parser 0.14.0", "zeroize", ] +[[package]] +name = "iroh-base" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a1a5323b25a181b1434a44f9f59ebc478d21156cf9bf91aa850ad0d626f833" +dependencies = [ + "aead", + "anyhow", + "bao-tree", + "crypto_box", + "data-encoding", + "derive_more 1.0.0-beta.6", + "ed25519-dalek 2.1.1", + "hex", + "once_cell", + "postcard", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "serde-error", + "ssh-key 0.6.6", + "thiserror", + "ttl_cache", + "url", + "zeroize", +] + +[[package]] +name = "iroh-blake3" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbba31f40a650f58fa28dd585a8ca76d8ae3ba63aacab4c8269004a0c803930" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "iroh-gossip" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11daf47e11d00016eeac662b8b13343d40233764fe4b971e0d6cf15b1c98f0a1" +dependencies = [ + "anyhow", + "bytes", + "derive_more 1.0.0-beta.6", + "ed25519-dalek 2.1.1", + "futures-lite 2.3.0", + "genawaiter", + "indexmap", + "iroh-base", + "iroh-blake3", + "iroh-metrics", + "iroh-net", + "postcard", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "iroh-io" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d1047ad5ca29ab4ff316b6830d86e7ea52cea54325e4d4a849692e1274b498" +dependencies = [ + "bytes", + "futures-lite 2.3.0", + "pin-project", +] + +[[package]] +name = "iroh-metrics" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b4f668653628979461eabe56853a694b1eb4713e87ed25f2224618165c0e67" +dependencies = [ + "anyhow", + "erased_set", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "once_cell", + "prometheus-client", + "reqwest", + "serde", + "struct_iterable", + "time 0.3.34", + "tokio", + "tracing", +] + +[[package]] +name = "iroh-net" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bea6e221dfbe6301965a5ec9b6bae2c156375a4baafdbdbad7a93c3dcf950d6" +dependencies = [ + "aead", + "anyhow", + "backoff", + "bytes", + "der 0.7.8", + "derive_more 1.0.0-beta.6", + "duct", + "flume", + "futures-buffered", + "futures-concurrency", + "futures-lite 2.3.0", + "futures-sink", + "futures-util", + "governor", + "hex", + "hickory-proto", + "hickory-resolver", + "hostname", + "http 1.1.0", + "http-body-util", + "hyper 1.2.0", + "hyper-util", + "igd-next", + "iroh-base", + "iroh-metrics", + "iroh-quinn", + "iroh-quinn-proto", + "iroh-quinn-udp", + "libc", + "netdev", + "netlink-packet-core 0.7.0", + "netlink-packet-route 0.17.1", + "netlink-sys", + "num_enum", + "once_cell", + "parking_lot", + "pin-project", + "pkarr", + "postcard", + "rand 0.8.5", + "rand_core 0.6.4", + "rcgen 0.11.3", + "reqwest", + "ring 0.17.8", + "rtnetlink", + "rustls", + "rustls-webpki", + "serde", + "smallvec", + "socket2", + "strum", + "stun-rs", + "surge-ping", + "thiserror", + "time 0.3.34", + "tokio", + "tokio-rustls", + "tokio-rustls-acme", + "tokio-util", + "tracing", + "url", + "watchable", + "webpki-roots", + "windows 0.51.1", + "wmi", + "x509-parser 0.15.1", + "z32", +] + +[[package]] +name = "iroh-quinn" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b934380145fd5d53a583d01ae9500f4807efe6b0f0fe115c7be4afa2b35db99f" +dependencies = [ + "bytes", + "iroh-quinn-proto", + "iroh-quinn-udp", + "pin-project-lite", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "iroh-quinn-proto" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f2656b322c7f6cf3eb95e632d1c0f2fa546841915b0270da581f918c70c4be" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls", + "rustls-native-certs", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "iroh-quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6679979a7271c24f9dae9622c0b4a543881508aa3a7396f55dfbaaa56f01c063" +dependencies = [ + "bytes", + "libc", + "socket2", + "tracing", + "windows-sys 0.48.0", +] + [[package]] name = "is-terminal" version = "0.4.12" @@ -2948,6 +3716,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memalloc" version = "0.1.0" @@ -3026,6 +3800,23 @@ dependencies = [ "tempfile", ] +[[package]] +name = "netdev" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb353f5a5a852d5cc779c1c80bec0bd14a696ef832f3a761cb10091802c37109" +dependencies = [ + "dlopen2 0.5.0", + "libc", + "memalloc", + "netlink-packet-core 0.7.0", + "netlink-packet-route 0.17.1", + "netlink-sys", + "once_cell", + "system-configuration 0.6.0", + "windows 0.54.0", +] + [[package]] name = "netlink-packet-core" version = "0.5.0" @@ -3038,6 +3829,17 @@ dependencies = [ "netlink-packet-utils", ] +[[package]] +name = "netlink-packet-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" +dependencies = [ + "anyhow", + "byteorder", + "netlink-packet-utils", +] + [[package]] name = "netlink-packet-route" version = "0.15.0" @@ -3048,7 +3850,21 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "libc", - "netlink-packet-core", + "netlink-packet-core 0.5.0", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "byteorder", + "libc", + "netlink-packet-core 0.7.0", "netlink-packet-utils", ] @@ -3064,6 +3880,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "netlink-proto" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b33524dc0968bfad349684447bfce6db937a9ac3332a1fe60c0c5a5ce63f21" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core 0.7.0", + "netlink-sys", + "thiserror", + "tokio", +] + [[package]] name = "netlink-sys" version = "0.8.5" @@ -3071,8 +3902,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" dependencies = [ "bytes", + "futures", "libc", "log", + "tokio", ] [[package]] @@ -3084,6 +3917,17 @@ dependencies = [ "smallvec", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + [[package]] name = "nix" version = "0.28.0" @@ -3096,6 +3940,18 @@ dependencies = [ "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + [[package]] name = "nom" version = "7.1.3" @@ -3106,6 +3962,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "ntapi" version = "0.4.1" @@ -3247,7 +4109,16 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs", + "asn1-rs 0.5.2", +] + +[[package]] +name = "oid-registry" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +dependencies = [ + "asn1-rs 0.6.1", ] [[package]] @@ -3339,6 +4210,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "overload" version = "0.1.1" @@ -3391,6 +4272,20 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct 0.2.0", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "rand_core 0.6.4", + "sha2 0.10.8", +] + [[package]] name = "parking" version = "2.2.0" @@ -3435,6 +4330,16 @@ dependencies = [ "base64 0.13.1", ] +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + [[package]] name = "pem-rfc7468" version = "0.6.0" @@ -3459,6 +4364,51 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "pest_meta" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + [[package]] name = "pgp" version = "0.11.0" @@ -3547,6 +4497,23 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkarr" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "242ae92dfb9d2ba3aaa9caf4723e72043bc50729ad05a763771771ba03196ffb" +dependencies = [ + "bytes", + "ed25519-dalek 2.1.1", + "rand 0.8.5", + "reqwest", + "self_cell", + "simple-dns", + "thiserror", + "url", + "z32", +] + [[package]] name = "pkcs1" version = "0.4.1" @@ -3630,6 +4597,48 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_macros" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.60", +] + +[[package]] +name = "pnet_macros_support" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56" +dependencies = [ + "pnet_base", +] + +[[package]] +name = "pnet_packet" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba" +dependencies = [ + "glob", + "pnet_base", + "pnet_macros", + "pnet_macros_support", +] + [[package]] name = "png" version = "0.17.13" @@ -3643,12 +4652,33 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +[[package]] +name = "positioned-io" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccabfeeb89c73adf4081f0dca7f8e28dbda90981a222ceea37f619e93ea6afe9" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "postcard" version = "1.0.8" @@ -3685,6 +4715,40 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precis-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d73e9dd26361c32e7cd13d1032bb01c4e26a23287274e8a4e2f228cf2c9ff77b" +dependencies = [ + "precis-tools", + "ucd-parse", + "unicode-normalization", +] + +[[package]] +name = "precis-profiles" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde4bd6624c60cb0abe2bea1dbdbb9085f629a853861e64df4abb099f8076ad4" +dependencies = [ + "lazy_static", + "precis-core", + "precis-tools", + "unicode-normalization", +] + +[[package]] +name = "precis-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07ecadec70b0f560f09abf815ae0ee1a940d38d2354c938ba7229ac7c9f5f52" +dependencies = [ + "lazy_static", + "regex", + "ucd-parse", +] + [[package]] name = "pretty_assertions" version = "1.4.0" @@ -3723,16 +4787,42 @@ dependencies = [ "toml_edit 0.21.1", ] +[[package]] +name = "proc-macro-error" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" +dependencies = [ + "proc-macro-error-attr 0.4.12", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + [[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "proc-macro-error-attr", + "proc-macro-error-attr 1.0.4", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" +dependencies = [ "proc-macro2", "quote", "syn 1.0.109", + "syn-mid", "version_check", ] @@ -3747,6 +4837,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.81" @@ -3756,6 +4852,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prometheus-client" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +dependencies = [ + "dtoa", + "itoa", + "parking_lot", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "proptest" version = "1.4.0" @@ -3778,6 +4897,21 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quic-rpc" version = "0.6.2" @@ -3869,12 +5003,28 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted-string-parser" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc75379cdb451d001f1cb667a9f74e8b355e9df84cc5193513cbe62b96fc5e9" +dependencies = [ + "pest", + "pest_derive", +] + [[package]] name = "quoted_printable" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "radix_trie" version = "0.2.1" @@ -3965,10 +5115,31 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "range-collections" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9edd21e2db51000ac63eccddabba622f826e631a60be7bade9bd6a76b69537" +dependencies = [ + "binary-merge", + "inplace-vec-builder", + "ref-cast", + "smallvec", +] + [[package]] name = "ratelimit" version = "1.0.0" +[[package]] +name = "raw-cpuid" +version = "11.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +dependencies = [ + "bitflags 2.4.2", +] + [[package]] name = "rayon" version = "1.9.0" @@ -3995,12 +5166,36 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ - "pem", + "pem 1.1.1", + "ring 0.16.20", + "time 0.3.34", + "yasna", +] + +[[package]] +name = "rcgen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" +dependencies = [ + "pem 3.0.4", "ring 0.16.20", "time 0.3.34", "yasna", ] +[[package]] +name = "rcgen" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1" +dependencies = [ + "pem 3.0.4", + "ring 0.17.8", + "time 0.3.34", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -4030,6 +5225,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "regex" version = "1.10.4" @@ -4062,6 +5277,12 @@ dependencies = [ "regex-syntax 0.8.2", ] +[[package]] +name = "regex-lite" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -4076,9 +5297,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.12.2" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -4086,12 +5307,11 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "http-body-util", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls", "hyper-tls", - "hyper-util", "ipnet", "js-sys", "log", @@ -4100,19 +5320,22 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -4221,12 +5444,31 @@ dependencies = [ "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", + "sha2 0.10.8", "signature 2.2.0", "spki 0.7.3", "subtle", "zeroize", ] +[[package]] +name = "rtnetlink" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0" +dependencies = [ + "futures", + "log", + "netlink-packet-core 0.7.0", + "netlink-packet-route 0.17.1", + "netlink-packet-utils", + "netlink-proto", + "netlink-sys", + "nix 0.26.4", + "thiserror", + "tokio", +] + [[package]] name = "rusqlite" version = "0.31.0" @@ -4296,6 +5538,7 @@ version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ + "log", "ring 0.17.8", "rustls-webpki", "sct", @@ -4352,7 +5595,7 @@ dependencies = [ "libc", "log", "memchr", - "nix", + "nix 0.28.0", "radix_trie", "unicode-segmentation", "unicode-width", @@ -4366,6 +5609,15 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + [[package]] name = "same-file" version = "1.0.6" @@ -4591,6 +5843,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha-1" version = "0.10.1" @@ -4656,6 +5918,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -4691,6 +5963,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simple-dns" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01607fe2e61894468c6dc0b26103abb073fb08b79a3d9e4b6d76a1a341549958" +dependencies = [ + "bitflags 2.4.2", +] + [[package]] name = "slab" version = "0.4.9" @@ -4737,6 +6018,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.6.0" @@ -4757,6 +6047,16 @@ dependencies = [ "der 0.7.8", ] +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "cipher", + "ssh-encoding 0.2.0", +] + [[package]] name = "ssh-encoding" version = "0.1.0" @@ -4768,6 +6068,17 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "pem-rfc7468 0.7.0", + "sha2 0.10.8", +] + [[package]] name = "ssh-key" version = "0.5.1" @@ -4782,7 +6093,28 @@ dependencies = [ "sec1 0.3.0", "sha2 0.10.8", "signature 1.6.4", - "ssh-encoding", + "ssh-encoding 0.1.0", + "zeroize", +] + +[[package]] +name = "ssh-key" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" +dependencies = [ + "ed25519-dalek 2.1.1", + "p256 0.13.2", + "p384 0.13.0", + "p521", + "rand_core 0.6.4", + "rsa 0.9.6", + "sec1 0.7.3", + "sha2 0.10.8", + "signature 2.2.0", + "ssh-cipher", + "ssh-encoding 0.2.0", + "subtle", "zeroize", ] @@ -4799,16 +6131,48 @@ dependencies = [ ] [[package]] -name = "strsim" -version = "0.10.0" +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "struct_iterable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "849a064c6470a650b72e41fa6c057879b68f804d113af92900f27574828e7712" +dependencies = [ + "struct_iterable_derive", + "struct_iterable_internal", +] + +[[package]] +name = "struct_iterable_derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb939ce88a43ea4e9d012f2f6b4cc789deb2db9d47bad697952a85d6978662c" +dependencies = [ + "erased-serde", + "proc-macro2", + "quote", + "struct_iterable_internal", + "syn 2.0.60", +] + +[[package]] +name = "struct_iterable_internal" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "e9426b2a0c03e6cc2ea8dbc0168dbbf943f88755e409fb91bcb8f6a268305f4a" [[package]] name = "strum" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] [[package]] name = "strum_macros" @@ -4823,12 +6187,52 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "stun-rs" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0adebf9fb8fba5c39ee34092b0383f247e4d1255b98fcffec94b4b797b85b677" +dependencies = [ + "base64 0.22.1", + "bounded-integer", + "byteorder", + "crc", + "enumflags2", + "fallible-iterator", + "hmac-sha1", + "hmac-sha256", + "hostname-validator", + "lazy_static", + "md5", + "paste", + "precis-core", + "precis-profiles", + "quoted-string-parser", + "rand 0.8.5", +] + [[package]] name = "subtle" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "surge-ping" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbf95ce4c7c5b311d2ce3f088af2b93edef0f09727fa50fbe03c7a979afce77" +dependencies = [ + "hex", + "parking_lot", + "pnet_packet", + "rand 0.8.5", + "socket2", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "syn" version = "1.0.109" @@ -4851,6 +6255,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-mid" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -4875,6 +6290,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "sysinfo" version = "0.26.9" @@ -4897,7 +6323,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +dependencies = [ + "bitflags 2.4.2", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -4910,12 +6347,28 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tagger" version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "094c9f64d6de9a8506b1e49b63a29333b37ed9e821ee04be694d431b3264c3c5" +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.10.1" @@ -4923,7 +6376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.0.1", "rustix", "windows-sys 0.52.0", ] @@ -5109,6 +6562,44 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-rustls-acme" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ebc06d846f8367f24c3a8882328707d1a5e507ef4f40943723ddbe2c17b9f24" +dependencies = [ + "async-trait", + "base64 0.21.7", + "chrono", + "futures", + "log", + "num-bigint", + "pem 3.0.4", + "proc-macro2", + "rcgen 0.12.1", + "reqwest", + "ring 0.17.8", + "rustls", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "url", + "webpki-roots", + "x509-parser 0.16.0", +] + [[package]] name = "tokio-serde" version = "0.8.0" @@ -5327,6 +6818,15 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "ttl_cache" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4189890526f0168710b6ee65ceaedf1460c48a14318ceec933cb26baa492096a" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "tungstenite" version = "0.21.0" @@ -5336,7 +6836,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.1.0", "httparse", "log", "rand 0.8.5", @@ -5379,12 +6879,27 @@ checksum = "2835fe6badda3e20a012d19d6593ded0fc11f659d5d5152394061ffbb03b4b04" dependencies = [ "darling 0.13.4", "ident_case", - "proc-macro-error", + "proc-macro-error 1.0.4", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "ucd-parse" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06ff81122fcbf4df4c1660b15f7e3336058e7aec14437c9f85c6b31a0f279b9" +dependencies = [ + "regex-lite", +] + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unarray" version = "0.1.4" @@ -5436,6 +6951,16 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.7.1" @@ -5457,6 +6982,7 @@ dependencies = [ "form_urlencoded", "idna 0.5.0", "percent-encoding", + "serde", ] [[package]] @@ -5499,6 +7025,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -5608,6 +7140,18 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "watchable" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45b42a2f611916b5965120a9cde2b60f2db4454826dd9ad5e6f47c24a5b3b259" +dependencies = [ + "event-listener 4.0.3", + "futures-util", + "parking_lot", + "thiserror", +] + [[package]] name = "web-sys" version = "0.3.69" @@ -5618,6 +7162,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "weezl" version = "0.1.8" @@ -5685,13 +7235,95 @@ dependencies = [ "windows_x86_64_msvc 0.32.0", ] +[[package]] +name = "windows" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core 0.51.1", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-implement", + "windows-interface", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-implement" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12168c33176773b86799be25e2a2ba07c7aab9968b37541f1094dbd7a60c8946" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "windows-interface" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d8dc32e0095a7eeccebd0e3f09e9509365ecb3fc6ac4d6f5f14a3f6392942d1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "windows-result" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b" +dependencies = [ + "windows-targets 0.52.5", ] [[package]] @@ -5709,7 +7341,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5729,17 +7361,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -5750,9 +7383,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -5768,9 +7401,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -5786,9 +7419,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -5804,9 +7443,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -5822,9 +7461,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -5834,9 +7473,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -5852,9 +7491,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -5884,6 +7523,29 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wmi" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f0a4062ca522aad4705a2948fd4061b3857537990202a8ddd5af21607f79a" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror", + "windows 0.52.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x25519-dalek" version = "2.0.1" @@ -5902,13 +7564,47 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "asn1-rs", + "asn1-rs 0.5.2", "base64 0.13.1", "data-encoding", - "der-parser", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time 0.3.34", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs 0.5.2", + "data-encoding", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time 0.3.34", +] + +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs 0.6.1", + "data-encoding", + "der-parser 9.0.0", "lazy_static", "nom", - "oid-registry", + "oid-registry 0.7.0", "rusticata-macros", "thiserror", "time 0.3.34", @@ -5925,6 +7621,21 @@ dependencies = [ "rustix", ] +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + [[package]] name = "yansi" version = "0.5.1" @@ -5976,6 +7687,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "z32" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb37266251c28b03d08162174a91c3a092e3bd4f476f8205ee1c507b78b7bdc" + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 3d23816f94..fd2ee01b1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,10 @@ hex = "0.4.0" hickory-resolver = "0.24" humansize = "2" image = { version = "0.25.1", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] } -iroh = { version = "0.4.2", default-features = false } +iroh_old = { version = "0.4.2", default-features = false, package = "iroh"} +iroh-net = "0.16.2" +iroh-gossip = { version = "0.16.2", features = ["net"] } +quinn = "0.10.0" kamadak-exif = "0.5.3" lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" } libc = "0.2" @@ -79,7 +82,7 @@ quick-xml = "0.31" quoted_printable = "0.5" rand = "0.8" regex = { workspace = true } -reqwest = { version = "0.12.2", features = ["json"] } +reqwest = { version = "0.11.27", features = ["json"] } rusqlite = { workspace = true, features = ["sqlcipher"] } rust-hsluv = "0.1" sanitize-filename = "0.5" @@ -178,4 +181,4 @@ vendored = [ "async-native-tls/vendored", "rusqlite/bundled-sqlcipher-vendored-openssl", "reqwest/native-tls-vendored" -] +] \ No newline at end of file diff --git a/benches/contacts.rs b/benches/contacts.rs index 48dab7c778..83d85d2ae7 100644 --- a/benches/contacts.rs +++ b/benches/contacts.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use criterion::{black_box, criterion_group, criterion_main, Criterion}; use deltachat::contact::Contact; use deltachat::context::Context; diff --git a/benches/create_account.rs b/benches/create_account.rs index c487004acb..9a3f2d3776 100644 --- a/benches/create_account.rs +++ b/benches/create_account.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::path::PathBuf; use criterion::{black_box, criterion_group, criterion_main, Criterion}; diff --git a/benches/get_chat_msgs.rs b/benches/get_chat_msgs.rs index 3da10e6599..69058ba284 100644 --- a/benches/get_chat_msgs.rs +++ b/benches/get_chat_msgs.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::path::Path; use criterion::{black_box, criterion_group, criterion_main, Criterion}; diff --git a/benches/get_chatlist.rs b/benches/get_chatlist.rs index 7b0f5556ee..60f4441fc2 100644 --- a/benches/get_chatlist.rs +++ b/benches/get_chatlist.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::path::Path; use criterion::{black_box, criterion_group, criterion_main, Criterion}; diff --git a/benches/receive_emails.rs b/benches/receive_emails.rs index ece40985e6..68dd0c7956 100644 --- a/benches/receive_emails.rs +++ b/benches/receive_emails.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::path::PathBuf; use criterion::{black_box, criterion_group, criterion_main, Criterion}; diff --git a/benches/search_msgs.rs b/benches/search_msgs.rs index 5605eb3cf9..cd66b44316 100644 --- a/benches/search_msgs.rs +++ b/benches/search_msgs.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::path::Path; use criterion::{black_box, criterion_group, criterion_main, Criterion}; diff --git a/benches/send_events.rs b/benches/send_events.rs index ec83f7a865..f13f3e6348 100644 --- a/benches/send_events.rs +++ b/benches/send_events.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use criterion::{criterion_group, criterion_main, Criterion}; use deltachat::context::Context; diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 6ae7d6724d..3e0cdc6470 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] #![warn(unused, clippy::all)] #![allow( non_camel_case_types, @@ -561,6 +562,7 @@ pub unsafe extern "C" fn dc_event_get_id(event: *mut dc_event_t) -> libc::c_int EventType::ConfigSynced { .. } => 2111, EventType::WebxdcStatusUpdate { .. } => 2120, EventType::WebxdcInstanceDeleted { .. } => 2121, + EventType::WebxdcRealtimeData { .. } => 2150, EventType::AccountsBackgroundFetchDone => 2200, EventType::ChatlistChanged => 2300, EventType::ChatlistItemChanged { .. } => 2301, @@ -616,8 +618,9 @@ pub unsafe extern "C" fn dc_event_get_data1_int(event: *mut dc_event_t) -> libc: | EventType::SecurejoinJoinerProgress { contact_id, .. } => { contact_id.to_u32() as libc::c_int } - EventType::WebxdcStatusUpdate { msg_id, .. } => msg_id.to_u32() as libc::c_int, - EventType::WebxdcInstanceDeleted { msg_id, .. } => msg_id.to_u32() as libc::c_int, + EventType::WebxdcRealtimeData { msg_id, .. } + | EventType::WebxdcStatusUpdate { msg_id, .. } + | EventType::WebxdcInstanceDeleted { msg_id, .. } => msg_id.to_u32() as libc::c_int, EventType::ChatlistItemChanged { chat_id } => { chat_id.unwrap_or_default().to_u32() as libc::c_int } @@ -655,6 +658,7 @@ pub unsafe extern "C" fn dc_event_get_data2_int(event: *mut dc_event_t) -> libc: | EventType::ConnectivityChanged | EventType::WebxdcInstanceDeleted { .. } | EventType::IncomingMsgBunch { .. } + | EventType::WebxdcRealtimeData { .. } | EventType::SelfavatarChanged | EventType::AccountsBackgroundFetchDone | EventType::ChatlistChanged @@ -721,6 +725,7 @@ pub unsafe extern "C" fn dc_event_get_data2_str(event: *mut dc_event_t) -> *mut | EventType::SelfavatarChanged | EventType::WebxdcStatusUpdate { .. } | EventType::WebxdcInstanceDeleted { .. } + | EventType::WebxdcRealtimeData { .. } | EventType::AccountsBackgroundFetchDone | EventType::ChatEphemeralTimerModified { .. } | EventType::IncomingMsgBunch { .. } diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 9855df949b..5e232551fe 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -18,12 +18,14 @@ use deltachat::constants::DC_MSG_ID_DAYMARKER; use deltachat::contact::{may_be_valid_addr, Contact, ContactId, Origin}; use deltachat::context::get_info; use deltachat::ephemeral::Timer; -use deltachat::imex; use deltachat::location; use deltachat::message::get_msg_read_receipts; use deltachat::message::{ self, delete_msgs, markseen_msgs, Message, MessageState, MsgId, Viewtype, }; +use deltachat::peer_channels::{ + leave_webxdc_realtime, send_webxdc_realtime_advertisement, send_webxdc_realtime_data, +}; use deltachat::provider::get_provider_info; use deltachat::qr::{self, Qr}; use deltachat::qr_code_generator::{generate_backup_qr, get_securejoin_qr_svg}; @@ -32,6 +34,7 @@ use deltachat::securejoin; use deltachat::stock_str::StockMessage; use deltachat::webxdc::StatusUpdateSerial; use deltachat::EventEmitter; +use deltachat::{imex, info}; use sanitize_filename::is_sanitized; use tokio::fs; use tokio::sync::{watch, Mutex, RwLock}; @@ -1763,6 +1766,37 @@ impl CommandApi { .await } + async fn send_webxdc_realtime_data( + &self, + account_id: u32, + instance_msg_id: u32, + data: Vec, + ) -> Result<()> { + let ctx = self.get_context(account_id).await?; + send_webxdc_realtime_data(&ctx, MsgId::new(instance_msg_id), data).await + } + + async fn send_webxdc_realtime_advertisement( + &self, + account_id: u32, + instance_msg_id: u32, + ) -> Result<()> { + let ctx = self.get_context(account_id).await?; + let fut = send_webxdc_realtime_advertisement(&ctx, MsgId::new(instance_msg_id)).await?; + if let Some(fut) = fut { + tokio::spawn(async move { + fut.await.ok(); + info!(ctx, "send_webxdc_realtime_advertisement done") + }); + } + Ok(()) + } + + async fn leave_webxdc_realtime(&self, account_id: u32, instance_message_id: u32) -> Result<()> { + let ctx = self.get_context(account_id).await?; + leave_webxdc_realtime(&ctx, MsgId::new(instance_message_id)).await + } + async fn get_webxdc_status_updates( &self, account_id: u32, diff --git a/deltachat-jsonrpc/src/api/types/events.rs b/deltachat-jsonrpc/src/api/types/events.rs index 7aa2e394e5..59b89cfbd9 100644 --- a/deltachat-jsonrpc/src/api/types/events.rs +++ b/deltachat-jsonrpc/src/api/types/events.rs @@ -240,6 +240,10 @@ pub enum EventType { status_update_serial: u32, }, + /// Data received over an ephemeral peer channel. + #[serde(rename_all = "camelCase")] + WebxdcRealtimeData { msg_id: u32, data: Vec }, + /// Inform that a message containing a webxdc instance has been deleted #[serde(rename_all = "camelCase")] WebxdcInstanceDeleted { msg_id: u32 }, @@ -362,6 +366,10 @@ impl From for EventType { msg_id: msg_id.to_u32(), status_update_serial: status_update_serial.to_u32(), }, + CoreEventType::WebxdcRealtimeData { msg_id, data } => WebxdcRealtimeData { + msg_id: msg_id.to_u32(), + data, + }, CoreEventType::WebxdcInstanceDeleted { msg_id } => WebxdcInstanceDeleted { msg_id: msg_id.to_u32(), }, diff --git a/deltachat-jsonrpc/src/api/types/message.rs b/deltachat-jsonrpc/src/api/types/message.rs index dd51f3fc79..95742cc522 100644 --- a/deltachat-jsonrpc/src/api/types/message.rs +++ b/deltachat-jsonrpc/src/api/types/message.rs @@ -379,6 +379,9 @@ pub enum SystemMessageType { /// Webxdc info added with `info` set in `send_webxdc_status_update()`. WebxdcInfoMessage, + + /// This message contains a users iroh node address. + IrohNodeAddr, } impl From for SystemMessageType { @@ -401,6 +404,7 @@ impl From for SystemMessageType { SystemMessage::WebxdcStatusUpdate => SystemMessageType::WebxdcStatusUpdate, SystemMessage::WebxdcInfoMessage => SystemMessageType::WebxdcInfoMessage, SystemMessage::InvalidUnencryptedMail => SystemMessageType::InvalidUnencryptedMail, + SystemMessage::IrohNodeAddr => SystemMessageType::IrohNodeAddr, SystemMessage::SecurejoinWait => SystemMessageType::SecurejoinWait, SystemMessage::SecurejoinWaitTimeout => SystemMessageType::SecurejoinWaitTimeout, } diff --git a/deltachat-jsonrpc/src/lib.rs b/deltachat-jsonrpc/src/lib.rs index cba1625cea..6c262ea870 100644 --- a/deltachat-jsonrpc/src/lib.rs +++ b/deltachat-jsonrpc/src/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] pub mod api; pub use yerpc; diff --git a/deltachat-jsonrpc/src/webserver.rs b/deltachat-jsonrpc/src/webserver.rs index 116ceb0536..512372c0f9 100644 --- a/deltachat-jsonrpc/src/webserver.rs +++ b/deltachat-jsonrpc/src/webserver.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] use std::net::SocketAddr; use std::path::PathBuf; diff --git a/deltachat-repl/src/main.rs b/deltachat-repl/src/main.rs index ded5abcbd9..9f666b318d 100644 --- a/deltachat-repl/src/main.rs +++ b/deltachat-repl/src/main.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] //! This is a CLI program and a little testing frame. This file must not be //! included when using Delta Chat Core as a library. //! diff --git a/deltachat-rpc-server/src/main.rs b/deltachat-rpc-server/src/main.rs index 0fd981e5bd..2ed9766096 100644 --- a/deltachat-rpc-server/src/main.rs +++ b/deltachat-rpc-server/src/main.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] //! Delta Chat core RPC server. //! //! It speaks JSON Lines over stdio. diff --git a/deny.toml b/deny.toml index 16482ca230..49638def4f 100644 --- a/deny.toml +++ b/deny.toml @@ -23,6 +23,9 @@ ignore = [ # when upgrading. # Please keep this list alphabetically sorted. skip = [ + { name = "asn1-rs-derive", version = "0.4.0" }, + { name = "asn1-rs-impl", version = "0.1.0" }, + { name = "asn1-rs", version = "0.5.2" }, { name = "async-channel", version = "1.9.0" }, { name = "base16ct", version = "0.1.1" }, { name = "base64", version = "<0.21" }, @@ -34,20 +37,38 @@ skip = [ { name = "darling_core", version = "<0.14" }, { name = "darling_macro", version = "<0.14" }, { name = "darling", version = "<0.14" }, + { name = "der_derive", version = "0.6.1" }, + { name = "derive_more", version = "0.99.17" }, + { name = "der-parser", version = "8.2.0" }, { name = "der", version = "0.6.1" }, { name = "digest", version = "<0.10" }, + { name = "dlopen2", version = "0.4.1" }, { name = "ed25519-dalek", version = "1.0.1" }, { name = "ed25519", version = "1.5.3" }, { name = "env_logger", version = "0.10.2" }, { name = "event-listener", version = "2.5.3" }, + { name = "event-listener", version = "4.0.3" }, + { name = "fastrand", version = "1.9.0" }, + { name = "futures-lite", version = "1.13.0" }, { name = "getrandom", version = "<0.2" }, + { name = "http-body", version = "0.4.6" }, + { name = "http", version = "0.2.12" }, + { name = "hyper", version = "0.14.28" }, { name = "idna", version = "0.4.0" }, + { name = "netlink-packet-core", version = "0.5.0" }, + { name = "netlink-packet-route", version = "0.15.0" }, + { name = "nix", version = "0.26.4" }, + { name = "oid-registry", version = "0.6.1" }, { name = "pem-rfc7468", version = "0.6.0" }, + { name = "pem", version = "1.1.1" }, { name = "pkcs8", version = "0.9.0" }, + { name = "proc-macro-error-attr", version = "0.4.12" }, + { name = "proc-macro-error", version = "0.4.12" }, { name = "quick-error", version = "<2.0" }, { name = "rand_chacha", version = "<0.3" }, { name = "rand_core", version = "<0.6" }, { name = "rand", version = "<0.8" }, + { name = "rcgen", version = "<0.12.1" }, { name = "redox_syscall", version = "0.3.5" }, { name = "regex-automata", version = "0.1.10" }, { name = "regex-syntax", version = "0.6.29" }, @@ -57,23 +78,31 @@ skip = [ { name = "signature", version = "1.6.4" }, { name = "spin", version = "<0.9.6" }, { name = "spki", version = "0.6.0" }, + { name = "ssh-encoding", version = "0.1.0" }, + { name = "ssh-key", version = "0.5.1" }, { name = "sync_wrapper", version = "0.1.2" }, + { name = "synstructure", version = "0.12.6" }, { name = "syn", version = "1.0.109" }, + { name = "system-configuration-sys", version = "0.5.0" }, + { name = "system-configuration", version = "0.5.1" }, { name = "time", version = "<0.3" }, { name = "toml_edit", version = "0.21.1" }, { name = "untrusted", version = "0.7.1" }, { name = "wasi", version = "<0.11" }, { name = "windows_aarch64_gnullvm", version = "<0.52" }, { name = "windows_aarch64_msvc", version = "<0.52" }, + { name = "windows-core", version = "<0.54.0" }, { name = "windows_i686_gnu", version = "<0.52" }, { name = "windows_i686_msvc", version = "<0.52" }, { name = "windows-sys", version = "<0.52" }, { name = "windows-targets", version = "<0.52" }, { name = "windows", version = "0.32.0" }, + { name = "windows", version = "<0.54.0" }, { name = "windows_x86_64_gnullvm", version = "<0.52" }, { name = "windows_x86_64_gnu", version = "<0.52" }, { name = "windows_x86_64_msvc", version = "<0.52" }, { name = "winnow", version = "0.5.40" }, + { name = "x509-parser", version = "<0.16.0" }, ] diff --git a/src/config.rs b/src/config.rs index 1c516e8257..bbe74021ec 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,7 @@ use base64::Engine as _; use deltachat_contact_tools::addr_cmp; use serde::{Deserialize, Serialize}; use strum::{EnumProperty, IntoEnumIterator}; -use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString}; +use strum_macros::{AsRefStr, Display, EnumIter, EnumString}; use tokio::fs; use crate::blob::BlobObject; @@ -362,6 +362,9 @@ pub enum Config { /// MsgId of webxdc map integration. WebxdcIntegration, + + /// Iroh secret key. + IrohSecretKey, } impl Config { diff --git a/src/context.rs b/src/context.rs index 98f2322496..b4e5e50e5d 100644 --- a/src/context.rs +++ b/src/context.rs @@ -12,7 +12,7 @@ use anyhow::{bail, ensure, Context as _, Result}; use async_channel::{self as channel, Receiver, Sender}; use pgp::SignedPublicKey; use ratelimit::Ratelimit; -use tokio::sync::{Mutex, Notify, RwLock}; +use tokio::sync::{Mutex, Notify, OnceCell, RwLock}; use crate::aheader::EncryptPreference; use crate::chat::{get_chat_cnt, ChatId, ProtectionStatus}; @@ -30,6 +30,7 @@ use crate::key::{load_self_public_key, load_self_secret_key, DcKey as _}; use crate::login_param::LoginParam; use crate::message::{self, Message, MessageState, MsgId, Viewtype}; use crate::param::{Param, Params}; +use crate::peer_channels::Iroh; use crate::peerstate::Peerstate; use crate::push::PushSubscriber; use crate::quota::QuotaInfo; @@ -288,6 +289,9 @@ pub struct InnerContext { /// True if account has subscribed to push notifications via IMAP. pub(crate) push_subscribed: AtomicBool, + + /// Iroh for realtime peer channels. + pub(crate) iroh: OnceCell, } /// The state of ongoing process. @@ -445,6 +449,7 @@ impl Context { debug_logging: std::sync::RwLock::new(None), push_subscriber, push_subscribed: AtomicBool::new(false), + iroh: OnceCell::new(), }; let ctx = Context { @@ -482,6 +487,9 @@ impl Context { /// Indicate that the network likely has come back. pub async fn maybe_network(&self) { + if let Some(iroh) = self.iroh.get() { + iroh.network_change().await; + } self.scheduler.maybe_network().await; } @@ -1648,6 +1656,7 @@ mod tests { "socks5_password", "key_id", "webxdc_integration", + "iroh_secret_key", ]; let t = TestContext::new().await; let info = t.get_info().await.unwrap(); diff --git a/src/events/payload.rs b/src/events/payload.rs index 47e3526c2e..2ae379cb0e 100644 --- a/src/events/payload.rs +++ b/src/events/payload.rs @@ -279,6 +279,15 @@ pub enum EventType { status_update_serial: StatusUpdateSerial, }, + /// Data received over an ephemeral peer channel. + WebxdcRealtimeData { + /// Message ID. + msg_id: MsgId, + + /// Realtime data. + data: Vec, + }, + /// Inform that a message containing a webxdc instance has been deleted. WebxdcInstanceDeleted { /// ID of the deleted message. diff --git a/src/headerdef.rs b/src/headerdef.rs index c2aa7e4cac..3b9b8e007c 100644 --- a/src/headerdef.rs +++ b/src/headerdef.rs @@ -93,6 +93,12 @@ pub enum HeaderDef { /// See AuthenticationResults, + /// Node address from iroh where direct addresses have been removed. + IrohNodeAddr, + + /// Advertised gossip topic for one webxdc. + IrohGossipTopic, + #[cfg(test)] TestHeader, } diff --git a/src/imap.rs b/src/imap.rs index 0dc52cee8f..7d46ead638 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -22,6 +22,7 @@ use futures_lite::FutureExt; use num_traits::FromPrimitive; use rand::Rng; use ratelimit::Ratelimit; +use url::Url; use crate::chat::{self, ChatId, ChatIdBlocked}; use crate::chatlist_events; @@ -111,6 +112,8 @@ pub(crate) struct ServerMetadata { /// IMAP METADATA `/shared/admin` as defined in /// . pub admin: Option, + + pub iroh_relay: Option, } impl async_imap::Authenticator for OAuth2 { @@ -1449,11 +1452,16 @@ impl Session { let mut comment = None; let mut admin = None; + let mut iroh_relay = None; let mailbox = ""; let options = ""; let metadata = self - .get_metadata(mailbox, options, "(/shared/comment /shared/admin)") + .get_metadata( + mailbox, + options, + "(/shared/comment /shared/admin /shared/vendor/deltachat/irohrelay)", + ) .await?; for m in metadata { match m.entry.as_ref() { @@ -1463,10 +1471,24 @@ impl Session { "/shared/admin" => { admin = m.value; } + "/shared/vendor/deltachat/irohrelay" => { + if let Some(url) = m.value.as_deref().and_then(|s| Url::parse(s).ok()) { + iroh_relay = Some(url); + } else { + warn!( + context, + "Got invalid URL from iroh relay metadata: {:?}.", m.value + ); + } + } _ => {} } } - *lock = Some(ServerMetadata { comment, admin }); + *lock = Some(ServerMetadata { + comment, + admin, + iroh_relay, + }); Ok(()) } diff --git a/src/imex/transfer.rs b/src/imex/transfer.rs index 7196aed6f9..e8843d6534 100644 --- a/src/imex/transfer.rs +++ b/src/imex/transfer.rs @@ -38,6 +38,7 @@ use iroh::progress::ProgressEmitter; use iroh::protocol::AuthToken; use iroh::provider::{DataSource, Event, Provider, Ticket}; use iroh::Hash; +use iroh_old as iroh; use tokio::fs::{self, File}; use tokio::io::{self, AsyncWriteExt, BufWriter}; use tokio::sync::broadcast::error::RecvError; diff --git a/src/lib.rs b/src/lib.rs index 55d56c27f2..4f6bafb9a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,6 +106,7 @@ pub mod receive_imf; pub mod tools; pub mod accounts; +pub mod peer_channels; pub mod reaction; /// If set IMAP/incoming and SMTP/outgoing MIME messages will be printed. diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 066892331f..17baa6f3e2 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -17,11 +17,12 @@ use crate::contact::Contact; use crate::context::Context; use crate::e2ee::EncryptHelper; use crate::ephemeral::Timer as EphemeralTimer; +use crate::headerdef::HeaderDef; use crate::html::new_html_mimepart; -use crate::location; use crate::message::{self, Message, MsgId, Viewtype}; use crate::mimeparser::SystemMessage; use crate::param::Param; +use crate::peer_channels::create_iroh_header; use crate::peerstate::Peerstate; use crate::simplify::escape_message_footer_marks; use crate::stock_str; @@ -29,6 +30,7 @@ use crate::tools::IsNoneOrEmpty; use crate::tools::{ create_outgoing_rfc724_mid, create_smeared_timestamp, remove_subject_prefix, time, }; +use crate::{location, peer_channels}; // attachments of 25 mb brutto should work on the majority of providers // (brutto examples: web.de=50, 1&1=40, t-online.de=32, gmail=25, posteo=50, yahoo=25, all-inkl=100). @@ -1148,6 +1150,18 @@ impl<'a> MimeFactory<'a> { "protection-disabled".to_string(), )); } + SystemMessage::IrohNodeAddr => { + headers.protected.push(Header::new( + HeaderDef::IrohNodeAddr.get_headername().to_string(), + serde_json::to_string( + &context + .get_or_try_init_peer_channel() + .await? + .get_node_addr() + .await?, + )?, + )); + } _ => {} } @@ -1314,6 +1328,10 @@ impl<'a> MimeFactory<'a> { let json = self.msg.param.get(Param::Arg).unwrap_or_default(); parts.push(context.build_status_update_part(json)); } else if self.msg.viewtype == Viewtype::Webxdc { + let topic = peer_channels::create_random_topic(); + headers + .protected + .push(create_iroh_header(context, topic, self.msg.id).await?); if let Some(json) = context .render_webxdc_status_update_object(self.msg.id, None) .await? diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 93f212ea8f..6a4355b680 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -199,6 +199,9 @@ pub enum SystemMessage { /// Webxdc info added with `info` set in `send_webxdc_status_update()`. WebxdcInfoMessage = 32, + + /// This message contains a users iroh node address. + IrohNodeAddr = 40, } const MIME_AC_SETUP_FILE: &str = "application/autocrypt-setup"; diff --git a/src/peer_channels.rs b/src/peer_channels.rs new file mode 100644 index 0000000000..0efeb89914 --- /dev/null +++ b/src/peer_channels.rs @@ -0,0 +1,711 @@ +//! Peer channels for realtime communication in webxdcs. +//! +//! We use Iroh as an ephemeral peer channels provider to create direct communication +//! channels between webxdcs. See [here](https://webxdc.org/docs/spec/joinRealtimeChannel.html) for the webxdc specs. +//! +//! Ephemeral channels should be established lazily, to avoid bootstrapping p2p connectivity +//! when it's not required. Only when a webxdc subscribes to realtime data or when a reatlime message is sent, +//! the p2p machinery should be started. +//! +//! Adding peer channels to webxdc needs upfront negotation of a topic and sharing of public keys so that +//! nodes can connect to each other. The explicit approach is as follows: +//! +//! 1. We introduce a new [GossipTopic](crate::headerdef::HeaderDef::IrohGossipTopic) message header with a random 32-byte TopicId, +//! securely generated on the initial webxdc sender's device. This message header is encrypted +//! and sent in the same message as the webxdc application. +//! 2. Whenever `joinRealtimeChannel().setListener()` or `joinRealtimeChannel().send()` is called by the webxdc application, +//! we start a routine to establish p2p connectivity and join the gossip swarm with Iroh. +//! 3. The first step of this routine is to introduce yourself with a regular message containing the `IrohPublicKey`. +//! This message contains the users relay-server and public key. +//! Direct IP address is not included as this information can be persisted by email providers. +//! 4. After the announcement, the sending peer joins the gossip swarm with an empty list of peer IDs (as they don't know anyone yet). +//! 5. Upon receiving an announcement message, other peers store the sender's [NodeAddr] in the database +//! (scoped per WebXDC app instance/message-id). The other peers can then join the gossip with `joinRealtimeChannel().setListener()` +//! and `joinRealtimeChannel().send()` just like the other peers. + +use anyhow::{anyhow, Context as _, Result}; +use email::Header; +use iroh_gossip::net::{Gossip, JoinTopicFut, GOSSIP_ALPN}; +use iroh_gossip::proto::{Event as IrohEvent, TopicId}; +use iroh_net::relay::{RelayMap, RelayUrl}; +use iroh_net::{key::SecretKey, relay::RelayMode, MagicEndpoint}; +use iroh_net::{NodeAddr, NodeId}; +use std::collections::{BTreeSet, HashMap}; +use std::env; +use tokio::sync::RwLock; +use tokio::task::JoinHandle; +use url::Url; + +use crate::chat::send_msg; +use crate::context::Context; +use crate::headerdef::HeaderDef; +use crate::message::{Message, MsgId, Viewtype}; +use crate::mimeparser::SystemMessage; +use crate::EventType; + +/// The length of an ed25519 `PublicKey`, in bytes. +const PUBLIC_KEY_LENGTH: usize = 32; +const PUBLIC_KEY_STUB: &[u8] = "static_string".as_bytes(); + +/// Store iroh peer channels for the context. +#[derive(Debug)] +pub struct Iroh { + /// [MagicEndpoint] needed for iroh peer channels. + pub(crate) endpoint: MagicEndpoint, + + /// [Gossip] needed for iroh peer channels. + pub(crate) gossip: Gossip, + + /// Topics for which an advertisement has already been sent. + pub(crate) iroh_channels: RwLock>, + + /// Currently used Iroh secret key + pub(crate) secret_key: SecretKey, +} + +impl Iroh { + /// Notify the endpoint that the network has changed. + pub(crate) async fn network_change(&self) { + self.endpoint.network_change().await + } + + /// Join a topic and create the subscriber loop for it. + /// + /// If there is no gossip, create it. + /// + /// The returned future resolves when the swarm becomes operational. + async fn join_and_subscribe_gossip( + &self, + ctx: &Context, + msg_id: MsgId, + ) -> Result> { + let topic = get_iroh_topic_for_msg(ctx, msg_id).await?; + let seq = if let Some(channel_state) = self.iroh_channels.read().await.get(&topic) { + if channel_state.subscribe_loop.is_some() { + return Ok(None); + } + channel_state.seq_number + } else { + 0 + }; + + let peers = get_iroh_gossip_peers(ctx, msg_id).await?; + info!( + ctx, + "IROH_REALTIME: Joining gossip with peers: {:?}", + peers.iter().map(|p| p.node_id).collect::>() + ); + + // Connect to all peers + for peer in &peers { + self.endpoint.add_node_addr(peer.clone())?; + } + + let connect_future = self + .gossip + .join(topic, peers.into_iter().map(|addr| addr.node_id).collect()) + .await?; + + let ctx = ctx.clone(); + let gossip = self.gossip.clone(); + let subscribe_loop = tokio::spawn(async move { + if let Err(e) = subscribe_loop(&ctx, gossip, topic, msg_id).await { + warn!(ctx, "subscribe_loop failed: {e}") + } + }); + + self.iroh_channels + .write() + .await + .insert(topic, ChannelState::new(seq, subscribe_loop)); + + Ok(Some(connect_future)) + } + + /// Send realtime data to the gossip swarm. + pub async fn send_webxdc_realtime_data( + &self, + ctx: &Context, + msg_id: MsgId, + mut data: Vec, + ) -> Result<()> { + let topic = get_iroh_topic_for_msg(ctx, msg_id).await?; + self.join_and_subscribe_gossip(ctx, msg_id).await?; + + let seq_num = self.get_and_incr(&topic).await; + data.extend(seq_num.to_le_bytes()); + data.extend(self.secret_key.public().as_bytes()); + + self.gossip.broadcast(topic, data.into()).await?; + + if env::var("REALTIME_DEBUG").is_ok() { + info!(ctx, "Sent realtime data"); + } + + Ok(()) + } + + async fn get_and_incr(&self, topic: &TopicId) -> i32 { + let mut seq = 0; + if let Some(state) = self.iroh_channels.write().await.get_mut(topic) { + seq = state.seq_number; + state.seq_number = state.seq_number.wrapping_add(1) + } + seq + } + + /// Get the iroh [NodeAddr] without direct IP addresses. + pub(crate) async fn get_node_addr(&self) -> Result { + let mut addr = self.endpoint.my_addr().await?; + addr.info.direct_addresses = BTreeSet::new(); + Ok(addr) + } + + /// Leave the realtime channel for a given topic. + pub(crate) async fn leave_realtime(&self, topic: TopicId) -> Result<()> { + if let Some(channel) = &mut self.iroh_channels.write().await.get_mut(&topic) { + if let Some(subscribe_loop) = channel.subscribe_loop.take() { + subscribe_loop.abort(); + } + } + self.gossip.quit(topic).await?; + Ok(()) + } +} + +/// Single gossip channel state. +#[derive(Debug)] +pub(crate) struct ChannelState { + /// Sequence number for the gossip channel. + seq_number: i32, + /// The subscribe loop handle. + subscribe_loop: Option>, +} + +impl ChannelState { + fn new(seq_number: i32, subscribe_loop: JoinHandle<()>) -> Self { + Self { + seq_number, + subscribe_loop: Some(subscribe_loop), + } + } +} + +impl Context { + /// Create magic endpoint and gossip. + async fn init_peer_channels(&self) -> Result { + let secret_key: SecretKey = SecretKey::generate(); + + let relay_mode = if let Some(relay_url) = self + .metadata + .read() + .await + .as_ref() + .and_then(|conf| conf.iroh_relay.clone()) + { + RelayMode::Custom(RelayMap::from_url(RelayUrl::from(relay_url))) + } else { + // FIXME: this should be RelayMode::Disabled instead. + // Currently using default relays because otherwise Rust tests fail. + RelayMode::Default + }; + + let endpoint = MagicEndpoint::builder() + .secret_key(secret_key.clone()) + .alpns(vec![GOSSIP_ALPN.to_vec()]) + .relay_mode(relay_mode) + .bind(0) + .await?; + + // create gossip + let my_addr = endpoint.my_addr().await?; + let gossip = Gossip::from_endpoint(endpoint.clone(), Default::default(), &my_addr.info); + + // spawn endpoint loop that forwards incoming connections to the gossiper + let context = self.clone(); + + // Shuts down on deltachat shutdown + tokio::spawn(endpoint_loop(context, endpoint.clone(), gossip.clone())); + + Ok(Iroh { + endpoint, + gossip, + iroh_channels: RwLock::new(HashMap::new()), + secret_key, + }) + } + + /// Get or initialize the iroh peer channel. + pub async fn get_or_try_init_peer_channel(&self) -> Result<&Iroh> { + let ctx = self.clone(); + self.iroh + .get_or_try_init(|| async { ctx.init_peer_channels().await }) + .await + } +} + +/// Cache a peers [NodeId] for one topic. +pub(crate) async fn iroh_add_peer_for_topic( + ctx: &Context, + msg_id: MsgId, + topic: TopicId, + peer: NodeId, + relay_server: Option<&str>, +) -> Result<()> { + ctx.sql + .execute( + "INSERT OR REPLACE INTO iroh_gossip_peers (msg_id, public_key, topic, relay_server) VALUES (?, ?, ?, ?)", + (msg_id, peer.as_bytes(), topic.as_bytes(), relay_server), + ) + .await?; + Ok(()) +} + +/// Insert topicId into the database so that we can use it to retrieve the topic. +pub(crate) async fn insert_topic_stub(ctx: &Context, msg_id: MsgId, topic: TopicId) -> Result<()> { + ctx.sql + .execute( + "INSERT OR REPLACE INTO iroh_gossip_peers (msg_id, public_key, topic, relay_server) VALUES (?, ?, ?, ?)", + (msg_id, PUBLIC_KEY_STUB, topic.as_bytes(), Option::<&str>::None), + ) + .await?; + Ok(()) +} + +/// Get a list of [NodeAddr]s for one webxdc. +async fn get_iroh_gossip_peers(ctx: &Context, msg_id: MsgId) -> Result> { + ctx.sql + .query_map( + "SELECT public_key, relay_server FROM iroh_gossip_peers WHERE msg_id = ? AND public_key != ?", + (msg_id, PUBLIC_KEY_STUB), + |row| { + let key: Vec = row.get(0)?; + let server: Option = row.get(1)?; + Ok((key, server)) + }, + |g| { + g.map(|data| { + let (key, server) = data?; + let server = server.map(|data| Ok::<_, url::ParseError>(RelayUrl::from(Url::parse(&data)?))).transpose()?; + let id = NodeId::from_bytes(&key.try_into() + .map_err(|_| anyhow!("Can't convert sql data to [u8; 32]"))?)?; + Ok::<_, anyhow::Error>(NodeAddr::from_parts( + id, server, vec![] + )) + }) + .collect::, _>>() + .map_err(Into::into) + }, + ) + .await +} + +/// Get the topic for a given [MsgId]. +pub(crate) async fn get_iroh_topic_for_msg(ctx: &Context, msg_id: MsgId) -> Result { + let bytes: Vec = ctx + .sql + .query_get_value( + "SELECT topic FROM iroh_gossip_peers WHERE msg_id = ? LIMIT 1", + (msg_id,), + ) + .await? + .context("couldn't restore topic from db")?; + Ok(TopicId::from_bytes(bytes.try_into().unwrap())) +} + +/// Send a gossip advertisement to the chat that [MsgId] belongs to. +/// This method should be called from the frontend when `joinRealtimeChannel` is called. +pub async fn send_webxdc_realtime_advertisement( + ctx: &Context, + msg_id: MsgId, +) -> Result> { + let iroh = ctx.get_or_try_init_peer_channel().await?; + let conn = iroh.join_and_subscribe_gossip(ctx, msg_id).await?; + + let webxdc = Message::load_from_db(ctx, msg_id).await?; + let mut msg = Message::new(Viewtype::Text); + msg.hidden = true; + msg.param.set_cmd(SystemMessage::IrohNodeAddr); + msg.in_reply_to = Some(webxdc.rfc724_mid.clone()); + send_msg(ctx, webxdc.chat_id, &mut msg).await?; + info!(ctx, "IROH_REALTIME: Sent realtime advertisement"); + Ok(conn) +} + +/// Send realtime data to the gossip swarm. +pub async fn send_webxdc_realtime_data(ctx: &Context, msg_id: MsgId, data: Vec) -> Result<()> { + let iroh = ctx.get_or_try_init_peer_channel().await?; + iroh.send_webxdc_realtime_data(ctx, msg_id, data).await?; + Ok(()) +} + +/// Leave the gossip of the webxdc with given [MsgId]. +pub async fn leave_webxdc_realtime(ctx: &Context, msg_id: MsgId) -> Result<()> { + let iroh = ctx.get_or_try_init_peer_channel().await?; + iroh.leave_realtime(get_iroh_topic_for_msg(ctx, msg_id).await?) + .await?; + info!(ctx, "IROH_REALTIME: Left gossip for message {msg_id}"); + + Ok(()) +} + +pub(crate) fn create_random_topic() -> TopicId { + TopicId::from_bytes(rand::random()) +} + +pub(crate) async fn create_iroh_header( + ctx: &Context, + topic: TopicId, + msg_id: MsgId, +) -> Result
{ + insert_topic_stub(ctx, msg_id, topic).await?; + Ok(Header::new( + HeaderDef::IrohGossipTopic.get_headername().to_string(), + topic.to_string(), + )) +} + +async fn endpoint_loop(context: Context, endpoint: MagicEndpoint, gossip: Gossip) { + while let Some(conn) = endpoint.accept().await { + info!(context, "IROH_REALTIME: accepting iroh connection"); + let gossip = gossip.clone(); + let context = context.clone(); + tokio::spawn(async move { + if let Err(err) = handle_connection(&context, conn, gossip).await { + warn!(context, "IROH_REALTIME: iroh connection error: {err}"); + } + }); + } +} + +async fn handle_connection( + context: &Context, + mut conn: iroh_net::magic_endpoint::Connecting, + gossip: Gossip, +) -> anyhow::Result<()> { + let alpn = conn.alpn().await?; + let conn = conn.await?; + let peer_id = iroh_net::magic_endpoint::get_remote_node_id(&conn)?; + + match alpn.as_bytes() { + GOSSIP_ALPN => gossip + .handle_connection(conn) + .await + .context(format!("Connection to {peer_id} with ALPN {alpn} failed"))?, + _ => warn!( + context, + "Ignoring connection from {peer_id}: unsupported ALPN protocol" + ), + } + Ok(()) +} + +async fn subscribe_loop( + context: &Context, + gossip: Gossip, + topic: TopicId, + msg_id: MsgId, +) -> Result<()> { + let mut stream = gossip.subscribe(topic).await?; + loop { + let event = stream.recv().await?; + match event { + IrohEvent::NeighborUp(node) => { + info!(context, "IROH_REALTIME: NeighborUp: {}", node.to_string()); + iroh_add_peer_for_topic(context, msg_id, topic, node, None).await?; + } + IrohEvent::Received(event) => { + info!(context, "IROH_REALTIME: Received realtime data"); + context.emit_event(EventType::WebxdcRealtimeData { + msg_id, + data: event + .content + .get(0..event.content.len() - 4 - PUBLIC_KEY_LENGTH) + .context("too few bytes in iroh message")? + .into(), + }); + } + _ => (), + }; + } +} + +#[cfg(test)] +mod tests { + use crate::{ + chat::send_msg, + message::{Message, Viewtype}, + peer_channels::{ + get_iroh_gossip_peers, get_iroh_topic_for_msg, leave_webxdc_realtime, + send_webxdc_realtime_advertisement, + }, + test_utils::TestContextManager, + EventType, + }; + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_can_communicate() { + let mut tcm = TestContextManager::new(); + let alice = &mut tcm.alice().await; + let bob = &mut tcm.bob().await; + + // Alice sends webxdc to bob + let alice_chat = alice.create_chat(bob).await; + let mut instance = Message::new(Viewtype::File); + instance + .set_file_from_bytes( + alice, + "minimal.xdc", + include_bytes!("../test-data/webxdc/minimal.xdc"), + None, + ) + .await + .unwrap(); + + send_msg(alice, alice_chat.id, &mut instance).await.unwrap(); + let alice_webxdc = alice.get_last_msg().await; + assert_eq!(alice_webxdc.get_viewtype(), Viewtype::Webxdc); + + let webxdc = alice.pop_sent_msg().await; + let bob_webdxc = bob.recv_msg(&webxdc).await; + assert_eq!(bob_webdxc.get_viewtype(), Viewtype::Webxdc); + + bob_webdxc.chat_id.accept(bob).await.unwrap(); + + // Alice advertises herself. + send_webxdc_realtime_advertisement(alice, alice_webxdc.id) + .await + .unwrap(); + + bob.recv_msg_trash(&alice.pop_sent_msg().await).await; + let bob_iroh = bob.get_or_try_init_peer_channel().await.unwrap(); + + // Bob adds alice to gossip peers. + let members = get_iroh_gossip_peers(bob, bob_webdxc.id) + .await + .unwrap() + .into_iter() + .map(|addr| addr.node_id) + .collect::>(); + + let alice_iroh = alice.get_or_try_init_peer_channel().await.unwrap(); + assert_eq!( + members, + vec![alice_iroh.get_node_addr().await.unwrap().node_id] + ); + + bob_iroh + .join_and_subscribe_gossip(bob, bob_webdxc.id) + .await + .unwrap() + .unwrap() + .await + .unwrap(); + + // Alice sends ephemeral message + alice_iroh + .send_webxdc_realtime_data(alice, alice_webxdc.id, "alice -> bob".as_bytes().to_vec()) + .await + .unwrap(); + + loop { + let event = bob.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == "alice -> bob".as_bytes() { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + // Bob sends ephemeral message + bob_iroh + .send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice".as_bytes().to_vec()) + .await + .unwrap(); + + loop { + let event = alice.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == "bob -> alice".as_bytes() { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + + // Alice adds bob to gossip peers. + let members = get_iroh_gossip_peers(alice, alice_webxdc.id) + .await + .unwrap() + .into_iter() + .map(|addr| addr.node_id) + .collect::>(); + + assert_eq!( + members, + vec![bob_iroh.get_node_addr().await.unwrap().node_id] + ); + + bob_iroh + .send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice 2".as_bytes().to_vec()) + .await + .unwrap(); + + loop { + let event = alice.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == "bob -> alice 2".as_bytes() { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_can_reconnect() { + let mut tcm = TestContextManager::new(); + let alice = &mut tcm.alice().await; + let bob = &mut tcm.bob().await; + + // Alice sends webxdc to bob + let alice_chat = alice.create_chat(bob).await; + let mut instance = Message::new(Viewtype::File); + instance + .set_file_from_bytes( + alice, + "minimal.xdc", + include_bytes!("../test-data/webxdc/minimal.xdc"), + None, + ) + .await + .unwrap(); + + send_msg(alice, alice_chat.id, &mut instance).await.unwrap(); + let alice_webxdc = alice.get_last_msg().await; + assert_eq!(alice_webxdc.get_viewtype(), Viewtype::Webxdc); + + let webxdc = alice.pop_sent_msg().await; + let bob_webdxc = bob.recv_msg(&webxdc).await; + assert_eq!(bob_webdxc.get_viewtype(), Viewtype::Webxdc); + + bob_webdxc.chat_id.accept(bob).await.unwrap(); + + // Alice advertises herself. + send_webxdc_realtime_advertisement(alice, alice_webxdc.id) + .await + .unwrap(); + + bob.recv_msg_trash(&alice.pop_sent_msg().await).await; + let bob_iroh = bob.get_or_try_init_peer_channel().await.unwrap(); + + // Bob adds alice to gossip peers. + let members = get_iroh_gossip_peers(bob, bob_webdxc.id) + .await + .unwrap() + .into_iter() + .map(|addr| addr.node_id) + .collect::>(); + + let alice_iroh = alice.get_or_try_init_peer_channel().await.unwrap(); + assert_eq!( + members, + vec![alice_iroh.get_node_addr().await.unwrap().node_id] + ); + + bob_iroh + .join_and_subscribe_gossip(bob, bob_webdxc.id) + .await + .unwrap() + .unwrap() + .await + .unwrap(); + + // Alice sends ephemeral message + alice_iroh + .send_webxdc_realtime_data(alice, alice_webxdc.id, "alice -> bob".as_bytes().to_vec()) + .await + .unwrap(); + + loop { + let event = bob.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == "alice -> bob".as_bytes() { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + + // TODO: check that seq number is persisted + leave_webxdc_realtime(bob, bob_webdxc.id).await.unwrap(); + + bob_iroh + .join_and_subscribe_gossip(bob, bob_webdxc.id) + .await + .unwrap() + .unwrap() + .await + .unwrap(); + + bob_iroh + .send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice".as_bytes().to_vec()) + .await + .unwrap(); + + loop { + let event = alice.evtracker.recv().await.unwrap(); + if let EventType::WebxdcRealtimeData { data, .. } = event.typ { + if data == "bob -> alice".as_bytes() { + break; + } else { + panic!( + "Unexpected status update: {}", + String::from_utf8_lossy(&data) + ); + } + } + } + + // channel is only used to remeber if an advertisement has been sent + // bob for example does not change the channels because he never sends an + // advertisement + assert_eq!( + alice.iroh.get().unwrap().iroh_channels.read().await.len(), + 1 + ); + leave_webxdc_realtime(alice, alice_webxdc.id).await.unwrap(); + let topic = get_iroh_topic_for_msg(alice, alice_webxdc.id) + .await + .unwrap(); + assert!(if let Some(state) = alice + .iroh + .get() + .unwrap() + .iroh_channels + .read() + .await + .get(&topic) + { + state.subscribe_loop.is_none() + } else { + false + }); + } +} diff --git a/src/qr.rs b/src/qr.rs index 0c349e8488..72e4f356e5 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -23,6 +23,7 @@ use crate::peerstate::Peerstate; use crate::socks::Socks5Config; use crate::token; use crate::tools::validate_id; +use iroh_old as iroh; const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase const IDELTACHAT_SCHEME: &str = "https://i.delta.chat/#"; diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 9810abc3b3..5e6a547dcf 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -1,11 +1,13 @@ //! Internet Message Format reception pipeline. use std::collections::HashSet; +use std::str::FromStr; use anyhow::{Context as _, Result}; use deltachat_contact_tools::{ addr_cmp, may_be_valid_addr, normalize_name, strip_rtlo_characters, ContactAddress, }; +use iroh_gossip::proto::TopicId; use mailparse::{parse_mail, SingleInfo}; use num_traits::FromPrimitive; use once_cell::sync::Lazy; @@ -30,6 +32,7 @@ use crate::message::{ }; use crate::mimeparser::{parse_message_ids, AvatarAction, MimeMessage, SystemMessage}; use crate::param::{Param, Params}; +use crate::peer_channels::{get_iroh_topic_for_msg, insert_topic_stub, iroh_add_peer_for_topic}; use crate::peerstate::Peerstate; use crate::reaction::{set_msg_reaction, Reaction}; use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on_other_device}; @@ -40,6 +43,7 @@ use crate::sync::Sync::*; use crate::tools::{self, buf_compress, extract_grpid_from_rfc724_mid}; use crate::{chatlist_events, location}; use crate::{contact, imap}; +use iroh_net::NodeAddr; /// This is the struct that is returned after receiving one email (aka MIME message). /// @@ -1220,7 +1224,7 @@ async fn add_parts( } let orig_chat_id = chat_id; - let chat_id = if is_mdn || is_reaction { + let mut chat_id = if is_mdn || is_reaction { DC_CHAT_ID_TRASH } else { chat_id.unwrap_or_else(|| { @@ -1430,6 +1434,24 @@ async fn add_parts( .await?; } + if let Some(node_addr) = mime_parser.get_header(HeaderDef::IrohNodeAddr) { + match serde_json::from_str::(node_addr).context("Failed to parse node address") { + Ok(node_addr) => { + info!(context, "Adding iroh peer with address {node_addr:?}."); + let instance_id = parent.context("Failed to get parent message")?.id; + let node_id = node_addr.node_id; + let relay_server = node_addr.relay_url().map(|relay| relay.as_str()); + let topic = get_iroh_topic_for_msg(context, instance_id).await?; + iroh_add_peer_for_topic(context, instance_id, topic, node_id, relay_server).await?; + + chat_id = DC_CHAT_ID_TRASH; + } + Err(err) => { + warn!(context, "Couldn't parse NodeAddr: {err:#}."); + } + } + } + for part in &mime_parser.parts { if part.is_reaction { let reaction_str = simplify::remove_footers(part.msg.as_str()); @@ -1597,6 +1619,16 @@ RETURNING id // check all parts whether they contain a new logging webxdc for (part, msg_id) in mime_parser.parts.iter().zip(&created_db_entries) { + // check if any part contains a webxdc topic id + if part.typ == Viewtype::Webxdc { + if let Some(topic) = mime_parser.get_header(HeaderDef::IrohGossipTopic) { + let topic = TopicId::from_str(topic).context("wrong gossip topic header")?; + insert_topic_stub(context, *msg_id, topic).await?; + } else { + warn!(context, "webxdc doesn't have a gossip topic") + } + } + maybe_set_logging_xdc_inner( context, part.typ, diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index 2bf3ab57c7..644dbfa9f5 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -912,6 +912,30 @@ CREATE INDEX msgs_status_updates_index2 ON msgs_status_updates (uid); .await?; } + if dbversion < 111 { + sql.execute_migration( + "CREATE TABLE iroh_gossip_peers (msg_id TEXT not NULL, topic TEXT NOT NULL, public_key TEXT NOT NULL)", + 111, + ) + .await?; + } + + if dbversion < 112 { + sql.execute_migration( + "DROP TABLE iroh_gossip_peers; CREATE TABLE iroh_gossip_peers (msg_id INTEGER not NULL, topic BLOB NOT NULL, public_key BLOB NOT NULL, relay_server TEXT, UNIQUE (public_key, topic)) STRICT", + 112, + ) + .await?; + } + + if dbversion < 113 { + sql.execute_migration( + "DROP TABLE iroh_gossip_peers; CREATE TABLE iroh_gossip_peers (msg_id INTEGER not NULL, topic BLOB NOT NULL, public_key BLOB NOT NULL, relay_server TEXT, UNIQUE (topic, public_key), PRIMARY KEY(topic, public_key)) STRICT", + 113, + ) + .await?; + } + let new_version = sql .get_raw_config_int(VERSION_CFG) .await?