From bddebad3d026bce34e4a8bab6c2c4a0ba2c5591a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Mon, 3 Jul 2023 14:42:41 +0100 Subject: [PATCH 01/41] feat(protocols): Add initial UPnP protocol --- Cargo.lock | 1108 ++++++++++++++++------ Cargo.toml | 2 + libp2p/Cargo.toml | 9 +- libp2p/src/lib.rs | 3 + protocols/upnp/Cargo.toml | 27 + protocols/upnp/src/behaviour.rs | 515 ++++++++++ protocols/upnp/src/lib.rs | 101 ++ protocols/upnp/src/provider.rs | 77 ++ protocols/upnp/src/provider/async_std.rs | 94 ++ protocols/upnp/src/provider/tokio.rs | 94 ++ 10 files changed, 1754 insertions(+), 276 deletions(-) create mode 100644 protocols/upnp/Cargo.toml create mode 100644 protocols/upnp/src/behaviour.rs create mode 100644 protocols/upnp/src/lib.rs create mode 100644 protocols/upnp/src/provider.rs create mode 100644 protocols/upnp/src/provider/async_std.rs create mode 100644 protocols/upnp/src/provider/tokio.rs diff --git a/Cargo.lock b/Cargo.lock index cef33101b5f..5fa3f1faaf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -62,9 +71,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if 1.0.0", "cipher 0.4.4", @@ -73,14 +82,28 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.9.4" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" +dependencies = [ + "aead 0.3.2", + "aes 0.6.0", + "cipher 0.2.5", + "ctr 0.6.0", + "ghash 0.3.1", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" dependencies = [ "aead 0.4.3", "aes 0.7.5", "cipher 0.3.0", - "ctr 0.8.0", + "ctr 0.7.0", "ghash 0.4.4", "subtle", ] @@ -92,7 +115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ "aead 0.5.2", - "aes 0.8.2", + "aes 0.8.3", "cipher 0.4.4", "ctr 0.9.2", "ghash 0.5.0", @@ -162,15 +185,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -181,7 +204,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -191,7 +214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -237,7 +260,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time", + "time 0.3.22", ] [[package]] @@ -253,7 +276,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time", + "time 0.3.22", ] [[package]] @@ -373,7 +396,7 @@ dependencies = [ "log", "parking", "polling", - "rustix", + "rustix 0.37.22", "slab", "socket2 0.4.9", "waker-fn", @@ -413,9 +436,9 @@ dependencies = [ "cfg-if 1.0.0", "event-listener", "futures-lite", - "rustix", + "rustix 0.37.22", "signal-hook", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -440,7 +463,7 @@ dependencies = [ "log", "memchr", "once_cell", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "pin-utils", "slab", "wasm-bindgen-futures", @@ -484,11 +507,11 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" dependencies = [ - "bytes", + "bytes 1.4.0", "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", ] [[package]] @@ -497,6 +520,30 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +[[package]] +name = "attohttpc" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247" +dependencies = [ + "http", + "log", + "url", + "wildmatch 1.1.0", +] + +[[package]] +name = "attohttpc" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262c3f7f5d61249d8c00e5546e2685cd15ebeeb1bc0f3cc5449350a1cb07319e" +dependencies = [ + "http", + "log", + "url", + "wildmatch 2.1.1", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -523,7 +570,7 @@ dependencies = [ "async-trait", "axum-core", "bitflags 1.3.2", - "bytes", + "bytes 1.4.0", "futures-util", "http", "http-body", @@ -533,7 +580,7 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "rustversion", "serde", "serde_json", @@ -553,7 +600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes", + "bytes 1.4.0", "futures-util", "http", "http-body", @@ -563,6 +610,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base-x" version = "0.2.11" @@ -714,6 +776,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.4.0" @@ -903,10 +971,10 @@ version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ - "bytes", + "bytes 1.4.0", "futures-core", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tokio-util", ] @@ -932,9 +1000,32 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" + +[[package]] +name = "const_fn" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" + +[[package]] +name = "cookie" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" +dependencies = [ + "aes-gcm 0.8.0", + "base64 0.13.1", + "hkdf 0.10.0", + "hmac 0.10.1", + "percent-encoding", + "rand 0.8.5", + "sha2 0.9.9", + "time 0.2.27", + "version_check", +] [[package]] name = "cookie" @@ -943,7 +1034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time", + "time 0.3.22", "version_check", ] @@ -974,13 +1065,19 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] +[[package]] +name = "cpuid-bool" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" + [[package]] name = "crc" version = "3.0.1" @@ -1064,22 +1161,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", ] @@ -1135,6 +1232,34 @@ dependencies = [ "subtle", ] +[[package]] +name = "crypto-mac" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +dependencies = [ + "cipher 0.2.5", +] + +[[package]] +name = "ctr" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" +dependencies = [ + "cipher 0.3.0", +] + [[package]] name = "ctr" version = "0.8.0" @@ -1164,6 +1289,37 @@ dependencies = [ "rand 0.7.3", ] +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2 0.4.9", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.63+curl-8.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc" +dependencies = [ + "cc", + "libc", + "libnghttp2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1278,9 +1434,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", "pem-rfc7468 0.7.0", @@ -1367,6 +1523,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + [[package]] name = "displaydoc" version = "0.2.4" @@ -1391,9 +1553,9 @@ dependencies = [ [[package]] name = "dtoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65d09067bfacaa79114679b279d7f5885b53295b1e2cfb4e79c8e4bd3d633169" +checksum = "519b83cd10f5f6e969625a409f735182bea5558cd8b64c655806ceaae36f1999" [[package]] name = "ecdsa" @@ -1413,11 +1575,11 @@ version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ - "der 0.7.6", + "der 0.7.7", "digest 0.10.7", "elliptic-curve 0.13.5", "rfc6979 0.4.0", - "signature 2.0.0", + "signature 2.1.0", "spki 0.7.2", ] @@ -1463,7 +1625,7 @@ dependencies = [ "ff 0.12.1", "generic-array", "group 0.12.1", - "hkdf", + "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -1550,7 +1712,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1576,7 +1738,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5eb32b0001134a1d3b9e16010eb4b119451edf68446963a30a8130a0d056e98" dependencies = [ "base64 0.13.1", - "cookie", + "cookie 0.16.2", "futures-core", "futures-util", "http", @@ -1585,7 +1747,7 @@ dependencies = [ "mime", "serde", "serde_json", - "time", + "time 0.3.22", "tokio", "url", "webdriver", @@ -1650,6 +1812,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bebadab126f8120d410b677ed95eee4ba6eb7c6dd8e34a5ec88a08050e26132" +dependencies = [ + "futures-core", + "futures-sink", + "spinning_top", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1740,7 +1913,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "waker-fn", ] @@ -1822,7 +1995,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "pin-utils", "slab", ] @@ -1836,7 +2009,7 @@ dependencies = [ "futures", "log", "ringbuf", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -1874,6 +2047,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" +dependencies = [ + "opaque-debug", + "polyval 0.4.5", +] + [[package]] name = "ghash" version = "0.4.4" @@ -1891,9 +2074,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ "opaque-debug", - "polyval 0.6.0", + "polyval 0.6.1", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "glob" version = "0.3.1" @@ -1936,11 +2125,11 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ - "bytes", + "bytes 1.4.0", "fnv", "futures-core", "futures-sink", @@ -1988,18 +2177,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -2019,6 +2199,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" +[[package]] +name = "hkdf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" +dependencies = [ + "digest 0.9.0", + "hmac 0.10.1", +] + [[package]] name = "hkdf" version = "0.12.3" @@ -2034,7 +2224,17 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "crypto-mac", + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac 0.10.0", "digest 0.9.0", ] @@ -2075,7 +2275,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes", + "bytes 1.4.0", "fnv", "itoa", ] @@ -2086,9 +2286,23 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes", + "bytes 1.4.0", "http", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", +] + +[[package]] +name = "http-client" +version = "6.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1947510dc91e2bf586ea5ffb412caad7673264e14bb39fb9078da114a94ce1a5" +dependencies = [ + "async-std", + "async-trait", + "cfg-if 1.0.0", + "http-types", + "isahc", + "log", ] [[package]] @@ -2097,6 +2311,28 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" +[[package]] +name = "http-types" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" +dependencies = [ + "anyhow", + "async-channel", + "async-std", + "base64 0.13.1", + "cookie 0.14.4", + "futures-lite", + "infer", + "pin-project-lite 0.2.10", + "rand 0.7.3", + "serde", + "serde_json", + "serde_qs", + "serde_urlencoded", + "url", +] + [[package]] name = "httparse" version = "1.8.0" @@ -2121,7 +2357,7 @@ version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes", + "bytes 1.4.0", "futures-channel", "futures-core", "futures-util", @@ -2131,7 +2367,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "socket2 0.4.9", "tokio", "tower-service", @@ -2160,7 +2396,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes", + "bytes 1.4.0", "hyper", "native-tls", "tokio", @@ -2234,6 +2470,42 @@ dependencies = [ "windows", ] +[[package]] +name = "igd" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556b5a75cd4adb7c4ea21c64af1c48cefb2ce7d43dc4352c720a1fe47c21f355" +dependencies = [ + "attohttpc 0.16.3", + "bytes 1.4.0", + "futures", + "http", + "hyper", + "log", + "rand 0.8.5", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "igd_async_std" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08b1b8bc4334daa2fc717ae3f285b42130c92c2078a5a94a4c0f86457a376c3" +dependencies = [ + "async-std", + "attohttpc 0.19.1", + "bytes 1.4.0", + "futures", + "http", + "log", + "rand 0.8.5", + "surf", + "url", + "xmltree", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -2254,6 +2526,12 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "infer" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" + [[package]] name = "inout" version = "0.1.3" @@ -2282,7 +2560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c142385498b53584546abbfa50188b2677af8e4f879da1ee5d905cb7de5b97a" dependencies = [ "async-trait", - "bytes", + "bytes 1.4.0", "log", "rand 0.8.5", "rtcp", @@ -2334,9 +2612,9 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2347,7 +2625,7 @@ checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ "socket2 0.5.3", "widestring", - "windows-sys 0.48.0", + "windows-sys", "winreg 0.50.0", ] @@ -2376,20 +2654,42 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", + "hermit-abi", + "rustix 0.38.2", + "windows-sys", +] + +[[package]] +name = "isahc" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2948a0ce43e2c2ef11d7edf6816508998d99e13badd1150be0914205df9388a" +dependencies = [ + "bytes 0.5.6", + "crossbeam-utils", + "curl", + "curl-sys", + "flume", + "futures-lite", + "http", + "log", + "once_cell", + "slab", + "sluice", + "tracing", + "tracing-futures", + "url", + "waker-fn", ] [[package]] @@ -2403,9 +2703,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" @@ -2465,13 +2765,23 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +[[package]] +name = "libnghttp2-sys" +version = "0.1.7+1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "libp2p" version = "0.52.1" dependencies = [ "async-std", "async-trait", - "bytes", + "bytes 1.4.0", "clap", "either", "env_logger 0.10.0", @@ -2504,6 +2814,7 @@ dependencies = [ "libp2p-tcp", "libp2p-tls", "libp2p-uds", + "libp2p-upnp", "libp2p-wasm-ext", "libp2p-websocket", "libp2p-webtransport-websys", @@ -2684,7 +2995,7 @@ dependencies = [ "asynchronous-codec", "base64 0.21.2", "byteorder", - "bytes", + "bytes 1.4.0", "either", "env_logger 0.10.0", "fnv", @@ -2772,7 +3083,7 @@ dependencies = [ "arrayvec", "async-std", "asynchronous-codec", - "bytes", + "bytes 1.4.0", "either", "env_logger 0.10.0", "fnv", @@ -2849,7 +3160,7 @@ version = "0.40.0" dependencies = [ "async-std", "asynchronous-codec", - "bytes", + "bytes 1.4.0", "criterion", "env_logger 0.10.0", "futures", @@ -2882,7 +3193,7 @@ dependencies = [ name = "libp2p-noise" version = "0.43.0" dependencies = [ - "bytes", + "bytes 1.4.0", "curve25519-dalek 3.2.0", "env_logger 0.10.0", "futures", @@ -2958,7 +3269,7 @@ name = "libp2p-plaintext" version = "0.40.0" dependencies = [ "asynchronous-codec", - "bytes", + "bytes 1.4.0", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -2997,7 +3308,7 @@ name = "libp2p-quic" version = "0.8.0-alpha" dependencies = [ "async-std", - "bytes", + "bytes 1.4.0", "env_logger 0.10.0", "futures", "futures-timer", @@ -3024,7 +3335,7 @@ name = "libp2p-relay" version = "0.16.0" dependencies = [ "asynchronous-codec", - "bytes", + "bytes 1.4.0", "either", "env_logger 0.10.0", "futures", @@ -3215,6 +3526,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "libp2p-upnp" +version = "0.1.0" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "igd", + "igd_async_std", + "libp2p-core", + "libp2p-swarm", + "log", + "void", +] + [[package]] name = "libp2p-wasm-ext" version = "0.40.0" @@ -3234,7 +3560,7 @@ dependencies = [ "anyhow", "async-trait", "asynchronous-codec", - "bytes", + "bytes 1.4.0", "env_logger 0.10.0", "futures", "futures-timer", @@ -3368,6 +3694,18 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libz-sys" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3380,6 +3718,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "lock_api" version = "0.4.10" @@ -3470,9 +3814,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -3529,7 +3873,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -3581,7 +3925,7 @@ name = "multistream-select" version = "0.13.0" dependencies = [ "async-std", - "bytes", + "bytes 1.4.0", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -3656,7 +4000,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "bytes", + "bytes 1.4.0", "futures", "log", "netlink-packet-core", @@ -3672,7 +4016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" dependencies = [ "async-io", - "bytes", + "bytes 1.4.0", "futures", "libc", "log", @@ -3749,14 +4093,23 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "oid-registry" version = "0.4.0" @@ -3918,9 +4271,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" [[package]] name = "pem" @@ -3983,9 +4336,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -4019,7 +4372,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.6", + "der 0.7.7", "spki 0.7.2", ] @@ -4037,9 +4390,9 @@ checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -4050,15 +4403,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -4075,8 +4428,8 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.9", - "windows-sys 0.48.0", + "pin-project-lite 0.2.10", + "windows-sys", ] [[package]] @@ -4087,7 +4440,18 @@ checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.4.1", + "universal-hash 0.4.0", +] + +[[package]] +name = "polyval" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +dependencies = [ + "cpuid-bool", + "opaque-debug", + "universal-hash 0.4.0", ] [[package]] @@ -4099,14 +4463,14 @@ dependencies = [ "cfg-if 1.0.0", "cpufeatures", "opaque-debug", - "universal-hash 0.4.1", + "universal-hash 0.4.0", ] [[package]] name = "polyval" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -4153,6 +4517,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-macro-warning" version = "0.4.1" @@ -4216,7 +4586,7 @@ name = "quick-protobuf-codec" version = "0.2.0" dependencies = [ "asynchronous-codec", - "bytes", + "bytes 1.4.0", "quick-protobuf", "thiserror", "unsigned-varint", @@ -4258,7 +4628,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85af4ed6ee5a89f26a26086e9089a6643650544c025158449a3626ebf72884b3" dependencies = [ - "bytes", + "bytes 1.4.0", "rand 0.8.5", "ring", "rustc-hash", @@ -4379,7 +4749,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time", + "time 0.3.22", "yasna", ] @@ -4391,7 +4761,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time", + "time 0.3.22", "x509-parser 0.14.0", "yasna", ] @@ -4403,12 +4773,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f" dependencies = [ "async-trait", - "bytes", + "bytes 1.4.0", "combine", "futures-util", "itoa", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "ryu", "tokio", "tokio-util", @@ -4489,7 +4859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", - "bytes", + "bytes 1.4.0", "encoding_rs", "futures-core", "futures-util", @@ -4505,7 +4875,7 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "serde", "serde_json", "serde_urlencoded", @@ -4602,7 +4972,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6423493804221c276d27f3cc383cd5cbe1a1f10f210909fd4951b579b01293cd" dependencies = [ - "bytes", + "bytes 1.4.0", "thiserror", "webrtc-util", ] @@ -4629,7 +4999,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b728adb99b88d932f2f0622b540bf7ccb196f81e9823b5b0eeb166526c88138c" dependencies = [ - "bytes", + "bytes 1.4.0", "rand 0.8.5", "serde", "thiserror", @@ -4670,19 +5040,34 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.17", ] [[package]] @@ -4696,16 +5081,29 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys 0.48.0", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", + "windows-sys", ] [[package]] @@ -4747,9 +5145,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -4759,9 +5157,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ "base64 0.21.2", ] @@ -4778,9 +5176,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "rw-stream-sink" @@ -4794,9 +5192,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "salsa20" @@ -4818,11 +5216,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -4890,7 +5288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct 0.2.0", - "der 0.7.6", + "der 0.7.7", "generic-array", "pkcs8 0.10.2", "subtle", @@ -4920,12 +5318,27 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "send_wrapper" version = "0.4.0" @@ -4943,9 +5356,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" dependencies = [ "serde_derive", ] @@ -4962,9 +5375,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" dependencies = [ "proc-macro2", "quote", @@ -4985,18 +5398,30 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b1b6471d7496b051e03f1958802a73f88b947866f5146f329e47e36554f4e55" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_qs" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" dependencies = [ + "percent-encoding", "serde", + "thiserror", ] [[package]] name = "serde_repr" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +checksum = "6f0a21fba416426ac927b1691996e82079f8b6156e920c85345f135b2e9ba2de" dependencies = [ "proc-macro2", "quote", @@ -5028,6 +5453,15 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + [[package]] name = "sha1" version = "0.10.5" @@ -5039,6 +5473,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sha2" version = "0.9.9" @@ -5113,9 +5553,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -5130,6 +5570,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "sluice" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +dependencies = [ + "async-channel", + "futures-core", + "futures-io", +] + [[package]] name = "smallvec" version = "1.10.0" @@ -5168,13 +5619,13 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ccba027ba85743e09d15c03296797cad56395089b832b48b5a5217880f57733" dependencies = [ - "aes-gcm 0.9.4", + "aes-gcm 0.9.2", "blake2", "chacha20poly1305", "curve25519-dalek 4.0.0-rc.1", "rand_core 0.6.4", "ring", - "rustc_version", + "rustc_version 0.4.0", "sha2 0.10.7", "subtle", ] @@ -5196,7 +5647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -5206,7 +5657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", - "bytes", + "bytes 1.4.0", "futures", "httparse", "log", @@ -5220,6 +5671,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spinning_top" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.6.0" @@ -5237,7 +5697,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der 0.7.6", + "der 0.7.7", +] + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", ] [[package]] @@ -5246,6 +5715,55 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version 0.2.3", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1 0.6.1", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + [[package]] name = "stringmatch" version = "0.4.0" @@ -5291,9 +5809,32 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "surf" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718b1ae6b50351982dedff021db0def601677f2120938b070eadb10ba4038dd7" +dependencies = [ + "async-std", + "async-trait", + "cfg-if 1.0.0", + "encoding_rs", + "futures-util", + "getrandom 0.2.10", + "http-client", + "http-types", + "log", + "mime_guess", + "once_cell", + "pin-project-lite 0.2.10", + "serde", + "serde_json", + "web-sys", +] [[package]] name = "syn" @@ -5366,8 +5907,8 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "redox_syscall", - "rustix", - "windows-sys 0.48.0", + "rustix 0.37.22", + "windows-sys", ] [[package]] @@ -5387,7 +5928,7 @@ checksum = "bf0fe180d5f1f7dd32bb5f1a8d19231bb63dc9bbb1985e1dbb6f07163b6a8578" dependencies = [ "async-trait", "base64 0.21.2", - "cookie", + "cookie 0.16.2", "fantoccini", "futures", "http", @@ -5449,14 +5990,29 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros 0.1.1", + "version_check", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", "time-core", - "time-macros", + "time-macros 0.2.9", ] [[package]] @@ -5465,6 +6021,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + [[package]] name = "time-macros" version = "0.2.9" @@ -5474,6 +6040,19 @@ dependencies = [ "time-core", ] +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn 1.0.109", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -5501,21 +6080,22 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", - "bytes", + "backtrace", + "bytes 1.4.0", "libc", "mio", "num_cpus", "parking_lot", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "signal-hook-registry", "socket2 0.4.9", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -5556,11 +6136,11 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ - "bytes", + "bytes 1.4.0", "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tracing", ] @@ -5574,7 +6154,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tower-layer", "tower-service", @@ -5588,7 +6168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8bd22a874a2d0b70452d5597b12c537331d49060824a95f49f108994f94aa4c" dependencies = [ "bitflags 2.3.3", - "bytes", + "bytes 1.4.0", "futures-core", "futures-util", "http", @@ -5598,7 +6178,7 @@ dependencies = [ "mime", "mime_guess", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tokio", "tokio-util", "tower-layer", @@ -5626,16 +6206,16 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", @@ -5652,6 +6232,16 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.3" @@ -5688,7 +6278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" dependencies = [ "async-trait", - "bytes", + "bytes 1.4.0", "cfg-if 1.0.0", "data-encoding", "enum-as-inner", @@ -5813,9 +6403,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -5840,9 +6430,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "universal-hash" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" dependencies = [ "generic-array", "subtle", @@ -5865,7 +6455,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" dependencies = [ "asynchronous-codec", - "bytes", + "bytes 1.4.0", ] [[package]] @@ -5883,6 +6473,7 @@ dependencies = [ "form_urlencoded", "idna 0.4.0", "percent-encoding", + "serde", ] [[package]] @@ -5893,9 +6484,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "getrandom 0.2.10", ] @@ -5908,9 +6499,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" [[package]] name = "vcpkg" @@ -5957,11 +6548,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -6095,14 +6685,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9973cb72c8587d5ad5efdb91e663d36177dc37725e6c90ca86c626b0cc45c93f" dependencies = [ "base64 0.13.1", - "bytes", - "cookie", + "bytes 1.4.0", + "cookie 0.16.2", "http", "log", "serde", "serde_derive", "serde_json", - "time", + "time 0.3.22", "unicode-segmentation", "url", ] @@ -6153,7 +6743,7 @@ checksum = "f60dde9fd592872bc371b3842e4616bc4c6984242e3cd2a7d7cb771db278601b" dependencies = [ "arc-swap", "async-trait", - "bytes", + "bytes 1.4.0", "cfg-if 0.1.10", "hex", "interceptor", @@ -6174,7 +6764,7 @@ dependencies = [ "smol_str", "stun", "thiserror", - "time", + "time 0.3.22", "tokio", "turn", "url", @@ -6195,7 +6785,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3c7ba7d11733e448d8d2d054814e97c558f52293f0e0a2eb05840f28b3be12" dependencies = [ - "bytes", + "bytes 1.4.0", "derive_builder", "log", "thiserror", @@ -6220,7 +6810,7 @@ dependencies = [ "curve25519-dalek 3.2.0", "der-parser 8.2.0", "elliptic-curve 0.12.3", - "hkdf", + "hkdf 0.12.3", "hmac 0.12.1", "log", "oid-registry 0.6.1", @@ -6234,7 +6824,7 @@ dependencies = [ "rustls 0.19.1", "sec1 0.3.0", "serde", - "sha1", + "sha1 0.10.5", "sha2 0.10.7", "signature 1.6.4", "subtle", @@ -6290,7 +6880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd8e3711a321f6a375973144f48065cf705316ab6709672954aace020c668eb6" dependencies = [ "byteorder", - "bytes", + "bytes 1.4.0", "rand 0.8.5", "rtp", "thiserror", @@ -6304,7 +6894,7 @@ checksum = "7df742d91cfbd982f6ab2bfd45a7c3ddfce5b2f55913b2f63877404d1b3259db" dependencies = [ "arc-swap", "async-trait", - "bytes", + "bytes 1.4.0", "crc", "log", "rand 0.8.5", @@ -6323,13 +6913,13 @@ dependencies = [ "aes 0.7.5", "aes-gcm 0.10.2", "byteorder", - "bytes", + "bytes 1.4.0", "ctr 0.8.0", "hmac 0.12.1", "log", "rtcp", "rtp", - "sha1", + "sha1 0.10.5", "subtle", "thiserror", "tokio", @@ -6344,7 +6934,7 @@ checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" dependencies = [ "async-trait", "bitflags 1.3.2", - "bytes", + "bytes 1.4.0", "cc", "ipnet", "lazy_static", @@ -6381,6 +6971,18 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +[[package]] +name = "wildmatch" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" + +[[package]] +name = "wildmatch" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" + [[package]] name = "winapi" version = "0.3.9" @@ -6425,21 +7027,6 @@ dependencies = [ "windows_x86_64_msvc 0.34.0", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -6451,25 +7038,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_gnullvm", "windows_aarch64_msvc 0.48.0", "windows_i686_gnu 0.48.0", "windows_i686_msvc 0.48.0", "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_gnullvm", "windows_x86_64_msvc 0.48.0", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" @@ -6482,12 +7063,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" @@ -6500,12 +7075,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" @@ -6518,12 +7087,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" @@ -6536,24 +7099,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" @@ -6566,12 +7117,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -6594,7 +7139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if 1.0.0", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -6634,7 +7179,7 @@ dependencies = [ "oid-registry 0.4.0", "rusticata-macros", "thiserror", - "time", + "time 0.3.22", ] [[package]] @@ -6653,7 +7198,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time", + "time 0.3.22", ] [[package]] @@ -6670,7 +7215,22 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time", + "time 0.3.22", +] + +[[package]] +name = "xml-rs" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a56c84a8ccd4258aed21c92f70c0f6dea75356b6892ae27c24139da456f9336" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", ] [[package]] @@ -6693,7 +7253,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time", + "time 0.3.22", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index db54152709f..426d86ad00f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ members = [ "protocols/relay", "protocols/rendezvous", "protocols/request-response", + "protocols/upnp", "swarm", "swarm-derive", "swarm-test", @@ -87,6 +88,7 @@ libp2p-quic = { version = "0.8.0-alpha", path = "transports/quic" } libp2p-relay = { version = "0.16.0", path = "protocols/relay" } libp2p-rendezvous = { version = "0.13.0", path = "protocols/rendezvous" } libp2p-request-response = { version = "0.25.0", path = "protocols/request-response" } +libp2p-upnp = { version = "0.1.0", path = "protocols/upnp" } libp2p-swarm = { version = "0.43.0", path = "swarm" } libp2p-swarm-derive = { version = "0.33.0", path = "swarm-derive" } libp2p-swarm-test = { version = "0.2.0", path = "swarm-test" } diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 06f269466ea..b0cca90283e 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -47,9 +47,11 @@ full = [ "websocket", "webtransport-websys", "yamux", + "upnp" ] -async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std"] +async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", +"libp2p-dns?/async-std", "libp2p-upnp?/async-std"] autonat = ["dep:libp2p-autonat"] cbor = ["libp2p-request-response?/cbor"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] @@ -76,7 +78,8 @@ secp256k1 = ["libp2p-identity/secp256k1"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tls = ["dep:libp2p-tls"] -tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio"] +tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", +"libp2p-upnp?/tokio"] uds = ["dep:libp2p-uds"] wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"] wasm-ext = ["dep:libp2p-wasm-ext"] @@ -84,6 +87,7 @@ wasm-ext-websocket = ["wasm-ext", "libp2p-wasm-ext?/websocket"] websocket = ["dep:libp2p-websocket"] webtransport-websys = ["dep:libp2p-webtransport-websys"] yamux = ["dep:libp2p-yamux"] +upnp = ["dep:libp2p-upnp"] [dependencies] bytes = "1" @@ -114,6 +118,7 @@ libp2p-swarm = { workspace = true } libp2p-wasm-ext = { workspace = true, optional = true } libp2p-webtransport-websys = { workspace = true, optional = true } libp2p-yamux = { workspace = true, optional = true } +libp2p-upnp = { workspace = true, optional = true } multiaddr = { workspace = true } pin-project = "1.0.0" diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 059857d3b8a..641510307a4 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -120,6 +120,9 @@ pub use libp2p_tls as tls; #[cfg(not(target_arch = "wasm32"))] #[doc(inline)] pub use libp2p_uds as uds; +#[cfg(feature = "upnp")] +#[doc(inline)] +pub use libp2p_upnp as upnp; #[cfg(feature = "wasm-ext")] #[doc(inline)] pub use libp2p_wasm_ext as wasm_ext; diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml new file mode 100644 index 00000000000..7a142762be9 --- /dev/null +++ b/protocols/upnp/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "libp2p-upnp" +edition = "2021" +rust-version = "1.60.0" +description = "UPnP support for libp2p transports" +version = "0.1.0" +authors = ["Parity Technologies "] +license = "MIT" +repository = "https://github.com/libp2p/rust-libp2p" +keywords = ["peer-to-peer", "libp2p", "networking"] +categories = ["network-programming", "asynchronous"] + +[dependencies] +async-trait = "0.1.68" +futures = "0.3.28" +futures-timer = "3.0.2" +igd = { version = "0.12.1", optional = true, features = ["aio"] } +igd_async_std = { version = "0.12.4", optional = true, features = ["aio"] } +libp2p-core = { workspace = true } +libp2p-swarm = { workspace = true } +log = "0.4.19" +void = "1.0.2" + +[features] +tokio = ["dep:igd"] +async-std = ["dep:igd_async_std"] + diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs new file mode 100644 index 00000000000..ca4d8d3ab1e --- /dev/null +++ b/protocols/upnp/src/behaviour.rs @@ -0,0 +1,515 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +use std::{ + borrow::Borrow, + collections::HashMap, + error::Error, + hash::{Hash, Hasher}, + net::{Ipv4Addr, SocketAddrV4}, + pin::Pin, + sync::Arc, + task::{Context, Poll}, + time::Duration, +}; + +use crate::{ + provider::{Protocol, Provider}, + Config, +}; +use futures::{future::BoxFuture, stream::FuturesUnordered, Future, FutureExt, StreamExt}; +use futures_timer::Delay; +use libp2p_core::{multiaddr, transport::ListenerId, Endpoint, Multiaddr}; +use libp2p_swarm::{ + derive_prelude::PeerId, dummy, ConnectionDenied, ConnectionId, ExpiredListenAddr, FromSwarm, + NetworkBehaviour, NewListenAddr, PollParameters, ToSwarm, +}; + +/// The duration in seconds of a port mapping on the gateway. +const MAPPING_DURATION: u64 = 3600; + +/// Renew the Mapping every half of `MAPPING_DURATION` to avoid the port being unmapped. +const MAPPING_TIMEOUT: u64 = MAPPING_DURATION / 2; + +/// Map a port on the gateway. +fn map_port( + gateway: Arc, + mapping: Mapping, + permanent: bool, +) -> BoxFuture<'static, Event> { + let duration = if permanent { 0 } else { MAPPING_DURATION }; + + P::add_port( + gateway, + mapping.protocol, + mapping.internal_addr, + Duration::from_secs(duration), + ) + .map(move |result| match result { + Ok(()) => Event::PortMapped(mapping.clone()), + Err(err) => Event::PortMapFailure(mapping, err.into()), + }) + .boxed() +} + +/// Remove a port mapping on the gateway. +fn remove_port_mapping( + gateway: Arc, + mapping: Mapping, +) -> BoxFuture<'static, Event> { + P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()) + .map(move |result| match result { + Ok(()) => Event::PortRemoved(mapping.clone()), + Err(err) => Event::PortRemovalFailure(mapping, err.into()), + }) + .boxed() +} + +/// A [`Gateway`] event. +#[derive(Debug)] +enum Event { + /// Port was successfully mapped. + PortMapped(Mapping), + /// There was a failure mapping port. + PortMapFailure(Mapping, Box), + /// Port was successfully removed. + PortRemoved(Mapping), + /// There was a failure removing the mapping port. + PortRemovalFailure(Mapping, Box), +} + +/// Mapping of a Protocol and Port on the gateway. +#[derive(Debug, Clone)] +struct Mapping { + listener_id: ListenerId, + protocol: Protocol, + multiaddr: Multiaddr, + internal_addr: SocketAddrV4, +} + +impl Hash for Mapping { + fn hash(&self, state: &mut H) { + self.listener_id.hash(state); + } +} + +impl PartialEq for Mapping { + fn eq(&self, other: &Self) -> bool { + self.listener_id == other.listener_id + } +} + +impl Eq for Mapping {} + +impl Borrow for Mapping { + fn borrow(&self) -> &ListenerId { + &self.listener_id + } +} + +/// Current state of a [`Mapping`]. +enum MappingState { + /// Port mapping is inactive, will be requested or re-requested on the next iteration. + Inactive, + /// Port mapping/removal has been requested on the gateway. + Pending, + /// Port mapping is active with the inner timeout. + Active(Delay), + /// Port mapping is permanent on the Gateway. + Permanent, +} + +/// Current state of the UPnP [`Transport`]. +enum GatewayState { + Searching(BoxFuture<'static, Result<(P::Gateway, Ipv4Addr), Box>>), + Available((Arc, Ipv4Addr)), + GatewayNotFound, +} + +/// A `NetworkBehaviour` for UPnP port mapping. Automatically tries to map the external port +/// to an internal address on the gateway on a `FromSwarm::NewListenAddr`. +pub struct Behaviour

+where + P: Provider, +{ + /// Gateway config. + config: Config, + /// UPnP interface state. + state: GatewayState

, + + /// List of port mappings. + mappings: HashMap, + + /// Pending gateway events. + pending_events: FuturesUnordered>, +} + +impl

Default for Behaviour

+where + P: Provider + 'static, +{ + fn default() -> Self { + Self::new(Config::default()) + } +} + +impl

Behaviour

+where + P: Provider + 'static, +{ + /// Builds a new `UPnP` behaviour. + pub fn new(config: Config) -> Self { + Self { + config, + state: GatewayState::Searching(P::search_gateway(config).boxed()), + mappings: Default::default(), + pending_events: Default::default(), + } + } +} + +impl

NetworkBehaviour for Behaviour

+where + P: Provider + 'static, +{ + type ConnectionHandler = dummy::ConnectionHandler; + + type ToSwarm = (); + + fn handle_established_inbound_connection( + &mut self, + _connection_id: ConnectionId, + _peer: PeerId, + _local_addr: &Multiaddr, + _remote_addr: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(dummy::ConnectionHandler) + } + + fn handle_established_outbound_connection( + &mut self, + _connection_id: ConnectionId, + _peer: PeerId, + _addr: &Multiaddr, + _role_override: Endpoint, + ) -> Result, libp2p_swarm::ConnectionDenied> { + Ok(dummy::ConnectionHandler) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::NewListenAddr(NewListenAddr { + listener_id, + addr: multiaddr, + }) => { + let (addr, protocol) = match multiaddr_to_socketaddr_protocol(multiaddr.clone()) { + Ok(addr_port) => addr_port, + Err(_) => { + log::debug!("multiaddress not supported for UPnP {multiaddr}"); + return; + } + }; + + if let Some((mapping, _state)) = self + .mappings + .iter() + .find(|(mapping, _state)| mapping.internal_addr.port() == addr.port()) + { + log::debug!("port from multiaddress {multiaddr} is already being mapped to another multiaddr: {}", mapping.multiaddr); + return; + } + + match &self.state { + GatewayState::Searching(_) => { + // As the gateway is not yet available we add the mapping with `MappingState::Inactive` + // so that when and if it becomes available we map it. + self.mappings.insert( + Mapping { + listener_id, + protocol, + internal_addr: addr, + multiaddr: multiaddr.clone(), + }, + MappingState::Inactive, + ); + } + GatewayState::Available((gateway, _external_addr)) => { + let mapping = Mapping { + listener_id, + protocol, + internal_addr: addr, + multiaddr: multiaddr.clone(), + }; + + self.pending_events.push(map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + )); + + self.mappings.insert(mapping, MappingState::Pending); + } + GatewayState::GatewayNotFound => { + log::debug!( + "network gateway not found, UPnP port mapping of {multiaddr} discarded" + ); + } + }; + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { + listener_id, + addr: _addr, + }) => { + if let GatewayState::Available((gateway, _external_addr)) = &self.state { + if let Some((mapping, _state)) = self.mappings.remove_entry(&listener_id) { + self.pending_events + .push(remove_port_mapping::

(gateway.clone(), mapping.clone())); + self.mappings.insert(mapping, MappingState::Pending); + } + } + } + FromSwarm::ConnectionEstablished(_) + | FromSwarm::ConnectionClosed(_) + | FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddrCandidate(_) + | FromSwarm::ExternalAddrConfirmed(_) + | FromSwarm::ExternalAddrExpired(_) => {} + } + } + + fn on_connection_handler_event( + &mut self, + _peer_id: PeerId, + _connection_id: ConnectionId, + event: libp2p_swarm::THandlerOutEvent, + ) { + void::unreachable(event) + } + + fn poll( + &mut self, + cx: &mut Context<'_>, + _params: &mut impl PollParameters, + ) -> Poll>> { + loop { + match self.state { + GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { + Poll::Ready(result) => match result { + Ok((gateway, external_addr)) => { + self.state = + GatewayState::Available((Arc::new(gateway), external_addr)); + } + Err(err) => { + log::debug!("could not find gateway: {err}"); + self.state = GatewayState::GatewayNotFound; + return Poll::Ready(ToSwarm::GenerateEvent(())); + } + }, + Poll::Pending => return Poll::Pending, + }, + GatewayState::Available((ref gateway, external_addr)) => { + // Check pending mappings. + if let Poll::Ready(Some(result)) = self.pending_events.poll_next_unpin(cx) { + match result { + Event::PortMapped(mapping) => { + let state = self + .mappings + .get_mut(&mapping) + .expect("mapping should exist"); + match state { + MappingState::Pending => { + log::debug!( + "succcessfuly UPnP mapped {} for {} protocol", + mapping.internal_addr, + mapping.protocol + ); + let external_multiaddr = mapping + .multiaddr + .replace(0, |_| { + Some(multiaddr::Protocol::Ip4(external_addr)) + }) + .expect("multiaddr should be valid"); + *state = if self.config.permanent { + MappingState::Permanent + } else { + MappingState::Active(Delay::new(Duration::from_secs( + MAPPING_TIMEOUT, + ))) + }; + + return Poll::Ready(ToSwarm::ExternalAddrConfirmed( + external_multiaddr, + )); + } + MappingState::Active(_) => { + *state = MappingState::Active(Delay::new( + Duration::from_secs(MAPPING_TIMEOUT), + )); + + log::debug!( + "succcessfuly remapped UPnP {} for {} protocol", + mapping.internal_addr, + mapping.protocol + ); + } + MappingState::Inactive | MappingState::Permanent => { + unreachable!() + } + } + } + Event::PortMapFailure(mapping, err) => { + let state = self + .mappings + .get_mut(&mapping) + .expect("mapping should exist"); + + match state { + MappingState::Active(_) => { + log::debug!( + "failed to remap UPnP mapped {} for {} protocol: {err}", + mapping.internal_addr, + mapping.protocol + ); + *state = MappingState::Inactive; + let external_multiaddr = mapping + .multiaddr + .replace(0, |_| { + Some(multiaddr::Protocol::Ip4(external_addr)) + }) + .expect("multiaddr should be valid"); + + return Poll::Ready(ToSwarm::ExternalAddrExpired( + external_multiaddr, + )); + } + MappingState::Pending => { + log::debug!( + "failed to map upnp mapped {} for {} protocol: {err}", + mapping.internal_addr, + mapping.protocol + ); + *state = MappingState::Inactive; + } + MappingState::Inactive | MappingState::Permanent => { + unreachable!() + } + } + } + Event::PortRemoved(mapping) => { + log::debug!( + "succcessfuly removed UPnP mapping {} for {} protocol", + mapping.internal_addr, + mapping.protocol + ); + self.mappings + .remove(&mapping) + .expect("mapping should exist"); + } + Event::PortRemovalFailure(mapping, err) => { + log::debug!( + "could not remove UPnP mapping {} for {} protocol: {err}", + mapping.internal_addr, + mapping.protocol + ); + self.pending_events + .push(remove_port_mapping::

(gateway.clone(), mapping)); + } + } + } + + // Renew expired and request inactive mappings. + for (mapping, state) in self.mappings.iter_mut() { + match state { + MappingState::Inactive => { + self.pending_events.push(map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + )); + *state = MappingState::Pending; + } + MappingState::Active(timeout) => { + if Pin::new(timeout).poll(cx).is_ready() { + self.pending_events.push(map_port::

