This commit is contained in:
John Smith 2022-08-22 13:27:26 -04:00
parent 53ae04aff9
commit 997eca05b6
14 changed files with 920 additions and 154 deletions

3
.gitmodules vendored
View File

@ -28,3 +28,6 @@
[submodule "external/hashlink"]
path = external/hashlink
url = ../hashlink.git
[submodule "external/rust-igd"]
path = external/rust-igd
url = git@gitlab.hackers.town:veilid/rust-igd.git

382
Cargo.lock generated
View File

@ -124,7 +124,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -218,7 +218,7 @@ dependencies = [
"slab",
"socket2",
"waker-fn",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -244,7 +244,7 @@ dependencies = [
"libc",
"once_cell",
"signal-hook",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -269,7 +269,7 @@ dependencies = [
"log",
"memchr",
"once_cell",
"pin-project-lite",
"pin-project-lite 0.2.9",
"pin-utils",
"slab",
"wasm-bindgen-futures",
@ -364,7 +364,7 @@ dependencies = [
"futures-io",
"futures-util",
"log",
"pin-project-lite",
"pin-project-lite 0.2.9",
"tungstenite 0.17.2",
]
@ -382,7 +382,7 @@ dependencies = [
"futures-util",
"pin-project 1.0.11",
"rustc_version",
"tokio",
"tokio 1.19.2",
"wasm-bindgen-futures",
]
@ -412,6 +412,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
[[package]]
name = "attohttpc"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247"
dependencies = [
"http",
"log",
"url",
"wildmatch",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -420,7 +432,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -782,7 +794,7 @@ dependencies = [
"num-integer",
"num-traits",
"time 0.1.44",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1067,11 +1079,11 @@ dependencies = [
"bitflags",
"crossterm_winapi",
"libc",
"mio",
"mio 0.8.4",
"parking_lot 0.12.1",
"signal-hook",
"signal-hook-mio",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1080,7 +1092,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1148,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
dependencies = [
"nix 0.24.1",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1165,7 +1177,7 @@ dependencies = [
"libc",
"log",
"signal-hook",
"tokio",
"tokio 1.19.2",
"unicode-segmentation",
"unicode-width",
]
@ -1210,7 +1222,7 @@ dependencies = [
"num",
"owning_ref",
"time 0.3.11",
"tokio",
"tokio 1.19.2",
"toml",
"unicode-segmentation",
"unicode-width",
@ -1350,7 +1362,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1670,9 +1682,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cef5c93884e5cef757f63446122c2f420713c3e03f85540d09485b9415983b4a"
dependencies = [
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"fuchsia-zircon-sys",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "funty"
version = "2.0.0"
@ -1738,7 +1766,7 @@ dependencies = [
"futures-io",
"memchr",
"parking",
"pin-project-lite",
"pin-project-lite 0.2.9",
"waker-fn",
]
@ -1788,7 +1816,7 @@ dependencies = [
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-project-lite 0.2.9",
"pin-utils",
"slab",
]
@ -1904,7 +1932,7 @@ dependencies = [
"http",
"indexmap",
"slab",
"tokio",
"tokio 1.19.2",
"tokio-util 0.7.3",
"tracing",
]
@ -2008,7 +2036,7 @@ checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
dependencies = [
"libc",
"match_cfg",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -2030,7 +2058,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes 1.1.0",
"http",
"pin-project-lite",
"pin-project-lite 0.2.9",
]
[[package]]
@ -2061,9 +2089,9 @@ dependencies = [
"httparse",
"httpdate",
"itoa 1.0.2",
"pin-project-lite",
"pin-project-lite 0.2.9",
"socket2",
"tokio",
"tokio 1.19.2",
"tower-service",
"tracing",
"want",
@ -2076,8 +2104,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper",
"pin-project-lite",
"tokio",
"pin-project-lite 0.2.9",
"tokio 1.19.2",
"tokio-io-timeout",
]
@ -2108,6 +2136,25 @@ dependencies = [
"libc",
]
[[package]]
name = "igd"
version = "0.12.0"
dependencies = [
"attohttpc",
"bytes 1.1.0",
"futures",
"http",
"hyper",
"log",
"rand 0.8.5",
"simplelog 0.9.0",
"tokio 0.2.25",
"tokio 0.3.7",
"tokio 1.19.2",
"url",
"xmltree",
]
[[package]]
name = "impl-codec"
version = "0.6.0"
@ -2192,6 +2239,15 @@ dependencies = [
"web-sys",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
dependencies = [
"libc",
]
[[package]]
name = "ipconfig"
version = "0.3.0"
@ -2200,7 +2256,7 @@ checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98"
dependencies = [
"socket2",
"widestring 0.5.1",
"winapi",
"winapi 0.3.9",
"winreg",
]
@ -2287,6 +2343,16 @@ dependencies = [
"tiny-keccak",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "keychain-services"
version = "0.0.2"
@ -2324,10 +2390,10 @@ dependencies = [
"serde",
"serde_cbor",
"serial_test",
"simplelog",
"simplelog 0.12.0",
"snailquote",
"tempfile",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -2427,7 +2493,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
dependencies = [
"cfg-if 1.0.0",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -2560,6 +2626,38 @@ dependencies = [
"adler",
]
[[package]]
name = "mio"
version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
dependencies = [
"cfg-if 0.1.10",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
"kernel32-sys",
"libc",
"log",
"miow 0.2.2",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
dependencies = [
"libc",
"log",
"miow 0.3.7",
"ntapi",
"winapi 0.3.9",
]
[[package]]
name = "mio"
version = "0.8.4"
@ -2572,6 +2670,38 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "mio-uds"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
dependencies = [
"iovec",
"libc",
"mio 0.6.23",
]
[[package]]
name = "miow"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
dependencies = [
"kernel32-sys",
"net2",
"winapi 0.2.8",
"ws2_32-sys",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "multimap"
version = "0.8.3"
@ -2654,6 +2784,17 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "net2"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
dependencies = [
"cfg-if 0.1.10",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "netlink-packet-core"
version = "0.4.1"
@ -2695,7 +2836,7 @@ dependencies = [
"log",
"netlink-packet-core",
"netlink-sys",
"tokio",
"tokio 1.19.2",
]
[[package]]
@ -2707,7 +2848,7 @@ dependencies = [
"futures",
"libc",
"log",
"tokio",
"tokio 1.19.2",
]
[[package]]
@ -2769,7 +2910,7 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -2939,7 +3080,7 @@ dependencies = [
"pin-project 1.0.11",
"rand 0.8.5",
"thiserror",
"tokio",
"tokio 1.19.2",
"tokio-stream",
]
@ -2958,7 +3099,7 @@ dependencies = [
"prost",
"protobuf",
"thiserror",
"tokio",
"tokio 1.19.2",
"tonic",
"tonic-build",
]
@ -3067,7 +3208,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3210,6 +3351,12 @@ dependencies = [
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -3266,7 +3413,7 @@ dependencies = [
"libc",
"log",
"wepoll-ffi",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3578,7 +3725,7 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3603,7 +3750,7 @@ dependencies = [
"spin 0.5.2",
"untrusted",
"web-sys",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3634,7 +3781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb"
dependencies = [
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3646,7 +3793,7 @@ dependencies = [
"libc",
"serde",
"serde_json",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3660,7 +3807,7 @@ dependencies = [
"netlink-proto",
"nix 0.22.3",
"thiserror",
"tokio",
"tokio 1.19.2",
]
[[package]]
@ -4079,7 +4226,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
"libc",
"mio",
"mio 0.8.4",
"signal-hook",
]
@ -4098,6 +4245,17 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4"
[[package]]
name = "simplelog"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bc0ffd69814a9b251d43afcabf96dad1b29f5028378056257be9e3fecc9f720"
dependencies = [
"chrono",
"log",
"termcolor",
]
[[package]]
name = "simplelog"
version = "0.12.0"
@ -4138,7 +4296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
dependencies = [
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4177,7 +4335,7 @@ dependencies = [
"async-channel",
"cfg-if 1.0.0",
"futures-core",
"pin-project-lite",
"pin-project-lite 0.2.9",
]
[[package]]
@ -4233,7 +4391,7 @@ dependencies = [
"ntapi",
"once_cell",
"rayon",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4253,7 +4411,7 @@ dependencies = [
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4317,7 +4475,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4372,6 +4530,34 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
dependencies = [
"bytes 0.5.6",
"iovec",
"lazy_static",
"libc",
"mio 0.6.23",
"mio-uds",
"pin-project-lite 0.1.12",
"slab",
]
[[package]]
name = "tokio"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46409491c9375a693ce7032101970a54f8a2010efb77e13f70788f0d84489e39"
dependencies = [
"autocfg",
"libc",
"mio 0.7.14",
"pin-project-lite 0.2.9",
]
[[package]]
name = "tokio"
version = "1.19.2"
@ -4381,15 +4567,15 @@ dependencies = [
"bytes 1.1.0",
"libc",
"memchr",
"mio",
"mio 0.8.4",
"num_cpus",
"once_cell",
"parking_lot 0.12.1",
"pin-project-lite",
"pin-project-lite 0.2.9",
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4398,8 +4584,8 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
dependencies = [
"pin-project-lite",
"tokio",
"pin-project-lite 0.2.9",
"tokio 1.19.2",
]
[[package]]
@ -4420,8 +4606,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
"pin-project-lite 0.2.9",
"tokio 1.19.2",
]
[[package]]
@ -4434,8 +4620,8 @@ dependencies = [
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
"pin-project-lite 0.2.9",
"tokio 1.19.2",
]
[[package]]
@ -4448,8 +4634,8 @@ dependencies = [
"futures-core",
"futures-io",
"futures-sink",
"pin-project-lite",
"tokio",
"pin-project-lite 0.2.9",
"tokio 1.19.2",
"tracing",
]
@ -4483,7 +4669,7 @@ dependencies = [
"pin-project 1.0.11",
"prost",
"prost-derive",
"tokio",
"tokio 1.19.2",
"tokio-stream",
"tokio-util 0.6.10",
"tower",
@ -4515,10 +4701,10 @@ dependencies = [
"futures-util",
"indexmap",
"pin-project 1.0.11",
"pin-project-lite",
"pin-project-lite 0.2.9",
"rand 0.8.5",
"slab",
"tokio",
"tokio 1.19.2",
"tokio-util 0.7.3",
"tower-layer",
"tower-service",
@ -4545,7 +4731,7 @@ checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite",
"pin-project-lite 0.2.9",
"tracing-attributes",
"tracing-core",
]
@ -4688,7 +4874,7 @@ dependencies = [
"smallvec",
"thiserror",
"tinyvec",
"tokio",
"tokio 1.19.2",
"url",
]
@ -4708,7 +4894,7 @@ dependencies = [
"resolv-conf",
"smallvec",
"thiserror",
"tokio",
"tokio 1.19.2",
"trust-dns-proto",
]
@ -4907,7 +5093,7 @@ dependencies = [
"serde_derive",
"serial_test",
"thiserror",
"tokio",
"tokio 1.19.2",
"tokio-util 0.7.3",
"veilid-core",
]
@ -4950,6 +5136,7 @@ dependencies = [
"hashlink 0.8.0",
"hex",
"ifstructs",
"igd",
"jni",
"jni-sys",
"js-sys",
@ -4981,12 +5168,12 @@ dependencies = [
"serde_cbor",
"serde_json",
"serial_test",
"simplelog",
"simplelog 0.12.0",
"socket2",
"static_assertions",
"stop-token",
"thiserror",
"tokio",
"tokio 1.19.2",
"tokio-stream",
"tokio-util 0.7.3",
"tracing",
@ -5002,7 +5189,7 @@ dependencies = [
"webpki 0.22.0",
"webpki-roots 0.22.3",
"wee_alloc",
"winapi",
"winapi 0.3.9",
"windows",
"windows-permissions",
"ws_stream_wasm",
@ -5028,7 +5215,7 @@ dependencies = [
"parking_lot 0.12.1",
"serde",
"serde_json",
"tokio",
"tokio 1.19.2",
"tokio-stream",
"tokio-util 0.7.3",
"tracing",
@ -5072,7 +5259,7 @@ dependencies = [
"signal-hook",
"signal-hook-async-std",
"stop-token",
"tokio",
"tokio 1.19.2",
"tokio-stream",
"tokio-util 0.7.3",
"tracing",
@ -5126,7 +5313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi 0.3.9",
"winapi-util",
]
@ -5318,7 +5505,7 @@ dependencies = [
"cfg-if 0.1.10",
"libc",
"memory_units",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -5353,6 +5540,18 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983"
[[package]]
name = "wildmatch"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
version = "0.3.9"
@ -5363,6 +5562,12 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
@ -5375,7 +5580,7 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -5404,7 +5609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e2ccdc3c6bf4d4a094e031b63fadd08d8e42abd259940eb8aa5fdc09d4bf9be"
dependencies = [
"bitflags",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -5416,7 +5621,7 @@ dependencies = [
"bitflags",
"err-derive",
"widestring 0.4.3",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -5498,7 +5703,17 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
@ -5546,6 +5761,21 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a"
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "xmltree"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb"
dependencies = [
"xml-rs",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"

View File

@ -4,8 +4,6 @@ VERSION 0.6
# Ensure we are using an amd64 platform because some of these targets use cross-platform tooling
FROM --platform amd64 ubuntu:16.04
# Choose where Rust ends up
# Install build prerequisites
deps-base:
RUN apt-get -y update

1
external/rust-igd vendored Submodule

@ -0,0 +1 @@
Subproject commit 330c8e2ea33f6b9bd34809bb1c504459920f4fe2

View File

@ -73,6 +73,7 @@ config = { version = "^0", features = ["yaml"] }
keyring-manager = { path = "../external/keyring-manager" }
lru = "^0"
async-tls = "^0.11"
igd = { path = "../external/rust-igd" }
webpki = "^0"
webpki-roots = "^0"
rustls = "^0.19"

View File

@ -150,6 +150,23 @@ where
}
}
pub async fn blocking_wrapper<F, R>(blocking_task: F, err_result: R) -> R
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
// run blocking stuff in blocking thread
cfg_if! {
if #[cfg(feature="rt-async-std")] {
async_std::task::spawn_blocking(blocking_task).await
} else if #[cfg(feature="rt-tokio")] {
tokio::task::spawn_blocking(blocking_task).await.unwrap_or(err_result)
} else {
#[compile_error("must use an executor")]
}
}
}
pub fn get_concurrency() -> u32 {
std::thread::available_parallelism()
.map(|x| x.get())

View File

@ -64,7 +64,7 @@ pub fn veilid_version() -> (u32, u32, u32) {
#[cfg(target_os = "android")]
pub use intf::utils::android::{veilid_core_setup_android, veilid_core_setup_android_no_log};
pub static DEFAULT_LOG_IGNORE_LIST: [&str; 18] = [
pub static DEFAULT_LOG_IGNORE_LIST: [&str; 19] = [
"mio",
"h2",
"hyper",
@ -83,4 +83,5 @@ pub static DEFAULT_LOG_IGNORE_LIST: [&str; 18] = [
"netlink_sys",
"trust_dns_resolver",
"trust_dns_proto",
"attohttpc",
];

View File

@ -1642,8 +1642,8 @@ impl NetworkManager {
connection_descriptor: ConnectionDescriptor, // the connection descriptor used
reporting_peer: NodeRef, // the peer's noderef reporting the socket address
) {
// xxx debug code
info!("report_global_socket_address\nsocket_address: {:#?}\nconnection_descriptor: {:#?}\nreporting_peer: {:#?}", socket_address, connection_descriptor, reporting_peer);
// debug code
//info!("report_global_socket_address\nsocket_address: {:#?}\nconnection_descriptor: {:#?}\nreporting_peer: {:#?}", socket_address, connection_descriptor, reporting_peer);
let key = PublicAddressCheckCacheKey(
connection_descriptor.protocol_type(),
@ -1671,10 +1671,8 @@ impl NetworkManager {
let network_class = net.get_network_class().unwrap_or(NetworkClass::Invalid);
// Determine if our external address has likely changed
let needs_public_address_detection = if matches!(
network_class,
NetworkClass::InboundCapable
) {
let needs_public_address_detection =
if matches!(network_class, NetworkClass::InboundCapable) {
// Get the dial info filter for this connection so we can check if we have any public dialinfo that may have changed
let dial_info_filter = connection_descriptor.make_dial_info_filter();
@ -1708,11 +1706,11 @@ impl NetworkManager {
}
}
// xxx debug code
if changed {
info!("XXX\npublic_address_check_cache: {:#?}\ncurrent_addresses: {:#?}\ninconsistencies: {}", inner
.public_address_check_cache, current_addresses, inconsistencies);
}
// // debug code
// if changed {
// trace!("public_address_check_cache: {:#?}\ncurrent_addresses: {:#?}\ninconsistencies: {}", inner
// .public_address_check_cache, current_addresses, inconsistencies);
// }
changed
} else {

View File

@ -0,0 +1,380 @@
use super::*;
use crate::xx::*;
use igd::*;
use std::net::UdpSocket;
const UPNP_GATEWAY_DETECT_TIMEOUT_MS: u32 = 5_000;
const UPNP_MAPPING_LIFETIME_MS: u32 = 120_000;
const UPNP_MAPPING_ATTEMPTS: u32 = 3;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct PortMapKey {
llpt: LowLevelProtocolType,
at: AddressType,
local_port: u16,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct PortMapValue {
ext_ip: IpAddr,
mapped_port: u16,
timestamp: u64,
renewal_lifetime: u64,
renewal_attempts: u32,
}
struct IGDManagerInner {
local_ip_addrs: BTreeMap<AddressType, IpAddr>,
gateways: BTreeMap<AddressType, Arc<Gateway>>,
port_maps: BTreeMap<PortMapKey, PortMapValue>,
}
#[derive(Clone)]
pub struct IGDManager {
config: VeilidConfig,
inner: Arc<Mutex<IGDManagerInner>>,
}
fn convert_llpt(llpt: LowLevelProtocolType) -> PortMappingProtocol {
match llpt {
LowLevelProtocolType::UDP => PortMappingProtocol::UDP,
LowLevelProtocolType::TCP => PortMappingProtocol::TCP,
}
}
impl IGDManager {
//
pub fn new(config: VeilidConfig) -> Self {
Self {
config,
inner: Arc::new(Mutex::new(IGDManagerInner {
local_ip_addrs: BTreeMap::new(),
gateways: BTreeMap::new(),
port_maps: BTreeMap::new(),
})),
}
}
fn get_routed_local_ip_address(address_type: AddressType) -> Option<IpAddr> {
let socket = match UdpSocket::bind(match address_type {
AddressType::IPV4 => SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0),
AddressType::IPV6 => SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 0),
}) {
Ok(s) => s,
Err(_) => return None,
};
// can be any routable ip address,
// this is just to make the system routing table calculate the appropriate local ip address
// using google's dns, but it wont actually send any packets to it
socket
.connect(match address_type {
AddressType::IPV4 => SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 0),
AddressType::IPV6 => SocketAddr::new(
IpAddr::V6(Ipv6Addr::new(0x2001, 0x4860, 0x4860, 0, 0, 0, 0, 0x8888)),
0,
),
})
.ok()?;
Some(socket.local_addr().ok()?.ip())
}
fn find_local_ip(inner: &mut IGDManagerInner,
address_type: AddressType,
) -> Option<IpAddr> {
if let Some(ip) = inner.local_ip_addrs.get(&address_type) {
return Some(*ip);
}
let ip = match Self::get_routed_local_ip_address(address_type) {
Some(x) => x,
None => {
log_net!("failed to get local ip address");
return None;
}
};
inner.local_ip_addrs.insert(address_type, ip);
Some(ip)
}
fn get_local_ip(
inner: &mut IGDManagerInner,
address_type: AddressType,
) -> Option<IpAddr> {
if let Some(ip) = inner.local_ip_addrs.get(&address_type) {
return Some(*ip);
}
None
}
fn find_gateway(
inner: &mut IGDManagerInner,
address_type: AddressType,
) -> Option<Arc<Gateway>> {
if let Some(gw) = inner.gateways.get(&address_type) {
return Some(gw.clone());
}
let gateway = match address_type {
AddressType::IPV4 => {
match igd::search_gateway(SearchOptions::new_v4(
UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64,
)) {
Ok(v) => v,
Err(e) => {
log_net!("couldn't find ipv4 igd: {}", e);
return None;
}
}
}
AddressType::IPV6 => {
match igd::search_gateway(SearchOptions::new_v6(
Ipv6SearchScope::LinkLocal,
UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64,
)) {
Ok(v) => v,
Err(e) => {
log_net!("couldn't find ipv6 igd: {}", e);
return None;
}
}
}
};
let gw = Arc::new(gateway);
inner.gateways.insert(address_type, gw.clone());
Some(gw)
}
fn get_gateway(
inner: &mut IGDManagerInner,
address_type: AddressType,
) -> Option<Arc<Gateway>> {
if let Some(gw) = inner.gateways.get(&address_type) {
return Some(gw.clone());
}
None
}
fn get_description(&self, llpt: LowLevelProtocolType, local_port:u16) -> String {
format!("{} map {} for port {}", self.config.get().program_name, convert_llpt(llpt), local_port )
}
pub async fn map_any_port(
&self,
llpt: LowLevelProtocolType,
at: AddressType,
local_port: u16,
expected_external_address: Option<IpAddr>,
) -> Option<SocketAddr> {
let this = self.clone();
intf::blocking_wrapper(move || {
let mut inner = this.inner.lock();
// If we already have this port mapped, just return the existing portmap
let pmkey = PortMapKey {
llpt,
at,
local_port,
};
if let Some(pmval) = inner.port_maps.get(&pmkey) {
return Some(SocketAddr::new(pmval.ext_ip, pmval.mapped_port));
}
// Get local ip address
let local_ip = Self::find_local_ip(&mut *inner, at)?;
// Find gateway
let gw = Self::find_gateway(&mut *inner, at)?;
// Get external address
let ext_ip = match gw.get_external_ip() {
Ok(ip) => ip,
Err(e) => {
log_net!(debug "couldn't get external ip from igd: {}", e);
return None;
}
};
// Ensure external IP matches address type
if ext_ip.is_ipv4() {
if at != AddressType::IPV4 {
log_net!(debug "mismatched ip address type from igd, wanted v4, got v6");
return None;
}
} else if ext_ip.is_ipv6() {
if at != AddressType::IPV6 {
log_net!(debug "mismatched ip address type from igd, wanted v6, got v4");
return None;
}
}
if let Some(expected_external_address) = expected_external_address {
if ext_ip != expected_external_address {
log_net!(debug "gateway external address does not match calculated external address: expected={} vs gateway={}", expected_external_address, ext_ip);
return None;
}
}
// Map any port
let desc = this.get_description(llpt, local_port);
let mapped_port = match gw.add_any_port(convert_llpt(llpt), SocketAddr::new(local_ip, local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) {
Ok(mapped_port) => mapped_port,
Err(e) => {
// Failed to map external port
log_net!(debug "upnp failed to map external port: {}", e);
return None;
}
};
// Add to mapping list to keep alive
let timestamp = intf::get_timestamp();
inner.port_maps.insert(PortMapKey {
llpt,
at,
local_port,
}, PortMapValue {
ext_ip,
mapped_port,
timestamp,
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
renewal_attempts: 0,
});
// Succeeded, return the externally mapped port
Some(SocketAddr::new(ext_ip, mapped_port))
}, None)
.await
}
pub async fn tick(&self) -> EyreResult<bool> {
// Refresh mappings if we have them
// If an error is received, then return false to restart the local network
let mut full_renews: Vec<(PortMapKey, PortMapValue)> = Vec::new();
let mut renews: Vec<(PortMapKey, PortMapValue)> = Vec::new();
let now = intf::get_timestamp();
const UPNP_MAPPING_LIFETIME_US:u64 = (UPNP_MAPPING_LIFETIME_MS as u64) * 1000u64;
{
let inner = self.inner.lock();
for (k, v) in &inner.port_maps {
if (now - v.timestamp) >= UPNP_MAPPING_LIFETIME_US || v.renewal_attempts >= UPNP_MAPPING_ATTEMPTS {
// Past expiration time or tried N times, do a full renew and fail out if we can't
full_renews.push((*k, *v));
}
else if (now - v.timestamp) >= v.renewal_lifetime {
// Attempt a normal renewal
renews.push((*k, *v));
}
}
// See if we need to do some blocking operations
if full_renews.is_empty() && renews.is_empty() {
// Just return now since there's nothing to renew
return Ok(true);
}
}
let this = self.clone();
intf::blocking_wrapper(move || {
let mut inner = this.inner.lock();
// Process full renewals
for (k, v) in full_renews {
// Get gateway for address type
let gw = match Self::get_gateway(&mut inner, k.at) {
Some(gw) => gw,
None => {
return Err(eyre!("gateway missing for address type"));
}
};
// Get local ip for address type
let local_ip = match Self::get_local_ip(&mut inner, k.at) {
Some(ip) => ip,
None => {
return Err(eyre!("local ip missing for address type"));
}
};
// Delete the mapping if it exists, ignore any errors here
let _ = gw.remove_port(convert_llpt(k.llpt), v.mapped_port);
inner.port_maps.remove(&k);
let desc = this.get_description(k.llpt, k.local_port);
match gw.add_any_port(convert_llpt(k.llpt), SocketAddr::new(local_ip, k.local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) {
Ok(mapped_port) => {
log_net!(debug "full-renewed mapped port {:?} -> {:?}", v, k);
inner.port_maps.insert(k, PortMapValue {
ext_ip: v.ext_ip,
mapped_port,
timestamp: intf::get_timestamp(),
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
renewal_attempts: 0,
});
},
Err(e) => {
info!("failed to full-renew mapped port {:?} -> {:?}: {}", v, k, e);
// Must restart network now :(
return Ok(false);
}
};
}
// Process normal renewals
for (k, mut v) in renews {
// Get gateway for address type
let gw = match Self::get_gateway(&mut inner, k.at) {
Some(gw) => gw,
None => {
return Err(eyre!("gateway missing for address type"));
}
};
// Get local ip for address type
let local_ip = match Self::get_local_ip(&mut inner, k.at) {
Some(ip) => ip,
None => {
return Err(eyre!("local ip missing for address type"));
}
};
let desc = this.get_description(k.llpt, k.local_port);
match gw.add_port(convert_llpt(k.llpt), v.mapped_port, SocketAddr::new(local_ip, k.local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) {
Ok(()) => {
log_net!(debug "renewed mapped port {:?} -> {:?}", v, k);
inner.port_maps.insert(k, PortMapValue {
ext_ip: v.ext_ip,
mapped_port: v.mapped_port,
timestamp: intf::get_timestamp(),
renewal_lifetime: (UPNP_MAPPING_LIFETIME_MS / 2) as u64 * 1000u64,
renewal_attempts: 0,
});
},
Err(e) => {
log_net!(debug "failed to renew mapped port {:?} -> {:?}: {}", v, k, e);
// Get closer to the maximum renewal timeline by a factor of two each time
v.renewal_lifetime = (v.renewal_lifetime + UPNP_MAPPING_LIFETIME_US) / 2;
v.renewal_attempts += 1;
// Store new value to try again
inner.port_maps.insert(k, v);
}
};
}
// Normal exit, no restart
Ok(true)
}, Err(eyre!("failed to process blocking task"))).await
}
}

View File

@ -1,3 +1,5 @@
mod igd_manager;
mod natpmp_manager;
mod network_class_discovery;
mod network_tcp;
mod network_udp;
@ -67,6 +69,12 @@ struct NetworkUnlockedInner {
// Background processes
update_network_class_task: TickTask<EyreReport>,
network_interfaces_task: TickTask<EyreReport>,
upnp_task: TickTask<EyreReport>,
natpmp_task: TickTask<EyreReport>,
// Managers
igd_manager: igd_manager::IGDManager,
natpmp_manager: natpmp_manager::NATPMPManager,
}
#[derive(Clone)]
@ -108,6 +116,7 @@ impl Network {
routing_table: RoutingTable,
connection_manager: ConnectionManager,
) -> NetworkUnlockedInner {
let config = network_manager.config();
NetworkUnlockedInner {
network_manager,
routing_table,
@ -115,6 +124,10 @@ impl Network {
interfaces: NetworkInterfaces::new(),
update_network_class_task: TickTask::new(1),
network_interfaces_task: TickTask::new(5),
upnp_task: TickTask::new(1),
natpmp_task: TickTask::new(1),
igd_manager: igd_manager::IGDManager::new(config.clone()),
natpmp_manager: natpmp_manager::NATPMPManager::new(config),
}
}
@ -151,6 +164,20 @@ impl Network {
Box::pin(this2.clone().network_interfaces_task_routine(s, l, t))
});
}
// Set upnp tick task
{
let this2 = this.clone();
this.unlocked_inner
.upnp_task
.set_routine(move |s, l, t| Box::pin(this2.clone().upnp_task_routine(s, l, t)));
}
// Set natpmp tick task
{
let this2 = this.clone();
this.unlocked_inner
.natpmp_task
.set_routine(move |s, l, t| Box::pin(this2.clone().natpmp_task_routine(s, l, t)));
}
this
}
@ -257,6 +284,17 @@ impl Network {
}
}
pub fn get_local_port(&self, protocol_type: ProtocolType) -> u16 {
let inner = self.inner.lock();
let local_port = match protocol_type {
ProtocolType::UDP => inner.udp_port,
ProtocolType::TCP => inner.tcp_port,
ProtocolType::WS => inner.ws_port,
ProtocolType::WSS => inner.wss_port,
};
local_port
}
fn get_preferred_local_address(&self, dial_info: &DialInfo) -> SocketAddr {
let inner = self.inner.lock();
@ -749,11 +787,47 @@ impl Network {
Ok(())
}
#[instrument(level = "trace", skip(self), err)]
pub async fn upnp_task_routine(
self,
stop_token: StopToken,
_l: u64,
_t: u64,
) -> EyreResult<()> {
if !self.unlocked_inner.igd_manager.tick().await? {
info!("upnp failed, restarting local network");
let mut inner = self.inner.lock();
inner.network_needs_restart = true;
}
Ok(())
}
#[instrument(level = "trace", skip(self), err)]
pub async fn natpmp_task_routine(
self,
stop_token: StopToken,
_l: u64,
_t: u64,
) -> EyreResult<()> {
if !self.unlocked_inner.natpmp_manager.tick().await? {
info!("natpmp failed, restarting local network");
let mut inner = self.inner.lock();
inner.network_needs_restart = true;
}
Ok(())
}
pub async fn tick(&self) -> EyreResult<()> {
let detect_address_changes = {
let (detect_address_changes, upnp, natpmp) = {
let config = self.network_manager().config();
let c = config.get();
c.network.detect_address_changes
(
c.network.detect_address_changes,
c.network.upnp,
c.network.natpmp,
)
};
// If we need to figure out our network class, tick the task for it
@ -776,6 +850,16 @@ impl Network {
}
}
// If we need to tick upnp, do it
if upnp && !self.needs_restart() {
self.unlocked_inner.upnp_task.tick().await?;
}
// If we need to tick natpmp, do it
if natpmp && !self.needs_restart() {
self.unlocked_inner.natpmp_task.tick().await?;
}
Ok(())
}
}

View File

@ -0,0 +1,18 @@
use super::*;
pub struct NATPMPManager {
config: VeilidConfig,
}
impl NATPMPManager {
//
pub fn new(config: VeilidConfig) -> Self {
Self { config }
}
pub async fn tick(&self) -> EyreResult<bool> {
// xxx
Ok(true)
}
}

View File

@ -3,6 +3,7 @@ use super::*;
use futures_util::stream::FuturesUnordered;
use futures_util::FutureExt;
use stop_token::future::FutureExt as StopTokenFutureExt;
use tokio::task::spawn_blocking;
struct DetectedPublicDialInfo {
dial_info: DialInfo,
@ -213,7 +214,39 @@ impl DiscoveryContext {
#[instrument(level = "trace", skip(self), ret)]
async fn try_port_mapping(&self) -> Option<DialInfo> {
//xxx
let (enable_upnp, enable_natpmp) = {
let c = self.net.config.get();
(c.network.upnp, c.network.natpmp)
};
if enable_upnp {
let (pt, llpt, at, external_address_1, local_port) = {
let inner = self.inner.lock();
let pt = inner.protocol_type.unwrap();
let llpt = pt.low_level_protocol_type();
let at = inner.address_type.unwrap();
let external_address_1 = inner.external_1_address.unwrap();
let local_port = self.net.get_local_port(pt);
(pt, llpt, at, external_address_1, local_port)
};
if let Some(mapped_external_address) = self
.net
.unlocked_inner
.igd_manager
.map_any_port(llpt, at, local_port, Some(external_address_1.to_ip_addr()))
.await
{
// make dial info from the port
return Some(
self.make_dial_info(
SocketAddress::from_socket_addr(mapped_external_address),
pt,
),
);
}
}
None
}

View File

@ -103,6 +103,8 @@ cfg_if! {
pub use tokio::sync::Mutex as AsyncMutex;
pub use tokio::sync::MutexGuard as AsyncMutexGuard;
pub use tokio::task::JoinHandle as LowLevelJoinHandle;
} else {
#[compile_error("must use an executor")]
}
}
pub use std::net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };

View File

@ -96,7 +96,7 @@ core:
min_peer_count: 20
min_peer_refresh_time_ms: 2000
validate_dial_info_receipt_time_ms: 2000
upnp: false
upnp: true
natpmp: false
detect_address_changes: true
enable_local_peer_scope: false
@ -1500,7 +1500,7 @@ mod tests {
2_000u32
);
//
assert_eq!(s.core.network.upnp, false);
assert_eq!(s.core.network.upnp, true);
assert_eq!(s.core.network.natpmp, false);
assert_eq!(s.core.network.detect_address_changes, true);
assert_eq!(s.core.network.enable_local_peer_scope, false);