( + gateway.clone(), + mapping.clone(), + false, + )); + } + } + MappingState::Pending | MappingState::Permanent => {} + } + } + return Poll::Pending; + } + GatewayState::GatewayNotFound => { + return Poll::Ready(ToSwarm::GenerateEvent(())); + } + } + } + } +} + +/// Extracts a `SocketAddr` and `Protocol` from a given `Multiaddr`. +/// +/// Fails if the given `Multiaddr` does not begin with an IP +/// protocol encapsulating a TCP or UDP port. +fn multiaddr_to_socketaddr_protocol(mut addr: Multiaddr) -> Result<(SocketAddrV4, Protocol), ()> { + let mut port = None; + let mut protocol = None; + while let Some(proto) = addr.pop() { + match proto { + multiaddr::Protocol::Ip6(_) => { + // Idg only supports Ipv4. + return Err(()); + } + multiaddr::Protocol::Ip4(ipv4) if ipv4.is_private() => match (port, protocol) { + (Some(port), Some(protocol)) => { + return Ok((SocketAddrV4::new(ipv4.into(), port), protocol)); + } + _ => return Err(()), + }, + multiaddr::Protocol::Tcp(portnum) => match (port, protocol) { + (None, None) => { + port = Some(portnum); + protocol = Some(Protocol::Tcp); + } + _ => return Err(()), + }, + multiaddr::Protocol::Udp(portnum) => match (port, protocol) { + (None, None) => { + port = Some(portnum); + protocol = Some(Protocol::Udp); + } + _ => return Err(()), + }, + + _ => {} + } + } + Err(()) +} diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs new file mode 100644 index 00000000000..8435e40afad --- /dev/null +++ b/protocols/upnp/src/lib.rs @@ -0,0 +1,101 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//! Implementation of UPnP port mapping for libp2p. +//! +//! This crate provides a `tokio::Behaviour` and `async_std::Behaviour`, depending on the enabled features, which +//! implements the `NetworkBehaviour` trait. This struct will automatically try to map the ports externally to internal +//! addresses on the gateway. +//! + +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod behaviour; +mod provider; + +use std::{ + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + time::Duration, +}; + +#[cfg(feature = "async-std")] +pub use provider::async_std; +#[cfg(feature = "tokio")] +pub use provider::tokio; + +/// The configuration for UPnP capabilities for libp2p. +#[derive(Clone, Copy, Debug)] +pub struct Config { + /// Bind address for UDP socket (defaults to all `0.0.0.0`). + pub bind_addr: SocketAddr, + /// Broadcast address for discovery packets (defaults to `239.255.255.250:1900`). + pub broadcast_addr: SocketAddr, + /// Timeout for a search iteration (defaults to 10s). + pub timeout: Option, + /// Should the port mappings be temporary or permanent. + pub permanent: bool, +} + +impl Config { + /// Creates a new configuration for a UPnP transport: + /// * Bind address for UDP socket is `0.0.0.0`. + /// See [`Config::bind_addr`]. + /// * Broadcast address for discovery packets is `239.255.255.250:1900`. + /// See [`Config::broadcast_address`]. + /// * Timeout for a search iteration is 10s. + /// See [`Config::timeout`]. + pub fn new() -> Self { + Self { + bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), + broadcast_addr: "239.255.255.250:1900".parse().unwrap(), + timeout: Some(Duration::from_secs(10)), + permanent: false, + } + } + + /// Configures the Bind address for UDP socket. + pub fn bind_addr(self, bind_addr: SocketAddr) -> Self { + Self { bind_addr, ..self } + } + + /// Configures the Broadcast address for discovery packets. + pub fn broadcast_address(self, broadcast_addr: SocketAddr) -> Self { + Self { + broadcast_addr, + ..self + } + } + + /// Configures the timeout for search iteration. + pub fn timeout(self, timeout: Option) -> Self { + Self { timeout, ..self } + } + + /// Configures if the port mappings should be temporary or permanent. + pub fn permanent(self, permanent: bool) -> Self { + Self { permanent, ..self } + } +} + +impl Default for Config { + fn default() -> Self { + Self::new() + } +} diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs new file mode 100644 index 00000000000..ba3f5dbc8e4 --- /dev/null +++ b/protocols/upnp/src/provider.rs @@ -0,0 +1,77 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{ + error::Error, + fmt, + net::{Ipv4Addr, SocketAddrV4}, + sync::Arc, + time::Duration, +}; + +pub use crate::Config; +use async_trait::async_trait; + +#[cfg(feature = "async-std")] +pub mod async_std; + +#[cfg(feature = "tokio")] +pub mod tokio; + +/// Protocols available for port mapping. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub enum Protocol { + Tcp, + Udp, +} + +impl fmt::Display for Protocol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Protocol::Tcp => f.write_str("tcp"), + Protocol::Udp => f.write_str("udp"), + } + } +} + +/// The interface for non-blocking UPnP I/O providers. +#[async_trait] +pub trait Provider { + /// The gateway of obtained from [`Provider::search_gateway`]. + type Gateway; + + /// Search for the gateway endpoint on the local network. + async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box>; + + /// Add the input port mapping on the gateway so that traffic is forwarded to the input address. + async fn add_port( + _: Arc, + protocol: Protocol, + addr: SocketAddrV4, + duration: Duration, + ) -> Result<(), Box>; + + /// Remove port mapping on the gateway. + async fn remove_port( + _: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box>; +} diff --git a/protocols/upnp/src/provider/async_std.rs b/protocols/upnp/src/provider/async_std.rs new file mode 100644 index 00000000000..b18da2256d2 --- /dev/null +++ b/protocols/upnp/src/provider/async_std.rs @@ -0,0 +1,94 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{ + error::Error, + net::{Ipv4Addr, SocketAddrV4}, + sync::Arc, + time::Duration, +}; + +use super::Protocol; +use crate::Config; + +use async_trait::async_trait; +use igd_async_std::{ + aio::{self, Gateway}, + PortMappingProtocol, SearchOptions, +}; + +#[doc(hidden)] +pub struct Provider; + +#[async_trait] +impl super::Provider for Provider { + type Gateway = Gateway; + + async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box> { + let options = SearchOptions { + bind_addr: config.bind_addr, + broadcast_address: config.broadcast_addr, + timeout: config.timeout, + }; + let gateway = aio::search_gateway(options).await?; + let addr = gateway.get_external_ip().await?; + Ok((gateway, addr)) + } + + async fn add_port( + gateway: Arc, + protocol: Protocol, + addr: SocketAddrV4, + duration: Duration, + ) -> Result<(), Box> { + let protocol = match protocol { + Protocol::Tcp => PortMappingProtocol::TCP, + Protocol::Udp => PortMappingProtocol::UDP, + }; + gateway + .add_port( + protocol, + addr.port(), + addr, + duration.as_secs() as u32, + "rust-libp2p mapping", + ) + .await + .map_err(|err| err.into()) + } + + async fn remove_port( + gateway: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box> { + let protocol = match protocol { + Protocol::Tcp => PortMappingProtocol::TCP, + Protocol::Udp => PortMappingProtocol::UDP, + }; + gateway + .remove_port(protocol, port) + .await + .map_err(|err| err.into()) + } +} + +/// The type of a [`Behaviour`] using the `async-io` implementation. +pub type Behaviour = crate::behaviour::Behaviour; diff --git a/protocols/upnp/src/provider/tokio.rs b/protocols/upnp/src/provider/tokio.rs new file mode 100644 index 00000000000..fc988dc15ad --- /dev/null +++ b/protocols/upnp/src/provider/tokio.rs @@ -0,0 +1,94 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{ + error::Error, + net::{Ipv4Addr, SocketAddrV4}, + sync::Arc, + time::Duration, +}; + +use super::Protocol; +use crate::Config; + +use async_trait::async_trait; +use igd::{ + aio::{self, Gateway}, + PortMappingProtocol, SearchOptions, +}; + +#[doc(hidden)] +pub struct Provider; + +#[async_trait] +impl super::Provider for Provider { + type Gateway = Gateway; + + async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box> { + let options = SearchOptions { + bind_addr: config.bind_addr, + broadcast_address: config.broadcast_addr, + timeout: config.timeout, + }; + let gateway = aio::search_gateway(options).await?; + let addr = gateway.get_external_ip().await?; + Ok((gateway, addr)) + } + + async fn add_port( + gateway: Arc, + protocol: Protocol, + addr: SocketAddrV4, + duration: Duration, + ) -> Result<(), Box> { + let protocol = match protocol { + Protocol::Tcp => PortMappingProtocol::TCP, + Protocol::Udp => PortMappingProtocol::UDP, + }; + gateway + .add_port( + protocol, + addr.port(), + addr, + duration.as_secs() as u32, + "rust-libp2p mapping", + ) + .await + .map_err(|err| err.into()) + } + + async fn remove_port( + gateway: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box> { + let protocol = match protocol { + Protocol::Tcp => PortMappingProtocol::TCP, + Protocol::Udp => PortMappingProtocol::UDP, + }; + gateway + .remove_port(protocol, port) + .await + .map_err(|err| err.into()) + } +} + +/// The type of a [`Behaviour`] using the `tokio` implementation. +pub type Behaviour = crate::behaviour::Behaviour; From ba6ad5aa1faac9cc8430afe241701f931bdaa679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 4 Jul 2023 18:22:55 +0100 Subject: [PATCH 02/41] cargo clippy --- protocols/upnp/src/behaviour.rs | 26 +++++++++++++------------- protocols/upnp/src/provider.rs | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index ca4d8d3ab1e..7b4cfc95ad1 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -65,8 +65,8 @@ fn map_port( Duration::from_secs(duration), ) .map(move |result| match result { - Ok(()) => Event::PortMapped(mapping.clone()), - Err(err) => Event::PortMapFailure(mapping, err.into()), + Ok(()) => Event::Mapped(mapping), + Err(err) => Event::MapFailure(mapping, err), }) .boxed() } @@ -78,8 +78,8 @@ fn remove_port_mapping( ) -> BoxFuture<'static, Event> { P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()) .map(move |result| match result { - Ok(()) => Event::PortRemoved(mapping.clone()), - Err(err) => Event::PortRemovalFailure(mapping, err.into()), + Ok(()) => Event::Removed(mapping), + Err(err) => Event::RemovalFailure(mapping, err), }) .boxed() } @@ -88,13 +88,13 @@ fn remove_port_mapping( #[derive(Debug)] enum Event { /// Port was successfully mapped. - PortMapped(Mapping), + Mapped(Mapping), /// There was a failure mapping port. - PortMapFailure(Mapping, Box), + MapFailure(Mapping, Box), /// Port was successfully removed. - PortRemoved(Mapping), + Removed(Mapping), /// There was a failure removing the mapping port. - PortRemovalFailure(Mapping, Box), + RemovalFailure(Mapping, Box), } /// Mapping of a Protocol and Port on the gateway. @@ -335,7 +335,7 @@ where // Check pending mappings. if let Poll::Ready(Some(result)) = self.pending_events.poll_next_unpin(cx) { match result { - Event::PortMapped(mapping) => { + Event::Mapped(mapping) => { let state = self .mappings .get_mut(&mapping) @@ -381,7 +381,7 @@ where } } } - Event::PortMapFailure(mapping, err) => { + Event::MapFailure(mapping, err) => { let state = self .mappings .get_mut(&mapping) @@ -419,7 +419,7 @@ where } } } - Event::PortRemoved(mapping) => { + Event::Removed(mapping) => { log::debug!( "succcessfuly removed UPnP mapping {} for {} protocol", mapping.internal_addr, @@ -429,7 +429,7 @@ where .remove(&mapping) .expect("mapping should exist"); } - Event::PortRemovalFailure(mapping, err) => { + Event::RemovalFailure(mapping, err) => { log::debug!( "could not remove UPnP mapping {} for {} protocol: {err}", mapping.internal_addr, @@ -489,7 +489,7 @@ fn multiaddr_to_socketaddr_protocol(mut addr: Multiaddr) -> Result<(SocketAddrV4 } multiaddr::Protocol::Ip4(ipv4) if ipv4.is_private() => match (port, protocol) { (Some(port), Some(protocol)) => { - return Ok((SocketAddrV4::new(ipv4.into(), port), protocol)); + return Ok((SocketAddrV4::new(ipv4, port), protocol)); } _ => return Err(()), }, diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index ba3f5dbc8e4..4427dbe6eb3 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -26,7 +26,7 @@ use std::{ time::Duration, }; -pub use crate::Config; +use crate::Config; use async_trait::async_trait; #[cfg(feature = "async-std")] From 3638fd9dc9e1dbdc61bf67f96cf3d9ced817beb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 4 Jul 2023 18:27:59 +0100 Subject: [PATCH 03/41] fix docs --- protocols/upnp/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 7b4cfc95ad1..c1a9ae372cc 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -84,7 +84,7 @@ fn remove_port_mapping( .boxed() } -/// A [`Gateway`] event. +/// A [`Provider::Gateway`] event. #[derive(Debug)] enum Event { /// Port was successfully mapped. @@ -138,7 +138,7 @@ enum MappingState { Permanent, } -/// Current state of the UPnP [`Transport`]. +/// Current state of the UPnP [`Provider::Gateway`]. enum GatewayState { Searching(BoxFuture<'static, Result<(P::Gateway, Ipv4Addr), Box>>), Available((Arc, Ipv4Addr)), From 6671af394b2a35124df67e8e3f94679172f9f9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 4 Jul 2023 23:29:55 +0100 Subject: [PATCH 04/41] review: address Thomas review --- protocols/upnp/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 8435e40afad..8eda5617a0c 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -44,13 +44,13 @@ pub use provider::tokio; #[derive(Clone, Copy, Debug)] pub struct Config { /// Bind address for UDP socket (defaults to all `0.0.0.0`). - pub bind_addr: SocketAddr, + bind_addr: SocketAddr, /// Broadcast address for discovery packets (defaults to `239.255.255.250:1900`). - pub broadcast_addr: SocketAddr, + broadcast_addr: SocketAddr, /// Timeout for a search iteration (defaults to 10s). - pub timeout: Option, + timeout: Option, /// Should the port mappings be temporary or permanent. - pub permanent: bool, + permanent: bool, } impl Config { From 7edc88b1c91c58514bdf189e2e390cacc504d635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 5 Jul 2023 16:52:31 +0100 Subject: [PATCH 05/41] review: address Thomas review --- libp2p/src/lib.rs | 1 + protocols/upnp/src/behaviour.rs | 67 +++++++++++++++++---------------- protocols/upnp/src/provider.rs | 2 +- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 641510307a4..6dc05bf422e 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -121,6 +121,7 @@ pub use libp2p_tls as tls; #[doc(inline)] pub use libp2p_uds as uds; #[cfg(feature = "upnp")] +#[cfg(not(target_arch = "wasm32"))] #[doc(inline)] pub use libp2p_upnp as upnp; #[cfg(feature = "wasm-ext")] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index c1a9ae372cc..0078d165582 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -51,37 +51,35 @@ const MAPPING_DURATION: u64 = 3600; const MAPPING_TIMEOUT: u64 = MAPPING_DURATION / 2; /// Map a port on the gateway. -fn map_port( +async fn map_port( gateway: Arc, mapping: Mapping, permanent: bool, -) -> BoxFuture<'static, Event> { +) -> Event { let duration = if permanent { 0 } else { MAPPING_DURATION }; - P::add_port( + match P::add_port( gateway, mapping.protocol, mapping.internal_addr, Duration::from_secs(duration), ) - .map(move |result| match result { + .await + { Ok(()) => Event::Mapped(mapping), Err(err) => Event::MapFailure(mapping, err), - }) - .boxed() + } } /// Remove a port mapping on the gateway. -fn remove_port_mapping( +async fn remove_port_mapping( gateway: Arc, mapping: Mapping, -) -> BoxFuture<'static, Event> { - P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()) - .map(move |result| match result { - Ok(()) => Event::Removed(mapping), - Err(err) => Event::RemovalFailure(mapping, err), - }) - .boxed() +) -> Event { + match P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()).await { + Ok(()) => Event::Removed(mapping), + Err(err) => Event::RemovalFailure(mapping, err), + } } /// A [`Provider::Gateway`] event. @@ -260,11 +258,10 @@ where multiaddr: multiaddr.clone(), }; - self.pending_events.push(map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, - )); + self.pending_events.push( + map_port::

(gateway.clone(), mapping.clone(), self.config.permanent) + .boxed(), + ); self.mappings.insert(mapping, MappingState::Pending); } @@ -281,8 +278,9 @@ where }) => { if let GatewayState::Available((gateway, _external_addr)) = &self.state { if let Some((mapping, _state)) = self.mappings.remove_entry(&listener_id) { - self.pending_events - .push(remove_port_mapping::

(gateway.clone(), mapping.clone())); + self.pending_events.push( + remove_port_mapping::

(gateway.clone(), mapping.clone()).boxed(), + ); self.mappings.insert(mapping, MappingState::Pending); } } @@ -435,8 +433,9 @@ where mapping.internal_addr, mapping.protocol ); - self.pending_events - .push(remove_port_mapping::

(gateway.clone(), mapping)); + self.pending_events.push( + remove_port_mapping::

(gateway.clone(), mapping).boxed(), + ); } } } @@ -445,20 +444,22 @@ where for (mapping, state) in self.mappings.iter_mut() { match state { MappingState::Inactive => { - self.pending_events.push(map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, - )); + self.pending_events.push( + map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + ) + .boxed(), + ); *state = MappingState::Pending; } MappingState::Active(timeout) => { if Pin::new(timeout).poll(cx).is_ready() { - self.pending_events.push(map_port::

( - gateway.clone(), - mapping.clone(), - false, - )); + self.pending_events.push( + map_port::

(gateway.clone(), mapping.clone(), false) + .boxed(), + ); } } MappingState::Pending | MappingState::Permanent => {} diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 4427dbe6eb3..6842f486914 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -55,7 +55,7 @@ impl fmt::Display for Protocol { #[async_trait] pub trait Provider { /// The gateway of obtained from [`Provider::search_gateway`]. - type Gateway; + type Gateway: Send + Sync; /// Search for the gateway endpoint on the local network. async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box>; From 5c592165aef06ca573da1ff2117eb352e51fd6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 5 Jul 2023 18:28:43 +0100 Subject: [PATCH 06/41] review: address Thomas review --- libp2p/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index b0cca90283e..1ecfb56bc02 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -118,7 +118,6 @@ libp2p-swarm = { workspace = true } libp2p-wasm-ext = { workspace = true, optional = true } libp2p-webtransport-websys = { workspace = true, optional = true } libp2p-yamux = { workspace = true, optional = true } -libp2p-upnp = { workspace = true, optional = true } multiaddr = { workspace = true } pin-project = "1.0.0" @@ -130,6 +129,7 @@ libp2p-mdns = { workspace = true, optional = true } libp2p-tcp = { workspace = true, optional = true } libp2p-tls = { workspace = true, optional = true } libp2p-uds = { workspace = true, optional = true } +libp2p-upnp = { workspace = true, optional = true } libp2p-websocket = { workspace = true, optional = true } [dev-dependencies] From cb2dbbcb97c5bf22e972476780ac7ddde27eadd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 6 Jul 2023 22:14:41 +0100 Subject: [PATCH 07/41] update copyright --- protocols/upnp/Cargo.toml | 1 - protocols/upnp/src/behaviour.rs | 2 +- protocols/upnp/src/lib.rs | 2 +- protocols/upnp/src/provider.rs | 2 +- protocols/upnp/src/provider/async_std.rs | 2 +- protocols/upnp/src/provider/tokio.rs | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 7a142762be9..b621ef5f619 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -4,7 +4,6 @@ edition = "2021" rust-version = "1.60.0" description = "UPnP support for libp2p transports" version = "0.1.0" -authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" keywords = ["peer-to-peer", "libp2p", "networking"] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 0078d165582..be4ca840584 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -1,4 +1,4 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. +// Copyright 2023 Protocol Labs. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 8eda5617a0c..5db85c04e90 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2017 Parity Technologies (UK) Ltd. +// Copyright 2023 Protocol Labs. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 6842f486914..67c7c3071a1 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -1,4 +1,4 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. +// Copyright 2023 Protocol Labs. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/protocols/upnp/src/provider/async_std.rs b/protocols/upnp/src/provider/async_std.rs index b18da2256d2..ae96a217a58 100644 --- a/protocols/upnp/src/provider/async_std.rs +++ b/protocols/upnp/src/provider/async_std.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Parity Technologies (UK) Ltd. +// Copyright 2023 Protocol Labs. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/protocols/upnp/src/provider/tokio.rs b/protocols/upnp/src/provider/tokio.rs index fc988dc15ad..5a492144414 100644 --- a/protocols/upnp/src/provider/tokio.rs +++ b/protocols/upnp/src/provider/tokio.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Parity Technologies (UK) Ltd. +// Copyright 2023 Protocol Labs. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), From 4172755f96a9338010b66d25109516e2a2589b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 6 Jul 2023 22:31:10 +0100 Subject: [PATCH 08/41] rename Provider trait to Gateway --- protocols/upnp/src/behaviour.rs | 31 +++++++++---------- .../upnp/src/{provider.rs => gateway.rs} | 16 +++------- .../src/{provider => gateway}/async_std.rs | 15 +++------ .../upnp/src/{provider => gateway}/tokio.rs | 15 +++------ protocols/upnp/src/lib.rs | 6 ++-- 5 files changed, 32 insertions(+), 51 deletions(-) rename protocols/upnp/src/{provider.rs => gateway.rs} (84%) rename protocols/upnp/src/{provider => gateway}/async_std.rs (89%) rename protocols/upnp/src/{provider => gateway}/tokio.rs (89%) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index be4ca840584..051355976db 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -33,7 +33,7 @@ use std::{ }; use crate::{ - provider::{Protocol, Provider}, + gateway::{Gateway, Protocol}, Config, }; use futures::{future::BoxFuture, stream::FuturesUnordered, Future, FutureExt, StreamExt}; @@ -51,8 +51,8 @@ const MAPPING_DURATION: u64 = 3600; const MAPPING_TIMEOUT: u64 = MAPPING_DURATION / 2; /// Map a port on the gateway. -async fn map_port( - gateway: Arc, +async fn map_port( + gateway: Arc

, mapping: Mapping, permanent: bool, ) -> Event { @@ -72,17 +72,14 @@ async fn map_port( } /// Remove a port mapping on the gateway. -async fn remove_port_mapping( - gateway: Arc, - mapping: Mapping, -) -> Event { +async fn remove_port_mapping(gateway: Arc

, mapping: Mapping) -> Event { match P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()).await { Ok(()) => Event::Removed(mapping), Err(err) => Event::RemovalFailure(mapping, err), } } -/// A [`Provider::Gateway`] event. +/// A [`Gateway`] event. #[derive(Debug)] enum Event { /// Port was successfully mapped. @@ -136,10 +133,10 @@ enum MappingState { Permanent, } -/// Current state of the UPnP [`Provider::Gateway`]. -enum GatewayState { - Searching(BoxFuture<'static, Result<(P::Gateway, Ipv4Addr), Box>>), - Available((Arc, Ipv4Addr)), +/// Current state of the UPnP [`Gateway`]. +enum GatewayState { + Searching(BoxFuture<'static, Result<(P, Ipv4Addr), Box>>), + Available((Arc

, Ipv4Addr)), GatewayNotFound, } @@ -147,7 +144,7 @@ enum GatewayState { /// to an internal address on the gateway on a `FromSwarm::NewListenAddr`. pub struct Behaviour

where - P: Provider, + P: Gateway, { /// Gateway config. config: Config, @@ -163,7 +160,7 @@ where impl

Default for Behaviour

where - P: Provider + 'static, + P: Gateway + 'static, { fn default() -> Self { Self::new(Config::default()) @@ -172,13 +169,13 @@ where impl

Behaviour

where - P: Provider + 'static, + P: Gateway + 'static, { /// Builds a new `UPnP` behaviour. pub fn new(config: Config) -> Self { Self { config, - state: GatewayState::Searching(P::search_gateway(config).boxed()), + state: GatewayState::Searching(P::search(config).boxed()), mappings: Default::default(), pending_events: Default::default(), } @@ -187,7 +184,7 @@ where impl

NetworkBehaviour for Behaviour

where - P: Provider + 'static, + P: Gateway + 'static, { type ConnectionHandler = dummy::ConnectionHandler; diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/gateway.rs similarity index 84% rename from protocols/upnp/src/provider.rs rename to protocols/upnp/src/gateway.rs index 67c7c3071a1..20967c06f31 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/gateway.rs @@ -53,25 +53,19 @@ impl fmt::Display for Protocol { /// The interface for non-blocking UPnP I/O providers. #[async_trait] -pub trait Provider { - /// The gateway of obtained from [`Provider::search_gateway`]. - type Gateway: Send + Sync; - +pub trait Gateway: Sized + Send + Sync { /// Search for the gateway endpoint on the local network. - async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box>; + async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box>; /// Add the input port mapping on the gateway so that traffic is forwarded to the input address. async fn add_port( - _: Arc, + _: Arc, protocol: Protocol, addr: SocketAddrV4, duration: Duration, ) -> Result<(), Box>; /// Remove port mapping on the gateway. - async fn remove_port( - _: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box>; + async fn remove_port(_: Arc, protocol: Protocol, port: u16) + -> Result<(), Box>; } diff --git a/protocols/upnp/src/provider/async_std.rs b/protocols/upnp/src/gateway/async_std.rs similarity index 89% rename from protocols/upnp/src/provider/async_std.rs rename to protocols/upnp/src/gateway/async_std.rs index ae96a217a58..e4b59988822 100644 --- a/protocols/upnp/src/provider/async_std.rs +++ b/protocols/upnp/src/gateway/async_std.rs @@ -34,14 +34,9 @@ use igd_async_std::{ PortMappingProtocol, SearchOptions, }; -#[doc(hidden)] -pub struct Provider; - #[async_trait] -impl super::Provider for Provider { - type Gateway = Gateway; - - async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box> { +impl super::Gateway for Gateway { + async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box> { let options = SearchOptions { bind_addr: config.bind_addr, broadcast_address: config.broadcast_addr, @@ -53,7 +48,7 @@ impl super::Provider for Provider { } async fn add_port( - gateway: Arc, + gateway: Arc, protocol: Protocol, addr: SocketAddrV4, duration: Duration, @@ -75,7 +70,7 @@ impl super::Provider for Provider { } async fn remove_port( - gateway: Arc, + gateway: Arc, protocol: Protocol, port: u16, ) -> Result<(), Box> { @@ -91,4 +86,4 @@ impl super::Provider for Provider { } /// The type of a [`Behaviour`] using the `async-io` implementation. -pub type Behaviour = crate::behaviour::Behaviour; +pub type Behaviour = crate::behaviour::Behaviour; diff --git a/protocols/upnp/src/provider/tokio.rs b/protocols/upnp/src/gateway/tokio.rs similarity index 89% rename from protocols/upnp/src/provider/tokio.rs rename to protocols/upnp/src/gateway/tokio.rs index 5a492144414..926d89cd85f 100644 --- a/protocols/upnp/src/provider/tokio.rs +++ b/protocols/upnp/src/gateway/tokio.rs @@ -34,14 +34,9 @@ use igd::{ PortMappingProtocol, SearchOptions, }; -#[doc(hidden)] -pub struct Provider; - #[async_trait] -impl super::Provider for Provider { - type Gateway = Gateway; - - async fn search_gateway(config: Config) -> Result<(Self::Gateway, Ipv4Addr), Box> { +impl super::Gateway for Gateway { + async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box> { let options = SearchOptions { bind_addr: config.bind_addr, broadcast_address: config.broadcast_addr, @@ -53,7 +48,7 @@ impl super::Provider for Provider { } async fn add_port( - gateway: Arc, + gateway: Arc, protocol: Protocol, addr: SocketAddrV4, duration: Duration, @@ -75,7 +70,7 @@ impl super::Provider for Provider { } async fn remove_port( - gateway: Arc, + gateway: Arc, protocol: Protocol, port: u16, ) -> Result<(), Box> { @@ -91,4 +86,4 @@ impl super::Provider for Provider { } /// The type of a [`Behaviour`] using the `tokio` implementation. -pub type Behaviour = crate::behaviour::Behaviour; +pub type Behaviour = crate::behaviour::Behaviour; diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 5db85c04e90..00762ae2e40 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -28,7 +28,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod behaviour; -mod provider; +mod gateway; use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, @@ -36,9 +36,9 @@ use std::{ }; #[cfg(feature = "async-std")] -pub use provider::async_std; +pub use gateway::async_std; #[cfg(feature = "tokio")] -pub use provider::tokio; +pub use gateway::tokio; /// The configuration for UPnP capabilities for libp2p. #[derive(Clone, Copy, Debug)] From 6fc4cfc56b89cceaf8bb096854d7a184eb0be22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 6 Jul 2023 23:13:21 +0100 Subject: [PATCH 09/41] replace UnoderedFutures on the main behaviour for a channel that polls the futures on an async task. --- Cargo.lock | 2 + protocols/upnp/Cargo.toml | 4 +- protocols/upnp/src/behaviour.rs | 97 ++++++++++++++++++------- protocols/upnp/src/gateway.rs | 12 ++- protocols/upnp/src/gateway/async_std.rs | 20 +++-- protocols/upnp/src/gateway/tokio.rs | 21 ++++-- 6 files changed, 110 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fa3f1faaf2..1307cf59d0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3530,6 +3530,7 @@ dependencies = [ name = "libp2p-upnp" version = "0.1.0" dependencies = [ + "async-std", "async-trait", "futures", "futures-timer", @@ -3538,6 +3539,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", + "tokio", "void", ] diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index b621ef5f619..f0c71eb474e 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -19,8 +19,10 @@ libp2p-core = { workspace = true } libp2p-swarm = { workspace = true } log = "0.4.19" void = "1.0.2" +tokio = { version = "1.29", default-features = false, features = ["rt", "rt-multi-thread"], optional = true } +async-std = { version = "1.12.0"} [features] -tokio = ["dep:igd"] +tokio = ["dep:igd", "dep:tokio"] async-std = ["dep:igd_async_std"] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 051355976db..adfa60f6e94 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -23,7 +23,6 @@ use std::{ borrow::Borrow, collections::HashMap, - error::Error, hash::{Hash, Hasher}, net::{Ipv4Addr, SocketAddrV4}, pin::Pin, @@ -36,7 +35,13 @@ use crate::{ gateway::{Gateway, Protocol}, Config, }; -use futures::{future::BoxFuture, stream::FuturesUnordered, Future, FutureExt, StreamExt}; +use futures::{ + channel::mpsc::{self, Receiver, UnboundedSender}, + future::BoxFuture, + select, + stream::FuturesUnordered, + Future, FutureExt, SinkExt, StreamExt, +}; use futures_timer::Delay; use libp2p_core::{multiaddr, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_swarm::{ @@ -85,11 +90,11 @@ enum Event { /// Port was successfully mapped. Mapped(Mapping), /// There was a failure mapping port. - MapFailure(Mapping, Box), + MapFailure(Mapping, String), /// Port was successfully removed. Removed(Mapping), /// There was a failure removing the mapping port. - RemovalFailure(Mapping, Box), + RemovalFailure(Mapping, String), } /// Mapping of a Protocol and Port on the gateway. @@ -155,7 +160,10 @@ where mappings: HashMap, /// Pending gateway events. - pending_events: FuturesUnordered>, + events_queue: Receiver, + + /// Events sender. + events_sender: UnboundedSender>, } impl

Default for Behaviour

@@ -173,11 +181,29 @@ where { /// Builds a new `UPnP` behaviour. pub fn new(config: Config) -> Self { + let (events_sender, mut task_receiver) = mpsc::unbounded(); + let (mut task_sender, events_queue) = mpsc::channel(0); + P::spawn(async move { + let mut futs = FuturesUnordered::new(); + loop { + select! { + fut = task_receiver.select_next_some() => { + futs.push(fut); + }, + event = futs.select_next_some() => { + task_sender.send(event).await.expect("receiver should be available"); + } + complete => break, + } + } + }); + Self { config, state: GatewayState::Searching(P::search(config).boxed()), mappings: Default::default(), - pending_events: Default::default(), + events_queue, + events_sender, } } } @@ -255,10 +281,16 @@ where multiaddr: multiaddr.clone(), }; - self.pending_events.push( - map_port::

(gateway.clone(), mapping.clone(), self.config.permanent) + self.events_sender + .unbounded_send( + map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + ) .boxed(), - ); + ) + .expect("receiver should be available"); self.mappings.insert(mapping, MappingState::Pending); } @@ -275,9 +307,11 @@ where }) => { if let GatewayState::Available((gateway, _external_addr)) = &self.state { if let Some((mapping, _state)) = self.mappings.remove_entry(&listener_id) { - self.pending_events.push( - remove_port_mapping::

(gateway.clone(), mapping.clone()).boxed(), - ); + self.events_sender + .unbounded_send( + remove_port_mapping::

(gateway.clone(), mapping.clone()).boxed(), + ) + .expect("receiver should be available"); self.mappings.insert(mapping, MappingState::Pending); } } @@ -328,7 +362,7 @@ where }, GatewayState::Available((ref gateway, external_addr)) => { // Check pending mappings. - if let Poll::Ready(Some(result)) = self.pending_events.poll_next_unpin(cx) { + if let Poll::Ready(Some(result)) = self.events_queue.poll_next_unpin(cx) { match result { Event::Mapped(mapping) => { let state = self @@ -430,9 +464,12 @@ where mapping.internal_addr, mapping.protocol ); - self.pending_events.push( - remove_port_mapping::

(gateway.clone(), mapping).boxed(), - ); + self.events_sender + .unbounded_send( + remove_port_mapping::

(gateway.clone(), mapping.clone()) + .boxed(), + ) + .expect("receiver should be available"); } } } @@ -441,22 +478,30 @@ where for (mapping, state) in self.mappings.iter_mut() { match state { MappingState::Inactive => { - self.pending_events.push( - map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, + self.events_sender + .unbounded_send( + map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + ) + .boxed(), ) - .boxed(), - ); + .expect("receiver should be available"); *state = MappingState::Pending; } MappingState::Active(timeout) => { if Pin::new(timeout).poll(cx).is_ready() { - self.pending_events.push( - map_port::

(gateway.clone(), mapping.clone(), false) + self.events_sender + .unbounded_send( + map_port::

( + gateway.clone(), + mapping.clone(), + self.config.permanent, + ) .boxed(), - ); + ) + .expect("receiver should be available"); } } MappingState::Pending | MappingState::Permanent => {} diff --git a/protocols/upnp/src/gateway.rs b/protocols/upnp/src/gateway.rs index 20967c06f31..4ad8cf665d9 100644 --- a/protocols/upnp/src/gateway.rs +++ b/protocols/upnp/src/gateway.rs @@ -28,6 +28,7 @@ use std::{ use crate::Config; use async_trait::async_trait; +use futures::Future; #[cfg(feature = "async-std")] pub mod async_std; @@ -63,9 +64,14 @@ pub trait Gateway: Sized + Send + Sync { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), Box>; + ) -> Result<(), String>; /// Remove port mapping on the gateway. - async fn remove_port(_: Arc, protocol: Protocol, port: u16) - -> Result<(), Box>; + async fn remove_port(_: Arc, protocol: Protocol, port: u16) -> Result<(), String>; + + // /// Spawn a future on the executor. + fn spawn(f: F) + where + F: Future + Send + 'static, + F::Output: Send + 'static; } diff --git a/protocols/upnp/src/gateway/async_std.rs b/protocols/upnp/src/gateway/async_std.rs index e4b59988822..351c196a0fe 100644 --- a/protocols/upnp/src/gateway/async_std.rs +++ b/protocols/upnp/src/gateway/async_std.rs @@ -29,6 +29,7 @@ use super::Protocol; use crate::Config; use async_trait::async_trait; +use futures::Future; use igd_async_std::{ aio::{self, Gateway}, PortMappingProtocol, SearchOptions, @@ -52,7 +53,7 @@ impl super::Gateway for Gateway { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), Box> { + ) -> Result<(), String> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -66,14 +67,10 @@ impl super::Gateway for Gateway { "rust-libp2p mapping", ) .await - .map_err(|err| err.into()) + .map_err(|err| err.to_string()) } - async fn remove_port( - gateway: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box> { + async fn remove_port(gateway: Arc, protocol: Protocol, port: u16) -> Result<(), String> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -81,7 +78,14 @@ impl super::Gateway for Gateway { gateway .remove_port(protocol, port) .await - .map_err(|err| err.into()) + .map_err(|err| err.to_string()) + } + fn spawn(f: F) + where + F: Future + Send + 'static, + F::Output: Send + 'static, + { + async_std::task::spawn(f); } } diff --git a/protocols/upnp/src/gateway/tokio.rs b/protocols/upnp/src/gateway/tokio.rs index 926d89cd85f..2c035566b03 100644 --- a/protocols/upnp/src/gateway/tokio.rs +++ b/protocols/upnp/src/gateway/tokio.rs @@ -29,6 +29,7 @@ use super::Protocol; use crate::Config; use async_trait::async_trait; +use futures::Future; use igd::{ aio::{self, Gateway}, PortMappingProtocol, SearchOptions, @@ -52,7 +53,7 @@ impl super::Gateway for Gateway { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), Box> { + ) -> Result<(), String> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -66,14 +67,10 @@ impl super::Gateway for Gateway { "rust-libp2p mapping", ) .await - .map_err(|err| err.into()) + .map_err(|err| err.to_string()) } - async fn remove_port( - gateway: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box> { + async fn remove_port(gateway: Arc, protocol: Protocol, port: u16) -> Result<(), String> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -81,7 +78,15 @@ impl super::Gateway for Gateway { gateway .remove_port(protocol, port) .await - .map_err(|err| err.into()) + .map_err(|err| err.to_string()) + } + + fn spawn(f: F) + where + F: Future + Send + 'static, + F::Output: Send + 'static, + { + tokio::spawn(f); } } From 0eb75da19dab8c532202990d5b35862030ef5318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 7 Jul 2023 16:12:39 +0100 Subject: [PATCH 10/41] update Cargo.toml formatting --- libp2p/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 1ecfb56bc02..369e6df6bbe 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -78,8 +78,7 @@ secp256k1 = ["libp2p-identity/secp256k1"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tls = ["dep:libp2p-tls"] -tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", -"libp2p-upnp?/tokio"] +tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-upnp?/tokio"] uds = ["dep:libp2p-uds"] wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"] wasm-ext = ["dep:libp2p-wasm-ext"] From 7d679c8ddaac4305f0e621b107e58fe02b223043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 8 Jul 2023 11:06:12 +0100 Subject: [PATCH 11/41] revert Box to String conversion. --- protocols/upnp/src/behaviour.rs | 5 +++-- protocols/upnp/src/gateway.rs | 8 ++++++-- protocols/upnp/src/gateway/async_std.rs | 12 ++++++++---- protocols/upnp/src/gateway/tokio.rs | 12 ++++++++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index adfa60f6e94..035561689f6 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -23,6 +23,7 @@ use std::{ borrow::Borrow, collections::HashMap, + error::Error, hash::{Hash, Hasher}, net::{Ipv4Addr, SocketAddrV4}, pin::Pin, @@ -90,11 +91,11 @@ enum Event { /// Port was successfully mapped. Mapped(Mapping), /// There was a failure mapping port. - MapFailure(Mapping, String), + MapFailure(Mapping, Box), /// Port was successfully removed. Removed(Mapping), /// There was a failure removing the mapping port. - RemovalFailure(Mapping, String), + RemovalFailure(Mapping, Box), } /// Mapping of a Protocol and Port on the gateway. diff --git a/protocols/upnp/src/gateway.rs b/protocols/upnp/src/gateway.rs index 4ad8cf665d9..3d8155e123b 100644 --- a/protocols/upnp/src/gateway.rs +++ b/protocols/upnp/src/gateway.rs @@ -64,10 +64,14 @@ pub trait Gateway: Sized + Send + Sync { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), String>; + ) -> Result<(), Box>; /// Remove port mapping on the gateway. - async fn remove_port(_: Arc, protocol: Protocol, port: u16) -> Result<(), String>; + async fn remove_port( + _: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box>; // /// Spawn a future on the executor. fn spawn(f: F) diff --git a/protocols/upnp/src/gateway/async_std.rs b/protocols/upnp/src/gateway/async_std.rs index 351c196a0fe..7b199c67579 100644 --- a/protocols/upnp/src/gateway/async_std.rs +++ b/protocols/upnp/src/gateway/async_std.rs @@ -53,7 +53,7 @@ impl super::Gateway for Gateway { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), String> { + ) -> Result<(), Box> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -67,10 +67,14 @@ impl super::Gateway for Gateway { "rust-libp2p mapping", ) .await - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) } - async fn remove_port(gateway: Arc, protocol: Protocol, port: u16) -> Result<(), String> { + async fn remove_port( + gateway: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -78,7 +82,7 @@ impl super::Gateway for Gateway { gateway .remove_port(protocol, port) .await - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) } fn spawn(f: F) where diff --git a/protocols/upnp/src/gateway/tokio.rs b/protocols/upnp/src/gateway/tokio.rs index 2c035566b03..febc691c85d 100644 --- a/protocols/upnp/src/gateway/tokio.rs +++ b/protocols/upnp/src/gateway/tokio.rs @@ -53,7 +53,7 @@ impl super::Gateway for Gateway { protocol: Protocol, addr: SocketAddrV4, duration: Duration, - ) -> Result<(), String> { + ) -> Result<(), Box> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -67,10 +67,14 @@ impl super::Gateway for Gateway { "rust-libp2p mapping", ) .await - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) } - async fn remove_port(gateway: Arc, protocol: Protocol, port: u16) -> Result<(), String> { + async fn remove_port( + gateway: Arc, + protocol: Protocol, + port: u16, + ) -> Result<(), Box> { let protocol = match protocol { Protocol::Tcp => PortMappingProtocol::TCP, Protocol::Udp => PortMappingProtocol::UDP, @@ -78,7 +82,7 @@ impl super::Gateway for Gateway { gateway .remove_port(protocol, port) .await - .map_err(|err| err.to_string()) + .map_err(|err| err.into()) } fn spawn(f: F) From 28e0fdef5d1849a5f1efb9edc0d97a1c10c2a3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 8 Jul 2023 13:13:39 +0100 Subject: [PATCH 12/41] clippy --- protocols/upnp/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 035561689f6..e2d4f328c62 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -182,6 +182,7 @@ where { /// Builds a new `UPnP` behaviour. pub fn new(config: Config) -> Self { + #![allow(clippy::disallowed_methods)] let (events_sender, mut task_receiver) = mpsc::unbounded(); let (mut task_sender, events_queue) = mpsc::channel(0); P::spawn(async move { @@ -467,8 +468,7 @@ where ); self.events_sender .unbounded_send( - remove_port_mapping::

(gateway.clone(), mapping.clone()) - .boxed(), + remove_port_mapping::

(gateway.clone(), mapping).boxed(), ) .expect("receiver should be available"); } From 293133beedff64d03ae45795b1f5102a7f236861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Mon, 10 Jul 2023 16:21:02 +0100 Subject: [PATCH 13/41] address Thomas and Max review --- protocols/upnp/src/behaviour.rs | 86 +++++++++++++++++++++++---------- protocols/upnp/src/lib.rs | 18 ------- 2 files changed, 61 insertions(+), 43 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index e2d4f328c62..4d1d3087199 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -22,7 +22,7 @@ use std::{ borrow::Borrow, - collections::HashMap, + collections::{HashMap, VecDeque}, error::Error, hash::{Hash, Hasher}, net::{Ipv4Addr, SocketAddrV4}, @@ -61,7 +61,7 @@ async fn map_port( gateway: Arc

, mapping: Mapping, permanent: bool, -) -> Event { +) -> GatewayEvent { let duration = if permanent { 0 } else { MAPPING_DURATION }; match P::add_port( @@ -72,22 +72,25 @@ async fn map_port( ) .await { - Ok(()) => Event::Mapped(mapping), - Err(err) => Event::MapFailure(mapping, err), + Ok(()) => GatewayEvent::Mapped(mapping), + Err(err) => GatewayEvent::MapFailure(mapping, err), } } /// Remove a port mapping on the gateway. -async fn remove_port_mapping(gateway: Arc

, mapping: Mapping) -> Event { +async fn remove_port_mapping( + gateway: Arc

, + mapping: Mapping, +) -> GatewayEvent { match P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()).await { - Ok(()) => Event::Removed(mapping), - Err(err) => Event::RemovalFailure(mapping, err), + Ok(()) => GatewayEvent::Removed(mapping), + Err(err) => GatewayEvent::RemovalFailure(mapping, err), } } /// A [`Gateway`] event. #[derive(Debug)] -enum Event { +enum GatewayEvent { /// Port was successfully mapped. Mapped(Mapping), /// There was a failure mapping port. @@ -135,6 +138,8 @@ enum MappingState { Pending, /// Port mapping is active with the inner timeout. Active(Delay), + /// Port mapping failed, we will try again. + Failed, /// Port mapping is permanent on the Gateway. Permanent, } @@ -146,6 +151,16 @@ enum GatewayState { GatewayNotFound, } +/// The event produced by `Behaviour`. +pub enum Event { + /// The multiaddress is reachable externally. + NewExternalAddr(Multiaddr), + /// The renewal of the multiaddress on the gateway failed. + ExpiredExternalAddr(Multiaddr), + /// The IGD gateway was not found. + GatewayNotFound, +} + /// A `NetworkBehaviour` for UPnP port mapping. Automatically tries to map the external port /// to an internal address on the gateway on a `FromSwarm::NewListenAddr`. pub struct Behaviour

@@ -160,11 +175,14 @@ where /// List of port mappings. mappings: HashMap, - /// Pending gateway events. - events_queue: Receiver, + /// Pending behaviour events to be emitted. + pending_events: VecDeque, + + /// Pending gateway events to be polled. + gateway_events_queue: Receiver, /// Events sender. - events_sender: UnboundedSender>, + events_sender: UnboundedSender>, } impl

Default for Behaviour

@@ -204,7 +222,8 @@ where config, state: GatewayState::Searching(P::search(config).boxed()), mappings: Default::default(), - events_queue, + pending_events: VecDeque::new(), + gateway_events_queue: events_queue, events_sender, } } @@ -216,7 +235,7 @@ where { type ConnectionHandler = dummy::ConnectionHandler; - type ToSwarm = (); + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -347,6 +366,12 @@ where _params: &mut impl PollParameters, ) -> Poll>> { loop { + // If there are pending addresses to be emitted we emit them first. + if let Some(event) = self.pending_events.pop_front() { + return Poll::Ready(ToSwarm::GenerateEvent(event)); + } + + // We then check the `Gateway` current state. match self.state { GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { Poll::Ready(result) => match result { @@ -357,16 +382,17 @@ where Err(err) => { log::debug!("could not find gateway: {err}"); self.state = GatewayState::GatewayNotFound; - return Poll::Ready(ToSwarm::GenerateEvent(())); + return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); } }, Poll::Pending => return Poll::Pending, }, GatewayState::Available((ref gateway, external_addr)) => { // Check pending mappings. - if let Poll::Ready(Some(result)) = self.events_queue.poll_next_unpin(cx) { + if let Poll::Ready(Some(result)) = self.gateway_events_queue.poll_next_unpin(cx) + { match result { - Event::Mapped(mapping) => { + GatewayEvent::Mapped(mapping) => { let state = self .mappings .get_mut(&mapping) @@ -392,6 +418,9 @@ where ))) }; + self.pending_events.push_back(Event::NewExternalAddr( + external_multiaddr.clone(), + )); return Poll::Ready(ToSwarm::ExternalAddrConfirmed( external_multiaddr, )); @@ -407,12 +436,14 @@ where mapping.protocol ); } - MappingState::Inactive | MappingState::Permanent => { + MappingState::Inactive + | MappingState::Permanent + | MappingState::Failed => { unreachable!() } } } - Event::MapFailure(mapping, err) => { + GatewayEvent::MapFailure(mapping, err) => { let state = self .mappings .get_mut(&mapping) @@ -425,7 +456,7 @@ where mapping.internal_addr, mapping.protocol ); - *state = MappingState::Inactive; + *state = MappingState::Failed; let external_multiaddr = mapping .multiaddr .replace(0, |_| { @@ -433,6 +464,9 @@ where }) .expect("multiaddr should be valid"); + self.pending_events.push_back(Event::ExpiredExternalAddr( + external_multiaddr.clone(), + )); return Poll::Ready(ToSwarm::ExternalAddrExpired( external_multiaddr, )); @@ -443,14 +477,16 @@ where mapping.internal_addr, mapping.protocol ); - *state = MappingState::Inactive; + *state = MappingState::Failed; } - MappingState::Inactive | MappingState::Permanent => { + MappingState::Inactive + | MappingState::Permanent + | MappingState::Failed => { unreachable!() } } } - Event::Removed(mapping) => { + GatewayEvent::Removed(mapping) => { log::debug!( "succcessfuly removed UPnP mapping {} for {} protocol", mapping.internal_addr, @@ -460,7 +496,7 @@ where .remove(&mapping) .expect("mapping should exist"); } - Event::RemovalFailure(mapping, err) => { + GatewayEvent::RemovalFailure(mapping, err) => { log::debug!( "could not remove UPnP mapping {} for {} protocol: {err}", mapping.internal_addr, @@ -478,7 +514,7 @@ where // Renew expired and request inactive mappings. for (mapping, state) in self.mappings.iter_mut() { match state { - MappingState::Inactive => { + MappingState::Inactive | MappingState::Failed => { self.events_sender .unbounded_send( map_port::

( @@ -511,7 +547,7 @@ where return Poll::Pending; } GatewayState::GatewayNotFound => { - return Poll::Ready(ToSwarm::GenerateEvent(())); + return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); } } } diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 00762ae2e40..84a22314a08 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -70,24 +70,6 @@ impl Config { } } - /// Configures the Bind address for UDP socket. - pub fn bind_addr(self, bind_addr: SocketAddr) -> Self { - Self { bind_addr, ..self } - } - - /// Configures the Broadcast address for discovery packets. - pub fn broadcast_address(self, broadcast_addr: SocketAddr) -> Self { - Self { - broadcast_addr, - ..self - } - } - - /// Configures the timeout for search iteration. - pub fn timeout(self, timeout: Option) -> Self { - Self { timeout, ..self } - } - /// Configures if the port mappings should be temporary or permanent. pub fn permanent(self, permanent: bool) -> Self { Self { permanent, ..self } From a6b170fdba6c31351b53303936f42855ae26e1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 11 Jul 2023 16:04:22 +0100 Subject: [PATCH 14/41] convert Gateway back into Provider and make it a message interface --- protocols/upnp/src/behaviour.rs | 227 ++++++++++-------------- protocols/upnp/src/gateway.rs | 81 --------- protocols/upnp/src/gateway/async_std.rs | 97 ---------- protocols/upnp/src/gateway/tokio.rs | 98 ---------- protocols/upnp/src/lib.rs | 24 +-- protocols/upnp/src/provider.rs | 173 ++++++++++++++++++ 6 files changed, 275 insertions(+), 425 deletions(-) delete mode 100644 protocols/upnp/src/gateway.rs delete mode 100644 protocols/upnp/src/gateway/async_std.rs delete mode 100644 protocols/upnp/src/gateway/tokio.rs create mode 100644 protocols/upnp/src/provider.rs diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 4d1d3087199..3d1233f8a85 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -25,24 +25,18 @@ use std::{ collections::{HashMap, VecDeque}, error::Error, hash::{Hash, Hasher}, - net::{Ipv4Addr, SocketAddrV4}, + marker::PhantomData, + net::SocketAddrV4, pin::Pin, - sync::Arc, task::{Context, Poll}, time::Duration, }; use crate::{ - gateway::{Gateway, Protocol}, + provider::{Gateway, Protocol, Provider}, Config, }; -use futures::{ - channel::mpsc::{self, Receiver, UnboundedSender}, - future::BoxFuture, - select, - stream::FuturesUnordered, - Future, FutureExt, SinkExt, StreamExt, -}; +use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; use futures_timer::Delay; use libp2p_core::{multiaddr, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_swarm::{ @@ -51,46 +45,21 @@ use libp2p_swarm::{ }; /// The duration in seconds of a port mapping on the gateway. -const MAPPING_DURATION: u64 = 3600; +const MAPPING_DURATION: u32 = 3600; /// Renew the Mapping every half of `MAPPING_DURATION` to avoid the port being unmapped. -const MAPPING_TIMEOUT: u64 = MAPPING_DURATION / 2; - -/// Map a port on the gateway. -async fn map_port( - gateway: Arc

, - mapping: Mapping, - permanent: bool, -) -> GatewayEvent { - let duration = if permanent { 0 } else { MAPPING_DURATION }; - - match P::add_port( - gateway, - mapping.protocol, - mapping.internal_addr, - Duration::from_secs(duration), - ) - .await - { - Ok(()) => GatewayEvent::Mapped(mapping), - Err(err) => GatewayEvent::MapFailure(mapping, err), - } -} +const MAPPING_TIMEOUT: u64 = MAPPING_DURATION as u64 / 2; -/// Remove a port mapping on the gateway. -async fn remove_port_mapping( - gateway: Arc

, - mapping: Mapping, -) -> GatewayEvent { - match P::remove_port(gateway, mapping.protocol, mapping.internal_addr.port()).await { - Ok(()) => GatewayEvent::Removed(mapping), - Err(err) => GatewayEvent::RemovalFailure(mapping, err), - } +/// A [`Gateway`] Request. +#[derive(Debug)] +pub(crate) enum GatewayRequest { + AddMapping(Mapping, Option), + RemoveMapping(Mapping), } /// A [`Gateway`] event. #[derive(Debug)] -enum GatewayEvent { +pub(crate) enum GatewayEvent { /// Port was successfully mapped. Mapped(Mapping), /// There was a failure mapping port. @@ -103,11 +72,11 @@ enum GatewayEvent { /// Mapping of a Protocol and Port on the gateway. #[derive(Debug, Clone)] -struct Mapping { - listener_id: ListenerId, - protocol: Protocol, - multiaddr: Multiaddr, - internal_addr: SocketAddrV4, +pub(crate) struct Mapping { + pub(crate) listener_id: ListenerId, + pub(crate) protocol: Protocol, + pub(crate) multiaddr: Multiaddr, + pub(crate) internal_addr: SocketAddrV4, } impl Hash for Mapping { @@ -145,13 +114,14 @@ enum MappingState { } /// Current state of the UPnP [`Gateway`]. -enum GatewayState { - Searching(BoxFuture<'static, Result<(P, Ipv4Addr), Box>>), - Available((Arc

, Ipv4Addr)), +enum GatewayState { + Searching(BoxFuture<'static, Result>>), + Available(Gateway), GatewayNotFound, } /// The event produced by `Behaviour`. +#[derive(Debug)] pub enum Event { /// The multiaddress is reachable externally. NewExternalAddr(Multiaddr), @@ -165,12 +135,12 @@ pub enum Event { /// to an internal address on the gateway on a `FromSwarm::NewListenAddr`. pub struct Behaviour

where - P: Gateway, + P: Provider, { /// Gateway config. config: Config, /// UPnP interface state. - state: GatewayState

, + state: GatewayState, /// List of port mappings. mappings: HashMap, @@ -178,16 +148,13 @@ where /// Pending behaviour events to be emitted. pending_events: VecDeque, - /// Pending gateway events to be polled. - gateway_events_queue: Receiver, - - /// Events sender. - events_sender: UnboundedSender>, + /// Provider. + provider: PhantomData

, } impl

Default for Behaviour

where - P: Gateway + 'static, + P: Provider + 'static, { fn default() -> Self { Self::new(Config::default()) @@ -196,42 +163,23 @@ where impl

Behaviour

where - P: Gateway + 'static, + P: Provider + 'static, { /// Builds a new `UPnP` behaviour. pub fn new(config: Config) -> Self { - #![allow(clippy::disallowed_methods)] - let (events_sender, mut task_receiver) = mpsc::unbounded(); - let (mut task_sender, events_queue) = mpsc::channel(0); - P::spawn(async move { - let mut futs = FuturesUnordered::new(); - loop { - select! { - fut = task_receiver.select_next_some() => { - futs.push(fut); - }, - event = futs.select_next_some() => { - task_sender.send(event).await.expect("receiver should be available"); - } - complete => break, - } - } - }); - Self { config, - state: GatewayState::Searching(P::search(config).boxed()), + state: GatewayState::Searching(P::search_gateway(config).boxed()), mappings: Default::default(), pending_events: VecDeque::new(), - gateway_events_queue: events_queue, - events_sender, + provider: PhantomData, } } } impl

NetworkBehaviour for Behaviour

where - P: Gateway + 'static, + P: Provider + 'static, { type ConnectionHandler = dummy::ConnectionHandler; @@ -280,7 +228,7 @@ where return; } - match &self.state { + match &mut self.state { GatewayState::Searching(_) => { // As the gateway is not yet available we add the mapping with `MappingState::Inactive` // so that when and if it becomes available we map it. @@ -294,7 +242,7 @@ where MappingState::Inactive, ); } - GatewayState::Available((gateway, _external_addr)) => { + GatewayState::Available(ref mut gateway) => { let mapping = Mapping { listener_id, protocol, @@ -302,16 +250,17 @@ where multiaddr: multiaddr.clone(), }; - self.events_sender - .unbounded_send( - map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, - ) - .boxed(), - ) - .expect("receiver should be available"); + let duration = self.config.temporary.then_some(MAPPING_DURATION); + if let Err(err) = gateway + .sender + .try_send(GatewayRequest::AddMapping(mapping.clone(), duration)) + { + log::debug!( + "could not request port mapping for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } self.mappings.insert(mapping, MappingState::Pending); } @@ -326,13 +275,18 @@ where listener_id, addr: _addr, }) => { - if let GatewayState::Available((gateway, _external_addr)) = &self.state { + if let GatewayState::Available(ref mut gateway) = &mut self.state { if let Some((mapping, _state)) = self.mappings.remove_entry(&listener_id) { - self.events_sender - .unbounded_send( - remove_port_mapping::

(gateway.clone(), mapping.clone()).boxed(), - ) - .expect("receiver should be available"); + if let Err(err) = gateway + .sender + .try_send(GatewayRequest::RemoveMapping(mapping.clone())) + { + log::debug!( + "could not request port removal for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } self.mappings.insert(mapping, MappingState::Pending); } } @@ -375,9 +329,8 @@ where match self.state { GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { Poll::Ready(result) => match result { - Ok((gateway, external_addr)) => { - self.state = - GatewayState::Available((Arc::new(gateway), external_addr)); + Ok(gateway) => { + self.state = GatewayState::Available(gateway); } Err(err) => { log::debug!("could not find gateway: {err}"); @@ -387,10 +340,9 @@ where }, Poll::Pending => return Poll::Pending, }, - GatewayState::Available((ref gateway, external_addr)) => { + GatewayState::Available(ref mut gateway) => { // Check pending mappings. - if let Poll::Ready(Some(result)) = self.gateway_events_queue.poll_next_unpin(cx) - { + if let Poll::Ready(Some(result)) = gateway.receiver.poll_next_unpin(cx) { match result { GatewayEvent::Mapped(mapping) => { let state = self @@ -407,10 +359,10 @@ where let external_multiaddr = mapping .multiaddr .replace(0, |_| { - Some(multiaddr::Protocol::Ip4(external_addr)) + Some(multiaddr::Protocol::Ip4(gateway.addr)) }) .expect("multiaddr should be valid"); - *state = if self.config.permanent { + *state = if self.config.temporary { MappingState::Permanent } else { MappingState::Active(Delay::new(Duration::from_secs( @@ -460,7 +412,7 @@ where let external_multiaddr = mapping .multiaddr .replace(0, |_| { - Some(multiaddr::Protocol::Ip4(external_addr)) + Some(multiaddr::Protocol::Ip4(gateway.addr)) }) .expect("multiaddr should be valid"); @@ -502,11 +454,16 @@ where mapping.internal_addr, mapping.protocol ); - self.events_sender - .unbounded_send( - remove_port_mapping::

(gateway.clone(), mapping).boxed(), - ) - .expect("receiver should be available"); + if let Err(err) = gateway + .sender + .try_send(GatewayRequest::RemoveMapping(mapping.clone())) + { + log::debug!( + "could not request port removal for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } } } } @@ -515,30 +472,32 @@ where for (mapping, state) in self.mappings.iter_mut() { match state { MappingState::Inactive | MappingState::Failed => { - self.events_sender - .unbounded_send( - map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, - ) - .boxed(), - ) - .expect("receiver should be available"); + let duration = self.config.temporary.then_some(MAPPING_DURATION); + if let Err(err) = gateway + .sender + .try_send(GatewayRequest::AddMapping(mapping.clone(), duration)) + { + log::debug!( + "could not request port mapping for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } *state = MappingState::Pending; } MappingState::Active(timeout) => { if Pin::new(timeout).poll(cx).is_ready() { - self.events_sender - .unbounded_send( - map_port::

( - gateway.clone(), - mapping.clone(), - self.config.permanent, - ) - .boxed(), - ) - .expect("receiver should be available"); + let duration = + self.config.temporary.then_some(MAPPING_DURATION); + if let Err(err) = gateway.sender.try_send( + GatewayRequest::AddMapping(mapping.clone(), duration), + ) { + log::debug!( + "could not request port mapping for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } } } MappingState::Pending | MappingState::Permanent => {} diff --git a/protocols/upnp/src/gateway.rs b/protocols/upnp/src/gateway.rs deleted file mode 100644 index 3d8155e123b..00000000000 --- a/protocols/upnp/src/gateway.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2023 Protocol Labs. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use std::{ - error::Error, - fmt, - net::{Ipv4Addr, SocketAddrV4}, - sync::Arc, - time::Duration, -}; - -use crate::Config; -use async_trait::async_trait; -use futures::Future; - -#[cfg(feature = "async-std")] -pub mod async_std; - -#[cfg(feature = "tokio")] -pub mod tokio; - -/// Protocols available for port mapping. -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -pub enum Protocol { - Tcp, - Udp, -} - -impl fmt::Display for Protocol { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Protocol::Tcp => f.write_str("tcp"), - Protocol::Udp => f.write_str("udp"), - } - } -} - -/// The interface for non-blocking UPnP I/O providers. -#[async_trait] -pub trait Gateway: Sized + Send + Sync { - /// Search for the gateway endpoint on the local network. - async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box>; - - /// Add the input port mapping on the gateway so that traffic is forwarded to the input address. - async fn add_port( - _: Arc, - protocol: Protocol, - addr: SocketAddrV4, - duration: Duration, - ) -> Result<(), Box>; - - /// Remove port mapping on the gateway. - async fn remove_port( - _: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box>; - - // /// Spawn a future on the executor. - fn spawn(f: F) - where - F: Future + Send + 'static, - F::Output: Send + 'static; -} diff --git a/protocols/upnp/src/gateway/async_std.rs b/protocols/upnp/src/gateway/async_std.rs deleted file mode 100644 index 7b199c67579..00000000000 --- a/protocols/upnp/src/gateway/async_std.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2023 Protocol Labs. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use std::{ - error::Error, - net::{Ipv4Addr, SocketAddrV4}, - sync::Arc, - time::Duration, -}; - -use super::Protocol; -use crate::Config; - -use async_trait::async_trait; -use futures::Future; -use igd_async_std::{ - aio::{self, Gateway}, - PortMappingProtocol, SearchOptions, -}; - -#[async_trait] -impl super::Gateway for Gateway { - async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box> { - let options = SearchOptions { - bind_addr: config.bind_addr, - broadcast_address: config.broadcast_addr, - timeout: config.timeout, - }; - let gateway = aio::search_gateway(options).await?; - let addr = gateway.get_external_ip().await?; - Ok((gateway, addr)) - } - - async fn add_port( - gateway: Arc, - protocol: Protocol, - addr: SocketAddrV4, - duration: Duration, - ) -> Result<(), Box> { - let protocol = match protocol { - Protocol::Tcp => PortMappingProtocol::TCP, - Protocol::Udp => PortMappingProtocol::UDP, - }; - gateway - .add_port( - protocol, - addr.port(), - addr, - duration.as_secs() as u32, - "rust-libp2p mapping", - ) - .await - .map_err(|err| err.into()) - } - - async fn remove_port( - gateway: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box> { - let protocol = match protocol { - Protocol::Tcp => PortMappingProtocol::TCP, - Protocol::Udp => PortMappingProtocol::UDP, - }; - gateway - .remove_port(protocol, port) - .await - .map_err(|err| err.into()) - } - fn spawn(f: F) - where - F: Future + Send + 'static, - F::Output: Send + 'static, - { - async_std::task::spawn(f); - } -} - -/// The type of a [`Behaviour`] using the `async-io` implementation. -pub type Behaviour = crate::behaviour::Behaviour; diff --git a/protocols/upnp/src/gateway/tokio.rs b/protocols/upnp/src/gateway/tokio.rs deleted file mode 100644 index febc691c85d..00000000000 --- a/protocols/upnp/src/gateway/tokio.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2023 Protocol Labs. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use std::{ - error::Error, - net::{Ipv4Addr, SocketAddrV4}, - sync::Arc, - time::Duration, -}; - -use super::Protocol; -use crate::Config; - -use async_trait::async_trait; -use futures::Future; -use igd::{ - aio::{self, Gateway}, - PortMappingProtocol, SearchOptions, -}; - -#[async_trait] -impl super::Gateway for Gateway { - async fn search(config: Config) -> Result<(Self, Ipv4Addr), Box> { - let options = SearchOptions { - bind_addr: config.bind_addr, - broadcast_address: config.broadcast_addr, - timeout: config.timeout, - }; - let gateway = aio::search_gateway(options).await?; - let addr = gateway.get_external_ip().await?; - Ok((gateway, addr)) - } - - async fn add_port( - gateway: Arc, - protocol: Protocol, - addr: SocketAddrV4, - duration: Duration, - ) -> Result<(), Box> { - let protocol = match protocol { - Protocol::Tcp => PortMappingProtocol::TCP, - Protocol::Udp => PortMappingProtocol::UDP, - }; - gateway - .add_port( - protocol, - addr.port(), - addr, - duration.as_secs() as u32, - "rust-libp2p mapping", - ) - .await - .map_err(|err| err.into()) - } - - async fn remove_port( - gateway: Arc, - protocol: Protocol, - port: u16, - ) -> Result<(), Box> { - let protocol = match protocol { - Protocol::Tcp => PortMappingProtocol::TCP, - Protocol::Udp => PortMappingProtocol::UDP, - }; - gateway - .remove_port(protocol, port) - .await - .map_err(|err| err.into()) - } - - fn spawn(f: F) - where - F: Future + Send + 'static, - F::Output: Send + 'static, - { - tokio::spawn(f); - } -} - -/// The type of a [`Behaviour`] using the `tokio` implementation. -pub type Behaviour = crate::behaviour::Behaviour; diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 84a22314a08..c84b55df357 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -28,7 +28,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod behaviour; -mod gateway; +mod provider; use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, @@ -36,9 +36,9 @@ use std::{ }; #[cfg(feature = "async-std")] -pub use gateway::async_std; +pub use provider::async_std; #[cfg(feature = "tokio")] -pub use gateway::tokio; +pub use provider::tokio; /// The configuration for UPnP capabilities for libp2p. #[derive(Clone, Copy, Debug)] @@ -49,30 +49,24 @@ pub struct Config { broadcast_addr: SocketAddr, /// Timeout for a search iteration (defaults to 10s). timeout: Option, - /// Should the port mappings be temporary or permanent. - permanent: bool, + /// Should the port mappings be temporary (1 hour) or permanent. + temporary: bool, } impl Config { /// Creates a new configuration for a UPnP transport: - /// * Bind address for UDP socket is `0.0.0.0`. - /// See [`Config::bind_addr`]. - /// * Broadcast address for discovery packets is `239.255.255.250:1900`. - /// See [`Config::broadcast_address`]. - /// * Timeout for a search iteration is 10s. - /// See [`Config::timeout`]. pub fn new() -> Self { Self { bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), broadcast_addr: "239.255.255.250:1900".parse().unwrap(), timeout: Some(Duration::from_secs(10)), - permanent: false, + temporary: true, } } - /// Configures if the port mappings should be temporary or permanent. - pub fn permanent(self, permanent: bool) -> Self { - Self { permanent, ..self } + /// Configures if the port mappings be temporary (1 hour) or permanent. + pub fn temporary(self, temporary: bool) -> Self { + Self { temporary, ..self } } } diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs new file mode 100644 index 00000000000..896c0c2e48c --- /dev/null +++ b/protocols/upnp/src/provider.rs @@ -0,0 +1,173 @@ +// Copyright 2023 Protocol Labs. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{error::Error, fmt, net::Ipv4Addr}; + +use crate::{ + behaviour::{GatewayEvent, GatewayRequest}, + Config, +}; +use async_trait::async_trait; +use futures::channel::mpsc::{Receiver, Sender}; + +/// Protocols available for port mapping. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub(crate) enum Protocol { + Tcp, + Udp, +} + +impl fmt::Display for Protocol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Protocol::Tcp => f.write_str("tcp"), + Protocol::Udp => f.write_str("udp"), + } + } +} + +/// Interface that interacts with the inner gateway by messages, +/// `GatewayRequest`s and `GatewayEvent`s. +pub struct Gateway { + pub(crate) sender: Sender, + pub(crate) receiver: Receiver, + pub(crate) addr: Ipv4Addr, +} + +/// Abstraction to allow for compatibility with various async runtimes. +#[async_trait] +pub trait Provider { + async fn search_gateway(config: Config) -> Result>; +} + +macro_rules! impl_provider { + ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident, $options: ident) => { + use crate::behaviour::{GatewayRequest, GatewayEvent}; + use super::{Gateway, Config, Protocol}; + + use async_trait::async_trait; + use std::error::Error; + use futures::{channel::mpsc, select, stream::FuturesUnordered, FutureExt, StreamExt, SinkExt}; + + impl From for $protocol { + fn from(protocol: Protocol) -> Self { + match protocol { + Protocol::Tcp => $protocol::TCP, + Protocol::Udp => $protocol::UDP, + } + } + } + + #[async_trait] + impl super::Provider for $impl { + async fn search_gateway(config: Config) -> Result> { + let options = $options { + bind_addr: config.bind_addr, + broadcast_address: config.broadcast_addr, + timeout: config.timeout, + }; + let gateway = $gateway::search_gateway(options).await?; + let addr = gateway.get_external_ip().await?; + + let (events_sender, mut task_receiver) = mpsc::channel(5); + let (mut task_sender, events_queue) = mpsc::channel(0); + + $executor::spawn(async move { + let mut futs = FuturesUnordered::new(); + loop { + select! { + req = task_receiver.select_next_some() => { + let fut = match req { + GatewayRequest::AddMapping(mapping, duration) => { + let duration = duration.unwrap_or(0); + let gateway = gateway.clone(); + async move { + match gateway + .add_port( + mapping.protocol.into(), + mapping.internal_addr.port(), + mapping.internal_addr, + duration, + "rust-libp2p mapping", + ).await { + Ok(()) => GatewayEvent::Mapped(mapping), + Err(err) => GatewayEvent::MapFailure(mapping, err.into()), + } + }.boxed() + } + GatewayRequest::RemoveMapping(mapping) => { + let gateway = gateway.clone(); + async move { + match gateway + .remove_port( + mapping.protocol.into(), + mapping.internal_addr.port() + ).await { + Ok(()) => GatewayEvent::Removed(mapping), + Err(err) => GatewayEvent::RemovalFailure(mapping, err.into()), + } + }.boxed() + } + + }; + futs.push(fut); + }, + event = futs.select_next_some() => { + task_sender.send(event).await.expect("receiver should be available"); + } + complete => break, + } + } + }); + + Ok(Gateway { + sender: events_sender, + receiver: events_queue, + addr, + }) + } + } + }; +} + +#[cfg(feature = "tokio")] +pub mod tokio { + use igd::{aio, PortMappingProtocol, SearchOptions}; + + #[doc(hidden)] + pub struct Tokio; + impl_provider! {Tokio, tokio, aio, PortMappingProtocol, SearchOptions} + + /// The type of a [`Behaviour`] using the `tokio` implementation. + pub type Behaviour = crate::behaviour::Behaviour; +} + +#[cfg(feature = "async-std")] +pub mod async_std { + use async_std::task; + use igd_async_std::{aio, PortMappingProtocol, SearchOptions}; + + #[doc(hidden)] + pub struct AsyncStd; + impl_provider! {AsyncStd, task, aio, PortMappingProtocol, SearchOptions} + + /// The type of a [`Behaviour`] using the `async-std` implementation. + pub type Behaviour = crate::behaviour::Behaviour; +} From b0f8f7abc9d9d28acff7da77edf97a089bc96d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 25 Jul 2023 16:30:30 +0100 Subject: [PATCH 15/41] refactor behaviour to reduce the amount of code namely in the poll function. --- protocols/upnp/src/behaviour.rs | 228 +++++++++++++++++--------------- protocols/upnp/src/lib.rs | 4 +- protocols/upnp/src/provider.rs | 2 +- 3 files changed, 127 insertions(+), 107 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 3d1233f8a85..1a13c00879a 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -26,7 +26,8 @@ use std::{ error::Error, hash::{Hash, Hasher}, marker::PhantomData, - net::SocketAddrV4, + net::{Ipv4Addr, SocketAddrV4}, + ops::{Deref, DerefMut}, pin::Pin, task::{Context, Poll}, time::Duration, @@ -53,7 +54,10 @@ const MAPPING_TIMEOUT: u64 = MAPPING_DURATION as u64 / 2; /// A [`Gateway`] Request. #[derive(Debug)] pub(crate) enum GatewayRequest { - AddMapping(Mapping, Option), + AddMapping { + mapping: Mapping, + duration: Option, + }, RemoveMapping(Mapping), } @@ -66,7 +70,7 @@ pub(crate) enum GatewayEvent { MapFailure(Mapping, Box), /// Port was successfully removed. Removed(Mapping), - /// There was a failure removing the mapping port. + /// There was a failure removing the mapped port. RemovalFailure(Mapping, Box), } @@ -79,6 +83,16 @@ pub(crate) struct Mapping { pub(crate) internal_addr: SocketAddrV4, } +impl Mapping { + /// Given the input gateway address, calculate the + /// open external `Multiaddr`. + fn external_addr(&self, gateway_addr: Ipv4Addr) -> Multiaddr { + self.multiaddr + .replace(0, |_| Some(multiaddr::Protocol::Ip4(gateway_addr))) + .expect("multiaddr should be valid") + } +} + impl Hash for Mapping { fn hash(&self, state: &mut H) { self.listener_id.hash(state); @@ -100,6 +114,7 @@ impl Borrow for Mapping { } /// Current state of a [`Mapping`]. +#[derive(Debug)] enum MappingState { /// Port mapping is inactive, will be requested or re-requested on the next iteration. Inactive, @@ -131,8 +146,67 @@ pub enum Event { GatewayNotFound, } -/// A `NetworkBehaviour` for UPnP port mapping. Automatically tries to map the external port -/// to an internal address on the gateway on a `FromSwarm::NewListenAddr`. +/// A list of port mappings and its state. +#[derive(Debug, Default)] +struct MappingList(HashMap); + +impl Deref for MappingList { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for MappingList { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl MappingList { + /// Queue for renewal the current mapped ports on the `Gateway` that are expiring, + /// and try to activate the inactive. + fn renew(&mut self, config: &Config, gateway: &mut Gateway, cx: &mut Context<'_>) { + for (mapping, state) in self.iter_mut() { + match state { + MappingState::Inactive | MappingState::Failed => { + let duration = config.temporary.then_some(MAPPING_DURATION); + if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { + mapping: mapping.clone(), + duration, + }) { + log::debug!( + "could not request port mapping for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } + *state = MappingState::Pending; + } + MappingState::Active(timeout) => { + if Pin::new(timeout).poll(cx).is_ready() { + let duration = config.temporary.then_some(MAPPING_DURATION); + if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { + mapping: mapping.clone(), + duration, + }) { + log::debug!( + "could not request port mapping for {} on the gateway: {}", + mapping.multiaddr, + err + ); + } + } + } + MappingState::Pending | MappingState::Permanent => {} + } + } + } +} + +/// A [`NetworkBehaviour`] for UPnP port mapping. Automatically tries to map the external port +/// to an internal address on the gateway on a [`FromSwarm::NewListenAddr`]. pub struct Behaviour

where P: Provider, @@ -143,7 +217,7 @@ where state: GatewayState, /// List of port mappings. - mappings: HashMap, + mappings: MappingList, /// Pending behaviour events to be emitted. pending_events: VecDeque, @@ -213,7 +287,7 @@ where }) => { let (addr, protocol) = match multiaddr_to_socketaddr_protocol(multiaddr.clone()) { Ok(addr_port) => addr_port, - Err(_) => { + Err(()) => { log::debug!("multiaddress not supported for UPnP {multiaddr}"); return; } @@ -251,10 +325,10 @@ where }; let duration = self.config.temporary.then_some(MAPPING_DURATION); - if let Err(err) = gateway - .sender - .try_send(GatewayRequest::AddMapping(mapping.clone(), duration)) - { + if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { + mapping: mapping.clone(), + duration, + }) { log::debug!( "could not request port mapping for {} on the gateway: {}", mapping.multiaddr, @@ -319,13 +393,14 @@ where cx: &mut Context<'_>, _params: &mut impl PollParameters, ) -> Poll>> { - loop { - // If there are pending addresses to be emitted we emit them first. - if let Some(event) = self.pending_events.pop_front() { - return Poll::Ready(ToSwarm::GenerateEvent(event)); - } + // If there are pending addresses to be emitted we emit them. + if let Some(event) = self.pending_events.pop_front() { + return Poll::Ready(ToSwarm::GenerateEvent(event)); + } - // We then check the `Gateway` current state. + // Loop through the gateway state so that if it changes from `Searching` to `Available` + // we poll the pending mapping requests. + loop { match self.state { GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { Poll::Ready(result) => match result { @@ -341,81 +416,62 @@ where Poll::Pending => return Poll::Pending, }, GatewayState::Available(ref mut gateway) => { - // Check pending mappings. + // Poll pending mapping requests. if let Poll::Ready(Some(result)) = gateway.receiver.poll_next_unpin(cx) { match result { GatewayEvent::Mapped(mapping) => { - let state = self + let new_state = if self.config.temporary { + MappingState::Active(Delay::new(Duration::from_secs( + MAPPING_TIMEOUT, + ))) + } else { + MappingState::Permanent + }; + + match self .mappings - .get_mut(&mapping) - .expect("mapping should exist"); - match state { + .insert(mapping.clone(), new_state) + .expect("mapping should exist") + { MappingState::Pending => { + let external_multiaddr = + mapping.external_addr(gateway.addr); + self.pending_events.push_back(Event::NewExternalAddr( + external_multiaddr.clone(), + )); log::debug!( - "succcessfuly UPnP mapped {} for {} protocol", + "succcessfully mapped UPnP {} for {} protocol", mapping.internal_addr, mapping.protocol ); - let external_multiaddr = mapping - .multiaddr - .replace(0, |_| { - Some(multiaddr::Protocol::Ip4(gateway.addr)) - }) - .expect("multiaddr should be valid"); - *state = if self.config.temporary { - MappingState::Permanent - } else { - MappingState::Active(Delay::new(Duration::from_secs( - MAPPING_TIMEOUT, - ))) - }; - - self.pending_events.push_back(Event::NewExternalAddr( - external_multiaddr.clone(), - )); return Poll::Ready(ToSwarm::ExternalAddrConfirmed( external_multiaddr, )); } MappingState::Active(_) => { - *state = MappingState::Active(Delay::new( - Duration::from_secs(MAPPING_TIMEOUT), - )); - log::debug!( - "succcessfuly remapped UPnP {} for {} protocol", + "succcessfully renewed UPnP mapping {} for {} protocol", mapping.internal_addr, mapping.protocol ); } - MappingState::Inactive - | MappingState::Permanent - | MappingState::Failed => { - unreachable!() - } + _ => unreachable!(), } } GatewayEvent::MapFailure(mapping, err) => { - let state = self + match self .mappings - .get_mut(&mapping) - .expect("mapping should exist"); - - match state { + .insert(mapping.clone(), MappingState::Failed) + .expect("mapping should exist") + { MappingState::Active(_) => { log::debug!( "failed to remap UPnP mapped {} for {} protocol: {err}", mapping.internal_addr, mapping.protocol ); - *state = MappingState::Failed; - let external_multiaddr = mapping - .multiaddr - .replace(0, |_| { - Some(multiaddr::Protocol::Ip4(gateway.addr)) - }) - .expect("multiaddr should be valid"); - + let external_multiaddr = + mapping.external_addr(gateway.addr); self.pending_events.push_back(Event::ExpiredExternalAddr( external_multiaddr.clone(), )); @@ -429,18 +485,15 @@ where mapping.internal_addr, mapping.protocol ); - *state = MappingState::Failed; } - MappingState::Inactive - | MappingState::Permanent - | MappingState::Failed => { + _ => { unreachable!() } } } GatewayEvent::Removed(mapping) => { log::debug!( - "succcessfuly removed UPnP mapping {} for {} protocol", + "succcessfully removed UPnP mapping {} for {} protocol", mapping.internal_addr, mapping.protocol ); @@ -469,40 +522,7 @@ where } // Renew expired and request inactive mappings. - for (mapping, state) in self.mappings.iter_mut() { - match state { - MappingState::Inactive | MappingState::Failed => { - let duration = self.config.temporary.then_some(MAPPING_DURATION); - if let Err(err) = gateway - .sender - .try_send(GatewayRequest::AddMapping(mapping.clone(), duration)) - { - log::debug!( - "could not request port mapping for {} on the gateway: {}", - mapping.multiaddr, - err - ); - } - *state = MappingState::Pending; - } - MappingState::Active(timeout) => { - if Pin::new(timeout).poll(cx).is_ready() { - let duration = - self.config.temporary.then_some(MAPPING_DURATION); - if let Err(err) = gateway.sender.try_send( - GatewayRequest::AddMapping(mapping.clone(), duration), - ) { - log::debug!( - "could not request port mapping for {} on the gateway: {}", - mapping.multiaddr, - err - ); - } - } - } - MappingState::Pending | MappingState::Permanent => {} - } - } + self.mappings.renew(&mut self.config, gateway, cx); return Poll::Pending; } GatewayState::GatewayNotFound => { @@ -513,9 +533,9 @@ where } } -/// Extracts a `SocketAddr` and `Protocol` from a given `Multiaddr`. +/// Extracts a [`SocketAddrV4`] and [`Protocol`] from a given [`Multiaddr`]. /// -/// Fails if the given `Multiaddr` does not begin with an IP +/// Fails if the given [`Multiaddr`] does not begin with an IP /// protocol encapsulating a TCP or UDP port. fn multiaddr_to_socketaddr_protocol(mut addr: Multiaddr) -> Result<(SocketAddrV4, Protocol), ()> { let mut port = None; diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index c84b55df357..309939c0351 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -21,7 +21,7 @@ //! Implementation of UPnP port mapping for libp2p. //! //! This crate provides a `tokio::Behaviour` and `async_std::Behaviour`, depending on the enabled features, which -//! implements the `NetworkBehaviour` trait. This struct will automatically try to map the ports externally to internal +//! implements the [`NetworkBehaviour`] trait. This struct will automatically try to map the ports externally to internal //! addresses on the gateway. //! @@ -64,7 +64,7 @@ impl Config { } } - /// Configures if the port mappings be temporary (1 hour) or permanent. + /// Configures the port mappings to be temporary (1 hour) or permanent. pub fn temporary(self, temporary: bool) -> Self { Self { temporary, ..self } } diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 896c0c2e48c..a2731b79575 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -95,7 +95,7 @@ macro_rules! impl_provider { select! { req = task_receiver.select_next_some() => { let fut = match req { - GatewayRequest::AddMapping(mapping, duration) => { + GatewayRequest::AddMapping{ mapping, duration } => { let duration = duration.unwrap_or(0); let gateway = gateway.clone(); async move { From 4a90a7814416dae6804a6212f58e8f325b6ce1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 25 Jul 2023 16:31:10 +0100 Subject: [PATCH 16/41] update provider to handle tasks sequentially instead of concurrently --- protocols/upnp/src/provider.rs | 87 ++++++++++++++++------------------ 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index a2731b79575..798c669ef19 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -59,12 +59,12 @@ pub trait Provider { macro_rules! impl_provider { ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident, $options: ident) => { - use crate::behaviour::{GatewayRequest, GatewayEvent}; - use super::{Gateway, Config, Protocol}; + use super::{Config, Gateway, Protocol}; + use crate::behaviour::{GatewayEvent, GatewayRequest}; use async_trait::async_trait; + use futures::{channel::mpsc, SinkExt, StreamExt}; use std::error::Error; - use futures::{channel::mpsc, select, stream::FuturesUnordered, FutureExt, StreamExt, SinkExt}; impl From for $protocol { fn from(protocol: Protocol) -> Self { @@ -86,54 +86,49 @@ macro_rules! impl_provider { let gateway = $gateway::search_gateway(options).await?; let addr = gateway.get_external_ip().await?; - let (events_sender, mut task_receiver) = mpsc::channel(5); + let (events_sender, mut task_receiver) = mpsc::channel(10); let (mut task_sender, events_queue) = mpsc::channel(0); $executor::spawn(async move { - let mut futs = FuturesUnordered::new(); loop { - select! { - req = task_receiver.select_next_some() => { - let fut = match req { - GatewayRequest::AddMapping{ mapping, duration } => { - let duration = duration.unwrap_or(0); - let gateway = gateway.clone(); - async move { - match gateway - .add_port( - mapping.protocol.into(), - mapping.internal_addr.port(), - mapping.internal_addr, - duration, - "rust-libp2p mapping", - ).await { - Ok(()) => GatewayEvent::Mapped(mapping), - Err(err) => GatewayEvent::MapFailure(mapping, err.into()), - } - }.boxed() - } - GatewayRequest::RemoveMapping(mapping) => { - let gateway = gateway.clone(); - async move { - match gateway - .remove_port( - mapping.protocol.into(), - mapping.internal_addr.port() - ).await { - Ok(()) => GatewayEvent::Removed(mapping), - Err(err) => GatewayEvent::RemovalFailure(mapping, err.into()), - } - }.boxed() - } - - }; - futs.push(fut); - }, - event = futs.select_next_some() => { - task_sender.send(event).await.expect("receiver should be available"); + // The task sender has dropped so we can return. + let Some(req) = task_receiver.next().await else { return; }; + let event = match req { + GatewayRequest::AddMapping { mapping, duration } => { + let duration = duration.unwrap_or(0); + let gateway = gateway.clone(); + match gateway + .add_port( + mapping.protocol.into(), + mapping.internal_addr.port(), + mapping.internal_addr, + duration, + "rust-libp2p mapping", + ) + .await + { + Ok(()) => GatewayEvent::Mapped(mapping), + Err(err) => GatewayEvent::MapFailure(mapping, err.into()), + } } - complete => break, - } + GatewayRequest::RemoveMapping(mapping) => { + let gateway = gateway.clone(); + match gateway + .remove_port( + mapping.protocol.into(), + mapping.internal_addr.port(), + ) + .await + { + Ok(()) => GatewayEvent::Removed(mapping), + Err(err) => GatewayEvent::RemovalFailure(mapping, err.into()), + } + } + }; + task_sender + .send(event) + .await + .expect("receiver should be available"); } }); From 960a50e5b4f4938db3e0c0448caab2d993b7c4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 26 Jul 2023 12:06:28 +0100 Subject: [PATCH 17/41] switch to idg-next , instead of using two different igd crates --- Cargo.lock | 450 ++++++++++++++++---------------- protocols/upnp/Cargo.toml | 7 +- protocols/upnp/src/behaviour.rs | 27 +- protocols/upnp/src/provider.rs | 44 +--- 4 files changed, 252 insertions(+), 276 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c44a7ba715..e5555b01e76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,6 +247,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.4" @@ -262,7 +268,7 @@ dependencies = [ "asn1-rs-derive 0.1.0", "asn1-rs-impl", "displaydoc", - "nom", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror", @@ -278,7 +284,7 @@ dependencies = [ "asn1-rs-derive 0.4.0", "asn1-rs-impl", "displaydoc", - "nom", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror", @@ -347,6 +353,16 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-dup" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" +dependencies = [ + "futures-io", + "simple-mutex", +] + [[package]] name = "async-executor" version = "1.5.1" @@ -388,6 +404,22 @@ dependencies = [ "once_cell", ] +[[package]] +name = "async-h1" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8101020758a4fc3a7c326cb42aa99e9fa77cbfb76987c128ad956406fe1f70a7" +dependencies = [ + "async-channel", + "async-dup", + "async-std", + "futures-core", + "http-types", + "httparse", + "log", + "pin-project", +] + [[package]] name = "async-io" version = "1.13.0" @@ -496,6 +528,19 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +[[package]] +name = "async-tls" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d85a97c4a0ecce878efd3f945f119c78a646d8975340bca0398f9bb05c30cc52" +dependencies = [ + "futures-core", + "futures-io", + "rustls 0.18.1", + "webpki 0.21.4", + "webpki-roots 0.20.0", +] + [[package]] name = "async-trait" version = "0.1.72" @@ -513,7 +558,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-sink", "futures-util", "memchr", @@ -528,26 +573,13 @@ checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" [[package]] name = "attohttpc" -version = "0.16.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" dependencies = [ "http", "log", "url", - "wildmatch 1.1.0", -] - -[[package]] -name = "attohttpc" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262c3f7f5d61249d8c00e5546e2685cd15ebeeb1bc0f3cc5449350a1cb07319e" -dependencies = [ - "http", - "log", - "url", - "wildmatch 2.1.1", ] [[package]] @@ -576,7 +608,7 @@ dependencies = [ "async-trait", "axum-core", "bitflags 1.3.2", - "bytes 1.4.0", + "bytes", "futures-util", "http", "http-body", @@ -606,7 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes", "futures-util", "http", "http-body", @@ -649,6 +681,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.13.1" @@ -782,12 +820,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.4.0" @@ -986,7 +1018,7 @@ version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-core", "memchr", "pin-project-lite 0.2.10", @@ -1003,6 +1035,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "config" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" +dependencies = [ + "lazy_static", + "nom 5.1.3", + "serde", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -1187,6 +1230,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -1304,37 +1357,6 @@ dependencies = [ "rand 0.7.3", ] -[[package]] -name = "curl" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" -dependencies = [ - "curl-sys", - "libc", - "openssl-probe", - "openssl-sys", - "schannel", - "socket2 0.4.9", - "winapi", -] - -[[package]] -name = "curl-sys" -version = "0.4.64+curl-8.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f96069f0b1cb1241c838740659a771ef143363f52772a9ce1bd9c04c75eee0dc" -dependencies = [ - "cc", - "libc", - "libnghttp2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", - "winapi", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1397,6 +1419,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dashmap" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -1436,6 +1471,20 @@ dependencies = [ "log", ] +[[package]] +name = "deadpool" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d126179d86aee4556e54f5f3c6bf6d9884e7cc52cef82f77ee6f90a7747616d" +dependencies = [ + "async-trait", + "config", + "crossbeam-queue", + "num_cpus", + "serde", + "tokio", +] + [[package]] name = "der" version = "0.6.1" @@ -1466,7 +1515,7 @@ checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" dependencies = [ "asn1-rs 0.3.1", "displaydoc", - "nom", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -1480,7 +1529,7 @@ checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ "asn1-rs 0.5.2", "displaydoc", - "nom", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -1833,17 +1882,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bebadab126f8120d410b677ed95eee4ba6eb7c6dd8e34a5ec88a08050e26132" -dependencies = [ - "futures-core", - "futures-sink", - "spinning_top", -] - [[package]] name = "fnv" version = "1.0.7" @@ -2150,7 +2188,7 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ - "bytes 1.4.0", + "bytes", "fnv", "futures-core", "futures-sink", @@ -2291,7 +2329,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.4.0", + "bytes", "fnv", "itoa", ] @@ -2302,7 +2340,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", + "bytes", "http", "pin-project-lite 0.2.10", ] @@ -2313,12 +2351,17 @@ version = "6.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1947510dc91e2bf586ea5ffb412caad7673264e14bb39fb9078da114a94ce1a5" dependencies = [ + "async-h1", "async-std", + "async-tls", "async-trait", "cfg-if 1.0.0", + "dashmap", + "deadpool", + "futures", "http-types", - "isahc", "log", + "rustls 0.18.1", ] [[package]] @@ -2373,7 +2416,7 @@ version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -2412,7 +2455,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.4.0", + "bytes", "hyper", "native-tls", "tokio", @@ -2487,37 +2530,21 @@ dependencies = [ ] [[package]] -name = "igd" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556b5a75cd4adb7c4ea21c64af1c48cefb2ce7d43dc4352c720a1fe47c21f355" -dependencies = [ - "attohttpc 0.16.3", - "bytes 1.4.0", - "futures", - "http", - "hyper", - "log", - "rand 0.8.5", - "tokio", - "url", - "xmltree", -] - -[[package]] -name = "igd_async_std" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08b1b8bc4334daa2fc717ae3f285b42130c92c2078a5a94a4c0f86457a376c3" +name = "igd-next" +version = "0.14.0" +source = "git+https://github.com/jxs/rust-igd.git#4954dd611832df5088eecfad9b6d9536d84a015b" dependencies = [ "async-std", - "attohttpc 0.19.1", - "bytes 1.4.0", + "async-trait", + "attohttpc", + "bytes", "futures", "http", + "hyper", "log", "rand 0.8.5", "surf", + "tokio", "url", "xmltree", ] @@ -2576,7 +2603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c142385498b53584546abbfa50188b2677af8e4f879da1ee5d905cb7de5b97a" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes", "log", "rand 0.8.5", "rtcp", @@ -2685,29 +2712,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "isahc" -version = "0.9.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2948a0ce43e2c2ef11d7edf6816508998d99e13badd1150be0914205df9388a" -dependencies = [ - "bytes 0.5.6", - "crossbeam-utils", - "curl", - "curl-sys", - "flume", - "futures-lite", - "http", - "log", - "once_cell", - "slab", - "sluice", - "tracing", - "tracing-futures", - "url", - "waker-fn", -] - [[package]] name = "itertools" version = "0.10.5" @@ -2769,6 +2773,19 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec 0.5.2", + "bitflags 1.3.2", + "cfg-if 1.0.0", + "ryu", + "static_assertions", +] + [[package]] name = "libc" version = "0.2.147" @@ -2781,23 +2798,13 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" -[[package]] -name = "libnghttp2-sys" -version = "0.1.7+1.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "libp2p" version = "0.52.2" dependencies = [ "async-std", "async-trait", - "bytes 1.4.0", + "bytes", "clap", "either", "env_logger 0.10.0", @@ -3011,7 +3018,7 @@ dependencies = [ "asynchronous-codec", "base64 0.21.2", "byteorder", - "bytes 1.4.0", + "bytes", "either", "env_logger 0.10.0", "fnv", @@ -3096,10 +3103,10 @@ dependencies = [ name = "libp2p-kad" version = "0.44.3" dependencies = [ - "arrayvec", + "arrayvec 0.7.4", "async-std", "asynchronous-codec", - "bytes 1.4.0", + "bytes", "either", "env_logger 0.10.0", "fnv", @@ -3176,7 +3183,7 @@ version = "0.40.0" dependencies = [ "async-std", "asynchronous-codec", - "bytes 1.4.0", + "bytes", "criterion", "env_logger 0.10.0", "futures", @@ -3209,7 +3216,7 @@ dependencies = [ name = "libp2p-noise" version = "0.43.0" dependencies = [ - "bytes 1.4.0", + "bytes", "curve25519-dalek 3.2.0", "env_logger 0.10.0", "futures", @@ -3285,7 +3292,7 @@ name = "libp2p-plaintext" version = "0.40.0" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -3324,7 +3331,7 @@ name = "libp2p-quic" version = "0.8.0-alpha" dependencies = [ "async-std", - "bytes 1.4.0", + "bytes", "env_logger 0.10.0", "futures", "futures-timer", @@ -3351,7 +3358,7 @@ name = "libp2p-relay" version = "0.16.1" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes", "either", "env_logger 0.10.0", "futures", @@ -3550,8 +3557,7 @@ dependencies = [ "async-trait", "futures", "futures-timer", - "igd", - "igd_async_std", + "igd-next", "libp2p-core", "libp2p-swarm", "log", @@ -3578,7 +3584,7 @@ dependencies = [ "anyhow", "async-trait", "asynchronous-codec", - "bytes 1.4.0", + "bytes", "env_logger 0.10.0", "futures", "futures-timer", @@ -3712,18 +3718,6 @@ dependencies = [ "libsecp256k1-core", ] -[[package]] -name = "libz-sys" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e6ab01971eb092ffe6a7d42f49f9ff42662f17604681e2843ad65077ba47dc" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3943,7 +3937,7 @@ name = "multistream-select" version = "0.13.0" dependencies = [ "async-std", - "bytes 1.4.0", + "bytes", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -4018,7 +4012,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "bytes 1.4.0", + "bytes", "futures", "log", "netlink-packet-core", @@ -4034,7 +4028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" dependencies = [ "async-io", - "bytes 1.4.0", + "bytes", "futures", "libc", "log", @@ -4059,6 +4053,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[package]] +name = "nom" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" +dependencies = [ + "lexical-core", + "memchr", + "version_check", +] + [[package]] name = "nom" version = "7.1.3" @@ -4370,6 +4375,7 @@ version = "0.1.0" dependencies = [ "async-std", "async-trait", + "env_logger 0.10.0", "futures", "libp2p", ] @@ -4604,7 +4610,7 @@ name = "quick-protobuf-codec" version = "0.2.0" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes", "quick-protobuf", "thiserror", "unsigned-varint", @@ -4646,7 +4652,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85af4ed6ee5a89f26a26086e9089a6643650544c025158449a3626ebf72884b3" dependencies = [ - "bytes 1.4.0", + "bytes", "rand 0.8.5", "ring", "rustc-hash", @@ -4791,7 +4797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes", "combine", "futures-util", "itoa", @@ -4889,7 +4895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", - "bytes 1.4.0", + "bytes", "encoding_rs", "futures-core", "futures-util", @@ -5002,7 +5008,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6423493804221c276d27f3cc383cd5cbe1a1f10f210909fd4951b579b01293cd" dependencies = [ - "bytes 1.4.0", + "bytes", "thiserror", "webrtc-util", ] @@ -5029,7 +5035,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b728adb99b88d932f2f0622b540bf7ccb196f81e9823b5b0eeb166526c88138c" dependencies = [ - "bytes 1.4.0", + "bytes", "rand 0.8.5", "serde", "thiserror", @@ -5106,7 +5112,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom", + "nom 7.1.3", ] [[package]] @@ -5136,6 +5142,19 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustls" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" +dependencies = [ + "base64 0.12.3", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + [[package]] name = "rustls" version = "0.19.1" @@ -5582,23 +5601,21 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.8" +name = "simple-mutex" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" dependencies = [ - "autocfg", + "event-listener", ] [[package]] -name = "sluice" -version = "0.5.5" +name = "slab" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ - "async-channel", - "futures-core", - "futures-io", + "autocfg", ] [[package]] @@ -5677,7 +5694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", - "bytes 1.4.0", + "bytes", "futures", "httparse", "log", @@ -5691,15 +5708,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spinning_top" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" -dependencies = [ - "lock_api", -] - [[package]] name = "spki" version = "0.6.0" @@ -5842,7 +5850,6 @@ dependencies = [ "async-std", "async-trait", "cfg-if 1.0.0", - "encoding_rs", "futures-util", "getrandom 0.2.10", "http-client", @@ -5851,9 +5858,9 @@ dependencies = [ "mime_guess", "once_cell", "pin-project-lite 0.2.10", + "rustls 0.18.1", "serde", "serde_json", - "web-sys", ] [[package]] @@ -6105,7 +6112,7 @@ checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", "backtrace", - "bytes 1.4.0", + "bytes", "libc", "mio", "num_cpus", @@ -6155,7 +6162,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-core", "futures-io", "futures-sink", @@ -6187,7 +6194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" dependencies = [ "bitflags 2.3.3", - "bytes 1.4.0", + "bytes", "futures-core", "futures-util", "http", @@ -6251,16 +6258,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.1.3" @@ -6297,7 +6294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes", "cfg-if 1.0.0", "data-encoding", "enum-as-inner", @@ -6474,7 +6471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes", ] [[package]] @@ -6704,7 +6701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9973cb72c8587d5ad5efdb91e663d36177dc37725e6c90ca86c626b0cc45c93f" dependencies = [ "base64 0.13.1", - "bytes 1.4.0", + "bytes", "cookie 0.16.2", "http", "log", @@ -6736,6 +6733,15 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki-roots" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" +dependencies = [ + "webpki 0.21.4", +] + [[package]] name = "webpki-roots" version = "0.22.6" @@ -6762,7 +6768,7 @@ checksum = "f60dde9fd592872bc371b3842e4616bc4c6984242e3cd2a7d7cb771db278601b" dependencies = [ "arc-swap", "async-trait", - "bytes 1.4.0", + "bytes", "cfg-if 0.1.10", "hex", "interceptor", @@ -6804,7 +6810,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3c7ba7d11733e448d8d2d054814e97c558f52293f0e0a2eb05840f28b3be12" dependencies = [ - "bytes 1.4.0", + "bytes", "derive_builder", "log", "thiserror", @@ -6899,7 +6905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd8e3711a321f6a375973144f48065cf705316ab6709672954aace020c668eb6" dependencies = [ "byteorder", - "bytes 1.4.0", + "bytes", "rand 0.8.5", "rtp", "thiserror", @@ -6913,7 +6919,7 @@ checksum = "7df742d91cfbd982f6ab2bfd45a7c3ddfce5b2f55913b2f63877404d1b3259db" dependencies = [ "arc-swap", "async-trait", - "bytes 1.4.0", + "bytes", "crc", "log", "rand 0.8.5", @@ -6932,7 +6938,7 @@ dependencies = [ "aes 0.7.5", "aes-gcm 0.10.2", "byteorder", - "bytes 1.4.0", + "bytes", "ctr 0.8.0", "hmac 0.12.1", "log", @@ -6953,7 +6959,7 @@ checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" dependencies = [ "async-trait", "bitflags 1.3.2", - "bytes 1.4.0", + "bytes", "cc", "ipnet", "lazy_static", @@ -6990,18 +6996,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" -[[package]] -name = "wildmatch" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" - -[[package]] -name = "wildmatch" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" - [[package]] name = "winapi" version = "0.3.9" @@ -7194,7 +7188,7 @@ dependencies = [ "data-encoding", "der-parser 7.0.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.4.0", "rusticata-macros", "thiserror", @@ -7212,7 +7206,7 @@ dependencies = [ "data-encoding", "der-parser 8.2.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.6.1", "ring", "rusticata-macros", @@ -7230,7 +7224,7 @@ dependencies = [ "data-encoding", "der-parser 8.2.0", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry 0.6.1", "rusticata-macros", "thiserror", diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index f0c71eb474e..6ea699217ea 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -13,8 +13,7 @@ categories = ["network-programming", "asynchronous"] async-trait = "0.1.68" futures = "0.3.28" futures-timer = "3.0.2" -igd = { version = "0.12.1", optional = true, features = ["aio"] } -igd_async_std = { version = "0.12.4", optional = true, features = ["aio"] } +igd-next = { git = "https://github.com/jxs/rust-igd.git" } libp2p-core = { workspace = true } libp2p-swarm = { workspace = true } log = "0.4.19" @@ -23,6 +22,6 @@ tokio = { version = "1.29", default-features = false, features = ["rt", "rt-mult async-std = { version = "1.12.0"} [features] -tokio = ["dep:igd", "dep:tokio"] -async-std = ["dep:igd_async_std"] +tokio = ["igd-next/aio_tokio", "dep:tokio"] +async-std = ["igd-next/aio_async_std"] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 1a13c00879a..5651a6da968 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -26,7 +26,7 @@ use std::{ error::Error, hash::{Hash, Hasher}, marker::PhantomData, - net::{Ipv4Addr, SocketAddrV4}, + net::{IpAddr, SocketAddr, SocketAddrV4}, ops::{Deref, DerefMut}, pin::Pin, task::{Context, Poll}, @@ -34,11 +34,12 @@ use std::{ }; use crate::{ - provider::{Gateway, Protocol, Provider}, + provider::{Gateway, Provider}, Config, }; use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; use futures_timer::Delay; +use igd_next::PortMappingProtocol; use libp2p_core::{multiaddr, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_swarm::{ derive_prelude::PeerId, dummy, ConnectionDenied, ConnectionId, ExpiredListenAddr, FromSwarm, @@ -78,17 +79,21 @@ pub(crate) enum GatewayEvent { #[derive(Debug, Clone)] pub(crate) struct Mapping { pub(crate) listener_id: ListenerId, - pub(crate) protocol: Protocol, + pub(crate) protocol: PortMappingProtocol, pub(crate) multiaddr: Multiaddr, - pub(crate) internal_addr: SocketAddrV4, + pub(crate) internal_addr: SocketAddr, } impl Mapping { /// Given the input gateway address, calculate the /// open external `Multiaddr`. - fn external_addr(&self, gateway_addr: Ipv4Addr) -> Multiaddr { + fn external_addr(&self, gateway_addr: IpAddr) -> Multiaddr { + let addr = match gateway_addr { + IpAddr::V4(ip) => multiaddr::Protocol::Ip4(ip), + IpAddr::V6(ip) => multiaddr::Protocol::Ip6(ip), + }; self.multiaddr - .replace(0, |_| Some(multiaddr::Protocol::Ip4(gateway_addr))) + .replace(0, |_| Some(addr)) .expect("multiaddr should be valid") } } @@ -537,7 +542,9 @@ where /// /// Fails if the given [`Multiaddr`] does not begin with an IP /// protocol encapsulating a TCP or UDP port. -fn multiaddr_to_socketaddr_protocol(mut addr: Multiaddr) -> Result<(SocketAddrV4, Protocol), ()> { +fn multiaddr_to_socketaddr_protocol( + mut addr: Multiaddr, +) -> Result<(SocketAddr, PortMappingProtocol), ()> { let mut port = None; let mut protocol = None; while let Some(proto) = addr.pop() { @@ -548,21 +555,21 @@ fn multiaddr_to_socketaddr_protocol(mut addr: Multiaddr) -> Result<(SocketAddrV4 } multiaddr::Protocol::Ip4(ipv4) if ipv4.is_private() => match (port, protocol) { (Some(port), Some(protocol)) => { - return Ok((SocketAddrV4::new(ipv4, port), protocol)); + return Ok((SocketAddr::V4(SocketAddrV4::new(ipv4, port)), protocol)); } _ => return Err(()), }, multiaddr::Protocol::Tcp(portnum) => match (port, protocol) { (None, None) => { port = Some(portnum); - protocol = Some(Protocol::Tcp); + protocol = Some(PortMappingProtocol::TCP); } _ => return Err(()), }, multiaddr::Protocol::Udp(portnum) => match (port, protocol) { (None, None) => { port = Some(portnum); - protocol = Some(Protocol::Udp); + protocol = Some(PortMappingProtocol::UDP); } _ => return Err(()), }, diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 798c669ef19..b15c2d4a7e2 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -18,7 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use std::{error::Error, fmt, net::Ipv4Addr}; +use std::{error::Error, net::IpAddr}; use crate::{ behaviour::{GatewayEvent, GatewayRequest}, @@ -27,28 +27,12 @@ use crate::{ use async_trait::async_trait; use futures::channel::mpsc::{Receiver, Sender}; -/// Protocols available for port mapping. -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -pub(crate) enum Protocol { - Tcp, - Udp, -} - -impl fmt::Display for Protocol { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Protocol::Tcp => f.write_str("tcp"), - Protocol::Udp => f.write_str("udp"), - } - } -} - /// Interface that interacts with the inner gateway by messages, /// `GatewayRequest`s and `GatewayEvent`s. pub struct Gateway { pub(crate) sender: Sender, pub(crate) receiver: Receiver, - pub(crate) addr: Ipv4Addr, + pub(crate) addr: IpAddr, } /// Abstraction to allow for compatibility with various async runtimes. @@ -58,27 +42,19 @@ pub trait Provider { } macro_rules! impl_provider { - ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident, $options: ident) => { - use super::{Config, Gateway, Protocol}; + ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident) => { + use super::{Config, Gateway}; use crate::behaviour::{GatewayEvent, GatewayRequest}; use async_trait::async_trait; use futures::{channel::mpsc, SinkExt, StreamExt}; + use igd_next::SearchOptions; use std::error::Error; - impl From for $protocol { - fn from(protocol: Protocol) -> Self { - match protocol { - Protocol::Tcp => $protocol::TCP, - Protocol::Udp => $protocol::UDP, - } - } - } - #[async_trait] impl super::Provider for $impl { async fn search_gateway(config: Config) -> Result> { - let options = $options { + let options = SearchOptions { bind_addr: config.bind_addr, broadcast_address: config.broadcast_addr, timeout: config.timeout, @@ -144,11 +120,11 @@ macro_rules! impl_provider { #[cfg(feature = "tokio")] pub mod tokio { - use igd::{aio, PortMappingProtocol, SearchOptions}; + use igd_next::aio::tokio as aio_tokio; #[doc(hidden)] pub struct Tokio; - impl_provider! {Tokio, tokio, aio, PortMappingProtocol, SearchOptions} + impl_provider! {Tokio, tokio, aio_tokio, PortMappingProtocol} /// The type of a [`Behaviour`] using the `tokio` implementation. pub type Behaviour = crate::behaviour::Behaviour; @@ -157,11 +133,11 @@ pub mod tokio { #[cfg(feature = "async-std")] pub mod async_std { use async_std::task; - use igd_async_std::{aio, PortMappingProtocol, SearchOptions}; + use igd_next::aio::async_std as aio_async_std; #[doc(hidden)] pub struct AsyncStd; - impl_provider! {AsyncStd, task, aio, PortMappingProtocol, SearchOptions} + impl_provider! {AsyncStd, task, aio_async_std, PortMappingProtocol} /// The type of a [`Behaviour`] using the `async-std` implementation. pub type Behaviour = crate::behaviour::Behaviour; From 92f5cea4a0d9c724fbac8c025de08c8dd8c59bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 28 Jul 2023 17:27:42 +0100 Subject: [PATCH 18/41] add Changelog entries update rust-igd to upstream. --- CHANGELOG.md | 1 + Cargo.lock | 5 +++-- libp2p/CHANGELOG.md | 3 +++ protocols/upnp/CHANGELOG.md | 4 ++++ protocols/upnp/Cargo.toml | 2 +- 5 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 protocols/upnp/CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf9f7c9559..f6b32c35f97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - [`libp2p-relay` CHANGELOG](protocols/relay/CHANGELOG.md) - [`libp2p-request-response` CHANGELOG](protocols/request-response/CHANGELOG.md) - [`libp2p-rendezvous` CHANGELOG](protocols/rendezvous/CHANGELOG.md) +- [`libp2p-upnp` CHANGELOG](protocols/upnp/CHANGELOG.md) ## Transport Protocols & Upgrades diff --git a/Cargo.lock b/Cargo.lock index e45090777a9..0abafcb9a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,8 +2531,9 @@ dependencies = [ [[package]] name = "igd-next" -version = "0.14.0" -source = "git+https://github.com/jxs/rust-igd.git#4954dd611832df5088eecfad9b6d9536d84a015b" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e065e90a518ab5fedf79aa1e4b784e10f8e484a834f6bda85c42633a2cb7af" dependencies = [ "async-std", "async-trait", diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 4161ed054c5..2b6827ff6f8 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -6,8 +6,11 @@ - Add `json` feature which exposes `request_response::json`. See [PR 4188]. +- Add initial version of `upnp` protocol see [PR 4156] + [PR 4188]: https://github.com/libp2p/rust-libp2p/pull/4188 [PR 4217]: https://github.com/libp2p/rust-libp2p/pull/4217 +[PR 4156]: https://github.com/libp2p/rust-libp2p/pull/4156 ## 0.52.1 diff --git a/protocols/upnp/CHANGELOG.md b/protocols/upnp/CHANGELOG.md new file mode 100644 index 00000000000..647b242ff91 --- /dev/null +++ b/protocols/upnp/CHANGELOG.md @@ -0,0 +1,4 @@ + +## 0.1.0 + +- Initial version diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 6ea699217ea..76a6206d8cf 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -13,7 +13,7 @@ categories = ["network-programming", "asynchronous"] async-trait = "0.1.68" futures = "0.3.28" futures-timer = "3.0.2" -igd-next = { git = "https://github.com/jxs/rust-igd.git" } +igd-next = "0.14.2" libp2p-core = { workspace = true } libp2p-swarm = { workspace = true } log = "0.4.19" From 5384ae68c4b358cb099f42f6afc53babb534a518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 28 Jul 2023 17:31:13 +0100 Subject: [PATCH 19/41] update Cargo.lock --- Cargo.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 187f05ea3f3..300f48aae55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4657,11 +4657,11 @@ dependencies = [ "async-std", "bytes", "futures-io", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.10", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.2", + "rustls 0.21.5", "thiserror", "tokio", "tracing", @@ -4694,7 +4694,7 @@ dependencies = [ "libc", "socket2 0.5.3", "tracing", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -4826,9 +4826,9 @@ dependencies = [ [[package]] name = "redis" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f" +checksum = "ff5d95dd18a4d76650f0c2607ed8ebdbf63baf9cb934e1c233cd220c694db1d7" dependencies = [ "async-trait", "bytes", @@ -5249,9 +5249,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.1" +version = "0.101.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" dependencies = [ "ring", "untrusted", @@ -5439,18 +5439,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.175" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" +checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.175" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" +checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" dependencies = [ "proc-macro2", "quote", @@ -5459,9 +5459,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "indexmap 2.0.0", "itoa", @@ -5492,9 +5492,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e168eaaf71e8f9bd6037feb05190485708e019f4fd87d161b3c0a0d37daf85e5" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", From 7398842c85affd5de2be9e178705a67240d4aa85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 28 Jul 2023 17:33:06 +0100 Subject: [PATCH 20/41] fix docs --- protocols/upnp/src/behaviour.rs | 2 +- protocols/upnp/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 5651a6da968..9ed6f6efd22 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -538,7 +538,7 @@ where } } -/// Extracts a [`SocketAddrV4`] and [`Protocol`] from a given [`Multiaddr`]. +/// Extracts a [`SocketAddrV4`] and [`PortMappingProtocol`] from a given [`Multiaddr`]. /// /// Fails if the given [`Multiaddr`] does not begin with an IP /// protocol encapsulating a TCP or UDP port. diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 309939c0351..c62111b0ba7 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -21,7 +21,7 @@ //! Implementation of UPnP port mapping for libp2p. //! //! This crate provides a `tokio::Behaviour` and `async_std::Behaviour`, depending on the enabled features, which -//! implements the [`NetworkBehaviour`] trait. This struct will automatically try to map the ports externally to internal +//! implement the [`libp2p_swarm::NetworkBehaviour`] trait. This struct will automatically try to map the ports externally to internal //! addresses on the gateway. //! From ac78e67791dbc989e45e44dc16387ad7618eb6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 29 Jul 2023 12:50:31 +0100 Subject: [PATCH 21/41] update multiaddr_to_socketaddr_protocol, start from the beginning instead of the end to be able to abort early. --- protocols/upnp/CHANGELOG.md | 1 - protocols/upnp/src/behaviour.rs | 48 +++++++++++++-------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/protocols/upnp/CHANGELOG.md b/protocols/upnp/CHANGELOG.md index 647b242ff91..51d1510cddd 100644 --- a/protocols/upnp/CHANGELOG.md +++ b/protocols/upnp/CHANGELOG.md @@ -1,4 +1,3 @@ - ## 0.1.0 - Initial version diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 9ed6f6efd22..b53a4ad37a4 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -543,39 +543,27 @@ where /// Fails if the given [`Multiaddr`] does not begin with an IP /// protocol encapsulating a TCP or UDP port. fn multiaddr_to_socketaddr_protocol( - mut addr: Multiaddr, + addr: Multiaddr, ) -> Result<(SocketAddr, PortMappingProtocol), ()> { - let mut port = None; - let mut protocol = None; - while let Some(proto) = addr.pop() { - match proto { - multiaddr::Protocol::Ip6(_) => { - // Idg only supports Ipv4. - return Err(()); + let mut iter = addr.into_iter(); + match iter.next() { + // Idg only supports Ipv4. + Some(multiaddr::Protocol::Ip4(ipv4)) if ipv4.is_private() => match iter.next() { + Some(multiaddr::Protocol::Tcp(port)) => { + return Ok(( + SocketAddr::V4(SocketAddrV4::new(ipv4, port)), + PortMappingProtocol::TCP, + )); + } + Some(multiaddr::Protocol::Udp(port)) => { + return Ok(( + SocketAddr::V4(SocketAddrV4::new(ipv4, port)), + PortMappingProtocol::TCP, + )); } - multiaddr::Protocol::Ip4(ipv4) if ipv4.is_private() => match (port, protocol) { - (Some(port), Some(protocol)) => { - return Ok((SocketAddr::V4(SocketAddrV4::new(ipv4, port)), protocol)); - } - _ => return Err(()), - }, - multiaddr::Protocol::Tcp(portnum) => match (port, protocol) { - (None, None) => { - port = Some(portnum); - protocol = Some(PortMappingProtocol::TCP); - } - _ => return Err(()), - }, - multiaddr::Protocol::Udp(portnum) => match (port, protocol) { - (None, None) => { - port = Some(portnum); - protocol = Some(PortMappingProtocol::UDP); - } - _ => return Err(()), - }, - _ => {} - } + }, + _ => {} } Err(()) } From 38434533ee806daf96e4275ed8444df70cab2ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Mon, 31 Jul 2023 12:07:51 +0100 Subject: [PATCH 22/41] clippy --- protocols/upnp/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index b53a4ad37a4..efa00167dee 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -527,7 +527,7 @@ where } // Renew expired and request inactive mappings. - self.mappings.renew(&mut self.config, gateway, cx); + self.mappings.renew(&self.config, gateway, cx); return Poll::Pending; } GatewayState::GatewayNotFound => { From 97129b6bba7699846683a0aa514fa71775894b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 1 Aug 2023 00:40:12 +0100 Subject: [PATCH 23/41] downgrade time and pin to 0.3.23 to comply with MSRV --- Cargo.lock | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e37889f5b5..9e0ba4ea807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,7 +272,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.24", + "time 0.3.23", ] [[package]] @@ -288,7 +288,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.24", + "time 0.3.23", ] [[package]] @@ -1092,7 +1092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.24", + "time 0.3.23", "version_check", ] @@ -1535,12 +1535,6 @@ dependencies = [ "rusticata-macros", ] -[[package]] -name = "deranged" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01" - [[package]] name = "derive_builder" version = "0.11.2" @@ -1817,7 +1811,7 @@ dependencies = [ "mime", "serde", "serde_json", - "time 0.3.24", + "time 0.3.23", "tokio", "url", "webdriver", @@ -4382,6 +4376,7 @@ version = "0.1.0" dependencies = [ "async-std", "async-trait", + "env_logger 0.10.0", "futures", "libp2p", ] @@ -4812,7 +4807,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.24", + "time 0.3.23", "yasna", ] @@ -4824,7 +4819,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.24", + "time 0.3.23", "x509-parser 0.14.0", "yasna", ] @@ -6070,15 +6065,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.24" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ - "deranged", "itoa", "serde", "time-core", - "time-macros 0.2.11", + "time-macros 0.2.10", ] [[package]] @@ -6099,9 +6093,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -6748,7 +6742,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.24", + "time 0.3.23", "unicode-segmentation", "url", ] @@ -6826,7 +6820,7 @@ dependencies = [ "smol_str", "stun", "thiserror", - "time 0.3.24", + "time 0.3.23", "tokio", "turn", "url", @@ -7229,7 +7223,7 @@ dependencies = [ "oid-registry 0.4.0", "rusticata-macros", "thiserror", - "time 0.3.24", + "time 0.3.23", ] [[package]] @@ -7248,7 +7242,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time 0.3.24", + "time 0.3.23", ] [[package]] @@ -7265,7 +7259,7 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.24", + "time 0.3.23", ] [[package]] @@ -7303,7 +7297,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.24", + "time 0.3.23", ] [[package]] From 550c24818cacb4e07fe155384481cce7d9431408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 1 Aug 2023 22:16:07 +0100 Subject: [PATCH 24/41] publicly export upnp::Event - rename gateway addr to external_addr. --- protocols/upnp/src/behaviour.rs | 4 ++-- protocols/upnp/src/lib.rs | 2 ++ protocols/upnp/src/provider.rs | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index efa00167dee..df037376ae4 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -440,7 +440,7 @@ where { MappingState::Pending => { let external_multiaddr = - mapping.external_addr(gateway.addr); + mapping.external_addr(gateway.external_addr); self.pending_events.push_back(Event::NewExternalAddr( external_multiaddr.clone(), )); @@ -476,7 +476,7 @@ where mapping.protocol ); let external_multiaddr = - mapping.external_addr(gateway.addr); + mapping.external_addr(gateway.external_addr); self.pending_events.push_back(Event::ExpiredExternalAddr( external_multiaddr.clone(), )); diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index c62111b0ba7..37dca2a78a4 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -35,6 +35,8 @@ use std::{ time::Duration, }; +pub use behaviour::Event; + #[cfg(feature = "async-std")] pub use provider::async_std; #[cfg(feature = "tokio")] diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index b15c2d4a7e2..c8eba8ca557 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -32,7 +32,7 @@ use futures::channel::mpsc::{Receiver, Sender}; pub struct Gateway { pub(crate) sender: Sender, pub(crate) receiver: Receiver, - pub(crate) addr: IpAddr, + pub(crate) external_addr: IpAddr, } /// Abstraction to allow for compatibility with various async runtimes. @@ -60,7 +60,7 @@ macro_rules! impl_provider { timeout: config.timeout, }; let gateway = $gateway::search_gateway(options).await?; - let addr = gateway.get_external_ip().await?; + let external_addr = gateway.get_external_ip().await?; let (events_sender, mut task_receiver) = mpsc::channel(10); let (mut task_sender, events_queue) = mpsc::channel(0); @@ -111,7 +111,7 @@ macro_rules! impl_provider { Ok(Gateway { sender: events_sender, receiver: events_queue, - addr, + external_addr, }) } } From 82cfe2afd2f19fc2a6a55151c0bde413561d62ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Tue, 1 Aug 2023 22:16:37 +0100 Subject: [PATCH 25/41] add upnp-example --- Cargo.lock | 11 ++++- Cargo.toml | 1 + examples/upnp-example/Cargo.toml | 12 +++++ examples/upnp-example/README.md | 23 +++++++++ examples/upnp-example/src/main.rs | 81 +++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 examples/upnp-example/Cargo.toml create mode 100644 examples/upnp-example/README.md create mode 100644 examples/upnp-example/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9e0ba4ea807..4e847a3e050 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4376,7 +4376,6 @@ version = "0.1.0" dependencies = [ "async-std", "async-trait", - "env_logger 0.10.0", "futures", "libp2p", ] @@ -6514,6 +6513,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "upnp-example" +version = "0.1.0" +dependencies = [ + "async-std", + "async-trait", + "futures", + "libp2p", +] + [[package]] name = "url" version = "2.4.0" diff --git a/Cargo.toml b/Cargo.toml index 1f1ac5b8a29..f014780d97f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "examples/ping-example", "examples/relay-server", "examples/rendezvous", + "examples/upnp-example", "identity", "interop-tests", "misc/allow-block-list", diff --git a/examples/upnp-example/Cargo.toml b/examples/upnp-example/Cargo.toml new file mode 100644 index 00000000000..9b40a2b265f --- /dev/null +++ b/examples/upnp-example/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "upnp-example" +version = "0.1.0" +edition = "2021" +publish = false +license = "MIT" + +[dependencies] +async-std = { version = "1.12", features = ["attributes"] } +async-trait = "0.1" +futures = "0.3.28" +libp2p = { path = "../../libp2p", features = ["async-std", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } diff --git a/examples/upnp-example/README.md b/examples/upnp-example/README.md new file mode 100644 index 00000000000..c78bf31cd4f --- /dev/null +++ b/examples/upnp-example/README.md @@ -0,0 +1,23 @@ +## Description + +The upnp example showcases how to use the upnp network behaviour to externally open ports on the +network gateway. + +## Usage + +To run the example, follow these steps: + +1. In a first terminal window, run the following command: + + ```sh + cargo run + ``` + +2. This command will start the swarm and print the `NewExternalAddr` if the gateway supports `UPnP` or + `GatewayNotFound` if it doesn't. + + +## Conclusion + +The upnp example demonstrates the usage of **libp2p** to externally open a port on the gateway if it +supports [`UPnP`](https://en.wikipedia.org/wiki/Universal_Plug_and_Play). diff --git a/examples/upnp-example/src/main.rs b/examples/upnp-example/src/main.rs new file mode 100644 index 00000000000..ff10ed47b12 --- /dev/null +++ b/examples/upnp-example/src/main.rs @@ -0,0 +1,81 @@ +// Copyright 2023 Protocol Labs. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#![doc = include_str!("../README.md")] + +use futures::prelude::*; +use libp2p::core::upgrade::Version; +use libp2p::{ + identity, noise, + swarm::{SwarmBuilder, SwarmEvent}, + tcp, upnp, yamux, Multiaddr, PeerId, Transport, +}; +use std::error::Error; + +#[async_std::main] +async fn main() -> Result<(), Box> { + let local_key = identity::Keypair::generate_ed25519(); + let local_peer_id = PeerId::from(local_key.public()); + println!("Local peer id: {local_peer_id:?}"); + + let transport = tcp::async_io::Transport::default() + .upgrade(Version::V1Lazy) + .authenticate(noise::Config::new(&local_key)?) + .multiplex(yamux::Config::default()) + .boxed(); + + let config = upnp::Config::new().temporary(false); + let mut swarm = SwarmBuilder::with_async_std_executor( + transport, + upnp::async_std::Behaviour::new(config), + local_peer_id, + ) + .build(); + + // Tell the swarm to listen on all interfaces and a random, OS-assigned + // port. + swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; + + // Dial the peer identified by the multi-address given as the second + // command-line argument, if any. + if let Some(addr) = std::env::args().nth(1) { + let remote: Multiaddr = addr.parse()?; + swarm.dial(remote)?; + println!("Dialed {addr}") + } + + loop { + match swarm.select_next_some().await { + SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), + SwarmEvent::Behaviour(event) => match event { + upnp::Event::NewExternalAddr(addr) => { + println!("New external address: {addr}"); + } + upnp::Event::GatewayNotFound => { + println!("Gateway does not support UPnP"); + break; + } + _ => {} + }, + _ => {} + } + } + Ok(()) +} From b599fafa99157925cf94c224970956bf1fd8e282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 2 Aug 2023 23:33:53 +0100 Subject: [PATCH 26/41] address Thomas review --- Cargo.toml | 2 +- examples/{upnp-example => upnp}/Cargo.toml | 0 examples/{upnp-example => upnp}/README.md | 6 +++--- examples/{upnp-example => upnp}/src/main.rs | 7 +++++-- libp2p/CHANGELOG.md | 3 ++- protocols/upnp/CHANGELOG.md | 2 +- protocols/upnp/Cargo.toml | 4 ++-- protocols/upnp/src/lib.rs | 2 +- 8 files changed, 15 insertions(+), 11 deletions(-) rename examples/{upnp-example => upnp}/Cargo.toml (100%) rename examples/{upnp-example => upnp}/README.md (82%) rename examples/{upnp-example => upnp}/src/main.rs (92%) diff --git a/Cargo.toml b/Cargo.toml index f014780d97f..db59c12a822 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ members = [ "examples/ping-example", "examples/relay-server", "examples/rendezvous", - "examples/upnp-example", + "examples/upnp", "identity", "interop-tests", "misc/allow-block-list", diff --git a/examples/upnp-example/Cargo.toml b/examples/upnp/Cargo.toml similarity index 100% rename from examples/upnp-example/Cargo.toml rename to examples/upnp/Cargo.toml diff --git a/examples/upnp-example/README.md b/examples/upnp/README.md similarity index 82% rename from examples/upnp-example/README.md rename to examples/upnp/README.md index c78bf31cd4f..48335bfa9fc 100644 --- a/examples/upnp-example/README.md +++ b/examples/upnp/README.md @@ -1,13 +1,13 @@ ## Description -The upnp example showcases how to use the upnp network behaviour to externally open ports on the -network gateway. +The upnp example showcases how to use the upnp network behaviour to externally open ports on the network gateway. + ## Usage To run the example, follow these steps: -1. In a first terminal window, run the following command: +1. In a terminal window, run the following command: ```sh cargo run diff --git a/examples/upnp-example/src/main.rs b/examples/upnp/src/main.rs similarity index 92% rename from examples/upnp-example/src/main.rs rename to examples/upnp/src/main.rs index ff10ed47b12..77f842aafa2 100644 --- a/examples/upnp-example/src/main.rs +++ b/examples/upnp/src/main.rs @@ -41,10 +41,9 @@ async fn main() -> Result<(), Box> { .multiplex(yamux::Config::default()) .boxed(); - let config = upnp::Config::new().temporary(false); let mut swarm = SwarmBuilder::with_async_std_executor( transport, - upnp::async_std::Behaviour::new(config), + upnp::async_std::Behaviour::new(upnp::Config::new()), local_peer_id, ) .build(); @@ -72,6 +71,10 @@ async fn main() -> Result<(), Box> { println!("Gateway does not support UPnP"); break; } + upnp::Event::NonRoutableGateway => { + println!("Gateway is not exposed directly to the public network."); + break; + } _ => {} }, _ => {} diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 2b6827ff6f8..0d3c4506525 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -6,7 +6,8 @@ - Add `json` feature which exposes `request_response::json`. See [PR 4188]. -- Add initial version of `upnp` protocol see [PR 4156] +- Add support for UPnP via the IGD protocol. + See [PR 4156]. [PR 4188]: https://github.com/libp2p/rust-libp2p/pull/4188 [PR 4217]: https://github.com/libp2p/rust-libp2p/pull/4217 diff --git a/protocols/upnp/CHANGELOG.md b/protocols/upnp/CHANGELOG.md index 51d1510cddd..60d76c2412c 100644 --- a/protocols/upnp/CHANGELOG.md +++ b/protocols/upnp/CHANGELOG.md @@ -1,3 +1,3 @@ -## 0.1.0 +## 0.1.0 - unreleased - Initial version diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 76a6206d8cf..2d0638e2b81 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -19,9 +19,9 @@ libp2p-swarm = { workspace = true } log = "0.4.19" void = "1.0.2" tokio = { version = "1.29", default-features = false, features = ["rt", "rt-multi-thread"], optional = true } -async-std = { version = "1.12.0"} +async-std = { version = "1.12.0", optional = true } [features] tokio = ["igd-next/aio_tokio", "dep:tokio"] -async-std = ["igd-next/aio_async_std"] +async-std = ["igd-next/aio_async_std", "dep:async-std"] diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 37dca2a78a4..66721d86512 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -56,7 +56,7 @@ pub struct Config { } impl Config { - /// Creates a new configuration for a UPnP transport: + /// Creates a new configuration for a UPnP [`NetworkBehaviour`]. pub fn new() -> Self { Self { bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), From f3e0fe83b47f1626207cb5d2a62c7e82cf3201e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 2 Aug 2023 23:34:42 +0100 Subject: [PATCH 27/41] check if the Gateway's external addres is public --- protocols/upnp/src/behaviour.rs | 33 +++++++++++++--- protocols/upnp/src/provider.rs | 70 +++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index df037376ae4..82bf1847f48 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -26,7 +26,7 @@ use std::{ error::Error, hash::{Hash, Hasher}, marker::PhantomData, - net::{IpAddr, SocketAddr, SocketAddrV4}, + net::{self, SocketAddr, SocketAddrV4}, ops::{Deref, DerefMut}, pin::Pin, task::{Context, Poll}, @@ -34,7 +34,7 @@ use std::{ }; use crate::{ - provider::{Gateway, Provider}, + provider::{Gateway, IpAddr, Provider}, Config, }; use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; @@ -88,9 +88,9 @@ impl Mapping { /// Given the input gateway address, calculate the /// open external `Multiaddr`. fn external_addr(&self, gateway_addr: IpAddr) -> Multiaddr { - let addr = match gateway_addr { - IpAddr::V4(ip) => multiaddr::Protocol::Ip4(ip), - IpAddr::V6(ip) => multiaddr::Protocol::Ip6(ip), + let addr = match gateway_addr.0 { + net::IpAddr::V4(ip) => multiaddr::Protocol::Ip4(ip), + net::IpAddr::V6(ip) => multiaddr::Protocol::Ip6(ip), }; self.multiaddr .replace(0, |_| Some(addr)) @@ -138,6 +138,7 @@ enum GatewayState { Searching(BoxFuture<'static, Result>>), Available(Gateway), GatewayNotFound, + NonRoutableGateway(IpAddr), } /// The event produced by `Behaviour`. @@ -149,6 +150,8 @@ pub enum Event { ExpiredExternalAddr(Multiaddr), /// The IGD gateway was not found. GatewayNotFound, + /// The Gateway is not exposed directly to the public network. + NonRoutableGateway, } /// A list of port mappings and its state. @@ -348,6 +351,12 @@ where "network gateway not found, UPnP port mapping of {multiaddr} discarded" ); } + GatewayState::NonRoutableGateway(addr) => { + log::debug!( + "the network gateway is not exposed to the public network, \ + it's ip is {addr}. UPnP port mapping of {multiaddr} discarded" + ); + } }; } FromSwarm::ExpiredListenAddr(ExpiredListenAddr { @@ -410,6 +419,17 @@ where GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { Poll::Ready(result) => match result { Ok(gateway) => { + if !gateway.external_addr.is_global() { + self.state = + GatewayState::NonRoutableGateway(gateway.external_addr); + log::debug!( + "the gateway is not routable, its address is {}", + gateway.external_addr + ); + return Poll::Ready(ToSwarm::GenerateEvent( + Event::NonRoutableGateway, + )); + } self.state = GatewayState::Available(gateway); } Err(err) => { @@ -533,6 +553,9 @@ where GatewayState::GatewayNotFound => { return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); } + GatewayState::NonRoutableGateway(_) => { + return Poll::Ready(ToSwarm::GenerateEvent(Event::NonRoutableGateway)); + } } } } diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index c8eba8ca557..1cdef605464 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -18,7 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use std::{error::Error, net::IpAddr}; +use std::{error::Error, fmt, net}; use crate::{ behaviour::{GatewayEvent, GatewayRequest}, @@ -27,6 +27,68 @@ use crate::{ use async_trait::async_trait; use futures::channel::mpsc::{Receiver, Sender}; +#[derive(Clone, Copy, Debug)] +pub(crate) struct IpAddr(pub(crate) net::IpAddr); + +impl fmt::Display for IpAddr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl IpAddr { + //TODO: remove when `IpAddr::is_global` stabilizes. + pub(crate) fn is_global(&self) -> bool { + match self.0 { + net::IpAddr::V4(ip) => { + !(ip.octets()[0] == 0 // "This network" + || ip.is_private() + // code for Ipv4::is_shared() + || (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) + || ip.is_loopback() + || ip.is_link_local() + // addresses reserved for future protocols (`192.0.0.0/24`) + ||(ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0) + || ip.is_documentation() + // code for Ipv4::is_benchmarking() + || (ip.octets()[0] == 198 && (ip.octets()[1] & 0xfe) == 18) + // code for Ipv4::is_reserved() + || (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) + || ip.is_broadcast()) + } + net::IpAddr::V6(ip) => { + !(ip.is_unspecified() + || ip.is_loopback() + // IPv4-mapped Address (`::ffff:0:0/96`) + || matches!(ip.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) + // IPv4-IPv6 Translat. (`64:ff9b:1::/48`) + || matches!(ip.segments(), [0x64, 0xff9b, 1, _, _, _, _, _]) + // Discard-Only Address Block (`100::/64`) + || matches!(ip.segments(), [0x100, 0, 0, 0, _, _, _, _]) + // IETF Protocol Assignments (`2001::/23`) + || (matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200) + && !( + // Port Control Protocol Anycast (`2001:1::1`) + u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001 + // Traversal Using Relays around NAT Anycast (`2001:1::2`) + || u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002 + // AMT (`2001:3::/32`) + || matches!(ip.segments(), [0x2001, 3, _, _, _, _, _, _]) + // AS112-v6 (`2001:4:112::/48`) + || matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) + // ORCHIDv2 (`2001:20::/28`) + || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F) + )) + // code for Ipv4::is_documentation() + || (ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8) + // code for Ipv4::is_unique_local() + || (ip.segments()[0] & 0xfe00) == 0xfc00 + // code for Ipv4::is_unicast_link_local() + || (ip.segments()[0] & 0xffc0) == 0xfe80) + } + } + } +} /// Interface that interacts with the inner gateway by messages, /// `GatewayRequest`s and `GatewayEvent`s. pub struct Gateway { @@ -35,6 +97,8 @@ pub struct Gateway { pub(crate) external_addr: IpAddr, } +impl Gateway {} + /// Abstraction to allow for compatibility with various async runtimes. #[async_trait] pub trait Provider { @@ -43,7 +107,7 @@ pub trait Provider { macro_rules! impl_provider { ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident) => { - use super::{Config, Gateway}; + use super::{Config, Gateway, IpAddr}; use crate::behaviour::{GatewayEvent, GatewayRequest}; use async_trait::async_trait; @@ -111,7 +175,7 @@ macro_rules! impl_provider { Ok(Gateway { sender: events_sender, receiver: events_queue, - external_addr, + external_addr: IpAddr(external_addr), }) } } From d5c2e82de02c061f0e0debe3266b96eba15cc5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 3 Aug 2023 10:17:25 +0100 Subject: [PATCH 28/41] cargo clippy --- protocols/upnp/src/provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 1cdef605464..d5e3255a6cb 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -77,7 +77,7 @@ impl IpAddr { // AS112-v6 (`2001:4:112::/48`) || matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) // ORCHIDv2 (`2001:20::/28`) - || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F) + || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if (0x20..=0x2F).contains(&b)) )) // code for Ipv4::is_documentation() || (ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8) From 1a81c76ade7c88585c08b0eea2eb198c68cb5f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 3 Aug 2023 10:23:13 +0100 Subject: [PATCH 29/41] fix docs --- protocols/upnp/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 66721d86512..7379e622d78 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -56,7 +56,7 @@ pub struct Config { } impl Config { - /// Creates a new configuration for a UPnP [`NetworkBehaviour`]. + /// Creates a new configuration for a UPnP [`libp2p_swarm::NetworkBehaviour`]. pub fn new() -> Self { Self { bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), From eb54f3abe1413a98930713d46e0c9ffee7142d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Mon, 7 Aug 2023 21:00:38 +0100 Subject: [PATCH 30/41] address review --- examples/upnp/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/upnp/src/main.rs b/examples/upnp/src/main.rs index 77f842aafa2..c9f82dfeba7 100644 --- a/examples/upnp/src/main.rs +++ b/examples/upnp/src/main.rs @@ -72,7 +72,7 @@ async fn main() -> Result<(), Box> { break; } upnp::Event::NonRoutableGateway => { - println!("Gateway is not exposed directly to the public network."); + println!("Gateway is not exposed directly to the public Internet, i.e. it itself has a private IP address."); break; } _ => {} From d631d3a08dfddb7754bcf823a3d717119b616e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 26 Aug 2023 13:45:48 +0100 Subject: [PATCH 31/41] remove config --- Cargo.lock | 6 ++--- protocols/upnp/src/behaviour.rs | 43 +++++++++++---------------------- protocols/upnp/src/lib.rs | 41 ------------------------------- protocols/upnp/src/provider.rs | 27 ++++++++++++--------- 4 files changed, 32 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed1b8813114..9c1ee6e51da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1381,7 +1381,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "platforms", - "rustc_version", + "rustc_version 0.4.0", "subtle", "zeroize", ] @@ -2396,7 +2396,7 @@ dependencies = [ "cookie 0.14.4", "futures-lite", "infer", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.12", "rand 0.7.3", "serde", "serde_json", @@ -5945,7 +5945,7 @@ dependencies = [ "log", "mime_guess", "once_cell", - "pin-project-lite 0.2.10", + "pin-project-lite 0.2.12", "rustls 0.18.1", "serde", "serde_json", diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 82bf1847f48..d3fd3a74127 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -33,10 +33,7 @@ use std::{ time::Duration, }; -use crate::{ - provider::{Gateway, IpAddr, Provider}, - Config, -}; +use crate::provider::{Gateway, IpAddr, Provider}; use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; use futures_timer::Delay; use igd_next::PortMappingProtocol; @@ -55,10 +52,7 @@ const MAPPING_TIMEOUT: u64 = MAPPING_DURATION as u64 / 2; /// A [`Gateway`] Request. #[derive(Debug)] pub(crate) enum GatewayRequest { - AddMapping { - mapping: Mapping, - duration: Option, - }, + AddMapping { mapping: Mapping, duration: u32 }, RemoveMapping(Mapping), } @@ -129,8 +123,6 @@ enum MappingState { Active(Delay), /// Port mapping failed, we will try again. Failed, - /// Port mapping is permanent on the Gateway. - Permanent, } /// Current state of the UPnP [`Gateway`]. @@ -175,11 +167,11 @@ impl DerefMut for MappingList { impl MappingList { /// Queue for renewal the current mapped ports on the `Gateway` that are expiring, /// and try to activate the inactive. - fn renew(&mut self, config: &Config, gateway: &mut Gateway, cx: &mut Context<'_>) { + fn renew(&mut self, gateway: &mut Gateway, cx: &mut Context<'_>) { for (mapping, state) in self.iter_mut() { match state { MappingState::Inactive | MappingState::Failed => { - let duration = config.temporary.then_some(MAPPING_DURATION); + let duration = MAPPING_DURATION; if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { mapping: mapping.clone(), duration, @@ -194,7 +186,7 @@ impl MappingList { } MappingState::Active(timeout) => { if Pin::new(timeout).poll(cx).is_ready() { - let duration = config.temporary.then_some(MAPPING_DURATION); + let duration = MAPPING_DURATION; if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { mapping: mapping.clone(), duration, @@ -207,7 +199,7 @@ impl MappingList { } } } - MappingState::Pending | MappingState::Permanent => {} + MappingState::Pending => {} } } } @@ -219,8 +211,6 @@ pub struct Behaviour

where P: Provider, { - /// Gateway config. - config: Config, /// UPnP interface state. state: GatewayState, @@ -239,7 +229,7 @@ where P: Provider + 'static, { fn default() -> Self { - Self::new(Config::default()) + Self::new() } } @@ -248,10 +238,9 @@ where P: Provider + 'static, { /// Builds a new `UPnP` behaviour. - pub fn new(config: Config) -> Self { + pub fn new() -> Self { Self { - config, - state: GatewayState::Searching(P::search_gateway(config).boxed()), + state: GatewayState::Searching(P::search_gateway().boxed()), mappings: Default::default(), pending_events: VecDeque::new(), provider: PhantomData, @@ -332,7 +321,7 @@ where multiaddr: multiaddr.clone(), }; - let duration = self.config.temporary.then_some(MAPPING_DURATION); + let duration = MAPPING_DURATION; if let Err(err) = gateway.sender.try_send(GatewayRequest::AddMapping { mapping: mapping.clone(), duration, @@ -445,13 +434,9 @@ where if let Poll::Ready(Some(result)) = gateway.receiver.poll_next_unpin(cx) { match result { GatewayEvent::Mapped(mapping) => { - let new_state = if self.config.temporary { - MappingState::Active(Delay::new(Duration::from_secs( - MAPPING_TIMEOUT, - ))) - } else { - MappingState::Permanent - }; + let new_state = MappingState::Active(Delay::new( + Duration::from_secs(MAPPING_TIMEOUT), + )); match self .mappings @@ -547,7 +532,7 @@ where } // Renew expired and request inactive mappings. - self.mappings.renew(&self.config, gateway, cx); + self.mappings.renew(gateway, cx); return Poll::Pending; } GatewayState::GatewayNotFound => { diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 7379e622d78..b15981ff589 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -30,50 +30,9 @@ mod behaviour; mod provider; -use std::{ - net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - time::Duration, -}; - pub use behaviour::Event; #[cfg(feature = "async-std")] pub use provider::async_std; #[cfg(feature = "tokio")] pub use provider::tokio; - -/// The configuration for UPnP capabilities for libp2p. -#[derive(Clone, Copy, Debug)] -pub struct Config { - /// Bind address for UDP socket (defaults to all `0.0.0.0`). - bind_addr: SocketAddr, - /// Broadcast address for discovery packets (defaults to `239.255.255.250:1900`). - broadcast_addr: SocketAddr, - /// Timeout for a search iteration (defaults to 10s). - timeout: Option, - /// Should the port mappings be temporary (1 hour) or permanent. - temporary: bool, -} - -impl Config { - /// Creates a new configuration for a UPnP [`libp2p_swarm::NetworkBehaviour`]. - pub fn new() -> Self { - Self { - bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), - broadcast_addr: "239.255.255.250:1900".parse().unwrap(), - timeout: Some(Duration::from_secs(10)), - temporary: true, - } - } - - /// Configures the port mappings to be temporary (1 hour) or permanent. - pub fn temporary(self, temporary: bool) -> Self { - Self { temporary, ..self } - } -} - -impl Default for Config { - fn default() -> Self { - Self::new() - } -} diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index d5e3255a6cb..11e7f2b27cc 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -20,10 +20,7 @@ use std::{error::Error, fmt, net}; -use crate::{ - behaviour::{GatewayEvent, GatewayRequest}, - Config, -}; +use crate::behaviour::{GatewayEvent, GatewayRequest}; use async_trait::async_trait; use futures::channel::mpsc::{Receiver, Sender}; @@ -102,14 +99,19 @@ impl Gateway {} /// Abstraction to allow for compatibility with various async runtimes. #[async_trait] pub trait Provider { - async fn search_gateway(config: Config) -> Result>; + async fn search_gateway() -> Result>; } macro_rules! impl_provider { ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident) => { - use super::{Config, Gateway, IpAddr}; + use super::{Gateway, IpAddr}; use crate::behaviour::{GatewayEvent, GatewayRequest}; + use std::{ + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + time::Duration, + }; + use async_trait::async_trait; use futures::{channel::mpsc, SinkExt, StreamExt}; use igd_next::SearchOptions; @@ -117,11 +119,11 @@ macro_rules! impl_provider { #[async_trait] impl super::Provider for $impl { - async fn search_gateway(config: Config) -> Result> { + async fn search_gateway() -> Result> { let options = SearchOptions { - bind_addr: config.bind_addr, - broadcast_address: config.broadcast_addr, - timeout: config.timeout, + bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), + broadcast_address: "239.255.255.250:1900".parse().unwrap(), + timeout: Some(Duration::from_secs(10)), }; let gateway = $gateway::search_gateway(options).await?; let external_addr = gateway.get_external_ip().await?; @@ -132,10 +134,11 @@ macro_rules! impl_provider { $executor::spawn(async move { loop { // The task sender has dropped so we can return. - let Some(req) = task_receiver.next().await else { return; }; + let Some(req) = task_receiver.next().await else { + return; + }; let event = match req { GatewayRequest::AddMapping { mapping, duration } => { - let duration = duration.unwrap_or(0); let gateway = gateway.clone(); match gateway .add_port( From fe3c94f01108d0ad294f7335219416e6bd365739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 26 Aug 2023 15:01:00 +0100 Subject: [PATCH 32/41] fix examples and feature flags --- examples/upnp/src/main.rs | 2 +- libp2p/Cargo.toml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/upnp/src/main.rs b/examples/upnp/src/main.rs index c9f82dfeba7..af84a40596d 100644 --- a/examples/upnp/src/main.rs +++ b/examples/upnp/src/main.rs @@ -43,7 +43,7 @@ async fn main() -> Result<(), Box> { let mut swarm = SwarmBuilder::with_async_std_executor( transport, - upnp::async_std::Behaviour::new(upnp::Config::new()), + upnp::async_std::Behaviour::new(), local_peer_id, ) .build(); diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index ca727535f2e..97fe30bd100 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -53,7 +53,8 @@ full = [ "upnp" ] -async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std"] +async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", +"libp2p-dns?/async-std", "libp2p-quic?/async-std", "libp2p-upnp?/async-std"] autonat = ["dep:libp2p-autonat"] cbor = ["libp2p-request-response?/cbor"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] @@ -83,7 +84,8 @@ secp256k1 = ["libp2p-identity/secp256k1"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tls = ["dep:libp2p-tls"] -tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio"] +tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", +"libp2p-quic?/tokio", "libp2p-upnp?/tokio"] uds = ["dep:libp2p-uds"] wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"] wasm-ext = ["dep:libp2p-wasm-ext"] From ef6fd56f076f61eabd0765d8a069ac5aab0ec34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sat, 26 Aug 2023 19:57:02 +0100 Subject: [PATCH 33/41] use SearchOptions::default --- protocols/upnp/src/provider.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 11e7f2b27cc..17b212a0fa1 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -107,11 +107,6 @@ macro_rules! impl_provider { use super::{Gateway, IpAddr}; use crate::behaviour::{GatewayEvent, GatewayRequest}; - use std::{ - net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - time::Duration, - }; - use async_trait::async_trait; use futures::{channel::mpsc, SinkExt, StreamExt}; use igd_next::SearchOptions; @@ -120,12 +115,7 @@ macro_rules! impl_provider { #[async_trait] impl super::Provider for $impl { async fn search_gateway() -> Result> { - let options = SearchOptions { - bind_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)), - broadcast_address: "239.255.255.250:1900".parse().unwrap(), - timeout: Some(Duration::from_secs(10)), - }; - let gateway = $gateway::search_gateway(options).await?; + let gateway = $gateway::search_gateway(SearchOptions::default()).await?; let external_addr = gateway.get_external_ip().await?; let (events_sender, mut task_receiver) = mpsc::channel(10); From e480e6157c8d5c9ca5b22a21e157500caab303ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Sun, 27 Aug 2023 13:14:54 +0100 Subject: [PATCH 34/41] feature gate everything --- protocols/upnp/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index b15981ff589..33304cb2481 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -27,9 +27,12 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#[cfg(any(feature = "async-std", feature = "tokio"))] mod behaviour; +#[cfg(any(feature = "async-std", feature = "tokio"))] mod provider; +#[cfg(any(feature = "async-std", feature = "tokio"))] pub use behaviour::Event; #[cfg(feature = "async-std")] From 029eaf6833a584013f33b06497ab6951e2630205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 31 Aug 2023 12:31:49 +0100 Subject: [PATCH 35/41] address review --- protocols/upnp/src/behaviour.rs | 14 ++----------- protocols/upnp/src/provider.rs | 35 ++++++++++++--------------------- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index d3fd3a74127..08d89384286 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -33,7 +33,7 @@ use std::{ time::Duration, }; -use crate::provider::{Gateway, IpAddr, Provider}; +use crate::provider::{is_addr_global, Gateway, IpAddr, Provider}; use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; use futures_timer::Delay; use igd_next::PortMappingProtocol; @@ -229,16 +229,6 @@ where P: Provider + 'static, { fn default() -> Self { - Self::new() - } -} - -impl

Behaviour

-where - P: Provider + 'static, -{ - /// Builds a new `UPnP` behaviour. - pub fn new() -> Self { Self { state: GatewayState::Searching(P::search_gateway().boxed()), mappings: Default::default(), @@ -408,7 +398,7 @@ where GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { Poll::Ready(result) => match result { Ok(gateway) => { - if !gateway.external_addr.is_global() { + if !is_addr_global(gateway.external_addr) { self.state = GatewayState::NonRoutableGateway(gateway.external_addr); log::debug!( diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 17b212a0fa1..af6f74b0cf5 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -18,27 +18,20 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use std::{error::Error, fmt, net}; +use std::{ + error::Error, + net::{self, IpAddr}, +}; use crate::behaviour::{GatewayEvent, GatewayRequest}; use async_trait::async_trait; use futures::channel::mpsc::{Receiver, Sender}; -#[derive(Clone, Copy, Debug)] -pub(crate) struct IpAddr(pub(crate) net::IpAddr); - -impl fmt::Display for IpAddr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl IpAddr { - //TODO: remove when `IpAddr::is_global` stabilizes. - pub(crate) fn is_global(&self) -> bool { - match self.0 { - net::IpAddr::V4(ip) => { - !(ip.octets()[0] == 0 // "This network" +//TODO: remove when `IpAddr::is_global` stabilizes. +pub(crate) fn is_addr_global(addr: IpAddr) -> bool { + match addr { + IpAddr::V4(ip) => { + !(ip.octets()[0] == 0 // "This network" || ip.is_private() // code for Ipv4::is_shared() || (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) @@ -52,9 +45,9 @@ impl IpAddr { // code for Ipv4::is_reserved() || (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) || ip.is_broadcast()) - } - net::IpAddr::V6(ip) => { - !(ip.is_unspecified() + } + IpAddr::V6(ip) => { + !(ip.is_unspecified() || ip.is_loopback() // IPv4-mapped Address (`::ffff:0:0/96`) || matches!(ip.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) @@ -82,10 +75,10 @@ impl IpAddr { || (ip.segments()[0] & 0xfe00) == 0xfc00 // code for Ipv4::is_unicast_link_local() || (ip.segments()[0] & 0xffc0) == 0xfe80) - } } } } + /// Interface that interacts with the inner gateway by messages, /// `GatewayRequest`s and `GatewayEvent`s. pub struct Gateway { @@ -94,8 +87,6 @@ pub struct Gateway { pub(crate) external_addr: IpAddr, } -impl Gateway {} - /// Abstraction to allow for compatibility with various async runtimes. #[async_trait] pub trait Provider { From e9b5cd6b389e978410b99a75a9bdbc345f5b465f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 1 Sep 2023 10:24:37 +0100 Subject: [PATCH 36/41] do not do io on the behaviour, use a oneshot channel in the provider instead. --- Cargo.lock | 2 -- examples/upnp/Cargo.toml | 1 - protocols/upnp/Cargo.toml | 1 - protocols/upnp/src/behaviour.rs | 46 +++++++++++++------------- protocols/upnp/src/provider.rs | 58 +++++++++++++++++++++++---------- 5 files changed, 65 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb371922bbd..971d1abf80f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3591,7 +3591,6 @@ name = "libp2p-upnp" version = "0.1.0" dependencies = [ "async-std", - "async-trait", "futures", "futures-timer", "igd-next", @@ -6576,7 +6575,6 @@ name = "upnp-example" version = "0.1.0" dependencies = [ "async-std", - "async-trait", "futures", "libp2p", ] diff --git a/examples/upnp/Cargo.toml b/examples/upnp/Cargo.toml index 9b40a2b265f..87789cb5efe 100644 --- a/examples/upnp/Cargo.toml +++ b/examples/upnp/Cargo.toml @@ -7,6 +7,5 @@ license = "MIT" [dependencies] async-std = { version = "1.12", features = ["attributes"] } -async-trait = "0.1" futures = "0.3.28" libp2p = { path = "../../libp2p", features = ["async-std", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 2d0638e2b81..99c193910d6 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -10,7 +10,6 @@ keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] [dependencies] -async-trait = "0.1.68" futures = "0.3.28" futures-timer = "3.0.2" igd-next = "0.14.2" diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index c754f027dd3..a33bbf04723 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -34,7 +34,7 @@ use std::{ }; use crate::provider::{is_addr_global, Gateway, Provider}; -use futures::{future::BoxFuture, Future, FutureExt, StreamExt}; +use futures::{channel::oneshot, Future, StreamExt}; use futures_timer::Delay; use igd_next::PortMappingProtocol; use libp2p_core::{multiaddr, transport::ListenerId, Endpoint, Multiaddr}; @@ -127,7 +127,7 @@ enum MappingState { /// Current state of the UPnP [`Gateway`]. enum GatewayState { - Searching(BoxFuture<'static, Result>>), + Searching(oneshot::Receiver>>), Available(Gateway), GatewayNotFound, NonRoutableGateway(IpAddr), @@ -230,7 +230,7 @@ where { fn default() -> Self { Self { - state: GatewayState::Searching(P::search_gateway().boxed()), + state: GatewayState::Searching(P::search_gateway()), mappings: Default::default(), pending_events: VecDeque::new(), provider: PhantomData, @@ -396,27 +396,29 @@ where loop { match self.state { GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) { - Poll::Ready(result) => match result { - Ok(gateway) => { - if !is_addr_global(gateway.external_addr) { - self.state = - GatewayState::NonRoutableGateway(gateway.external_addr); - log::debug!( - "the gateway is not routable, its address is {}", - gateway.external_addr - ); - return Poll::Ready(ToSwarm::GenerateEvent( - Event::NonRoutableGateway, - )); + Poll::Ready(result) => { + match result.expect("sender shouldn't have been dropped") { + Ok(gateway) => { + if !is_addr_global(gateway.external_addr) { + self.state = + GatewayState::NonRoutableGateway(gateway.external_addr); + log::debug!( + "the gateway is not routable, its address is {}", + gateway.external_addr + ); + return Poll::Ready(ToSwarm::GenerateEvent( + Event::NonRoutableGateway, + )); + } + self.state = GatewayState::Available(gateway); + } + Err(err) => { + log::debug!("could not find gateway: {err}"); + self.state = GatewayState::GatewayNotFound; + return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); } - self.state = GatewayState::Available(gateway); - } - Err(err) => { - log::debug!("could not find gateway: {err}"); - self.state = GatewayState::GatewayNotFound; - return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); } - }, + } Poll::Pending => return Poll::Pending, }, GatewayState::Available(ref mut gateway) => { diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs index 4a8b2c1b81e..02dca3b70fc 100644 --- a/protocols/upnp/src/provider.rs +++ b/protocols/upnp/src/provider.rs @@ -21,8 +21,7 @@ use std::{error::Error, net::IpAddr}; use crate::behaviour::{GatewayEvent, GatewayRequest}; -use async_trait::async_trait; -use futures::channel::mpsc::{Receiver, Sender}; +use futures::channel::{mpsc, oneshot}; //TODO: remove when `IpAddr::is_global` stabilizes. pub(crate) fn is_addr_global(addr: IpAddr) -> bool { @@ -78,16 +77,16 @@ pub(crate) fn is_addr_global(addr: IpAddr) -> bool { /// Interface that interacts with the inner gateway by messages, /// `GatewayRequest`s and `GatewayEvent`s. +#[derive(Debug)] pub struct Gateway { - pub(crate) sender: Sender, - pub(crate) receiver: Receiver, + pub(crate) sender: mpsc::Sender, + pub(crate) receiver: mpsc::Receiver, pub(crate) external_addr: IpAddr, } /// Abstraction to allow for compatibility with various async runtimes. -#[async_trait] pub trait Provider { - async fn search_gateway() -> Result>; + fn search_gateway() -> oneshot::Receiver>>; } macro_rules! impl_provider { @@ -95,21 +94,50 @@ macro_rules! impl_provider { use super::Gateway; use crate::behaviour::{GatewayEvent, GatewayRequest}; - use async_trait::async_trait; - use futures::{channel::mpsc, SinkExt, StreamExt}; + use futures::{ + channel::{mpsc, oneshot}, + SinkExt, StreamExt, + }; use igd_next::SearchOptions; use std::error::Error; - #[async_trait] impl super::Provider for $impl { - async fn search_gateway() -> Result> { - let gateway = $gateway::search_gateway(SearchOptions::default()).await?; - let external_addr = gateway.get_external_ip().await?; + fn search_gateway( + ) -> oneshot::Receiver>> { + let (search_result_sender, search_result_receiver) = oneshot::channel(); let (events_sender, mut task_receiver) = mpsc::channel(10); let (mut task_sender, events_queue) = mpsc::channel(0); $executor::spawn(async move { + let gateway = match $gateway::search_gateway(SearchOptions::default()).await { + Ok(gateway) => gateway, + Err(err) => { + search_result_sender + .send(Err(err.into())) + .expect("receiver shouldn't have been dropped"); + return; + } + }; + + let external_addr = match gateway.get_external_ip().await { + Ok(addr) => addr, + Err(err) => { + search_result_sender + .send(Err(err.into())) + .expect("receiver shouldn't have been dropped"); + return; + } + }; + + search_result_sender + .send(Ok(Gateway { + sender: events_sender, + receiver: events_queue, + external_addr, + })) + .expect("receiver shouldn't have been dropped"); + loop { // The task sender has dropped so we can return. let Some(req) = task_receiver.next().await else { @@ -153,11 +181,7 @@ macro_rules! impl_provider { } }); - Ok(Gateway { - sender: events_sender, - receiver: events_queue, - external_addr, - }) + search_result_receiver } } }; From ebc4fdb59f7ae80037b23a8348f66967d04eba53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Wed, 6 Sep 2023 18:46:40 +0100 Subject: [PATCH 37/41] replace example with tokio --- Cargo.lock | 30 +++++++++++++++--------------- examples/upnp/Cargo.toml | 4 ++-- examples/upnp/src/main.rs | 8 ++++---- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f0d207ac50..844a24a430b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1383,9 +1383,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "622178105f911d937a42cdb140730ba4a3ed2becd8ae6ce39c7d28b5d75d4588" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -1693,7 +1693,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.0", "ed25519", "rand_core 0.6.4", "serde", @@ -1897,9 +1897,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "file-sharing" @@ -3264,7 +3264,7 @@ name = "libp2p-noise" version = "0.43.1" dependencies = [ "bytes", - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.0", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -3824,9 +3824,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" dependencies = [ "hashbrown 0.14.0", ] @@ -5754,7 +5754,7 @@ dependencies = [ "aes-gcm 0.9.2", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.0", "rand_core 0.6.4", "ring", "rustc_version 0.4.0", @@ -6000,9 +6000,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.9" +version = "0.29.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d0e9cc2273cc8d31377bdd638d72e3ac3e5607b18621062b169d02787f1bab" +checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" dependencies = [ "cfg-if 1.0.0", "core-foundation-sys", @@ -6610,9 +6610,9 @@ dependencies = [ [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" dependencies = [ "asynchronous-codec", "bytes", @@ -6628,9 +6628,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" name = "upnp-example" version = "0.1.0" dependencies = [ - "async-std", "futures", "libp2p", + "tokio", ] [[package]] @@ -7312,7 +7312,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" dependencies = [ - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.0", "rand_core 0.6.4", "serde", "zeroize", diff --git a/examples/upnp/Cargo.toml b/examples/upnp/Cargo.toml index 87789cb5efe..afb8f61d2a2 100644 --- a/examples/upnp/Cargo.toml +++ b/examples/upnp/Cargo.toml @@ -6,6 +6,6 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12", features = ["attributes"] } +tokio = { version = "1", features = [ "rt-multi-thread", "macros"] } futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } +libp2p = { path = "../../libp2p", features = ["tokio", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } diff --git a/examples/upnp/src/main.rs b/examples/upnp/src/main.rs index 86ba0e50fc5..36f63e47b86 100644 --- a/examples/upnp/src/main.rs +++ b/examples/upnp/src/main.rs @@ -29,21 +29,21 @@ use libp2p::{ }; use std::error::Error; -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { let local_key = identity::Keypair::generate_ed25519(); let local_peer_id = PeerId::from(local_key.public()); println!("Local peer id: {local_peer_id:?}"); - let transport = tcp::async_io::Transport::default() + let transport = tcp::tokio::Transport::default() .upgrade(Version::V1Lazy) .authenticate(noise::Config::new(&local_key)?) .multiplex(yamux::Config::default()) .boxed(); - let mut swarm = SwarmBuilder::with_async_std_executor( + let mut swarm = SwarmBuilder::with_tokio_executor( transport, - upnp::async_std::Behaviour::default(), + upnp::tokio::Behaviour::default(), local_peer_id, ) .build(); From b642cd9a5e7c54d29dbb679ebef0ac80651d9c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 7 Sep 2023 13:10:43 +0100 Subject: [PATCH 38/41] deprecate async-std support --- Cargo.lock | 564 +++----------------------------- libp2p/Cargo.toml | 2 +- protocols/upnp/Cargo.toml | 2 - protocols/upnp/src/behaviour.rs | 24 +- protocols/upnp/src/lib.rs | 13 +- protocols/upnp/src/provider.rs | 213 ------------ protocols/upnp/src/tokio.rs | 169 ++++++++++ 7 files changed, 217 insertions(+), 770 deletions(-) delete mode 100644 protocols/upnp/src/provider.rs create mode 100644 protocols/upnp/src/tokio.rs diff --git a/Cargo.lock b/Cargo.lock index 99704bfd206..21d70a62e92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,20 +80,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "aes-gcm" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" -dependencies = [ - "aead 0.3.2", - "aes 0.6.0", - "cipher 0.2.5", - "ctr 0.6.0", - "ghash 0.3.1", - "subtle", -] - [[package]] name = "aes-gcm" version = "0.9.2" @@ -246,12 +232,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.4" @@ -267,11 +247,11 @@ dependencies = [ "asn1-rs-derive 0.1.0", "asn1-rs-impl", "displaydoc", - "nom 7.1.3", + "nom", "num-traits", "rusticata-macros", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -283,11 +263,11 @@ dependencies = [ "asn1-rs-derive 0.4.0", "asn1-rs-impl", "displaydoc", - "nom 7.1.3", + "nom", "num-traits", "rusticata-macros", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -352,16 +332,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-dup" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" -dependencies = [ - "futures-io", - "simple-mutex", -] - [[package]] name = "async-executor" version = "1.5.1" @@ -403,22 +373,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "async-h1" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8101020758a4fc3a7c326cb42aa99e9fa77cbfb76987c128ad956406fe1f70a7" -dependencies = [ - "async-channel", - "async-dup", - "async-std", - "futures-core", - "http-types", - "httparse", - "log", - "pin-project", -] - [[package]] name = "async-io" version = "1.13.0" @@ -527,19 +481,6 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" -[[package]] -name = "async-tls" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85a97c4a0ecce878efd3f945f119c78a646d8975340bca0398f9bb05c30cc52" -dependencies = [ - "futures-core", - "futures-io", - "rustls 0.18.1", - "webpki", - "webpki-roots 0.20.0", -] - [[package]] name = "async-trait" version = "0.1.73" @@ -680,12 +621,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.13.1" @@ -821,9 +756,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -1035,17 +970,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "config" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" -dependencies = [ - "lazy_static", - "nom 5.1.3", - "serde", -] - [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -1062,29 +986,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" -[[package]] -name = "const_fn" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" - -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "aes-gcm 0.8.0", - "base64 0.13.1", - "hkdf 0.10.0", - "hmac 0.10.1", - "percent-encoding", - "rand 0.8.5", - "sha2 0.9.9", - "time 0.2.27", - "version_check", -] - [[package]] name = "cookie" version = "0.16.2" @@ -1092,7 +993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.28", + "time", "version_check", ] @@ -1103,7 +1004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ "percent-encoding", - "time 0.3.28", + "time", "version_check", ] @@ -1141,12 +1042,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cpuid-bool" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - [[package]] name = "crc" version = "3.0.1" @@ -1241,16 +1136,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -1311,25 +1196,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "crypto-mac" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" -dependencies = [ - "cipher 0.2.5", -] - [[package]] name = "ctr" version = "0.7.0" @@ -1393,7 +1259,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "platforms", - "rustc_version 0.4.0", + "rustc_version", "subtle", "zeroize", ] @@ -1444,19 +1310,6 @@ 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 1.0.0", - "hashbrown 0.14.0", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "data-encoding" version = "2.4.0" @@ -1495,20 +1348,6 @@ dependencies = [ "log", ] -[[package]] -name = "deadpool" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d126179d86aee4556e54f5f3c6bf6d9884e7cc52cef82f77ee6f90a7747616d" -dependencies = [ - "async-trait", - "config", - "crossbeam-queue", - "num_cpus", - "serde", - "tokio", -] - [[package]] name = "der" version = "0.6.1" @@ -1539,7 +1378,7 @@ checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" dependencies = [ "asn1-rs 0.3.1", "displaydoc", - "nom 7.1.3", + "nom", "num-bigint", "num-traits", "rusticata-macros", @@ -1553,7 +1392,7 @@ checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ "asn1-rs 0.5.2", "displaydoc", - "nom 7.1.3", + "nom", "num-bigint", "num-traits", "rusticata-macros", @@ -1617,12 +1456,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "displaydoc" version = "0.2.4" @@ -1720,7 +1553,7 @@ dependencies = [ "ff 0.12.1", "generic-array", "group 0.12.1", - "hkdf 0.12.3", + "hkdf", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", "rand_core 0.6.4", @@ -1842,7 +1675,7 @@ dependencies = [ "mime", "serde", "serde_json", - "time 0.3.28", + "time", "tokio", "url", "webdriver", @@ -2088,7 +1921,7 @@ dependencies = [ "futures", "log", "ringbuf", - "rustc_version 0.4.0", + "rustc_version", ] [[package]] @@ -2126,16 +1959,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" -dependencies = [ - "opaque-debug", - "polyval 0.4.5", -] - [[package]] name = "ghash" version = "0.4.4" @@ -2273,16 +2096,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" -[[package]] -name = "hkdf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" -dependencies = [ - "digest 0.9.0", - "hmac 0.10.1", -] - [[package]] name = "hkdf" version = "0.12.3" @@ -2298,17 +2111,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - -[[package]] -name = "hmac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" -dependencies = [ - "crypto-mac 0.10.0", + "crypto-mac", "digest 0.9.0", ] @@ -2365,53 +2168,12 @@ dependencies = [ "pin-project-lite 0.2.13", ] -[[package]] -name = "http-client" -version = "6.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1947510dc91e2bf586ea5ffb412caad7673264e14bb39fb9078da114a94ce1a5" -dependencies = [ - "async-h1", - "async-std", - "async-tls", - "async-trait", - "cfg-if 1.0.0", - "dashmap", - "deadpool", - "futures", - "http-types", - "log", - "rustls 0.18.1", -] - [[package]] name = "http-range-header" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" -[[package]] -name = "http-types" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" -dependencies = [ - "anyhow", - "async-channel", - "async-std", - "base64 0.13.1", - "cookie 0.14.4", - "futures-lite", - "infer", - "pin-project-lite 0.2.13", - "rand 0.7.3", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "url", -] - [[package]] name = "httparse" version = "1.8.0" @@ -2545,7 +2307,6 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57e065e90a518ab5fedf79aa1e4b784e10f8e484a834f6bda85c42633a2cb7af" dependencies = [ - "async-std", "async-trait", "attohttpc", "bytes", @@ -2554,7 +2315,6 @@ dependencies = [ "hyper", "log", "rand 0.8.5", - "surf", "tokio", "url", "xmltree", @@ -2580,12 +2340,6 @@ dependencies = [ "hashbrown 0.14.0", ] -[[package]] -name = "infer" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" - [[package]] name = "inout" version = "0.1.3" @@ -2783,19 +2537,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec 0.5.2", - "bitflags 1.3.2", - "cfg-if 1.0.0", - "ryu", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.147" @@ -3110,7 +2851,7 @@ dependencies = [ name = "libp2p-kad" version = "0.44.4" dependencies = [ - "arrayvec 0.7.4", + "arrayvec", "async-std", "asynchronous-codec", "bytes", @@ -3599,7 +3340,6 @@ dependencies = [ name = "libp2p-upnp" version = "0.1.0" dependencies = [ - "async-std", "futures", "futures-timer", "igd-next", @@ -3679,7 +3419,7 @@ dependencies = [ "rw-stream-sink", "soketto", "url", - "webpki-roots 0.25.2", + "webpki-roots", ] [[package]] @@ -3969,9 +3709,9 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd59dcc2bbe70baabeac52cd22ae52c55eefe6c38ff11a9439f16a350a939f2" +checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" dependencies = [ "arbitrary", "core2", @@ -4102,17 +3842,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" -[[package]] -name = "nom" -version = "5.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" -dependencies = [ - "lexical-core", - "memchr", - "version_check", -] - [[package]] name = "nom" version = "7.1.3" @@ -4514,17 +4243,6 @@ dependencies = [ "universal-hash 0.4.0", ] -[[package]] -name = "polyval" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" -dependencies = [ - "cpuid-bool", - "opaque-debug", - "universal-hash 0.4.0", -] - [[package]] name = "polyval" version = "0.5.3" @@ -4588,12 +4306,6 @@ 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-macro-warning" version = "0.4.2" @@ -4853,7 +4565,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.28", + "time", "x509-parser 0.14.0", "yasna", ] @@ -5155,22 +4867,13 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver", ] [[package]] @@ -5179,7 +4882,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom 7.1.3", + "nom", ] [[package]] @@ -5209,19 +4912,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rustls" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" -dependencies = [ - "base64 0.12.3", - "log", - "ring", - "sct 0.6.1", - "webpki", -] - [[package]] name = "rustls" version = "0.19.1" @@ -5422,27 +5112,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "send_wrapper" version = "0.4.0" @@ -5500,17 +5175,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_qs" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", -] - [[package]] name = "serde_repr" version = "0.1.16" @@ -5547,15 +5211,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - [[package]] name = "sha1" version = "0.10.5" @@ -5567,12 +5222,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.9.9" @@ -5655,15 +5304,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simple-mutex" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" -dependencies = [ - "event-listener", -] - [[package]] name = "slab" version = "0.4.9" @@ -5717,7 +5357,7 @@ dependencies = [ "curve25519-dalek 4.1.0", "rand_core 0.6.4", "ring", - "rustc_version 0.4.0", + "rustc_version", "sha2 0.10.7", "subtle", ] @@ -5783,70 +5423,12 @@ dependencies = [ "der 0.7.8", ] -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1 0.6.1", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "stringmatch" version = "0.4.0" @@ -5896,28 +5478,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "surf" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718b1ae6b50351982dedff021db0def601677f2120938b070eadb10ba4038dd7" -dependencies = [ - "async-std", - "async-trait", - "cfg-if 1.0.0", - "futures-util", - "getrandom 0.2.10", - "http-client", - "http-types", - "log", - "mime_guess", - "once_cell", - "pin-project-lite 0.2.13", - "rustls 0.18.1", - "serde", - "serde_json", -] - [[package]] name = "syn" version = "1.0.109" @@ -6084,21 +5644,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros 0.1.1", - "version_check", - "winapi", -] - [[package]] name = "time" version = "0.3.28" @@ -6109,7 +5654,7 @@ dependencies = [ "itoa", "serde", "time-core", - "time-macros 0.2.14", + "time-macros", ] [[package]] @@ -6118,16 +5663,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - [[package]] name = "time-macros" version = "0.2.14" @@ -6137,19 +5672,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn 1.0.109", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -6387,7 +5909,7 @@ dependencies = [ "tokio-rustls", "tracing", "url", - "webpki-roots 0.25.2", + "webpki-roots", ] [[package]] @@ -6411,7 +5933,7 @@ dependencies = [ "tokio-rustls", "tracing", "trust-dns-proto", - "webpki-roots 0.25.2", + "webpki-roots", ] [[package]] @@ -6568,7 +6090,6 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -6787,7 +6308,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.28", + "time", "unicode-segmentation", "url", ] @@ -6802,15 +6323,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "webpki-roots" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.25.2" @@ -6846,7 +6358,7 @@ dependencies = [ "smol_str", "stun", "thiserror", - "time 0.3.28", + "time", "tokio", "turn", "url", @@ -6892,7 +6404,7 @@ dependencies = [ "curve25519-dalek 3.2.0", "der-parser 8.2.0", "elliptic-curve 0.12.3", - "hkdf 0.12.3", + "hkdf", "hmac 0.12.1", "log", "p256 0.11.1", @@ -6905,7 +6417,7 @@ dependencies = [ "rustls 0.19.1", "sec1 0.3.0", "serde", - "sha1 0.10.5", + "sha1", "sha2 0.10.7", "signature 1.6.4", "subtle", @@ -7000,7 +6512,7 @@ dependencies = [ "log", "rtcp", "rtp", - "sha1 0.10.5", + "sha1", "subtle", "thiserror", "tokio", @@ -7236,11 +6748,11 @@ dependencies = [ "data-encoding", "der-parser 7.0.0", "lazy_static", - "nom 7.1.3", + "nom", "oid-registry 0.4.0", "rusticata-macros", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -7254,12 +6766,12 @@ dependencies = [ "data-encoding", "der-parser 8.2.0", "lazy_static", - "nom 7.1.3", + "nom", "oid-registry 0.6.1", "ring", "rusticata-macros", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -7272,11 +6784,11 @@ dependencies = [ "data-encoding", "der-parser 8.2.0", "lazy_static", - "nom 7.1.3", + "nom", "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.28", + "time", ] [[package]] @@ -7315,7 +6827,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.28", + "time", ] [[package]] diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 97fe30bd100..10172de02bd 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -54,7 +54,7 @@ full = [ ] async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", -"libp2p-dns?/async-std", "libp2p-quic?/async-std", "libp2p-upnp?/async-std"] +"libp2p-dns?/async-std", "libp2p-quic?/async-std"] autonat = ["dep:libp2p-autonat"] cbor = ["libp2p-request-response?/cbor"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 99c193910d6..1bdf7c8c345 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -18,9 +18,7 @@ libp2p-swarm = { workspace = true } log = "0.4.19" void = "1.0.2" tokio = { version = "1.29", default-features = false, features = ["rt", "rt-multi-thread"], optional = true } -async-std = { version = "1.12.0", optional = true } [features] tokio = ["igd-next/aio_tokio", "dep:tokio"] -async-std = ["igd-next/aio_async_std", "dep:async-std"] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index a33bbf04723..f582e96e1e7 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -25,7 +25,6 @@ use std::{ collections::{HashMap, VecDeque}, error::Error, hash::{Hash, Hasher}, - marker::PhantomData, net::{self, IpAddr, SocketAddr, SocketAddrV4}, ops::{Deref, DerefMut}, pin::Pin, @@ -33,7 +32,7 @@ use std::{ time::Duration, }; -use crate::provider::{is_addr_global, Gateway, Provider}; +use crate::tokio::{is_addr_global, Gateway}; use futures::{channel::oneshot, Future, StreamExt}; use futures_timer::Delay; use igd_next::PortMappingProtocol; @@ -207,10 +206,7 @@ impl MappingList { /// A [`NetworkBehaviour`] for UPnP port mapping. Automatically tries to map the external port /// to an internal address on the gateway on a [`FromSwarm::NewListenAddr`]. -pub struct Behaviour

-where - P: Provider, -{ +pub struct Behaviour { /// UPnP interface state. state: GatewayState, @@ -219,29 +215,19 @@ where /// Pending behaviour events to be emitted. pending_events: VecDeque, - - /// Provider. - provider: PhantomData

, } -impl

Default for Behaviour

-where - P: Provider + 'static, -{ +impl Default for Behaviour { fn default() -> Self { Self { - state: GatewayState::Searching(P::search_gateway()), + state: GatewayState::Searching(crate::tokio::search_gateway()), mappings: Default::default(), pending_events: VecDeque::new(), - provider: PhantomData, } } } -impl

NetworkBehaviour for Behaviour

-where - P: Provider + 'static, -{ +impl NetworkBehaviour for Behaviour { type ConnectionHandler = dummy::ConnectionHandler; type ToSwarm = Event; diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index 33304cb2481..e0b139fe3c2 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -27,15 +27,10 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#[cfg(any(feature = "async-std", feature = "tokio"))] +#[cfg(feature = "tokio")] mod behaviour; -#[cfg(any(feature = "async-std", feature = "tokio"))] -mod provider; - -#[cfg(any(feature = "async-std", feature = "tokio"))] -pub use behaviour::Event; +#[cfg(feature = "tokio")] +pub mod tokio; -#[cfg(feature = "async-std")] -pub use provider::async_std; #[cfg(feature = "tokio")] -pub use provider::tokio; +pub use behaviour::Event; diff --git a/protocols/upnp/src/provider.rs b/protocols/upnp/src/provider.rs deleted file mode 100644 index 02dca3b70fc..00000000000 --- a/protocols/upnp/src/provider.rs +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2023 Protocol Labs. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use std::{error::Error, net::IpAddr}; - -use crate::behaviour::{GatewayEvent, GatewayRequest}; -use futures::channel::{mpsc, oneshot}; - -//TODO: remove when `IpAddr::is_global` stabilizes. -pub(crate) fn is_addr_global(addr: IpAddr) -> bool { - match addr { - IpAddr::V4(ip) => { - !(ip.octets()[0] == 0 // "This network" - || ip.is_private() - // code for Ipv4::is_shared() - || (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) - || ip.is_loopback() - || ip.is_link_local() - // addresses reserved for future protocols (`192.0.0.0/24`) - ||(ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0) - || ip.is_documentation() - // code for Ipv4::is_benchmarking() - || (ip.octets()[0] == 198 && (ip.octets()[1] & 0xfe) == 18) - // code for Ipv4::is_reserved() - || (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) - || ip.is_broadcast()) - } - IpAddr::V6(ip) => { - !(ip.is_unspecified() - || ip.is_loopback() - // IPv4-mapped Address (`::ffff:0:0/96`) - || matches!(ip.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) - // IPv4-IPv6 Translat. (`64:ff9b:1::/48`) - || matches!(ip.segments(), [0x64, 0xff9b, 1, _, _, _, _, _]) - // Discard-Only Address Block (`100::/64`) - || matches!(ip.segments(), [0x100, 0, 0, 0, _, _, _, _]) - // IETF Protocol Assignments (`2001::/23`) - || (matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200) - && !( - // Port Control Protocol Anycast (`2001:1::1`) - u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001 - // Traversal Using Relays around NAT Anycast (`2001:1::2`) - || u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002 - // AMT (`2001:3::/32`) - || matches!(ip.segments(), [0x2001, 3, _, _, _, _, _, _]) - // AS112-v6 (`2001:4:112::/48`) - || matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) - // ORCHIDv2 (`2001:20::/28`) - || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if (0x20..=0x2F).contains(&b)) - )) - // code for Ipv4::is_documentation() - || (ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8) - // code for Ipv4::is_unique_local() - || (ip.segments()[0] & 0xfe00) == 0xfc00 - // code for Ipv4::is_unicast_link_local() - || (ip.segments()[0] & 0xffc0) == 0xfe80) - } - } -} - -/// Interface that interacts with the inner gateway by messages, -/// `GatewayRequest`s and `GatewayEvent`s. -#[derive(Debug)] -pub struct Gateway { - pub(crate) sender: mpsc::Sender, - pub(crate) receiver: mpsc::Receiver, - pub(crate) external_addr: IpAddr, -} - -/// Abstraction to allow for compatibility with various async runtimes. -pub trait Provider { - fn search_gateway() -> oneshot::Receiver>>; -} - -macro_rules! impl_provider { - ($impl:ident, $executor: ident, $gateway:ident, $protocol: ident) => { - use super::Gateway; - use crate::behaviour::{GatewayEvent, GatewayRequest}; - - use futures::{ - channel::{mpsc, oneshot}, - SinkExt, StreamExt, - }; - use igd_next::SearchOptions; - use std::error::Error; - - impl super::Provider for $impl { - fn search_gateway( - ) -> oneshot::Receiver>> { - let (search_result_sender, search_result_receiver) = oneshot::channel(); - - let (events_sender, mut task_receiver) = mpsc::channel(10); - let (mut task_sender, events_queue) = mpsc::channel(0); - - $executor::spawn(async move { - let gateway = match $gateway::search_gateway(SearchOptions::default()).await { - Ok(gateway) => gateway, - Err(err) => { - search_result_sender - .send(Err(err.into())) - .expect("receiver shouldn't have been dropped"); - return; - } - }; - - let external_addr = match gateway.get_external_ip().await { - Ok(addr) => addr, - Err(err) => { - search_result_sender - .send(Err(err.into())) - .expect("receiver shouldn't have been dropped"); - return; - } - }; - - search_result_sender - .send(Ok(Gateway { - sender: events_sender, - receiver: events_queue, - external_addr, - })) - .expect("receiver shouldn't have been dropped"); - - loop { - // The task sender has dropped so we can return. - let Some(req) = task_receiver.next().await else { - return; - }; - let event = match req { - GatewayRequest::AddMapping { mapping, duration } => { - let gateway = gateway.clone(); - match gateway - .add_port( - mapping.protocol.into(), - mapping.internal_addr.port(), - mapping.internal_addr, - duration, - "rust-libp2p mapping", - ) - .await - { - Ok(()) => GatewayEvent::Mapped(mapping), - Err(err) => GatewayEvent::MapFailure(mapping, err.into()), - } - } - GatewayRequest::RemoveMapping(mapping) => { - let gateway = gateway.clone(); - match gateway - .remove_port( - mapping.protocol.into(), - mapping.internal_addr.port(), - ) - .await - { - Ok(()) => GatewayEvent::Removed(mapping), - Err(err) => GatewayEvent::RemovalFailure(mapping, err.into()), - } - } - }; - task_sender - .send(event) - .await - .expect("receiver should be available"); - } - }); - - search_result_receiver - } - } - }; -} - -#[cfg(feature = "tokio")] -pub mod tokio { - use igd_next::aio::tokio as aio_tokio; - - #[doc(hidden)] - pub struct Tokio; - impl_provider! {Tokio, tokio, aio_tokio, PortMappingProtocol} - - /// The type of a [`Behaviour`] using the `tokio` implementation. - pub type Behaviour = crate::behaviour::Behaviour; -} - -#[cfg(feature = "async-std")] -pub mod async_std { - use async_std::task; - use igd_next::aio::async_std as aio_async_std; - - #[doc(hidden)] - pub struct AsyncStd; - impl_provider! {AsyncStd, task, aio_async_std, PortMappingProtocol} - - /// The type of a [`Behaviour`] using the `async-std` implementation. - pub type Behaviour = crate::behaviour::Behaviour; -} diff --git a/protocols/upnp/src/tokio.rs b/protocols/upnp/src/tokio.rs new file mode 100644 index 00000000000..c6a40182b33 --- /dev/null +++ b/protocols/upnp/src/tokio.rs @@ -0,0 +1,169 @@ +// Copyright 2023 Protocol Labs. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{error::Error, net::IpAddr}; + +use crate::behaviour::{GatewayEvent, GatewayRequest}; +use futures::{ + channel::{mpsc, oneshot}, + SinkExt, StreamExt, +}; +use igd_next::SearchOptions; + +pub use crate::behaviour::Behaviour; + +//TODO: remove when `IpAddr::is_global` stabilizes. +pub(crate) fn is_addr_global(addr: IpAddr) -> bool { + match addr { + IpAddr::V4(ip) => { + !(ip.octets()[0] == 0 // "This network" + || ip.is_private() + // code for Ipv4::is_shared() + || (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) + || ip.is_loopback() + || ip.is_link_local() + // addresses reserved for future protocols (`192.0.0.0/24`) + ||(ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0) + || ip.is_documentation() + // code for Ipv4::is_benchmarking() + || (ip.octets()[0] == 198 && (ip.octets()[1] & 0xfe) == 18) + // code for Ipv4::is_reserved() + || (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) + || ip.is_broadcast()) + } + IpAddr::V6(ip) => { + !(ip.is_unspecified() + || ip.is_loopback() + // IPv4-mapped Address (`::ffff:0:0/96`) + || matches!(ip.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) + // IPv4-IPv6 Translat. (`64:ff9b:1::/48`) + || matches!(ip.segments(), [0x64, 0xff9b, 1, _, _, _, _, _]) + // Discard-Only Address Block (`100::/64`) + || matches!(ip.segments(), [0x100, 0, 0, 0, _, _, _, _]) + // IETF Protocol Assignments (`2001::/23`) + || (matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200) + && !( + // Port Control Protocol Anycast (`2001:1::1`) + u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001 + // Traversal Using Relays around NAT Anycast (`2001:1::2`) + || u128::from_be_bytes(ip.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002 + // AMT (`2001:3::/32`) + || matches!(ip.segments(), [0x2001, 3, _, _, _, _, _, _]) + // AS112-v6 (`2001:4:112::/48`) + || matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) + // ORCHIDv2 (`2001:20::/28`) + || matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if (0x20..=0x2F).contains(&b)) + )) + // code for Ipv4::is_documentation() + || (ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8) + // code for Ipv4::is_unique_local() + || (ip.segments()[0] & 0xfe00) == 0xfc00 + // code for Ipv4::is_unicast_link_local() + || (ip.segments()[0] & 0xffc0) == 0xfe80) + } + } +} + +/// Interface that interacts with the inner gateway by messages, +/// `GatewayRequest`s and `GatewayEvent`s. +#[derive(Debug)] +pub(crate) struct Gateway { + pub(crate) sender: mpsc::Sender, + pub(crate) receiver: mpsc::Receiver, + pub(crate) external_addr: IpAddr, +} + +pub(crate) fn search_gateway() -> oneshot::Receiver>> { + let (search_result_sender, search_result_receiver) = oneshot::channel(); + + let (events_sender, mut task_receiver) = mpsc::channel(10); + let (mut task_sender, events_queue) = mpsc::channel(0); + + tokio::spawn(async move { + let gateway = match igd_next::aio::tokio::search_gateway(SearchOptions::default()).await { + Ok(gateway) => gateway, + Err(err) => { + search_result_sender + .send(Err(err.into())) + .expect("receiver shouldn't have been dropped"); + return; + } + }; + + let external_addr = match gateway.get_external_ip().await { + Ok(addr) => addr, + Err(err) => { + search_result_sender + .send(Err(err.into())) + .expect("receiver shouldn't have been dropped"); + return; + } + }; + + search_result_sender + .send(Ok(Gateway { + sender: events_sender, + receiver: events_queue, + external_addr, + })) + .expect("receiver shouldn't have been dropped"); + + loop { + // The task sender has dropped so we can return. + let Some(req) = task_receiver.next().await else { + return; + }; + let event = match req { + GatewayRequest::AddMapping { mapping, duration } => { + let gateway = gateway.clone(); + match gateway + .add_port( + mapping.protocol, + mapping.internal_addr.port(), + mapping.internal_addr, + duration, + "rust-libp2p mapping", + ) + .await + { + Ok(()) => GatewayEvent::Mapped(mapping), + Err(err) => GatewayEvent::MapFailure(mapping, err.into()), + } + } + GatewayRequest::RemoveMapping(mapping) => { + let gateway = gateway.clone(); + match gateway + .remove_port(mapping.protocol, mapping.internal_addr.port()) + .await + { + Ok(()) => GatewayEvent::Removed(mapping), + Err(err) => GatewayEvent::RemovalFailure(mapping, err.into()), + } + } + }; + task_sender + .send(event) + .await + .expect("receiver should be available"); + } + }); + + search_result_receiver +} From 4c18dab2844aa38560c021da6266b680590a81ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 8 Sep 2023 09:08:54 +0100 Subject: [PATCH 39/41] address review --- Cargo.lock | 411 ++++++++++++++++++++------------------ libp2p/Cargo.toml | 6 +- protocols/upnp/Cargo.toml | 2 +- protocols/upnp/src/lib.rs | 5 +- 4 files changed, 224 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21d70a62e92..36ab96b3cfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] @@ -141,9 +141,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -162,23 +162,24 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.5.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" @@ -200,9 +201,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", "windows-sys", @@ -395,9 +396,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.8.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" dependencies = [ "event-listener", ] @@ -454,7 +455,7 @@ dependencies = [ "log", "memchr", "once_cell", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "pin-utils", "slab", "wasm-bindgen-futures", @@ -502,7 +503,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", ] [[package]] @@ -558,7 +559,7 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "rustversion", "serde", "serde_json", @@ -590,9 +591,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", @@ -671,9 +672,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "blake2" @@ -756,9 +757,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" dependencies = [ "serde", ] @@ -780,12 +781,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "ccm" @@ -903,19 +901,20 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.2" +version = "4.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3" dependencies = [ "clap_builder", "clap_derive", + "once_cell", ] [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98" dependencies = [ "anstream", "anstyle", @@ -925,9 +924,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -937,9 +936,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "colorchoice" @@ -956,7 +955,7 @@ dependencies = [ "bytes", "futures-core", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tokio-util", ] @@ -982,9 +981,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "cookie" @@ -997,17 +996,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "cookie" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -1165,9 +1153,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1249,9 +1237,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622178105f911d937a42cdb140730ba4a3ed2becd8ae6ce39c7d28b5d75d4588" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -1361,9 +1349,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", "pem-rfc7468 0.7.0", @@ -1398,12 +1386,6 @@ dependencies = [ "rusticata-macros", ] -[[package]] -name = "deranged" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" - [[package]] name = "derive_builder" version = "0.11.2" @@ -1502,7 +1484,7 @@ version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ - "der 0.7.8", + "der 0.7.7", "digest 0.10.7", "elliptic-curve 0.13.5", "rfc6979 0.4.0", @@ -1526,7 +1508,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.0", + "curve25519-dalek 4.0.0", "ed25519", "rand_core 0.6.4", "serde", @@ -1569,7 +1551,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", + "crypto-bigint 0.5.2", "digest 0.10.7", "ff 0.13.0", "generic-array", @@ -1584,9 +1566,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if 1.0.0", ] @@ -1634,9 +1616,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", @@ -1661,12 +1643,12 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fantoccini" -version = "0.20.0-rc.6" +version = "0.20.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01f6f1dccbd582d105616474d9651882fbf6b5e06b80794c11d594fdb9568dad" +checksum = "f5eb32b0001134a1d3b9e16010eb4b119451edf68446963a30a8130a0d056e98" dependencies = [ - "base64 0.21.3", - "cookie 0.17.0", + "base64 0.13.1", + "cookie", "futures-core", "futures-util", "http", @@ -1718,9 +1700,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" [[package]] name = "file-sharing" @@ -1836,7 +1818,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "waker-fn", ] @@ -1907,7 +1889,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "pin-utils", "slab", ] @@ -1981,9 +1963,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "glob" @@ -2027,9 +2009,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -2165,7 +2147,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", ] [[package]] @@ -2182,9 +2164,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "humantime" @@ -2208,7 +2190,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "socket2 0.4.9", "tokio", "tower-service", @@ -2218,18 +2200,17 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ - "futures-util", "http", "hyper", "log", - "rustls 0.21.7", + "rustls 0.20.8", "rustls-native-certs", "tokio", - "tokio-rustls", + "tokio-rustls 0.23.4", ] [[package]] @@ -2472,7 +2453,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.11", + "rustix 0.38.4", "windows-sys", ] @@ -2983,7 +2964,7 @@ name = "libp2p-noise" version = "0.43.1" dependencies = [ "bytes", - "curve25519-dalek 4.1.0", + "curve25519-dalek 4.0.0", "env_logger 0.10.0", "futures", "futures_ringbuf", @@ -3314,7 +3295,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "libp2p-yamux", - "rcgen", + "rcgen 0.10.0", "ring", "rustls 0.21.7", "rustls-webpki", @@ -3387,7 +3368,7 @@ dependencies = [ "quick-protobuf-codec", "quickcheck", "rand 0.8.5", - "rcgen", + "rcgen 0.10.0", "serde", "sha2 0.10.7", "stun", @@ -3415,7 +3396,7 @@ dependencies = [ "log", "parking_lot", "quicksink", - "rcgen", + "rcgen 0.10.0", "rw-stream-sink", "soketto", "url", @@ -3517,9 +3498,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" @@ -3542,9 +3523,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" dependencies = [ "hashbrown 0.14.0", ] @@ -3575,9 +3556,9 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "67827e6ea8ee8a7c4a72227ef4fc08957040acffdb5f122733b24fa12daff41b" [[package]] name = "md-5" @@ -3709,9 +3690,9 @@ dependencies = [ [[package]] name = "multihash" -version = "0.19.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +checksum = "2fd59dcc2bbe70baabeac52cd22ae52c55eefe6c38ff11a9439f16a350a939f2" dependencies = [ "arbitrary", "core2", @@ -3873,9 +3854,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -3913,9 +3894,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -3958,11 +3939,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags 2.4.0", + "bitflags 1.3.2", "cfg-if 1.0.0", "foreign-types", "libc", @@ -3990,9 +3971,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", @@ -4136,9 +4117,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -4172,7 +4153,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.7", "spki 0.7.2", ] @@ -4184,9 +4165,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "platforms" -version = "3.1.2" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "plotters" @@ -4228,7 +4209,7 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "windows-sys", ] @@ -4340,13 +4321,13 @@ dependencies = [ [[package]] name = "prometheus-client-derive-encode" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +checksum = "72b6a5217beb0ad503ee7fa752d451c905113d70721b937126158f3106a48cc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 1.0.109", ] [[package]] @@ -4415,7 +4396,7 @@ dependencies = [ "async-std", "bytes", "futures-io", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "quinn-proto", "quinn-udp", "rustc-hash", @@ -4427,9 +4408,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.4" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" +checksum = "f8c8bb234e70c863204303507d841e7fa2295e95c822b2bb4ca8ebf57f17b1cb" dependencies = [ "bytes", "rand 0.8.5", @@ -4444,9 +4425,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "6df19e284d93757a9fb91d63672f7741b129246a669db09d1c0063071debc0c0" dependencies = [ "bytes", "libc", @@ -4557,6 +4538,18 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rcgen" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +dependencies = [ + "pem", + "ring", + "time", + "yasna", +] + [[package]] name = "rcgen" version = "0.10.0" @@ -4582,7 +4575,7 @@ dependencies = [ "futures-util", "itoa", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "ryu", "tokio", "tokio-util", @@ -4690,7 +4683,7 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "serde", "serde_json", "serde_urlencoded", @@ -4901,14 +4894,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.11" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.5", + "linux-raw-sys 0.4.3", "windows-sys", ] @@ -4922,7 +4915,19 @@ dependencies = [ "log", "ring", "sct 0.6.1", - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", ] [[package]] @@ -5082,7 +5087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", - "der 0.7.8", + "der 0.7.7", "generic-array", "pkcs8 0.10.2", "subtle", @@ -5306,9 +5311,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -5354,7 +5359,7 @@ dependencies = [ "aes-gcm 0.9.2", "blake2", "chacha20poly1305", - "curve25519-dalek 4.1.0", + "curve25519-dalek 4.0.0", "rand_core 0.6.4", "ring", "rustc_version", @@ -5420,7 +5425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.7", ] [[package]] @@ -5520,9 +5525,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.10" +version = "0.29.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" +checksum = "a8d0e9cc2273cc8d31377bdd638d72e3ac3e5607b18621062b169d02787f1bab" dependencies = [ "cfg-if 1.0.0", "core-foundation-sys", @@ -5563,7 +5568,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand 2.0.0", "redox_syscall", - "rustix 0.38.11", + "rustix 0.38.4", "windows-sys", ] @@ -5584,7 +5589,7 @@ checksum = "bf0fe180d5f1f7dd32bb5f1a8d19231bb63dc9bbb1985e1dbb6f07163b6a8578" dependencies = [ "async-trait", "base64 0.21.3", - "cookie 0.16.2", + "cookie", "fantoccini", "futures", "http", @@ -5646,11 +5651,10 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ - "deranged", "itoa", "serde", "time-core", @@ -5665,9 +5669,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -5709,7 +5713,7 @@ dependencies = [ "mio", "num_cpus", "parking_lot", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "signal-hook-registry", "socket2 0.5.3", "tokio-macros", @@ -5737,6 +5741,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.8", + "tokio", + "webpki 0.22.0", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -5757,7 +5772,7 @@ dependencies = [ "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tracing", ] @@ -5771,7 +5786,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tower-layer", "tower-service", @@ -5784,7 +5799,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.3.3", "bytes", "futures-core", "futures-util", @@ -5795,7 +5810,7 @@ dependencies = [ "mime", "mime_guess", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tokio-util", "tower-layer", @@ -5823,7 +5838,7 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tracing-attributes", "tracing-core", ] @@ -5906,7 +5921,7 @@ dependencies = [ "thiserror", "tinyvec", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", "url", "webpki-roots", @@ -5930,7 +5945,7 @@ dependencies = [ "smallvec", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tracing", "trust-dns-proto", "webpki-roots", @@ -5996,9 +6011,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ "version_check", ] @@ -6058,9 +6073,9 @@ dependencies = [ [[package]] name = "unsigned-varint" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" dependencies = [ "asynchronous-codec", "bytes", @@ -6154,9 +6169,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", "winapi-util", @@ -6296,13 +6311,13 @@ dependencies = [ [[package]] name = "webdriver" -version = "0.48.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9ae70f0cb12332fe144def990a9e62b20db2361b8784f879bb2814aad6c763" +checksum = "9973cb72c8587d5ad5efdb91e663d36177dc37725e6c90ca86c626b0cc45c93f" dependencies = [ "base64 0.13.1", "bytes", - "cookie 0.16.2", + "cookie", "http", "log", "serde", @@ -6323,6 +6338,16 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki-roots" version = "0.25.2" @@ -6345,7 +6370,7 @@ dependencies = [ "log", "pem", "rand 0.8.5", - "rcgen", + "rcgen 0.10.0", "regex", "ring", "rtcp", @@ -6390,9 +6415,9 @@ dependencies = [ [[package]] name = "webrtc-dtls" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a00f4242f2db33307347bd5be53263c52a0331c96c14292118c9a6bb48d267" +checksum = "942be5bd85f072c3128396f6e5a9bfb93ca8c1939ded735d177b7bcba9a13d05" dependencies = [ "aes 0.6.0", "aes-gcm 0.10.2", @@ -6407,12 +6432,13 @@ dependencies = [ "hkdf", "hmac 0.12.1", "log", + "oid-registry 0.6.1", "p256 0.11.1", "p384", "pem", "rand 0.8.5", "rand_core 0.6.4", - "rcgen", + "rcgen 0.9.3", "ring", "rustls 0.19.1", "sec1 0.3.0", @@ -6423,9 +6449,9 @@ dependencies = [ "subtle", "thiserror", "tokio", - "webpki", + "webpki 0.21.4", "webrtc-util", - "x25519-dalek 2.0.0", + "x25519-dalek 2.0.0-pre.1", "x509-parser 0.13.2", ] @@ -6619,24 +6645,24 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.48.5", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" @@ -6646,9 +6672,9 @@ checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" @@ -6658,9 +6684,9 @@ checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" @@ -6670,9 +6696,9 @@ checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" @@ -6682,15 +6708,15 @@ checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" @@ -6700,9 +6726,9 @@ checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winreg" @@ -6727,13 +6753,12 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.0" +version = "2.0.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" dependencies = [ - "curve25519-dalek 4.1.0", + "curve25519-dalek 3.2.0", "rand_core 0.6.4", - "serde", "zeroize", ] diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 10172de02bd..6b11d7deec4 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -53,8 +53,7 @@ full = [ "upnp" ] -async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", -"libp2p-dns?/async-std", "libp2p-quic?/async-std"] +async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std"] autonat = ["dep:libp2p-autonat"] cbor = ["libp2p-request-response?/cbor"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] @@ -84,8 +83,7 @@ secp256k1 = ["libp2p-identity/secp256k1"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tls = ["dep:libp2p-tls"] -tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", -"libp2p-quic?/tokio", "libp2p-upnp?/tokio"] +tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio", "libp2p-upnp?/tokio"] uds = ["dep:libp2p-uds"] wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"] wasm-ext = ["dep:libp2p-wasm-ext"] diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 1bdf7c8c345..f599d085c14 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -17,7 +17,7 @@ libp2p-core = { workspace = true } libp2p-swarm = { workspace = true } log = "0.4.19" void = "1.0.2" -tokio = { version = "1.29", default-features = false, features = ["rt", "rt-multi-thread"], optional = true } +tokio = { version = "1.29", default-features = false, features = ["rt"], optional = true } [features] tokio = ["igd-next/aio_tokio", "dep:tokio"] diff --git a/protocols/upnp/src/lib.rs b/protocols/upnp/src/lib.rs index e0b139fe3c2..8a74d7e8f63 100644 --- a/protocols/upnp/src/lib.rs +++ b/protocols/upnp/src/lib.rs @@ -20,8 +20,9 @@ //! Implementation of UPnP port mapping for libp2p. //! -//! This crate provides a `tokio::Behaviour` and `async_std::Behaviour`, depending on the enabled features, which -//! implement the [`libp2p_swarm::NetworkBehaviour`] trait. This struct will automatically try to map the ports externally to internal +//! This crate provides a `tokio::Behaviour` which +//! implements the [`libp2p_swarm::NetworkBehaviour`] trait. +//! This struct will automatically try to map the ports externally to internal //! addresses on the gateway. //! From 1de13e802fe99e2d044ab5e5eeb9d6c4482e5d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Fri, 8 Sep 2023 12:28:08 +0100 Subject: [PATCH 40/41] address missing remark on review --- examples/upnp/src/main.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/examples/upnp/src/main.rs b/examples/upnp/src/main.rs index 36f63e47b86..b4350dc82ad 100644 --- a/examples/upnp/src/main.rs +++ b/examples/upnp/src/main.rs @@ -63,20 +63,17 @@ async fn main() -> Result<(), Box> { loop { match swarm.select_next_some().await { SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), - SwarmEvent::Behaviour(event) => match event { - upnp::Event::NewExternalAddr(addr) => { - println!("New external address: {addr}"); - } - upnp::Event::GatewayNotFound => { - println!("Gateway does not support UPnP"); - break; - } - upnp::Event::NonRoutableGateway => { - println!("Gateway is not exposed directly to the public Internet, i.e. it itself has a private IP address."); - break; - } - _ => {} - }, + SwarmEvent::Behaviour(upnp::Event::NewExternalAddr(addr)) => { + println!("New external address: {addr}"); + } + SwarmEvent::Behaviour(upnp::Event::GatewayNotFound) => { + println!("Gateway does not support UPnP"); + break; + } + SwarmEvent::Behaviour(upnp::Event::NonRoutableGateway) => { + println!("Gateway is not exposed directly to the public Internet, i.e. it itself has a private IP address."); + break; + } _ => {} } } From 4b68a48da1b52f350ca055f6512d22ce93714cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Mon, 11 Sep 2023 17:45:51 +0100 Subject: [PATCH 41/41] add publish false to overcome cargo semver --- protocols/upnp/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index f599d085c14..ab20496aa4b 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -8,6 +8,7 @@ license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] +publish = false [dependencies] futures = "0.3.28"